step.23.diff.txt -- narrative retro for step.23 (U5.2: the T3 oracle
                    tier). Companion: step.23.gdiff.txt via
                    ../scripts/step_gdiff (machine half).

Executed: 2026-07-22, same session as steps 22 (U5.1) and the b3u
UB.1/UB.2 pair. WORK commit 85a8b9f.

## Plan vs actual

+---+--------------------------------------+--------------------------------------+
| # | Planned (brief)                      | Actual                               |
+---+--------------------------------------+--------------------------------------+
| 1 | [T3:validate] vocabulary + handler   | Landed: t3_ccs kind, ladder T3=3,    |
|   | in the VERIFYING pass                | applied-.sgr targets (the py_compile |
|   |                                      | symmetry), unit = file stem.         |
| 2 | Verdict -> VerificationRecord ->     | Landed, STRONGER than planned: the   |
|   | repair-loop oracle_feedback          | repair diagnostics now feed the FULL |
|   |                                      | recorded detail from the JSONL row   |
|   |                                      | for ALL tiers (Q-23-C) -- the        |
|   |                                      | 300-char node-kv truncation was a    |
|   |                                      | uniform gap T3's tail exposed.       |
| 3 | Injectable service + honest refusal  | Landed: ccs= param; resolved once,   |
|   |                                      | up front, iff a T3 gate is named;    |
|   |                                      | B3uDevClient default refuses loudly  |
|   |                                      | with the named next action.          |
| 4 | (not planned) compiler               | FOUND MID-STEP: _ORACLE_GATE_RE's    |
|   | de-double-booking                    | \bT3\b matched the machine marker -> |
|   |                                      | execution-DAG oracle_gate node       |
|   |                                      | demanding a scripts/oracle_gate.sh   |
|   |                                      | stub. Fixed (Q-23-B/C-23-D): strip   |
|   |                                      | [T3:...] before the prose regex.     |
+---+--------------------------------------+--------------------------------------+

## Surprises / genuine findings

1. **The double-booking (Q-23-B).** The first hermetic T3 test run
   halted in EXECUTING, not VERIFYING -- the pre-U5.2 "T3 rides the
   execution DAG's oracle_gate today" shape collided with the tier it
   was standing in for. The fix is a one-owner rule (C-23-D): a
   machine-marked gate belongs to the VERIFYING pass alone; prose-
   named checks keep the planning node (their compiler tests stayed
   green untouched).
2. **The defect discipline cost zero code.** run_ready_frontier's
   generic-exception path (status=failed, `error` kv, no verdict) +
   verify_uow's existing verdict-vs-defect split meant RAISING a
   CCSError from the handler produced exactly the right "a provider
   cannot fix an unreachable plane" behavior -- designed at step.19,
   paid off at step.23.
3. **The truncation gap (Q-23-C).** Chasing "the cppcc tail must
   reach the repair provider IN FULL" exposed that every tier's
   repair diagnostics were feeding the 300-char kv surface. The fix
   (read the JSONL row) upgraded T0/T1/T2 repair quality as a side
   effect of T3's requirement.
4. **The live FAIL leg is the best evidence in the arc**: a broken
   spec travelled engine -> HTTP -> b3u -> sandboxed cppcc -> .log
   tail -> path-scrub -> Verdict -> VerificationRecord -> escalation
   report. Every seam in the trinity's oracle story exercised by one
   test.

## Scope discipline

In: the U5.2 row + the two mid-step findings (Q-23-B compiler rule,
Q-23-C full-detail feed) -- both named, both tested. Out and named:
U5.3 SCB tier (the unknown-T3-check refusal names it), U5.4/U5.4a/
U5.5, d9's richer verdict lattice (row stays OPEN, V0 default
untouched), Track B records (P4). Zero CLI changes; zero b3u-repo
changes.

## Numbers

- verifying.py: +1 tier (vocabulary, handler, resolution, full-detail
  feed); compiler.py: 1 regex-scope rule; 3 stale comment sites
  updated (errors/compiler/executing); 1 stale test split into 2.
- New tests: 9 hermetic + 2 live = 11; suite 602 -> 616 collected
  (11 new + 1 test split + 2 own-corpus step.23.txt), 596 passed +
  20 skipped (18 + the 2 live T3 legs), 0 failed.
- p5_gates.sh: live leg 7 -> 9 legs; hermetic twin 24+7 -> 33+9;
  ALL PASS live on the first post-extension run.
- Numbers measured AFTER the step file joined the corpus (the
  step.22 lesson, now routine).

End of retro.
