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<T1<T2<T3, the CCSService injectable (`ccs=`; a real run resolves
B3uDevClient and REFUSES with the named next action when no plane is
available). FAIL verdicts repair; CCS environment errors are DEFECTS
(never repaired). The repair diagnostics now feed the FULL recorded
detail from verifications.jsonl (all tiers -- the kv stays the
substrate-truncated surface). One cross-module finding executed as
part of this step: the compiler's prose-level T3 regex would have
DOUBLE-BOOKED a machine-marked gate into an execution-DAG oracle_gate
node demanding a scripts/oracle_gate.sh stub -- _names_oracle_gate now
strips [T3:...] markers first (Q-23-B). Suite 596 passed + 20 skipped
= 616 collected; p5_gates.sh ALL PASS with the 2 new live T3 legs
(real PASS verdict -> 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:<unknown>] 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.
