clay-borg/workplans/CB-WP-0048-a-configuration-not-a-variant.md
tegwick 75080beb03
Some checks are pending
ci / check (push) Waiting to run
CB-WP-0048: conform task headings to the parser's shape
status.py resolves `## Task: <text>` immediately above a task block;
`## Task T00:` resolved to nothing and the gate said so.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 22:09:58 +02:00

5.7 KiB

id kind title status
CB-WP-0048 product A configuration, not a variant in_progress

Purpose

structural tier  M   (changes the state and therefore the recording, and
                      replaces the selector every consumer names)
declared tier    M

Implements ADR-0022, adopting ground-game catalog schema 2 per CB-RES-0010.

The gap, stated exactly

scoped_plus_attack_soothe is a profile in the vendored catalog today. clay-borg cannot name it — not "has not implemented", cannot express. Variant has three arms; H1 bundles flat pressure with self-soothe and cannot be taken apart, H2 gives scoping alone, and their product has no arm. Every future combination has the same problem.

The kernel is not the obstacle: four sites branch on the variant and each belongs to exactly one aspect (ADR-0022 Context). The selector is the blob.

Task: the mirror is held by the gate

id: CB-WP-0048-T00
status: done
priority: high

Done 2026-08-08. The schema-2 mirror (catalog.yaml, ASPECTS.md, CATALOG.md, modules/) arrived vendored with no recorded digests — 19 files — and make edition-check was red on the working tree.

  • Digests are now generated by walking editions/, not typed. Two reviews (CB-REV-0002 #8, CB-REV-0003 #8) already found hand-written lists that made their own controls vacuous; a mirror that grows a directory is precisely the case a maintained list loses.
  • editions/PROVENANCE-catalog.md was a file inside the mirrored tree that upstream does not have, which the gate correctly refused as unexplained. Folded into editions/ground-darvo-r0/PROVENANCE.md — provenance about the mirror is ours, so it does not live inside the thing it describes.

Noted, not fixed: vendored_files() matches only .csv inside the edition directory, so a non-CSV added there is invisible to both the digest and the freshness check. The sibling walk has no such hole. The exposure is one file today (PROVENANCE.md, ours) — but this is F26's shape again and should be closed on its own terms.

Task: Configuration and Rules

id: CB-WP-0048-T01
status: todo
priority: high

Per ADR-0022 D1. Identity as data, behaviour exhaustive, resolve() between them.

Controls:

  • a proposed module is refused BY NAME, distinguishably from a typo — the two-error requirement is the reason this shape was chosen, so it is the first test;
  • two modules on one aspect are refused (GAME↔MODEL validation);
  • an aspect the catalog has and the kernel does not know still parses, because a configuration must be nameable before it is runnable;
  • Rules has no catch-all arm, so a new module cannot fall through silently (CB-WP-0034's exhaustiveness, which caught two commands before any test ran);
  • mutation-proven, each control against its own defect.

Task: legacy ids alias forever

id: CB-WP-0048-T02
status: todo
priority: high

Per ADR-0022 D2, through the catalog's own legacy_experiment_id.

Controls:

  • all 26 recordings replay byte-identically, which is the whole constraint — make sim is the authority;
  • --variant h2 and --profile h2 produce the same resolved configuration, asserted on the resolved object rather than on behaviour, so the equivalence is exact and not a coincidence of outcomes;
  • the expansion comes from the catalog, not a table in our source: a second copy of ground-game's mapping is F25's shape.

Task: the resolved configuration is recorded

id: CB-WP-0048-T03
status: todo
priority: high

Per ADR-0022 D3 and CB-RES-0010 §5.3: cb-play sessions, replays, trial logs and panel cells carry the resolved module list.

Controls:

  • the recorded configuration is the applied one, proven the way CB-WP-0046 proved the trial-log stamp — from the state, not the flag;
  • the trial-log marker carries the configuration, closing the gap CB-WP-0047 left open (variant stamped, scenario and mode not);
  • a bare field write cannot leave a module inert — the H2 defect had three call sites and this is the generalisation of it.

Task: the page and the panels speak aspects

id: CB-WP-0048-T04
status: todo
priority: normal

Controls:

  • the table names every live module, not a legacy id — the CB-WP-0044 family: a rules change the page cannot name is reported as "no changes";
  • panels facet by aspect (CB-RES-0010 §5.4), so "hold all aspects fixed, vary one" is what the harness does rather than what a reader reconstructs;
  • a module nothing measured is reported unmeasured, not absent.

Not done here

  • No policy reads the configuration. F27 already records that the three scoring modes produce identical play because GreedyPolicy never consults state.mode; the same will be true of every aspect. Selection without aspect-aware policies gives configurations we can run and cannot evaluate — CB-RES-0010 §5.4's last bullet is F27 restated. This is the next pass, and it is a prerequisite for measuring any new module, not a nicety.
  • end_condition and problem_deal get no kernel path here. Both their non-default modules are status: proposed; T01 makes them nameable and refusable, which is what ADR-0022 asks for and all it asks for.
  • specs/Taxonomy.md does not yet distinguish aspect from stratum. ADR-0022 D0 states the distinction; the taxonomy is where it belongs, and without it the two vocabularies will be crossed in exactly the way the taxonomy exists to prevent.