type: reference updated: 2026-10-13 mission: derived-consumer-census-01M4V5P5


Data model — the consumer census artifact

The census is a committed JSON artifact at .github/ci-consumer-census.json, regenerated by scripts/ci/consumer_census.py and read by the routing gate and the fan-out derivation. It is deterministic: keys sorted, lists sorted, provenance stable, so a re-run on an unchanged tree reproduces it byte-for-byte (NFR-003).

Schema

{
  "schema_version": 1,
  "description": "Derived consumer census (#6173): per test module, the src/** and packs/** paths its tests consume. Regenerate with `python scripts/ci/consumer_census.py --write`.",
  "generated_by": "scripts/ci/consumer_census.py",
  "modules": {
    "<module>": {                     // a registry module name (ci-module-registry.yml modules[].module)
      "consumes": [
        {
          "path": "<repo-relative src/** or packs/** path or glob>",
          "provenance": "static-import" | "static-read" | "static-literal" | "runtime",
          "via": "<short evidence, e.g. tests/next/test_discovery_step_contract.py>"
        }
      ]
    }
  }
}

Fields

_registry_module_names() (so a #6164 module-set change flows through; NFR-002). Only modules with ≥1 consumed src//packs/ path beyond their own roots appear (the census records the fan-out-relevant consumption, not a module's trivial self-ownership).

consume. Exact file when the consumer names/opens one file; a glob (packs/built-in/missions/mission-steps/**) when the consumer reads a whole sub-tree.

static scan did not name (the tests/next prompt case).

human review and gate diagnostics.

  • modules — keyed by registry module name, derived at build time from
  • consumes[].path — a repo-relative path or glob the module's tests
  • consumes[].provenance:
  • static-import — a test imports a src/** module (resolved to its file).
  • static-read — a test opens/reads a named src//packs/ file.
  • static-literal — a path string-literal appears in the test source.
  • runtime — captured by the audit-hook harness as a resolver-driven open the
  • consumes[].via — the test file (or harness case) that evidences it, for

Attribution

A consumed path is attributed to a module when the consuming test file lives in that module's test_dirs (or canonical mirror), using the same registry derivation gate_selection._modules_for_test_paths already trusts. A test file in multiple modules' test_dirs attributes to each (overlap preserved, never narrowed — matching select_modules).

How the gate and derivation read it

(module, consumes[].path), assert select_modules([path]) ⊇ {module}. A path matching no routing group (or only src groups that do not select the module, with no non-src fan-out group covering it) → the module is absent → RED. The authority for "which group does this path belong to" is the router globs (load_router), independent of the derived fan-out, so the check is not vacuous.

router group G, fanout[G] = { module : census has a consumed path P with provenance evidencing consumption, P matches a glob of G, and module ∉ base-select_modules(P) }. The base selection excludes the fan-out union to avoid self-reference. The result equals the known sets the existing test_group_module_fanout_is_wired pins (cross-check; NFR-001).

  • Routing gate (test_consumer_census_routing.py): for each
  • Fan-out derivation (gate_selection.GROUP_MODULE_FANOUT): for each non-src

Determinism contract

order, no network).

build_census() == json.load(committed) so a drift reds the ci module.

  • The artifact is sorted (modules, consumes by (path, provenance, via)).
  • The runtime capture enumerates a fixed set of resolver invocations (no random
  • A unit test (tests/ci/test_consumer_census.py) asserts