From 366ea2a125450ba932827caba86e406d119212c4 Mon Sep 17 00:00:00 2001 From: Shay Date: Mon, 15 Jun 2026 10:22:58 -0700 Subject: [PATCH] =?UTF-8?q?docs(adr-0170):=20reconcile=20status=20to=20shi?= =?UTF-8?q?pped=20reality=20=E2=80=94=20W1/W2=20serve;=20fix=20sealed-lane?= =?UTF-8?q?=20comment=20(#771)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mastery-v2 Step 2 (DCS/W2 reconciliation audit). The reviewer flagged that ADR-0170 might still read as pending while the code shipped. Audit (read source + provenance + measured the metric) confirms: - DCS-S1 acquisition (W2) is INTENTIONALLY SERVING, not a boundary escape: PR #377 (b190f3b6) landed it in serving _INJECTORS BEFORE the sealed lane (ADR-0186 = PR #487) existed. The sealed lane (_SEALED_INJECTORS = {}) is correctly empty, reserved for future W3-W5. - wrong=0 held: train_sample committed 4/0/46, confirmed live on current code (test_adr_0126_train_sample_runner 4/4 green); 6 committed cases exercise the acquisition path (collected x4, collects, receives). - Placement already mechanically pinned by the existing test pair — test_adr_0170_w2 (W2 emits via serving _INJECTORS) + test_adr_0186 (sealed lane is an empty no-op) — so NO new test is added (would be redundant). Two stale docs, now reconciled (documentation-only; no code/logic change): 1. ADR-0170 status: "Proposed / no runtime change" -> "Accepted; W1+W2 shipped"; implementation-outline annotated with shipped/deferred status per W-stage. 2. recognizer_anchor_inject.py sealed-lane comment: "resume ADR-0170 W2-W5" -> "W3-W5", noting W2 ships from serving _INJECTORS (PR #377), never the lane. W1+W2/sealed-lane/train_sample lanes: 36/36 green. --- .../ADR-0170-injector-contract-widening.md | 22 ++++++++++++++++--- generate/recognizer_anchor_inject.py | 8 +++++-- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/docs/decisions/ADR-0170-injector-contract-widening.md b/docs/decisions/ADR-0170-injector-contract-widening.md index 2f6f44bb..f902cdd4 100644 --- a/docs/decisions/ADR-0170-injector-contract-widening.md +++ b/docs/decisions/ADR-0170-injector-contract-widening.md @@ -1,6 +1,10 @@ # ADR-0170 — Recognizer Injector Contract Widening -**Status:** Proposed (scoping ADR; no runtime change in this PR) +**Status:** Accepted — W1 (type widening) + W2 (DCS-S1 acquisition → +`CandidateOperation(add)`) shipped to serving (`_INJECTORS`, PR #377; wrong=0, +train_sample 4/0/46). W3–W5 deferred (need `CandidateRate` / `apply_rate`, +ADR-0171). Status reconciled 2026-06-15 (mastery-v2 Step 2; was the stale +"Proposed / no runtime change in this PR", which never tracked W1/W2 landing). **Date:** 2026-05-27 **Author:** Shay **Parent:** ADR-0163.D.2 (parsed_anchors → MathProblemGraph) @@ -164,7 +168,18 @@ identical to what the parser already enforces. ## Implementation outline (subsequent PRs, not this one) -**ADR-0170-impl-W1** — Type widening, no behavior change: +> **Shipped-status reconciliation (2026-06-15, mastery-v2 Step 2).** This +> section was authored as a forward plan; parts have since landed. **W1 (type +> widening) and W2 (DCS-S1 acquisition → `CandidateOperation(add)`) are SHIPPED +> to serving** (`_INJECTORS`, PR #377; wrong=0 held, train_sample 4/0/46 — 6 +> committed cases exercise the acquisition path). The multiplicative-aggregation +> injector also shipped (WAVE-A). The **rate/currency and temporal categories +> remain DEFERRED** — they need the `CandidateRate` / `apply_rate` schema work +> (ADR-0171). The sealed-injector lane (ADR-0186, PR #487) **post-dates W2** and +> hosts *future* sealed capabilities only — W2 was never in it (the +> `recognizer_anchor_inject.py` lane comment is reconciled to match). + +**ADR-0170-impl-W1** *(SHIPPED)* — Type widening, no behavior change: - Change `inject_from_match` return type to `tuple[CandidateInitial | CandidateOperation, ...]` - Update `_INJECTORS` value type @@ -173,7 +188,8 @@ identical to what the parser already enforces. - Pinning test: existing `inject_discrete_count_statement` still emits only `CandidateInitial`; behavior byte-identical pre/post. -**ADR-0170-impl-W2** — First operation-emitting injector (DCS-S1): +**ADR-0170-impl-W2** *(SHIPPED — PR #377, serving `_INJECTORS`, wrong=0)* — +First operation-emitting injector (DCS-S1): - Extend matcher's `_POSSESSION_VERBS` to accept acquisition verbs OR add a separate `_ACQUISITION_VERBS` set - Injector emits `CandidateInitial` for `has/have/had` (existing) AND diff --git a/generate/recognizer_anchor_inject.py b/generate/recognizer_anchor_inject.py index 63faab1a..b7284063 100644 --- a/generate/recognizer_anchor_inject.py +++ b/generate/recognizer_anchor_inject.py @@ -581,8 +581,12 @@ _INJECTORS: Mapping[ShapeCategory, "type"] = { } -# ADR-0186 — the sealed injector lane (resume ADR-0170 W2-W5 under the -# ADR-0175 serving seal). Entries here are consulted **only** when +# ADR-0186 — the sealed injector lane (resume ADR-0170 W3-W5 under the +# ADR-0175 serving seal). Note: W2 (DCS-S1 acquisition verbs) is NOT sealed — +# it shipped directly to serving ``_INJECTORS`` in PR #377, *before* this lane +# existed (ADR-0186 = PR #487), and holds wrong=0 on train_sample (4/0/46). The +# lane hosts the *future* sealed capabilities (W3-W5) only. +# Entries here are consulted **only** when # ``inject_from_match(..., sealed=True)`` — i.e. by the sealed eval runner, # never by the frozen serving path or the ``train_sample`` runner (both pass # ``sealed=False``). This keeps the ratified serving metric byte-identical