Three small surgical anchors capturing the verified architectural insight surfaced during the ADR-0167 wave (no new ADR — the gap claim that prompted this resolved on verification; what remains is a sharper residual question worth memorialising). 1. CLAUDE.md — new "Schema-Defined Proof Obligations" section between Documentation Discipline and Validation Through CLI. Generalises the wrong=0 invariant pattern: schema types that name structural properties are real only when an executing test can meaningfully fail under the violations it is written to catch. Three-step rule for treating a schema as load-bearing. 2. language_packs/compiler.py — ARCHITECTURAL INVARIANT comment on _apply_mounted_primary_domain_resonance naming it as the single convergence-decision site for DEPTH_ROOT/DEPTH_RELATION packs. Anchors the doctrine at the code site so any future modification trips on the reference to the holonomy proof's coverage gap. 3. docs/handoff/ADR-0167-FOLLOWUPS.md §6 — captures the structural-vs- blend convergence isolation question. HolonomyAlignmentCase IS executed today (we verified), but the existing test doesn't distinguish structurally-derived convergence from blend-induced convergence. Ablation test or reframed claim — both acceptable resolutions. Verified before commit: - All 13 architectural references in the Gemini analysis resolve exactly: triliteral 0.30, root 0.40, prefix 0.03/(idx+1), stem 0.24, _INFLECTION_PRIORITY case-near-last, _apply_mounted_primary_domain_resonance with 40% English-prototype blend, HolonomyAlignmentCase defined AND executed - tests/test_alignment_graph.py: 8 passed (no behavioural change) - Documentation discipline (#355) honoured: pure Markdown, no HTML No code behaviour changes. No runtime effect. Drops the larger ADR-0168-PROPOSAL idea — the gap claim that prompted it dissolved under verification.
288 lines
13 KiB
Markdown
288 lines
13 KiB
Markdown
# ADR-0167 — Follow-ups Queue
|
|
|
|
**Date opened:** 2026-05-27 (end of Wave 3)
|
|
**Parent:** [ADR-0167](../decisions/ADR-0167-audit-as-teaching-evidence.md)
|
|
**Companion:** [SESSION-2026-05-27](../decisions/SESSION-2026-05-27-adr-0167-parallel-dispatch.md)
|
|
|
|
The LexicalClaim slice landed clean (W1-A → W2-A/B/C/D → W3-A merged
|
|
2026-05-27). This file captures the named follow-ups that surfaced
|
|
during the wave and were deliberately deferred so the slice could
|
|
converge. The next operator picking up ADR-0167 work should walk this
|
|
queue top-down and decide which item the project's current capability
|
|
gate actually needs.
|
|
|
|
Each item: scope, why deferred, where the breadcrumbs live, and the
|
|
acceptance criterion that would close it.
|
|
|
|
---
|
|
|
|
## 1. Frame-opener sub-types (FrameClaim / CompositionClaim / ReferenceClaim / SlotClaim)
|
|
|
|
**Scope.** Four additional ratification handlers, one per remaining
|
|
sub-type in `SUB_TYPE_FOR_OPERATOR`:
|
|
|
|
| Sub-type | Maps from | Ratification primitive |
|
|
|---|---|---|
|
|
| `FrameClaim` | `pre_frame_filler_sentence`, `multi_subject_sentence` | Verb-category reclassification |
|
|
| `CompositionClaim` | `multi_quantity_composition`, `quantity_extraction` | Frame-split rule |
|
|
| `ReferenceClaim` | `pronoun_resolution` | Anaphora-resolution entry |
|
|
| `SlotClaim` | `question_frame_slot`, `unit_binding`, `question_target_slot`, `descriptive_frame_question` | Slot-completion table entry |
|
|
|
|
**Why deferred.** ADR-0167 §"Proposed sub-type set" explicitly chose
|
|
LexicalClaim-first because it is the lowest-risk surface (drain_token
|
|
additions cannot create wrong admissions without also passing graph
|
|
completeness). The other four touch frame-opener decisions, anaphora,
|
|
or slot bindings — each is a new admission path multiplying the
|
|
`wrong=0` surface area, and each needs its own scoping ADR with the
|
|
six open questions from ADR-0167 §"Open questions" answered for that
|
|
sub-type's mechanics.
|
|
|
|
**Where breadcrumbs live.**
|
|
- `teaching/math_evidence.py::SUB_TYPE_FOR_OPERATOR` — already maps
|
|
the operator labels; no schema change needed
|
|
- `teaching/math_lexical_ratification.py` — the template for what a
|
|
sub-type handler looks like (preconditions, receipt, idempotency,
|
|
hazard pins)
|
|
- `tests/test_math_lexical_ratification.py::test_rejects_non_lexical_sub_type`
|
|
— pins that non-lexical claims currently raise `WrongClaimSubType`;
|
|
each new handler retires its corresponding rejection
|
|
|
|
**Acceptance.** Each new sub-type ships as an ADR (likely ADR-0168,
|
|
ADR-0169, ...) followed by a wave of PRs analogous to ADR-0167's W2-D.
|
|
Each handler must:
|
|
- declare its own `SAFE_CATEGORIES` allowlist analogous to W2-D's
|
|
`{"drain_token"}`
|
|
- preserve the case 0050 hazard pin (see [[feedback-wrong-zero-hazard-case-0050]])
|
|
- carry the same idempotency / evidence-tampering / unknown-category
|
|
guards W2-D established
|
|
- pass an e2e ratification → row-movement test analogous to
|
|
`test_lexical_ratification_advances_unknown_word_row`
|
|
|
|
**Priority hint.** FrameClaim is the highest-leverage next sub-type
|
|
(9 cases in the current taxonomy under `pre_frame_filler_sentence`),
|
|
but also the riskiest — frame-opener miscategorisation is exactly the
|
|
case 0050 hazard. CompositionClaim (8+11 cases) is the next-highest
|
|
count, also high-risk. ReferenceClaim (3 cases) and SlotClaim (smaller
|
|
buckets) are lower-leverage but structurally simpler.
|
|
|
|
---
|
|
|
|
## 2. Partition test architectural fix
|
|
|
|
**Scope.** Reframe or retire
|
|
`tests/test_candidate_domain_partition.py::test_existing_cognition_tests_untouched`.
|
|
|
|
**Why deferred.** The current test uses `git status --porcelain` at
|
|
test runtime to enumerate modified files, then asserts each name is in
|
|
a named allowlist. Opus's W3-A report flagged this as structurally
|
|
brittle: every future ADR-0167 PR has to edit the allowlist or the
|
|
test fails, regardless of whether the PR actually touched cognition
|
|
behaviour. Opus loosened from a single literal to a named set in W3-A
|
|
as a tactical fix, but the architectural problem remains — a partition
|
|
invariant doesn't belong as a git-state assertion in a pytest run.
|
|
|
|
**Where breadcrumbs live.**
|
|
- `tests/test_candidate_domain_partition.py::test_existing_cognition_tests_untouched`
|
|
— the current implementation
|
|
- W3-A's PR description (#357) — the deeper brittleness flag in
|
|
Opus's report-back
|
|
|
|
**Acceptance.** One of:
|
|
- **(a) Retire the test entirely** — partition is already enforced
|
|
structurally by the `domain` field default + type discriminator;
|
|
the cognition test suite already runs against every PR and would
|
|
break naturally if a PR modified cognition behaviour
|
|
- **(b) Move to CI** — a GitHub Actions workflow that runs `git diff
|
|
--name-only origin/main...HEAD -- tests/` and fails on any cognition
|
|
test path modification, with CODEOWNERS providing the human review
|
|
layer
|
|
- **(c) Reframe as a diff-review constraint** — drop the test, add a
|
|
CODEOWNERS entry requiring a cognition reviewer for any PR touching
|
|
`tests/test_*cognition*.py` or similar
|
|
|
|
Pick whichever fits the project's CI discipline. Option (a) is
|
|
simplest if the assertion is genuinely redundant; (b) is most precise;
|
|
(c) is most operator-friendly.
|
|
|
|
---
|
|
|
|
## 3. Pre-existing main test failures (unrelated to ADR-0167)
|
|
|
|
**Scope.** Two tests fail on clean `main` and on every branch that
|
|
touches anything; W3-A's regression run surfaced them but they
|
|
predate the LexicalClaim wave.
|
|
|
|
- `tests/test_math_candidate_graph.py::TestRefusals::test_unparseable_statement`
|
|
- `tests/test_teaching_audit.py::test_audit_real_corpus_runs_clean`
|
|
|
|
**Why deferred.** Out of scope for the LexicalClaim slice — these are
|
|
not regressions caused by the wave. Confirmed by W3-A's report: both
|
|
fail on origin/main with no ADR-0167 changes applied.
|
|
|
|
**Where breadcrumbs live.**
|
|
- Run `uv run pytest tests/test_math_candidate_graph.py -k
|
|
test_unparseable_statement -v` on clean main to reproduce
|
|
- Run `uv run pytest tests/test_teaching_audit.py -k
|
|
test_audit_real_corpus_runs_clean -v` on clean main to reproduce
|
|
|
|
**Acceptance.** Each test either:
|
|
- gets fixed (root cause investigation + minimal patch), or
|
|
- gets quarantined via the existing test-quarantine mechanism with a
|
|
written reason that names what's actually broken
|
|
|
|
The "fix or quarantine, don't ignore" principle stands. They are
|
|
distracting noise during regression runs and obscure real regressions.
|
|
|
|
---
|
|
|
|
## 4. Workbench v1 — math candidate rendering
|
|
|
|
**Scope.** Make the read-only operator UI (ADR-0160/0162) render
|
|
`MathReaderRefusalEvidence` candidates alongside cognition
|
|
`DiscoveryCandidate` records.
|
|
|
|
**Why deferred.** ADR-0167 §"Open questions Q4" explicitly out-of-scope.
|
|
The LexicalClaim slice ships the ratification handler but no UI to
|
|
trigger ratification through — today, an operator would call
|
|
`apply_lexical_claim()` from a Python REPL.
|
|
|
|
**Where breadcrumbs live.**
|
|
- ADR-0160 (Core Workbench v1)
|
|
- ADR-0162 (Workbench Design System)
|
|
- W-029 (proposal queue) — closest existing surface
|
|
- W-031 (replay theater) — replay primitive that math evidence
|
|
records inherit through ADR-0057
|
|
|
|
**Acceptance.** A workbench panel that lists pending
|
|
`MathReaderRefusalEvidence` candidates with sub-type, claim signature,
|
|
recognized terms, refusal context, and a ratify-action that calls
|
|
`apply_lexical_claim()` (or its sub-type-specific successor) with an
|
|
operator-supplied reviewer tag and category.
|
|
|
|
---
|
|
|
|
## 5. Cross-domain partition risks (from Gemini's W2-C audit)
|
|
|
|
Two specific code paths Gemini flagged in
|
|
`docs/handoff/ADR-0167-W2C-cross-domain-audit.md` as needing partition
|
|
discrimination:
|
|
|
|
### 5a. Contemplation pack indexing
|
|
|
|
**Scope.** `teaching/contemplation.py::contemplate()` uses hardcoded
|
|
cognition pack and corpus indexes (`_pack_index` and `_corpus_index`).
|
|
Future math-domain candidates would silently get cognition-domain
|
|
lookups.
|
|
|
|
**Acceptance.** Pack and corpus indexes parameterised by
|
|
`candidate.domain` — cognition candidates look up cognition packs,
|
|
math candidates look up math packs (currently `en_core_math_v1`).
|
|
Tests must exercise both paths.
|
|
|
|
### 5b. Replay gate default
|
|
|
|
**Scope.** `teaching/proposals.py` defaults its replay gate to
|
|
cognition's. Proposing math/admissibility candidates requires passing
|
|
`run_admissibility_replay_gate` explicitly to prevent false rejections.
|
|
|
|
**Acceptance.** Either the replay gate is selected by
|
|
`proposal.domain`, or the cognition default is made explicit and math
|
|
proposals are required to declare their gate. Decision goes in
|
|
ADR-0168 (or wherever the first non-lexical sub-type ADR lands —
|
|
that handler will be the first real exerciser of the proposals path
|
|
for math).
|
|
|
|
---
|
|
|
|
## 6. HolonomyAlignmentCase — structural-vs-blend convergence isolation
|
|
|
|
**Scope.** Determine whether the existing
|
|
`tests/test_alignment_graph.py::test_holonomy_alignment_case_positive_closer_than_negative`
|
|
proves *structurally-derived* cross-language convergence or only proves
|
|
*endpoint similarity under the mount-time blend*.
|
|
|
|
**Why deferred.** The proof obligation is executed today — the test
|
|
asserts that an aligned Logos clause produces nearer holonomies across
|
|
English/Hebrew/Greek than a misaligned negative triple. That clears the
|
|
schema's nominal claim. But the test does not distinguish two possible
|
|
explanations for the convergence:
|
|
|
|
1. **Structural.** The Hebrew tri-consonantal root rotors and Greek
|
|
case-last orientation rotations produce versors that genuinely
|
|
land in the same regions of the manifold because the morphology
|
|
operators encode equivalent semantic structure.
|
|
2. **Blend-induced.** `_apply_mounted_primary_domain_resonance`
|
|
(`language_packs/compiler.py:558`) nudges Hebrew/Greek versors
|
|
toward an English prototype at 40% blend, and the test passes
|
|
because both packs have been pulled close to the English anchor
|
|
regardless of structural derivation.
|
|
|
|
If (2) is doing the work, the three-language architecture is a *claim*
|
|
that English-anchored geometric averaging produces the right endpoints,
|
|
not a *proof* that the depth packs are structurally independent
|
|
operators converging coherently with the articulation surface.
|
|
|
|
**Where breadcrumbs live.**
|
|
- `language_packs/compiler.py::_apply_mounted_primary_domain_resonance`
|
|
— the architectural-invariant comment names this gap explicitly and
|
|
references this section
|
|
- `tests/test_alignment_graph.py:73` — the existing positive-closer-
|
|
than-negative assertion
|
|
- `language_packs/schema.py::HolonomyAlignmentCase` — the schema type
|
|
whose nominal contract is "proves structural divergence with
|
|
coherent convergence"
|
|
|
|
**Acceptance.** One of:
|
|
- **(a) Ablation test.** A test that runs the holonomy proof with
|
|
`_apply_mounted_primary_domain_resonance` disabled (or with the
|
|
blend factor set to 0.0) and asserts that the positive-closer-than-
|
|
negative relation still holds. This would prove (1) and retire the
|
|
concern.
|
|
- **(b) Reframe the claim.** If the ablation fails, document
|
|
explicitly that cross-language convergence depends on the
|
|
mount-time blend, and update `HolonomyAlignmentCase`'s contract to
|
|
reflect what it actually proves (endpoint similarity under blend,
|
|
not structural-derivation equivalence). Honest documentation of a
|
|
weaker property beats a stronger claim that the test can't support.
|
|
|
|
**Priority.** Low-urgency, high-information. Not blocking any current
|
|
capability gate. Worth picking up whenever someone next touches the
|
|
language-pack architecture — the comment at the convergence-decision
|
|
site is the trip-wire.
|
|
|
|
Per CLAUDE.md §"Schema-Defined Proof Obligations" — this is the
|
|
prototypical example of a schema-defined obligation that is executed
|
|
but where the test may not meaningfully fail under the violation it is
|
|
written to catch.
|
|
|
|
---
|
|
|
|
## Sequencing recommendation
|
|
|
|
For the operator picking this up next:
|
|
|
|
1. **First**, decide which of the four frame-opener sub-types (§1) the
|
|
next capability gate actually demands. ADR-0166 still gates this —
|
|
the three-question test must pass for whichever sub-type is chosen.
|
|
2. **In parallel**, do §2 (partition test fix) as a small docs/CI PR —
|
|
it unblocks every future ADR-0167 PR's regression run.
|
|
3. **At convenience**, handle §3 (pre-existing failures) — distracting
|
|
but not blocking.
|
|
4. **Defer §4 + §5** until §1 actually ships a second sub-type — they
|
|
only become load-bearing once a second domain candidate type
|
|
exists.
|
|
5. **Pick up §6 opportunistically** — whoever next modifies
|
|
`_apply_mounted_primary_domain_resonance` or the holonomy test owns
|
|
the ablation question.
|
|
|
|
No timelines. Order is by leverage, not calendar.
|
|
|
|
---
|
|
|
|
## Cross-references
|
|
|
|
- [ADR-0167](../decisions/ADR-0167-audit-as-teaching-evidence.md) — parent
|
|
- [SESSION-2026-05-27](../decisions/SESSION-2026-05-27-adr-0167-parallel-dispatch.md) — wave narrative
|
|
- [ADR-0167 Parallel Work Plan](./ADR-0167-PARALLEL-WORK-PLAN.md) — original dispatch plan
|
|
- [W2-C Cross-Domain Audit](./ADR-0167-W2C-cross-domain-audit.md) — Gemini's site survey
|
|
- [ADR-0166](../decisions/ADR-0166-measurement-capability-sequencing.md) — the gating rule every follow-up must answer
|