core/docs/adr/INDEX-by-domain.md
Shay dccce6a7b9 fix(generate): a proposition graph must be able to represent denial (ADR-0265)
CORE served the affirmative of propositions the user denied. Measured live on
main @ 536d6e55 with realizer_grounded_authority=True:

    "evidence does not support truth" -> 'Evidence is verified: what supports truth.'
    "evidence supports truth"         -> 'Evidence is verified: what supports truth.'

Byte-identical.

Phase 4 (#136) pinned "render_semantic has no negated parameter" as a defect.
Sizing the exposure before acting on it -- the step §7 requires -- showed the
pin was correct and INCOMPLETE. The defect is two drops in series, and the
first is in the graph:

  intent.negated      parsed from the user's words, always has been
  GraphNode           NO FIELD FOR IT  <-- first drop
  ground_graph        rebuilds nodes field-by-field; nothing to carry
  depth enrichment    rebuilds nodes field-by-field; nothing to carry
  plan_articulation   cannot carry what the node does not hold
  realize_semantic    never read step.negated
  render_semantic     no parameter for it                <-- second drop

Five separate constructors, each silently defaulting to the affirmative.

Why every gate was green
------------------------
On the default config the ungrounded realizer emits "...", _is_useful_surface
rejects it, and the runtime echo wins the resolver -- and the echo contains the
user's own "does not". The truth path was correct BY ACCIDENT. ADR-0088 Phase B
grounds the graph first, which is exactly when the realizer's surface becomes
useful enough to win. So the defect sat behind a shipped flag, invisible to
every property-of-one-surface test, because nothing compared a denial to its
assertion.

Delivered
---------
- GraphNode.negated, threaded intent -> graph -> ground -> enrich -> step ->
  surface. Serialized ONLY when True, so every pre-existing as_dict and every
  trace_hash folded from one stays byte-identical -- which is why no lane pin
  moves.
- Clause grammar delegated to its one owner. Four of the eight intent
  "templates" were never frames; they were plain clauses. They now call
  render_step. Writing a second negation implementation in semantic_templates
  was the tempting fix and is rejected: Phase 2A spent a unit giving every
  linguistic fact one owner, and that design rebuilds the disease one level up.
- Frames that keep a finite verb (VERIFICATION, PROCEDURE, COMPARISON) get an
  explicit negated form. RECALL is a speech act with no proposition to deny, so
  it falls back to the clause path rather than drop the denial (ADR-0261 §5.1).

Measured
--------
    delegation on affirmatives          192/192 byte-identical
    serving realizer, all corpora       85/347 -> 109/347   (+24 = the denials)
    feature-bearing bucket              49/214 -> 73/214
    CONTROL (nothing droppable)         33/33  -> 33/33     unchanged
    multi-node (clause joining)         3/100  -> 3/100     unchanged, out of scope
    lane pins                           11/11 byte-identical, none edited

The control staying 33/33 and multi-node staying 3/100 is the evidence that
this moved the denials and nothing else.

The exhaustive control earned its keep immediately
--------------------------------------------------
It found FIVE more intents serving a denial as its own assertion --
TRANSITIVE_QUERY, FRAME_TRANSFER, NARRATIVE, EXAMPLE, DEDUCTION -- because an
intent with no frame fell back to the UNKNOWN *template* (which cannot say
"not") rather than the UNKNOWN *clause* (which can). The default is now the
capable path, so the next intent added inherits correctness. Found by the
control, not by inspection.

Mutation -- every link reverted individually
--------------------------------------------
    baseline                                        19 pass
    graph_from_intent drops intent.negated           8 FAIL
    plan_articulation drops node.negated             6 FAIL
    ground_graph drops it on rebuild                 2 FAIL
    realize_semantic stops passing step.negated      6 FAIL
    unframed intents fall back to the template       1 FAIL
    pipeline depth-enrichment drops it               1 FAIL

The last row was GREEN on the first run -- my fix there was unguarded. That is
what added the structural invariant: every GraphNode(...) built on the serving
path must NAME `negated` or be recorded in an allowlist with a reason. The
defect was five constructors; a per-site test must be written per site, and a
site added without one is invisible. Only recognition/connector.py is exempt
(an EpistemicNode has no polarity to carry).

Four Phase 4 pins are revised, not relaxed -- #136's M2 mutation ("render_semantic
GAINS a negated parameter -> FAIL") has now happened for real, and forced the
deliberate revision it was built to force.

Registered in `smoke` in the same PR that creates it, per the #136 finding that
an unregistered pin runs nowhere.

Still unexpressed, deliberately: quantifier, tense, aspect. NO PRODUCER sets
them anywhere on the serving path, so threading them would be machinery with no
caller. render_step already handles all three the moment a producer exists.

[Verification]: in-worktree on CPython 3.12.13 with `uv sync --locked` --
smoke 641 (was 621), deductive 503, lane pins 11/11 with no pin edited.
2026-07-27 13:08:17 -07:00

10 KiB
Raw Blame History

ADR index, keyed by domain

docs/adr/ holds 312 files under a flat, purely sequential numbering. Sequence records when a decision was made and nothing about what it governs, so answering "which ADRs constrain the serving flag contract?" or "what governs the register axis?" currently means grepping. Past ~300 files that is how a decision corpus becomes a write-only archive.

This index is the lightweight fix: a maintained table keyed by capability domain and cross-referenced by the files each ADR actually governs. It is not a renumbering, and it does not replace README.md (which owns the Master-Blueprint collision reconciliation and the binding non-ADR notes).

Scope, stated honestly

This index covers the live serving, telemetry, and governance surfaces — the domains a Phase 5 / next-arc session needs to query. It is not a complete index of all 312 ADRs, and it does not pretend to be: an index asserting coverage it does not have is worse than none, because it converts "I should grep" into "I already checked."

Maintenance rule: index on mint. Adding a row when you write an ADR is cheap; back-filling 300 is not. Rows below carry the files each ADR governs so a reader can jump from a decision to its enforcement site.


Deduction serving (the deduction-serve arc)

ADR Decision Governs
0256 Deduction serving governed by an earned reliability license; flag ratified ON 2026-07-24 chat/deduction_serve_license.py, chat/data/deduction_serve_ledger.json, core/config.py::deduction_serving_enabled
0257 Band v2-EN — English-clause opaque-atom propositional serving; realizer-guard exemption for quoted templates generate/proof_chain/english.py, chat/runtime.py (guard exemption sites)
0258 Band v3-MEM — singular membership + universal premises generate/proof_chain/categorical.py
0259 Band v4-CM — conditional-membership fusion generate/proof_chain/cond_member.py
0260 Band v5-VP — verb-predicate arguments generate/proof_chain/verb.py
0261 Band v6-EX — existential witnesses; anonymous witness never transfers to a named individual generate/proof_chain/exist.py

Engine underneath all six: generate/proof_chain/entail.py (ROBDD tautology check). Surfaces: generate/proof_chain/render.py, chat/deduction_surface.py.

Curriculum serving

ADR Decision Governs
0262 Exams answered from the ratified curriculum, read OPEN-world; §5 records that curriculum volume is the binding constraint (~25× gap) — conclusion amended by 0264 §4.1 chat/curriculum_surface.py, chat/curriculum_serve_license.py, evals/curriculum_serve/runner.py
0264 Negatives via a row-level polarity field reusing the affirmative connective; premise compilation is query-scoped (superset of the query-atom rows ⇒ verdict-identical). §4.1: the 16-premise cap holds a band to ≤16 entailed cases, so no curriculum band can earn SERVE until scoping lands — the blocker is engineering, not content teaching/curriculum_premises.py, teaching/ratification.py, evals/curriculum_serve/oracle.py, teaching/domain_chains/*.jsonl
0265 A proposition graph must be able to represent denial: GraphNode.negated threaded intent → graph → step → surface, and clause grammar delegated to its one owner (render_step). Fixes a live truth defect — under realizer_grounded_authority, "evidence does not support truth" and "evidence supports truth" served byte-identical surfaces. Serialized only when True, so no trace_hash and no lane pin moves generate/graph_planner.py, generate/semantic_templates.py, generate/realizer.py, generate/intent_bridge.py, core/cognition/pipeline.py

Reliability licensing and the ledger bridge

ADR Decision Governs
0175 Two regimes under wrong=0; θ_SERVE Wilson floor; an engine cannot raise its own bar core/reliability_gate.py, generate/determine/estimation_license.py
0263 Seal → ratify → SHA-verify → serve-gate, extracted from three instances. Rule 5 (2026-07-25): absence policy is declared in CAPABILITY_LEDGERS, not passed at the call site core/ratified_ledger.py, all three license adapters
0206 Response governance bridge (govern_response / shape_surface) generate/determine/

Grounding sources and the epistemic taxonomy

ADR Decision Governs
0142 Epistemic state as first-class vocabulary core/epistemic_state.py
0048 / 0050 Pack-grounded cold-start DEFINITION / RECALL / COMPARISON chat/pack_grounding.py
0052 Teaching-grounded cold-start CAUSE / VERIFICATION chat/teaching_grounding.py
0064 Cross-pack residency + cross-corpus chain lookup for the discovery gate teaching/discovery.py

The closed set itself lives at core/epistemic_state.py::GroundingSource. Registration is a three-part cross-stack change — see docs/specs/runtime_contracts.md § "Grounding-source registration".

Register axis and the realizer guard

ADR Decision Governs
0069 Realizer register parameter; invariant C — register must not move trace_hash core/cognition/surface_resolution.py, core/cognition/pipeline.py
0071 Seeded surface variation + discourse markers; pre_decoration_surface chat/register_variation.py
0075 Realizer slot-type guard (C1 coherence floor). Deduction surfaces are exempt — quoted templates are not slot-composed articulations (rationale documented at both guard sites) chat/runtime.py (stub + main guard sites)
0077 Substantive register knobs (R6); register_canonical_surface chat/register_substantive.py

Telemetry, trace, and audit

ADR Decision Governs
0039 TurnVerdicts bundle, stub-path TurnEvent, hedge_injected chat/runtime.py
0153 TurnEvent trace_hash back-stamp (W-020a) core/cognition/pipeline.py, chat/runtime.py
0255 Discovery-yield-per-served-turn baseline; fail-closed on a missing baseline teaching/discovery_yield.py
0018 Typed deterministic operators folded into trace_hash core/cognition/trace.py

trace_hash is not reconstructable from TurnEvent — see docs/specs/runtime_contracts.md. Audit-ledger R7 (telemetry sink receives the pre-override event) is open and recorded there.

Workbench and the cross-stack UI contract

ADR Decision Governs
0160 Operator/auditor UI before public chat workbench/
0161 HITL async queue teaching/proposals.py, core proposal-queue CLI
0162 Design system v1; §3d — engine enums bind to UI badges, enforced by a build-time coverage test workbench-ui/src/design/, workbench-ui/enum-snapshot.json

Teaching, proposals, and review

ADR Decision Governs
0057 Teaching-chain proposal + review + replay-equivalence gate teaching/proposals.py, teaching/review.py, teaching/store.py
0254 Grounded-open hedge arm for the shadow-coherence gate chat/runtime.py

Reader arc / math capability

ADR Decision Governs
0251 Halt bespoke per-case regex work; clean-base reset. The prohibition that governs every math reader increment generate/math_roundtrip.py, generate/math_candidate_parser.py

Companion evidence: docs/research/reader-arc-overfit-inventory-2026-07-19.md, docs/research/math-reader-phase-4-1-status-2026-07-24.md (Phase 4.1 = complete-with-null-yield).

Substrate, field, and packs

ADR Decision Governs
0180 Delta-CRDT sharded substrate core-rs/src/vault.rs, engine_state/
0243 Wave-field cognitive lifecycle field/
0244 Wave-field identity manifold persona/, chat/runtime.py
0253 Blueprint collision resolution + dual-pack serve boundary (INV-33) packs/

Numbering note

The corpus is at ADR-0263 and minted eight ADRs in roughly 48 hours during the generalization arc. Sequential numbering is fine and should stay — the cost it imposes is discoverability, which is what this file pays down. ADR-0300 is a near-term milestone with no structural meaning; do not treat it as one.

The ADR-0206/ADR-0256 numbering collision that had to be resolved in doc form is the concrete failure this index is meant to make less likely: a domain-keyed view shows an in-flight number before it is minted twice.