feat(adr-0067): cross-pack teaching chains — Plan Phase 4 closed
ADR-0064 bound each teaching corpus 1:1 to a single ratified pack;
chains whose subject + object resolved to different packs were
dropped at load time. Phases 1–3 ratified the per-pack DAGs needed
to lift that constraint safely.
ADR-0067 introduces a deliberately narrow cross-pack chain shape.
Each entry carries explicit subject_pack_id and object_pack_id
fields, and the loader verifies per-chain residency. Same-pack
entries are rejected as corpus-misfilings (anti-leakage). The
cross-pack composer is the fall-through after the in-pack composer,
so the cognition lane stays byte-identical.
Files:
- chat/cross_pack_grounding.py — CrossPackChain + loader +
single-chain composer + multi-chain enumerators
- teaching/cross_pack_chains/cross_pack_chains_v1.jsonl — 5 seed
chains (family×identity, parent×understanding, family×memory,
identity×family, understanding×parent)
- chat/runtime.py — fall-through wiring in CAUSE/VERIFICATION
- chat/narrative_surface.py, chat/example_surface.py — merge
cross-pack chains, per-chain pack-residency helpers
- tests/test_cross_pack_chains.py — 31 tests covering loader,
surface, multi-chain access, runtime integration, in-pack
precedence
- tests/test_narrative_example_intents.py — corpus-tag assertions
widened to allow cross-pack aggregation
Verification:
- 31 new tests pass
- Curated lanes: smoke 67 / cognition 121 / teaching 17 / packs 6 /
runtime 19 — all green
- Cognition eval byte-identical (public 100/100/91.7/100, holdout
100/100/83.3/100)
- Full lane: 2098 passed, 2 skipped, 0 failed in 2:30