step.23.txt -- b3ubot U5.2: the T3 oracle tier, wired -- [T3:validate] runs every .sgr the execution APPLIED through the CCSService port in the VERIFYING pass; a FAIL verdict's cppcc .log tail rides the repair loop's oracle_feedback IN FULL; proven hermetically (ReplayCCSService) AND live (the real local b3u: engine -> HTTP -> cppcc -> verdict -> repair/escalation, end to end). Step: 23 Parent: end_to_end.md §7 P5 U5.2 row ("T3 oracle over the b3u validate operation (verdict + cppcc-log diagnostics -> VerificationRecord -> the repair loop's oracle_feedback)"). The row's cross-repo dependency (b3u UB.1) landed at b3u step.51, so its named interim (ride the full generate flow) was never needed. design.md §2.5 (the tier table + the U3.6 delivered-state paragraph whose closing sentence -- "T3 markers refuse naming P5/U5.2" -- this step retires), §2.8 (the port, U5.1 REALIZED at step.22). UoW: U5.2 -- second P5 UoW; U5.3 (SCB tier) and U5.4 (CCS-unit workflows) build on this tier; U5.5 is the trinity gate. Date: 2026-07-22 Origin: User directive 2026-07-22: "go with U5.2, step file and its execution" (the (p1) sequence). ## (0) Status EXECUTED same-session. The [T3:validate] tier is live in app/orchestrator/verifying.py: vocabulary + t3_ccs node kind + the handler (applied-.sgr targets, the py_compile symmetry; unit = file stem, the b3u path-identity contract), the tier ladder extended T0 RETRO; real FAIL tail -> escalation, verdict row carrying genuine path-scrubbed cppcc diagnostics). ## (1) Ground truth probed at drafting (outputs -> named writers) READ app/orchestrator/verifying.py end to end (1017 lines): the gate vocabulary (_classify_marker's T3 refusal to retire), _TIER_ORDER/_NODE_KIND, _applied_py_targets (the applied-set discovery to generalize), the repair loop's diagnostics construction (node-kv 300-char truncation -- the oracle_feedback gap this step closes), the defect-vs-verdict split after a halt. READ app/orchestrator/executing.py run_ready_frontier: a handler exception lands as status=failed + `error` kv and NO verdict -> verify_uow classifies it as a defect. So a CCSError RAISED from the T3 handler gets the correct never-repaired semantics for free. READ tests/test_orchestrator_verifying.py's molds (the toy arc: DRAFT_SKELETON_UT1, proposal = "file\\ncontent", SequenceAdapter capturing repair requests, the REPAIR_MARKER/diagnostics assertions). CONFIRMED the shipped tests/fixtures/ccs/ verdicts (step.22) are exactly what the hermetic T3 tests need: the GOOD/BAD spec bytes' sha keys, the BAD tail carrying a real-shaped `*** error ***` line. CONFIRMED (mid-execution) the compiler double-booking: the toy arc with a [T3:validate] skeleton halted in EXECUTING at an oracle_gate node ("no gate script named 'oracle_gate.sh'") -- _ORACLE_GATE_RE's \\bT3\\b matched the machine marker -> Q-23-B. ## (2) What U5.2 delivers 2.1 **The [T3:validate] vocabulary** (verifying.py): _T3_CHECKS, t3_ccs node kind, tier ladder T3=3 (network cost last); the pre-U5.2 T3 refusal replaced by an unknown-T3-check refusal naming U5.3 (SCB byte-identity, the named future); the unknown- tier message now lists T0/T1/T2/T3. 2.2 **The T3 handler**: targets = the execution DAG's applied .sgr set via the generalized _applied_targets (the py_compile symmetry -- engine fact, never provider prose); unit = file stem; spec bytes -> service.validate() -> Verdict. FAIL => normal red gate with the diagnostics as detail; no-.sgr => NAMED vacuous pass; CCSError => verdict-less defect (a provider cannot fix an unreachable plane). 2.3 **Service resolution**: verify_uow(..., ccs=None) -- injected service wins (tests: ReplayCCSService); resolved ONCE up front iff a T3 gate is named (a T3-less pass never touches the plane); no injection => B3uDevClient, REFUSED loudly with the named next action when unavailable (a named gate is never silently skipped). Zero CLI changes -- `b3ubot verify` gets the tier for free through the default. 2.4 **oracle_feedback IN FULL** (all tiers): the repair loop's diagnostics now pull the complete recorded detail from the verifications.jsonl row (fallback: the node kv) -- the cppcc .log tail reaches the repair provider untruncated. THE U5.2 row's core claim, made literal. 2.5 **The compiler de-double-booking** (Q-23-B): _names_oracle_gate strips [T3:...] machine markers before the prose regex -- the VERIFYING pass owns marked gates; the execution-DAG oracle_gate node remains for PROSE-named checks (the planning shape, unchanged for the legacy fixtures). 2.6 **Tests**: tests/test_orchestrator_t3.py (9 hermetic -- compile shape/ladder, green PASS -> RETRO, named vacuous pass, FAIL -> repair with the FULL `*** error ***` tail asserted in the provider context, budget escalation, defect never repaired, no-plane up-front refusal, T3-less-never-resolves, fixture-key coupling guard) + tests/test_orchestrator_t3_live.py (2 live: real PASS verdict -> RETRO; real FAIL -> escalation with genuine path-scrubbed cppcc diagnostics in the verdict row). Plus the stale pre-U5.2 refusal test in test_orchestrator_verifying.py updated into TWO tests (wired + unknown-check refusal); 3 stale cross-module comment sites (errors/compiler/executing) updated. 2.7 **scripts/p5_gates.sh extended**: the live leg runs 9 legs (client 7 + T3 2); the hermetic twin covers the new files (33 passed + 9 SKIPPED keyless); summary labeled U5.1-U5.2. 2.8 **Docs**: design §2.5 delivered-state paragraph updated (T3 wired; the refusal sentence retired); end_to_end U5.2 done; tests/testing.md same-commit re-measure. EXPLICITLY OUT OF SCOPE (each a named later UoW, never silent): - SCB quartet byte-identity checks ([T3:...] future vocabulary) -> U5.3 - grammar-aware workspace arcs (compile/validate/regenerate) -> U5.4 - foreign-workspace operation -> U5.4a - the full trinity AP arc, mock AND live -> U5.5 - a richer verdict lattice for d9's oracle-signal-driven policy (d9 stays OPEN with its V0 fixed default, untouched) -> later - Track B VerificationRecord entity (P4) -> P4 ## (3) Verification gates G1 VOCABULARY: [T3:validate] extracts + compiles to a t3_ccs node ordered after T0/T1/T2; [T3:] refuses naming U5.3; T4 refusal unchanged -- hermetic pytest green. G2 GREEN PATH: an applied GOOD .sgr -> PASS verdict (replay) -> VERIFYING -> RETRO; T3 verdict row in verifications.jsonl; vacuous pass NAMED when no .sgr was applied. G3 THE ORACLE_FEEDBACK CLAIM: a FAIL verdict drives the repair loop and the provider context carries the FULL cppcc tail (the `*** error ***` fixture line asserted verbatim in the captured repair request); fail -> repair -> green lands in RETRO; budget exhaustion escalates, state stays VERIFYING. G4 DEFECT DISCIPLINE: a CCSError (missing fixture / no plane) never reaches the repair loop -- verdict-less defect => VerifyError; the up-front no-plane refusal names the next action; a T3-less pass never resolves the plane. G5 LIVE (the trinity oracle arc): p5_gates.sh ALL PASS -- the engine's VERIFYING pass drove the REAL local b3u: meta.sgr applied -> PASS verdict -> RETRO; a broken spec -> FAIL with genuine path-scrubbed cppcc diagnostics -> escalation. 9/9 live legs; hermetic twin 33 passed + 9 SKIPPED; B-4 grep. G6 NO REGRESSION: full suite 596 passed + 20 skipped = 616 collected, 0 failed (measured with this file in the corpus); the compiler suite green over the Q-23-B change (prose-named T3 fixtures still get their oracle_gate planning node). G7 Hygiene: porcelain after the WORK commit; testing.md moved with the tests; ledger + design current; gdiff via ../scripts/step_gdiff. ## (4) LOCKs C-23-A b3ubot porcelain clean after each commit. C-23-B VERDICTS REPAIR, DEFECTS ESCALATE: only a recorded FAIL verdict may enter the repair loop; a CCS environment error (unreachable/auth/entitlement/fixture) is an engine/environment defect raised loudly -- burning provider tokens on an unreachable plane is the silent grind design §4 forbids. C-23-C THE APPLIED SET IS THE TARGET SET: T3 validates what the execution ACTUALLY wrote (the tool_call `applied` kvs), never what a skeleton or provider narrates -- the py_compile discipline, inherited verbatim. C-23-D ONE OWNER PER CHECK: a machine-marked [T3:...] gate runs in the VERIFYING pass ONLY -- never double-booked into an execution-DAG oracle_gate node (Q-23-B's rule, enforced in _names_oracle_gate). C-23-E standing locks inherited: B-1/C-22-B (the tier moves bytes over the port, no CCS code here), B-4/C-22-C (credentials env-only), C-22-D (the contract is the seam), B-6 (T4 advisory-only, refusal unchanged), B-3. ## (5) Open questions Q-23-A Unit-name derivation (DECIDED: the .sgr file's stem -- the b3u contract's own path-identity rule). A stem the b3u unit-name rules refuse surfaces as a CCSRequestError => defect (the workspace layout, not the spec content, is at fault -- a human problem, not a repair). Revisit only if a real workspace hits it. Q-23-B The compiler double-booking (FOUND MID-STEP, DECIDED HERE): _ORACLE_GATE_RE's \\bT3\\b matched the machine marker, so a [T3:validate] skeleton compiled an execution-DAG oracle_gate node demanding a scripts/oracle_gate.sh stub. DECIDED: strip [T3:...] markers before the prose regex (C-23-D); prose-named checks keep the planning node (legacy shape, its tests untouched and green). Q-23-C Full-detail feed scope (DECIDED: ALL tiers, not T3 only -- the JSONL row is the durable record for every gate; feeding the truncated kv to the repair provider was a uniform gap the T3 tail merely made visible first). Q-23-D Multi-.sgr policy (DECIDED for V0: validate ALL applied .sgr files, all must PASS; failures concatenate into one red-gate detail. Per-file gates would need per-file gate ids -- a future need with no present consumer). ## (6) Acceptance - [x] Vocabulary + handler + service resolution + full-detail feed live in verifying.py (2.1-2.4); compiler Q-23-B rule (2.5); zero CLI changes. - [x] 11 new tests green (9 hermetic + 2 live) + the verifying suite's updated pair (2.6); G1-G4 hermetic. - [x] p5_gates.sh extended and ALL PASS live (2.7, G5): 9/9 live legs incl. the real-cppcc FAIL tail; hermetic twin 33+9. - [x] Full suite 596 passed + 20 skipped = 616 collected, 0 failed (G6). - [x] Docs moved in the same commit (2.8, G7): design §2.5, end_to_end U5.2 done, testing.md re-measured. ## (7) Hash backfill WORK commit (everything above + this file): (this commit) GDIFF commit (step.23.gdiff.txt): (HEAD) End of step.