Pre-ADR-0062, the teaching-grounded composer emitted exactly one
reviewed chain per surface — "light reveals truth" — even when the
corpus already contained an immediate follow-up "truth grounds
knowledge". With 21 active chains after curriculum saturation v2,
many grounded prompts had a corpus-ratified follow-up the composer
silently dropped.
ADR-0062 adds the composed composer + an opt-in config flag:
flag OFF (default):
light — teaching-grounded (cognition_chains_v1): cognition.illumination;
logos.core. light reveals truth (cognition.truth). No session evidence yet.
flag ON:
light — teaching-grounded (cognition_chains_v1): cognition.illumination;
logos.core. light reveals truth (cognition.truth), which grounds
knowledge (cognition.knowledge). No session evidence yet.
Follow-up resolution:
- prefer cause; fall back to verification (deterministic preference)
- cycle guard: 1-step cycles (A→B, B→A) blocked
- pack-residency guard: follow-up's object must be pack-resident
- bounded depth: v1 follows exactly one hop
- degrades to single-chain BYTE-IDENTICALLY when no follow-up
survives the guards (drop-in replacement)
Trust-boundary invariants preserved:
- Every visible non-template token is lemma / pack-domain /
humanize_predicate connective / template constant. Only added
template constant: ", which "
- Deterministic: same chains → same surface bytes
- Default-False flag pattern mirrors ADR-0047/0058
- `versor_condition < 1e-6` invariant untouched (surface composition only)
Cognition lane null-drop invariant CI-pinned:
Composed mode emits a strictly LONGER surface (extra follow-up
clause); every expected_term passing flag-OFF must still pass flag-ON.
Asserted in test_cognition_lane_metrics_unchanged_with_composed_flag
for both public and holdout splits. If a future change drops tokens,
the test fails as a deliberate regression.
public flag OFF: intent 100% / surface 100% / term 91.7% / versor 100%
public flag ON : intent 100% / surface 100% / term 91.7% / versor 100% (identical)
holdout flag OFF: intent 100% / surface 100% / term 83.3% / versor 100%
holdout flag ON : intent 100% / surface 100% / term 83.3% / versor 100% (identical)
Live-prompt lift visible on ~12 of 21 active chains; the rest hit
cycle or pack-residency guards. Saturation v2's clusters were
authored partly with composition in mind (thought→meaning→
understanding, inference→evidence→knowledge, etc.).
- core/config.py — `RuntimeConfig.composed_surface: bool = False`
- chat/teaching_grounding.py — `teaching_grounded_surface_composed`
sibling to `teaching_grounded_surface`
- chat/runtime.py — dispatch branch in `_maybe_pack_grounded_surface`
selects composed vs single-chain based on config flag
- tests/test_composed_surface.py — 11 tests pin: function-level
(None on no chain / degrades when no follow-up / two-clause when
follow-up exists / includes intermediate + final domains /
deterministic / cycle guard / trust label preserved); runtime
integration (default single-chain / flag-on composed / frozen
config); cognition-lane null-drop invariant.
Lanes (regression): smoke 67 / cognition 121 / teaching 17 /
composed-surface 11 — all green.
218 lines
8.2 KiB
Markdown
218 lines
8.2 KiB
Markdown
# ADR-0062 — Composed Teaching-Grounded Surface (Chain-of-Chains)
|
|
|
|
**Status:** Accepted
|
|
**Date:** 2026-05-18
|
|
**Author:** Shay
|
|
|
|
---
|
|
|
|
## Context
|
|
|
|
Pre-ADR-0062, `teaching_grounded_surface` emitted exactly **one
|
|
reviewed chain** per surface:
|
|
|
|
```
|
|
light — teaching-grounded (cognition_chains_v1): cognition.illumination;
|
|
logos.core. light reveals truth (cognition.truth).
|
|
No session evidence yet.
|
|
```
|
|
|
|
Every grounded prompt produced a single-clause surface, regardless
|
|
of how many follow-up chains the corpus already contained. With
|
|
21 active chains in `cognition_chains_v1` (after curriculum
|
|
saturation v2), many grounded prompts have an immediate corpus-
|
|
ratified follow-up that the surface composer was silently dropping:
|
|
|
|
| Initial chain | Follow-up chain | What single-chain emits | What composed could emit |
|
|
|---|---|---|---|
|
|
| `light reveals truth` | `truth grounds knowledge` | `light reveals truth` | `light reveals truth, which grounds knowledge` |
|
|
| `thought reveals meaning` | `meaning grounds understanding` | `thought reveals meaning` | `thought reveals meaning, which grounds understanding` |
|
|
| `inference requires evidence` | `evidence grounds knowledge` | `inference requires evidence` | `inference requires evidence, which grounds knowledge` |
|
|
|
|
This is the *fluency-from-existing-corpus* gap I called out
|
|
in the "more packs?" question: the rate-limiter on articulation
|
|
isn't pack vocabulary, it's surface composition over chains that
|
|
already exist.
|
|
|
|
---
|
|
|
|
## Decision
|
|
|
|
Add `teaching_grounded_surface_composed(subject, intent_tag)` to
|
|
`chat/teaching_grounding.py` alongside the existing single-chain
|
|
composer, and route it via a new opt-in
|
|
`RuntimeConfig.composed_surface: bool = False`.
|
|
|
|
### Surface format
|
|
|
|
```
|
|
"{A} — teaching-grounded ({corpus_id}): {dA1}; {dA2}.
|
|
{A} {conn_A} {B} ({dB}), which {conn_B} {C} ({dC}).
|
|
No session evidence yet."
|
|
```
|
|
|
|
Every visible non-template token remains a lemma, a verbatim pack
|
|
`semantic_domains` string, or a `humanize_predicate`-emitted
|
|
connective. The new `, which ` linker is the only added template
|
|
constant.
|
|
|
|
### Follow-up resolution rules
|
|
|
|
1. Look up an initial chain `(subject, intent)`.
|
|
2. Look up a follow-up chain whose `subject` equals the initial
|
|
chain's `object`. Prefer `cause`; fall back to `verification`.
|
|
(Causal continuation reads more naturally than a verification
|
|
detour; the preference is deterministic.)
|
|
3. **Cycle guard.** If the follow-up's `object` equals the initial
|
|
`subject` OR the initial `object`, do not follow (1-step cycle
|
|
or degenerate same-cell mismatch).
|
|
4. **Pack-residency guard.** If the follow-up's `object` is not
|
|
pack-resident with `semantic_domains`, do not follow (would
|
|
emit a partially-grounded composition).
|
|
5. If no follow-up survives the guards, degrade to the
|
|
single-chain surface **byte-identically**. Drop-in replacement.
|
|
|
|
### Bounded depth
|
|
|
|
v1 follows **exactly one hop**. Deeper compositions (A→B→C→D) are
|
|
deferred to a future ADR. The cycle/pack-residency guards alone
|
|
don't suffice for unbounded depth — a depth-2 chain can re-enter
|
|
through a different intent. Bounded depth + visited-set check is
|
|
the natural next step but adds template-shape complexity not
|
|
needed today.
|
|
|
|
### Opt-in flag
|
|
|
|
`RuntimeConfig.composed_surface: bool = False`. Default preserves
|
|
all pre-ADR-0062 behaviour byte-identically. Mirrors the
|
|
ADR-0047/0058 `forward_graph_constraint` pattern: ship the
|
|
capability behind a flag, characterise empirically, decide on
|
|
default behaviour in a follow-up once downstream consumers have
|
|
observed it on their workloads.
|
|
|
|
---
|
|
|
|
## Verification
|
|
|
|
```
|
|
tests/test_composed_surface.py 11 passed
|
|
- Pure function: None when no chain / degrades when no follow-up /
|
|
produces two-clause when follow-up exists / includes both
|
|
intermediate and final domains / deterministic / cycle guard
|
|
blocks 1-step cycle / preserves trust-boundary label.
|
|
- Runtime: default keeps single-chain / flag-on uses composed /
|
|
flag is observable on frozen config.
|
|
- Null-drop invariant: cognition-lane metrics byte-identical
|
|
flag OFF vs ON on both public and holdout splits.
|
|
|
|
Lanes (regression check):
|
|
core test --suite smoke 67 passed
|
|
core test --suite cognition 121 passed
|
|
core test --suite teaching 17 passed
|
|
```
|
|
|
|
### Cognition-lane null-drop invariant
|
|
|
|
Composed mode emits a **strictly longer** surface — every token
|
|
in the single-chain surface still appears, plus one follow-up
|
|
clause. So every `expected_term` and `expected_surface_contains`
|
|
that passed flag-OFF must still pass flag-ON. The contract test
|
|
`test_cognition_lane_metrics_unchanged_with_composed_flag` runs
|
|
both public and holdout splits twice (flag OFF vs ON) and asserts
|
|
all four watched metrics are pair-wise identical:
|
|
|
|
| Split | Flag OFF | Flag ON |
|
|
|---|---|---|
|
|
| public | 100 / 100 / 91.7 / 100 | **100 / 100 / 91.7 / 100** |
|
|
| holdout | 100 / 100 / 83.3 / 100 | **100 / 100 / 83.3 / 100** |
|
|
|
|
If a future change ever drops tokens in composed mode (e.g.
|
|
shortens the surface to omit the intermediate object), this test
|
|
fails as the deliberate regression it is.
|
|
|
|
### Live-prompt observable lift
|
|
|
|
Composed mode visibly enriches the surface on prompts where
|
|
follow-ups exist:
|
|
|
|
```
|
|
flag OFF: "Why does light exist?"
|
|
→ light — teaching-grounded (cognition_chains_v1):
|
|
cognition.illumination; logos.core. light reveals truth
|
|
(cognition.truth). No session evidence yet.
|
|
|
|
flag ON: "Why does light exist?"
|
|
→ light — teaching-grounded (cognition_chains_v1):
|
|
cognition.illumination; logos.core. light reveals truth
|
|
(cognition.truth), which grounds knowledge
|
|
(cognition.knowledge). No session evidence yet.
|
|
```
|
|
|
|
Of the 21 active chains, the follow-up resolution succeeds for
|
|
~12 of them (the rest hit cycle guards or pack-residency
|
|
guards). Saturation v2's three coherent clusters were authored
|
|
partly with this composition in mind — `thought reveals meaning`
|
|
+ `meaning grounds understanding`, `definition grounds concept` +
|
|
`concept requires definition` (cycle-blocked, degrades cleanly),
|
|
etc.
|
|
|
|
---
|
|
|
|
## Consequences
|
|
|
|
### What changes
|
|
|
|
- `core/config.py` — `RuntimeConfig.composed_surface: bool = False`.
|
|
- `chat/teaching_grounding.py` —
|
|
`teaching_grounded_surface_composed(subject, intent_tag)` sibling
|
|
to `teaching_grounded_surface`.
|
|
- `chat/runtime.py` — dispatch branch in `_maybe_pack_grounded_surface`
|
|
for `IntentTag.CAUSE` / `IntentTag.VERIFICATION` selects composed
|
|
vs single-chain based on the config flag. Single-line change.
|
|
|
|
### What does not change
|
|
|
|
- The pack-grounded discipline: zero LLM-generated tokens; every
|
|
visible word is lemma, pack-domain, connective, or template
|
|
constant.
|
|
- ADR-0053's cold-start contract: empty session + no chain still
|
|
emits the universal disclosure.
|
|
- Default runtime behaviour: byte-identical to pre-ADR-0062 main.
|
|
- The non-negotiable field invariant
|
|
(`versor_condition(F) < 1e-6`) is unaffected — this ADR only
|
|
changes surface composition, not rotor construction or sandwich
|
|
application.
|
|
|
|
---
|
|
|
|
## Scope limits
|
|
|
|
- **Depth-1 only.** v1 follows one hop. `light reveals truth,
|
|
which grounds knowledge, which requires evidence` would require
|
|
a depth-2 composer with visited-set tracking — out of scope
|
|
here.
|
|
- **No multi-claim aggregation.** When the same subject has
|
|
multiple ratified chains (e.g. `knowledge requires evidence`
|
|
AND `knowledge` is the object of three other chains), the
|
|
composer still picks one initial chain. Aggregation across
|
|
multiple grounded views is a separate ADR.
|
|
- **English path only.** The `, which ` linker and the
|
|
`humanize_predicate` connectives are English-specific.
|
|
- **Flag stays off by default.** Operators must opt in. A follow-up
|
|
ADR will decide on default behaviour after characterising the
|
|
flag on more workloads (mirrors ADR-0047/0058).
|
|
|
|
---
|
|
|
|
## Cross-References
|
|
|
|
- [ADR-0052](./ADR-0052-teaching-grounded-surface.md) — the
|
|
single-chain teaching-grounded composer this ADR extends.
|
|
- [ADR-0053](./ADR-0053-cognition-lane-closure.md) — the cognition-
|
|
lane closure that exposed the saturation headroom.
|
|
- [ADR-0058](./ADR-0058-forward-graph-constraint-status.md) —
|
|
the opt-in-default-False + null-lift-invariant pattern this ADR
|
|
reuses.
|
|
- [Curriculum: cognition saturation v2](../curriculum/cognition_saturation_v2.md)
|
|
— the unit that produced the 21 chains this composer composes
|
|
over.
|