From exploration to reproducible computation#
Reproducibility is a chain of distinct operations, not a single download button. LunarTrace makes that chain explicit so a user can see which evidence is retained and which step still needs to run.
What the web exports#
Object |
Contains |
Does not contain |
|---|---|---|
Shared draft URL |
Research reference, query intent, windows, and scope |
Captured archive population or response bytes |
Draft JSON |
Validated exploratory intent and requested objectives |
An admitted Study or source capture |
Captured investigation JSON |
Draft, query, source-response bytes/hashes, normalized exploratory rows, included identities, and any current exploratory pair result |
Remote browse image bytes or automatic canonical admission |
View CSV |
Current visible observation rows and selected metadata |
A complete scientific bundle or all hidden source receipts |
The Lab envelope is named EXPLORATORY_LAB_EXPORT and versioned lunartrace-lab/2. It deliberately does not impersonate the Python CompiledStudy, ArchiveSnapshot, or canonical manifest schema.
Stage 1 — audit the captured metadata bytes#
uv run python tools/reproduce_lab.py lunartrace-lab-export.json
This bounded, offline operation checks the export type, draft conventions, fixed source profile, raw metadata-response byte lengths, and SHA-256 identities. It reports how many supplied response pages and bytes were checked.
The result explicitly does not verify normalized rows as canonical Python objects, authenticate the archive independently, prove query closure, verify image pixels, or establish scientific truth. A person can create a self-consistent file; a self-consistency check does not prove its origin.
Stage 2 — explicitly acquire a new point capture#
uv run python tools/reproduce_lab.py lunartrace-lab-export.json --acquire .build/lab-capture
The bridge translates user-defined point intent into a new LunarEvent and a StudyProtocol using real Python classes. It then invokes the existing bounded ODE client.
This is a fresh acquisition, not a replay of the browser population. The archive may have changed. The newly captured Python rows, receipts, closure, and currentness are the evidence for subsequent compilation.
The bridge rejects box intent because the current canonical compiler is point-based. It also requires an explicit supported objective set. It does not silently choose a different methodology because a field is missing.
Stage 3 — compile the new complete capture#
uv run python tools/reproduce_lab.py lunartrace-lab-export.json --acquire .build/lab-capture --compile-to .build/lab-study
For this continuation command, compilation is withheld if the new source capture is not complete. When it is complete, the tool invokes the real Compiler, passes the new typed capture and observations, and exports the candidate with its raw-response dependencies.
The new candidate may differ from the browser projection. The browser uses an exploratory representation, an explicitly included subset, interactive execution bounds, and time displays in days; the canonical compiler receives its own typed source capture and protocol.
Important
The continuation performs a new point query and compiles that new captured population. It does not silently carry a browser-only manual subset into the canonical population or claim exact reproduction of the browser’s exploratory frontier.
Stage 4 — verify the candidate bundle#
uv run lunartrace verify .build/lab-study
uv run lunartrace reproduce .build/lab-study
Verification inspects contracts, byte identities, manifest/reference consistency, dependencies, and supported replay. A compiled row-bearing Study has a different replay ceiling from the historical aggregate.
Scientific admission and interpretation remain distinct from successful computation and verification. The product does not automatically turn a compiled candidate into a public scientific claim.
Direct Python composition#
For workflows that already hold a valid ODEAcquisition, the existing building blocks are:
from lunartrace import Compiler
from lunartrace.bundles import export_study
# event, protocol, and acquisition are real typed inputs from your workflow.
# This is an interface composition, not a fabricated lunar-data example.
study = Compiler().compile(
event,
protocol,
acquisition.capture.snapshot,
acquisition.capture.observations,
source_mode="LIVE",
)
manifest = export_study(
study,
output_directory,
acquisition.payloads(),
)
The compiler checks query applicability, row identity/counts, source-response membership, data Standing, and protocol/screener consistency. Supplying plausible-looking rows without those relationships is not sufficient.
Preserve the full dependency trail#
Keep exact source revision, protocol, event/reference basis, source responses, normalized rows, candidate results, and exported manifest together. A filename or a URL is a locator; it is not a substitute for content identity.
Use new output directories for distinct acquisitions or Studies. Do not overwrite a previously cited result merely because its friendly name is convenient.