Contracts

collection-store.md

Contract: collection store and reuse evidence

collect_universe(repo_root: Path | None = None) -> list[TestRecord]

The signature and return value are unchanged. For identical inputs the returned list is equal, element for element, to what a fresh collection returns.

SituationStore readStore writtenReport outcome / reason
repo_root passednonobypassed / root-override
checkout has uncommitted changesnonobypassed / dirty-checkout
platform or store unusablenonobypassed / unsupported-platform
git cannot describe the checkoutnonobypassed / git-unavailable
lock or store errornonobypassed / unsupported-platform, with detail
operator env file exists but cannot be readnonobypassed / env-file-unreadable, with detail
valid record, matching key and originyesnoreused
no record for keyyesyes, after a successful collectioncollected / no-record
record unreadable, wrong schema, empty, below the 1,000-record sanity floor, count mismatchyesyes, replaced after a successful collectioncollected / invalid-record
record key matches, commit or tree differsyesyes, replacedcollected / origin-mismatch
collection fails—nonone; the existing RuntimeError is raised unchanged

Concurrency: for one key, at most one collection runs at a time on a machine; other callers block on the lock and then reuse.

python -m scripts.ci.collect_universe_prestep <command>

CommandBehaviourExit
keyprints the collection key for the current checkout and environment (used as the CI cache key)0; 2 when the checkout is dirty
collectcalls collect_universe() once; prints the report line0 only when its line is reused, or collected with the record stored, or bypassed / unsupported-platform with no detail; non-zero otherwise (dirty checkout, git unavailable, lock or store failure, record not stored, collection failure, no report line)
checkreads the report file, writes a table to the job summary, and compares with the pre-test step's outcome1 when the pre-test step's own line is anything other than reused, a stored collected, or bypassed / unsupported-platform with no detail; 1 when the pre-test step stored or reused a record and any later line is collected, or bypassed for a reason other than root-override; 1 on a malformed line; 0 otherwise. Fallback mode (exit 0 with a note) applies only when there is no report file, an empty report, or no prestep line
compareperforms one fresh collection with the store bypassed and diffs it against the stored record1 on any difference or when no stored record exists; 0 when equal

Workflow shape (pinned by test)

In each consuming job, in this order: compute key → restore store (guarded on a non-empty key) → collect → save store → pytest (unchanged command) → check with if: always(). The save does not depend on pytest's outcome. The pytest command line of each job is byte-identical to today's.

scheduled-recapture.md

Contract: generalised scheduled recapture

python -m scripts.ci.recapture_shard_timings

OptionMeaning
--module NAME (repeatable)restrict to these registry modules; default is every registry module
--budget-seconds Nstop starting captures once N seconds have elapsed
--writewrite refreshed data through the canonical producer; without it, report only

Behaviour, in order:

1. Count-only pass: collect each candidate module's test count without running tests. 2. A module is drifted when its collected count differs from the committed count, or its provenance record is missing or not valid. 3. For each drifted module, longest-untouched first, while budget remains: run the canonical producer for that module in its own subprocess. 4. A capture is valid when its exit status is 0 or 1 and it recorded at least one duration (the shared predicate). An invalid capture leaves that module's committed data byte-identical. 5. Shard counts are not touched by the script; the existing skew check reports a count that no longer fits. 6. Print a machine-readable result (drifted, captured, failed, deferred) and a job-summary table.

Exit status: 0 when nothing failed (including "nothing drifted"); 1 when any capture failed.

Workflow

  • Triggers and the primary-branch gate are unchanged.
  • A rejected push exits non-zero with a message naming the missing repository permission and the secret that supplies the token.
  • Publication: no drift → no proposal. Drift and no open proposal → push the fixed proposal branch and open a pull request. Drift and an open proposal → add a follow-up commit on that branch (never a forced push).
  • The strict agreement check stays in the same workflow as an independent job (no ordering between it and the recapture job, as before).

Provenance completeness (tests/architectural/test_shard_capture_provenance.py)

  • Every module in .github/ci-module-registry.yml has a valid provenance record; a failure names the module.
  • Self-mutation: removing one module's provenance, and replacing it with an invalid record, each make the check fail on the same data.
  • Shard counts are covered by the existing skew check in tests/architectural/test_module_shard_registry.py; this mission adds no second check.