The final AGI-spine step (A INSTRUMENT → B WIRE → C DEEPEN → D CLOSE → E ESTIMATION).
The engine may now SERVE a DISCLOSED estimate for a query it would otherwise refuse —
but only for a predicate-class that has measured itself reliable, and never as fact.
This executes the ADR-0206 §5 cognition-path widening: the bridge's LICENSE node
(reliability_gate.license_for), previously "built — not yet called from serving", is now
called. govern_response returns APPROXIMATE iff a genuine licensed Action.SERVE
LicenseDecision is passed (STRICT for every other input — so every existing serving call
site is byte-identical); shape_surface DISCLOSES the estimate as "[approximate] …".
Mechanism:
- generate/determine/estimate.py — a BLIND converse-guesser: told p(a,b), asked p(b,a),
it commits the converse. It never reads the pack's symmetry metadata; whether the guess
is right is MEASURED, not assumed.
- evals/determination_estimation/ — the gold lane: run_practice (sealed, ADR-0199) folds
the converse-guesser over symmetric (sibling_of) vs directed (parent_of) cases, scored
against the pack's graph.edge.symmetric truth (gold independent of the solver). The gate
DISCRIMINATES: sibling_of earns SERVE (660 correct → Wilson floor 0.990046 ≥ θ_SERVE),
parent_of does not (660 wrong → 0.0). The license is earned by VOLUME — 657 perfect
commits is the exact θ_SERVE=0.99 threshold (656 is below).
- generate/determine/data/estimation_ledger.json — the ratified committed ledger,
hash-verified on load (a hand-edited ledger raises RatifiedLedgerError); it IS the
deterministic sealed-practice output (a GSM8K-style --check test pins this).
- chat/runtime.py — when a converse query is refused and the class holds a SERVE license,
the disclosed estimate is surfaced through the bridge (gated by config.estimation_enabled,
default OFF; only meaningful with accrue_realized_knowledge).
Invariants:
- wrong=0 by construction — an estimate is ALWAYS disclosed ([approximate]), never a silent
commit (UNVERIFIED_POSSIBLE is never in APPROXIMATE's admissible set), and only a genuine
ratified license widens (a forged {"licensed":True} dict / a PROPOSE license / an
unlicensed SERVE all stay STRICT). Defense-in-depth: type-gate ∧ admissible-set ∧
hardcoded disclosed state.
- never self-authored — ceilings stay at safe defaults (θ_SERVE=0.99); the engine cannot
raise its own bar. The ledger is sealed practice, hash-verified.
- session/serving only — no corpus/pack/identity/proposal/vault mutation; the HITL teaching
path is untouched. Deterministic; no clock/random.
- byte-identical for every non-E turn (the 2643 govern_response call passes no license).
Out of scope (separate ADR-0206 §5 PRs): the math-serving seam (select_self_verified,
touches the sealed metric), SITUATE (stakes), and the live FEED-BACK loop.
Verified green: smoke (90), architectural invariants (56), response_governance (321,
incl. the new license-gated widening test), the determination-estimation lane (12), and
the B/D/determine regression net. Four-lens adversarial review (disclosure/wrong=0,
calibration integrity, byte-identity, boundary/determinism): all held. Design:
docs/analysis/E-estimation-design-2026-06-06.md.
9.4 KiB
ADR-0206 — Response Governance Bridge (scaffold)
- Status: Accepted (scaffold step) — cognition-path widening landed 2026-06-06 (Step E: the license-gated APPROXIMATE rung). The math-serving seam (§5) remains deferred.
- Date: 2026-06-03 (amended 2026-06-06)
- Supersedes / relates to: ADR-0175 (calibrated-learning reliability
gate), the Epistemic-State program (Phase 3,
core/epistemic_state.py) - Scope of THIS PR: purely additive — design on record + cognition-path seam, STRICT-only, no behavior change.
2026-06-06 amendment (Step E — cognition-path widening landed). The
LICENSEnode is now called from serving:govern_responsereturnsAPPROXIMATE_POLICYfor a genuine licensedAction.SERVELicenseDecision(STRICT for everything else, so every existing call site is byte-identical). The first consumer is the converse-guess estimator (generate.determine.estimate): a refused converse query whose predicate-class earned SERVE on the ratified reliability ledger (generate/determine/data/estimation_ledger.json) is served as a disclosed[approximate]estimate viashape_surface. wrong=0 is preserved by construction (disclosure) + by the gate (θ_SERVE=0.99, earned by volume). Still deferred: the math-serving seam (select_self_verified, §5),SITUATE(stakes), and the liveFEED BACKloop — E uses an offline, sealed, hash-verified ledger. Lane:evals.determination_estimation.
Context — the consumption gap
CORE has two built epistemic substrates:
-
A ratified decode-state taxonomy —
core/epistemic_state.py, a@unique15-memberEpistemicStateenum plus an orthogonalNormativeClearanceaxis. Every chat turn is labeled with its decode-state (derived from the grounding source) and the label is stamped ontoTurnEvent/ChatResponseand emitted to telemetry. -
A deterministic risk-reward gate —
core/reliability_gate/(ADR-0175).license_for(class, action, ceilings)decides whether a class has earned an action viameasured_reliability / θ_required ≥ 1.
A source audit (2026-06-03) established the load-bearing fact this ADR addresses:
The decode-state taxonomy is LABEL-ONLY. No consumer reads a decode-state to weigh stakes, modulate response risk, or gate approximation/creativity. Every read is a stamp, serialize, badge, or filter. The reliability gate is likewise explicitly not serving-wired (
core/reliability_gate/__init__.py: "NOT wired into the serving/eval path"). The loop that would let these substrates govern response behavior has zero consumers.
This is the same shape as the ratify-vs-consume gap: the artifacts exist, the runtime does not read them to act.
Decision
Introduce the Response Governance Bridge — the missing consumer that
reads the two substrates and produces a per-response ReachPolicy
governing how far into uncertainty a response may reach. This ADR ships
only the scaffold: the design on record + a live but inert seam on the
cognition path. The risk-reward widening logic and the math-serving seam
are explicitly deferred (§5).
§1 — The governing loop (designed; not all built)
flowchart LR
T[turn] --> S[SITUATE<br/>stakes/gravity]
S --> L[LICENSE<br/>reliability_gate.license_for]
L --> G[GOVERN<br/>govern_response → ReachPolicy]
G --> H[SHAPE<br/>shape_surface reads policy]
H --> D[DISCLOSE<br/>decode-state label]
D --> F[FEED BACK<br/>outcome → ledger]
F -. next turn .-> L
| Step | Status |
|---|---|
| SITUATE (stakes/gravity from intent + domain + decode-state) | designed — not built |
LICENSE (reliability_gate.license_for) |
built + called from serving (Step E, 2026-06-06) |
GOVERN (govern_response → ReachPolicy) |
STRICT, + license-gated APPROXIMATE (Step E) |
SHAPE (shape_surface, response path reads policy) |
STRICT = identity; APPROXIMATE = disclosed |
| DISCLOSE (decode-state label) | built |
| FEED BACK (outcome → reliability ledger) | designed — not built |
Only GOVERN + SHAPE ship here. SITUATE and FEED-BACK are named and deferred to follow-ups.
§2 — The reach policy
core/response_governance/policy.py defines:
ReachLevel—STRICT < APPROXIMATE < EXTRAPOLATE < CREATIVE. OnlySTRICTis emitted today; the rest name the spectrum the bridge will earn entry to via the reliability gate.ReachPolicy(level, admissible_states, rationale, license_ratio)— the inspectable per-response decision (same discipline asreliability_gate.LicenseDecision).govern_response(*, epistemic_state, license_decision, stakes)— the decision point. Scaffold: returnsSTRICT_POLICYfor every input.shape_surface(policy, *, committed_surface, decode_state, disclosed_alternative)— the consumer. AtSTRICTit is the IDENTITY transform. Higher levels surface a disclosed alternative for non-admissible decode-states — real, policy-sensitive code so the seam is live, but unreachable in production becausegovern_responsenever emits them.
§3 — Why STRICT-only scaffold
The scaffold makes the email's "in active development" claim true the
moment it lands while guaranteeing wrong == 0 is untouched:
govern_response → STRICTis the single load-bearing return. The cognition response surface now flows throughshape_surface, but STRICT is identity, so the path is byte-identical to pre-bridge.- The seam is live wiring, not dead code:
test_seam_is_live_wiringforcesAPPROXIMATEand proves the same consumer the production path calls yields a different surface. The cognition path's strictness is held by exactly the STRICT return — mutate it and the proofs diverge. - The math-serving chokepoint (
select_self_verified) is not touched. It is the single most load-bearing line forwrong == 0; after the ProofNode lesson (a merge silently killed a guard) it does not get its first edit in a scaffold PR. The deferred math seam (§5) carries its own widening test.
§4 — Taxonomy scoping (honestly scoped, not half-dead)
Source-verified split of the 15 EpistemicState members (2026-06-03,
including the mapping functions in epistemic_state.py): 9 produced, 6
never produced. (The earlier audit's "7 never produced" over-counted —
its grep excluded epistemic_state.py, where the partial→EVIDENCED_INCOMPLETE
mapping lives. EVIDENCED_INCOMPLETE is produced; corrected count is 6.)
| Role | Count | States | Consumed by loop as |
|---|---|---|---|
| ACTIVE (produced + consumed) | 9 | DECODED, EVIDENCED_INCOMPLETE, INFERRED, UNVERIFIED_POSSIBLE, UNVERIFIED_NOVEL, CONTRADICTED, AMBIGUOUS, UNDETERMINED, EPISTEMIC_STATE_NEEDED |
strict-admissible / approximate+ / extrapolate+ / creative / force-refuse / sentinel |
| RESERVED (named trigger, not produced) | 5 | VERIFIED, COMPUTATIONALLY_BOUNDED, SCOPE_BOUNDARY, PERCEIVED, DECODED_UNARTICULATED |
each gated on a capability that must land first |
| RECONCILE (drift, own PR) | 1 | EVIDENCED |
declared but never produced; recognition/outcome.py owns its own "evidenced" |
Reserved triggers:
VERIFIED— needs a canonical-comparison pass (the soundness ≠ correctness gap); the only state that will license widening past gold.COMPUTATIONALLY_BOUNDED— search-budget exhausted;generate/derivation/search.pyis the near-term emitter.SCOPE_BOUNDARY— out-of-domain refusal with a reason; needs domain-scope detection.PERCEIVED— raw ingest pre-comprehension; needs a perception lane.DECODED_UNARTICULATED— decoded but no realizer surface; articulation-gap.
The partition is enforced by test_taxonomy_partition_is_total_and_disjoint
(total + pairwise-disjoint over the live enum), so adding an enum member
without scoping it fails the build.
§5 — Deferred (one kind of change per PR)
- Math-serving seam — parameterizing
select_self_verifiedwith aReachPolicy(STRICT branch byte-identical) + the full math-serving widening test. Its own PR; smaller blast radius on the wrong==0 organ. EVIDENCEDreconcile — map recognition's outcome intoEpistemicState.EVIDENCEDat the boundary (or document the two axes). A real corrective defect; kept out of this purely-additive scaffold.- JSONL emission of
reach_level—reach_levelis carried onTurnEvent/ChatResponsebut not added to the telemetry audit dict here, so every pinned lane SHA stays byte-identical. Emission + SHA re-pin is a follow-up (re-pinning a frozen gate is not "additive"). - SITUATE / FEED-BACK / widening — the risk-reward logic itself.
Consequences
- Honest claim unlocked: decode-state taxonomy + risk-reward gate = built; the bridge that lets them govern response reach = in active development (committed seam, STRICT-only, design on record, widening gated behind wrong==0 proofs). Never "live."
wrong == 0preserved: STRICT identity + untouchedselect_self_verified; serving metric stays3/47/0.- No frozen gate touched: telemetry JSONL byte-identical → all pinned lane SHAs green.
Verification
tests/test_response_governance.py— STRICT-only contract, STRICT identity, live-wiring proof (cognition path), taxonomy partition.- Full-surface suite green (doctrine: not smoke).
scripts/verify_lane_shas.pygreen;3/47/0preserved.