Discovery Integrity Audit Guide¶
Use this audit when a workflow learns its sample set from files and you need to answer a precise question:
What declared change tells Snakemake that discovery must run again?
A checkpoint can alter a DAG after it runs. That fact does not make every future change to the outside world visible to Snakemake. The audit isolates that distinction with two tiny workflows, the same arrival experiment, and four execution receipts for each workflow.
The result you are trying to explain¶
Run:
The evidence bundle is written under the repository-level artifacts/audit/ tree. Start
with:
route.txtsummary.tsv- the two
change-dryruntraces - the two specimen
Snakefilefiles report.json- the forced-run traces
Do not begin with the forced runs. They answer what discovery could find when compelled to run. The change dry-runs answer whether the workflow knew it needed to run.
The two models¶
Both models begin with one raw file named alpha.fastq. Both checkpoints write a
manifest, and both downstream input functions turn that manifest into output targets.
Their only important difference is the checkpoint input contract.
flowchart LR
registry["data/arrivals.tsv"] --> governed["governed checkpoint"]
rawA["data/raw/alpha.fastq"] --> materializeA["materialize alpha"]
governed --> manifestA["state/discovered.txt"]
manifestA --> materializeA
ambient["ambient directory listing"] -.hidden read.-> scan["ambient checkpoint"]
rawB["data/raw/alpha.fastq"] --> materializeB["materialize alpha"]
scan --> manifestB["state/discovered.txt"]
manifestB --> materializeB
The governed model declares data/arrivals.tsv as the checkpoint input. The ambient
model reads data/raw/ inside its run block but declares no input.
That is not a style difference. It changes the invalidation graph.
The arrival experiment¶
The audit performs the same sequence against clean copies of both models:
- execute the baseline with only
alpha; - add raw files for
betaandgamma; - add only
betato the governed arrival registry; - ask Snakemake for a dry-run;
- execute normally;
- force the discovery checkpoint and execute again.
sequenceDiagram
participant A as Audit
participant G as Governed model
participant H as Ambient model
A->>G: run alpha baseline
A->>H: run alpha baseline
A->>G: add beta + gamma, register beta
A->>H: add beta + gamma
A->>G: dry-run
G-->>A: discovery and beta are planned
A->>H: dry-run
H-->>A: nothing to do
A->>G: normal execution
G-->>A: alpha, beta
A->>H: normal execution
H-->>A: alpha
A->>H: force discovery
H-->>A: alpha, beta, gamma
gamma matters. Its presence proves that the registry is an ownership boundary, not
merely a timestamp trigger. The governed model does not silently absorb every matching
file beside a registered arrival.
Read the dry-runs before the outputs¶
For the governed model, the change dry-run should contain a checkpoint discover job.
The registry changed, so Snakemake has a declared causal path:
arrival registry changed
-> checkpoint is stale
-> discovery manifest is rebuilt
-> downstream target function is reevaluated
-> beta output enters the DAG
For the ambient model, the change dry-run should say that there is nothing to do. The directory contains new information, but no declared input changed. Snakemake is not watching every read performed inside Python or shell code.
This is the critical review sentence:
The ambient model contains discovery logic, but it does not contain a discovery invalidation contract.
Interpret the normal and forced executions¶
The four sample lists in summary.tsv separate scope from capability:
| Model | Normal execution after arrivals | Forced reevaluation | Meaning |
|---|---|---|---|
| governed registry | alpha,beta |
alpha,beta |
the declared event reruns discovery, and registry membership bounds scope |
| ambient scan | alpha |
alpha,beta,gamma |
the code can find arrivals, but ordinary scheduling does not know when to invoke it |
A forced run is diagnostic evidence. It is not a repair. A production instruction that says “remember to force the checkpoint whenever files might have arrived” transfers a workflow invariant into human memory.
What PASS means¶
The audit reports two PASS findings, but they do not endorse both designs.
DECLARED_DISCOVERY_INVALIDATION_PRESERVED means:
- the governed checkpoint visibly declares the registry;
- the baseline contains only
alpha; - changing the registry schedules discovery;
- normal execution adds registered
beta; - unregistered
gammaremains out of scope.
AMBIENT_DISCOVERY_STALENESS_REPRODUCED means:
- the counterexample really has no checkpoint input;
- the baseline contains only
alpha; - ambient arrivals do not change the normal plan;
- normal execution remains stale;
- forced reevaluation proves the hidden scan could see all arrivals.
The second PASS means “the named failure was reproduced honestly.” Read finding
together with result.
Why a checkpoint is still involved¶
If the registry already names every sample, you might ask why a checkpoint is needed. In this specimen, the checkpoint exists to isolate reevaluation behavior. In a real workflow, an upstream job might produce a registry of accepted samples only after validating delivery metadata, decompressing an archive, or reading tool output.
Use a checkpoint only when an executed job reveals information needed to construct later jobs. If a stable config file already contains the final sample list, ordinary input functions are usually enough.
This yields a decision table:
| Situation | Suitable model |
|---|---|
| sample list is known before execution | config or a checked sample sheet |
| candidate arrivals are governed, but execution validates which are accepted | declared registry input followed by a checkpoint |
| a directory is scanned during workflow parsing | acceptable only when the directory snapshot is an explicit operational assumption |
| a directory is scanned inside a checkpoint with no declared invalidation event | incomplete contract |
Connect the specimen to the capstone¶
The capstone uses data/raw/arrivals.tsv as the governed event. Its path column names
candidate FASTQ files relative to the registry's data/raw/ directory. The checkpoint:
- declares the registry as an input;
- validates the registry structure;
- rejects duplicate, escaping, missing, and pattern-mismatched paths;
- derives stable sample identities;
- records the registry path and digest in
discovered_samples.json; - lets downstream input functions construct sample-specific jobs.
Adding a raw file by itself does not add a sample. Updating the governed registry does. That boundary is deliberate: filesystem proximity is not consent to process data.
Failure diagnosis¶
Use the first failing observation, not the last missing file.
| Observation | Likely contract defect | First inspection |
|---|---|---|
| registry changed, dry-run says nothing to do | registry is not a checkpoint input | checkpoint input: block |
| discovery runs, but a registered sample is absent | parser, validation, or sample-name collision | discovery log and manifest |
| an unregistered file enters the DAG | discovery reads ambient directory membership | discovery implementation |
| dry-run schedules discovery forever | checkpoint output is unstable or its declared input is rewritten | timestamps, content stability, and producers |
| forced run sees files that normal execution misses | hidden invalidation dependency | checkpoint inputs and upstream event artifact |
Test whether the gate is discriminating¶
Run:
The self-test checks the accepted experiment, removes the registry input declaration, and damages the ambient counterexample so forced reevaluation can no longer reveal new arrivals. A trustworthy audit must fail when either causal distinction disappears.
A bounded extension¶
Copy the governed specimen into an artifact workspace. Add a second registry column named
delivery_id, then change the checkpoint output to record both the sample and delivery.
Keep only the sample column responsible for downstream fanout.
Before running anything, predict:
- which file change invalidates discovery;
- whether changing only
delivery_idshould rebuild downstream sample outputs; - where the delivery metadata should remain visible for review;
- what evidence would distinguish a metadata-only rebuild from a sample-domain change.
The point is not to maximize dynamism. It is to make the boundary between arrival evidence, accepted membership, and downstream targets explainable.
Review checklist¶
- I can point to the declared event that invalidates discovery.
- I read the normal dry-run before treating a forced run as evidence.
- I can distinguish files present on disk from files admitted to workflow scope.
- I can explain why the checkpoint is needed after execution rather than at parse time.
- I can name the artifact that records the discovered set.
- I can show that the audit fails when the invalidation edge is removed.
- I do not claim that a checkpoint automatically watches hidden filesystem state.