Skip to content

CI two-tier placement + progress-observation lane, and the two defects debugging it surfaced (supersedes #7162) - #7216

Merged
briansrls merged 73 commits into
mainfrom
claude/pr-7162-debug-logs-9f7h53
Jul 26, 2026
Merged

briansrls merged 73 commits into
mainfrom
claude/pr-7162-debug-logs-9f7h53

Conversation

@briansrls

@briansrls briansrls commented Jul 25, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Supersedes #7162 — this branch contains PR #7162's head (82184ae) in full plus two commits, verified: git merge-base --is-ancestor 82184ae HEAD holds and git rev-list --count 82184ae ^HEAD is 0. #7162 is closed in favour of this PR; its review history stays there.

Under the atomic-delivery bar this body describes everything that merges: the inherited CI-placement + observation lane, and the defects that surfaced while debugging its CI runs.

Inherited from #7162 (unchanged)

D0 retention-truth close-out (cli_run.rs) · D3 placement axis (ci_placement.dag, Placement = PrTier | Gauntlet, mechanism landed, not live-wired) · derived floor clamps (gunbc_ci_floor_batch_clamp_params) · observation P0–P3 (model, CI/TTY/seed renderers, census + lockstep witnesses) with floor-memory, [gantt], [governor], [typecheck-attribution], [measurement] migrated · native shell.Env.Get (killed the printenv-per-read spawn class and the false Anomaly lines it painted on unset vars) · warm-cost TSV emitter.

Added here

129b7fe — unstale the slice control

Also lifted to #7222 against main, per operator direction, so it lands without waiting on this PR's timeline — main is red-but-blind on it today.

invalid_slice_returns_compiler_error_type asserted that slicing a List<Int> is a type error. bb4347d (#7196, on main, an ancestor of this branch's merge base) deliberately widened check_slice_access_node (src/v1/04_access.dag) to admit ordered element collections and never updated the witness — left: 0, right: 1.

Bisected by execution in isolated worktrees: green at bb4347d^ (051d06a), red at merge base b86660a, red at PR head — a pre-existing red inherited from main, not a regression from this lane. Confirmed green in this PR's floor: ✓ infer_semantics_witness_keystone_holds … 135.0ms.

The negative control is repointed at a Map base (ordered_element_collections() holds List alone) rather than deleted, and the positive control #7196 admitted but never witnessed is added. Both proven live by perturbation.

Why it reached main green: it never ran there. dag/tools/infer_semantics_witness_transport.dag names its binary by bare string and declares no source-ref edge to the Rust it is compiled from, so the affected set cannot see the edge; main's run at bb4347d skipped 44 of 52 explicit wet-lane witnesses, this among them. It fires here only because this lane adds broadly-imported dag/std/observation.dag / symbols.dag / measure.dag.

c097928 — --arg name=value on gunbc run

Commands::Run was zero-arity by construction: run_in_context ends in call_function(ctx, node, &[], &env), while run_in_context_with_args has sat twenty lines below at v1_interpreter.rs:1564 the whole time, already used by claim_executor.rs:166. Only the CLI flag was missing — and the corpus states the consequence itself (dag/gunbc/roadmap_belt_actuate.dag:689): "gunbc run --function cannot pass an argument (there is no --arg flag), so the node id enters through the environment."

Named-only by construction; a missing = or empty name refuses with exit 2 before the compile, and one malformed spec refuses the whole list. Values enter as Value::Str; no coercion is fabricated. With an empty list the call is byte-identical to the old path. Threaded through the emission authority (05_emit_rust.dag:10270, :10495) and its seed mirror so regen stays a fixed point.

probe result
--arg node_id=roadmap-7 ExitSuccess, exit 0
--arg node_id=wrong-node callee received wrong-node — the value transports, not merely the flag parses
--arg node_id exit 2, names the expected form
--arg =orphan exit 2, names the empty parameter
--arg ok=1 --arg broken --arg also=2 exit 2, whole list refused — no partial application
no --arg zero-arity path unchanged

Plus six unit tests (three RED controls) and 05_emit_rust.dag through the real pipeline: 0 blocking errors. Re-verified after the main merge.

619bba5 — merge origin/main, and a DESIGN correction

Two conflicts in the design_document.dag / DESIGN.md authority pair, resolved by checking the tree rather than by recency:

  • Batch-2 gate list: took main's trim. layering_imports_gate_passes runs in batch 1 (CI receipt) and perturb-receipts is now the discovery witness dag_compile_clean_perturb_receipts_holds, so listing either under "Batch-2 also carries the effectful gates" was stale on our side.
  • Disposition row name: kept ours. Main's prose cites rust_tests_removed_disposition, which exists in neither branch; the real row is commit_gate_rust_suite_removed_disposition (dag/gunbc/commit_workflow.dag:56, identical both sides). Main's DESIGN was citing a nonexistent carrier — this corrects it.

Known gaps in this PR

  • The --arg unit tests run under cargo test, which left CI on 2026-07-11 (gunbc.commit_workflow commit_gate_rust_suite_removed_disposition). An enrolled floor witness for the channel is a follow-on.
  • This adds the parameter channel; it does not migrate callers. GUNBC_BELT_NODE_ID, GUNBC_CI_DIFF_* and CI_FLOOR_EXIT still cross through the environment.

Known blocker: batch-4 clamp

The floor is green on every witness; the sole failure is ✗ FLOOR-BATCH-OVER-BUDGET batch=4 wall_ms=613864 clamp_ms=420000 units=74. The clamp is refusing correctly.

Twelve witnesses account for 483 s of batch 4's 494 s eval (97.8%); the other 62 rows cost ~11 s combined. Every one of the twelve is ≥5 s — over the signed fast-lane budget whose home is already dag/test/claim/long/ + src/v2/test/claim/long/, already excluded at dir grain (ci_layer_roots.dag:440). Moving them lands batch 4 near 130 s against the unchanged clamp. Roster selection held for an operator call, since those rows would stop running per-PR.

The clamp note's own declared calibration gap ("Index 3 (wet corpora) stays a fixed overhead pending a wet-per-witness rate from the D2 probe") was checked and rejected as the remedy: the honest measured rate is ~8 s/unit, giving a 918 s clamp against today's 420 s — filling the gap honestly is a 2.2× raise. Decompose wins, via the roster.

Diagnosis carried forward (no code here)

  1. Affected-set fail-open — src/v2/lens/affected_set/declared_source_ref_selection.dag:101, NoDeclaredSourceRefs => false: an undeclared source-ref set permits a skip. 54 of 55 bin-witness rows declare none. The sibling arm DeclaredSourceRefsUnresolved => true fails closed correctly, so the shape is known — undeclared should refuse, typed and counted.
  2. The fast-lane construction wall has a subprocess-shaped hole — long_lane_exclusion_note claims the 5 s deadline makes an over-budget witness "unwritable-in-place, so the roster cannot silently grow stale (§5 construction over validation)." It did. The deadline is cooperative and unwinds from inside eval; these witnesses block in Command::output() on a spawned child, so it never gets a tick. The §5 claim in that note is not currently true.
  3. Expectation is modeled but unbound — ExpectedOutcome = ExpectSuccess | ExpectFailure exists (output_policy.dag:107), threaded to v1_interpreter.rs:5932, but the sole binding at :6058 is hardwired ExpectSuccess. 24 of the 25 ❌ lines in run 30148859947 are deliberate negative controls; exactly one is the real failure, glyph-identical.
  4. rewire dominates, and Floor batch-3: dissolve the per-(module x key x import) binding rescan in the import-identity rewire (191s -> 17s local); + reconcile-assembly sub-row attribution #7205's fix may not hold at CI scale — [assembly-split] rewire=136772.0ms is 98.3% of reconcile_assembly, with typecheck=91354.7ms second. This branch's merge base is "dissolve the per-(module × key × import) binding rescan … 191s → 17s local"; CI still shows 137 s. Same-counters local-vs-CI comparison is filed, sequenced after the instrument reconciles, non-blocking.
  5. *_failure_receipt is a string-suffix nickname — synthesized for all 1223 *_holds witnesses while exactly one companion exists corpus-wide. b613b3f replaced the loud wrong error with a silent swallow (Err(NoMainFunction) => String::new()), conflating undeclared / out-of-closure / renamed. run_claim_failure_receipt has no RED control anywhere.
  6. Census still one-directional — [attribution] emits un-rostered in a log captured after the census-bidir fix.
  7. Glyph authority is hand-mirrored, and has drifted — the printers that produce the CI log hardcode literals (cli_run.rs:16215, v1_interpreter.rs:5885, :5892) instead of reading extdeps.render.glyphs; the duration formatter at v1_interpreter.rs:5875 uses a 60,000 ms threshold where the authority says 90 s. Separately, batch verdicts go to stdout while the lines they summarize go to stderr — OutputChannel models loudness with no destination axis.

Merge-bar ledger (inherited from #7162, unchanged)

Item Status
First clean live floor log (DoD demo) + warm-cost TSV Needs one uncancelled floor run
D3b gauntlet split Not started — still on bar
Lens-door Not started — still on bar
Two stage collapses Not started — still on bar
Expectation sheet Not started — still on bar
D4 Parked (M2 out of scope)

🤖 Generated with Claude Code

https://claude.ai/code/session_013GELyMsZrGgZRrxte2TCsk

claude and others added 30 commits July 24, 2026 04:51
…hit keys, arm from loader closure

The three post-merge retention defects from the ci-two-tier-placement-redesign §5
review (routed to the #7129 worker) plus the two §7 acceptance controls. Sequenced
first: the falsifier cannot go green — and no downstream placement row can cite true
retention receipts — until these hold.

D0.1 — compile-clean aggregate memo unpin. The whole-tree gate resolved through
resolved_graph_from_sources_with_index, pinning the aggregate ResolvedGraph (hence
every TypedModule) in resolved_graph_memo for the process lifetime — a large slice of
the measured 9.2GB resident floor. Thread a ResolvedGraphMemoShare::{Memoize,Ephemeral}
flag: the gate resolves Ephemeral (no aggregate pin); per-entry discovery keeps
memoizing. The per-module typed-cache warming that IS the gate's purpose is unaffected.

D0.2 — prewarm all-hit registration. try_reconcile_all_cache_hits assembled and
returned on all-hit WITHOUT index_record_schedule_module, so a prewarmed run armed
retention referencing nothing (completion reported evictions while removing nothing).
Record each confirmed hit in the probe, same key forms as the slow path.

D0.3 — arm from the loader's exact closure (the #6985 Class-B root, third appearance).
Arming used selection_adjacency; the discovery loader load_sources_for_entry_with_pool
reaches wider via qualified-projection references from import-bearing files, so those
modules were re-cached after eviction and never re-evicted or counted — an invisible
resident leak. Arm from the loader itself (not a re-derived BFS that could become a
fourth divergence); cost-neutral because the loader memoizes into entry_closure_sources,
which discovery reuses. Removed the now-dead selection_closure_live_paths_with_facts.

D0.4 — the two §7 acceptance controls. index_schedule_entry_completed dropped the
resolved-graph pin unconditionally, so the eviction-disabled retain-all baseline
understated peak retention; gate it on evict_enabled. The E2E control armed BEFORE
prewarming (the order-blindness that let D0.2 pass green), so it never exercised the
all-hit probe; restructure to prewarm -> clear graph memo -> arm -> re-resolve through
the probe, and add a real-index retain-all RED.

Verified green by execution: 7/7 schedule_retention tests, incl. the two restructured
REDs (E2E arm-after-prewarm; real-index retain-all).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
…l-closed admission

The placement-axis half of ci-two-tier-placement-redesign.md D3, buildable ahead of the
D2 srv warm-cost probe. Placement is modeled as DATA (Placement = PrTier | Gauntlet),
never per-site prose, with a FAIL-CLOSED admission law: a check is admissible as PrTier
only with (a) a measured warm-cost receipt within the fast-lane budget AND (b) a
hermetic/ephemeral classification; unmeasured or unclassified => inadmissible as PrTier,
so its only valid placement is Gauntlet. No row rides the fast path by taste.

The 5s threshold is REUSED from the single fast-lane authority
(gunbc_ci_fast_lane_eval_budget_ms, v2.workflow.ci_floor_plan) — never a second 5s
definition (DESIGN §3).

Verified green by execution (claim_batch, 4 witnesses):
  - Gauntlet always admissible
  - a within-budget hermetic PrTier admissible
  - RED control: an over-budget (6000ms > 5s) PrTier is refused
  - RED control: an unclassified PrTier is refused
The controls pin the threshold discriminatingly (1600ms admits, 6000ms refuses) and the
classification gate (Hermetic admits, Unclassified refuses).

Deferred to PR-1 (D2-gated): filling the roster of real checks with measured receipts
(flipping rows to PrTier as srv warm-cost lands), wiring the law onto the live check
rows, and the Gauntlet workflow split (D3b).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
… authority

Per ci-two-tier-placement-redesign.md §11. Introduces DiffBaseline
(MergeTarget | PushParent | OperatorOverride{ref}) as the single authority for
"which git ref a diff/merge selects against", grounded on the extdeps.git atoms
(GitRef, git_remote_ref_parts). resolve_diff_baseline is a pure, fail-closed fold
over injected env values — a PushParent with no parent ref REFUSES rather than
fabricating a ref.

Live consequence fixed (site 1, floor selection): a stacked PR now selects
against its real merge target (origin/$GITHUB_BASE_REF), not origin/main.
DiffPolicy.base becomes a DiffBaseline; floor_diff_observe.floor_resolved_base
resolves it at eval time from GITHUB_BASE_REF, fail-closed to UnifiedDiffFail
(the floor widens to the full corpus) on an unresolvable base — never a silent
wrong selection.

Fork dissolution (no behavior change) — sites 2/3/4 re-ground the same literal
onto the authority: merge_admission_produce (merges into main),
roadmap_dispatch_actuator (branches from main), ci_workflow Push/PR triggers
(main). The ci_merge_base_ref alias and the dead ci_merge_base_diff_range are
deleted.

Also carries the parked miscite fix (rust_tests_removed_disposition ->
commit_gate_rust_suite_removed_disposition) in DESIGN.md / design_document.dag /
ci_spec.dag, per plan §3.3.

Verified by execution: ci_diff_baseline_witness_test (6/6, incl. the
discriminating stacked-PR pair and the PushParent-refuses fail-closed control);
ci_spec_witnesses (fetch renders "origin $GITHUB_BASE_REF"; single authority);
roadmap_dispatch_actuator_witnesses. ci.yml + DESIGN.md regenerated via main_wet
(drift clean; the two floor/regen fetch lines now expand $GITHUB_BASE_REF).

floor_diff_observe_witness_test runs green in the floor's wet mode; its eval-time
env reads are unmockable under claim_batch strict-hermetic, a PRE-EXISTING
harness limitation confirmed by a clean-tree stash run of the same witness (this
change adds no new hermetic red).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
P0 of the progress-and-observation lane (docs/plans/progress-observation-design.md,
operator-signed 2026-07-23; §6b/§6c doctrine from #7169 folded in). Model only —
no renderer, no emit site touched.

ObservationEvent = subject (a typed containment path: run ⊃ batch ⊃ entry ⊃ module
⊃ phase) × Begin | Step{k,n} | Concluded{outcome} × measured facts. Outcomes are a
closed sum with Refused DISTINCT from Failed — the reference implementation conflates
them, which is how a deliberate refusal reads as a crash.

Grounded on existing authorities rather than minted:
- ancestry reuses std.effect_grant.path_is_prefix (one prefix relation, not a second walk)
- over-budget arithmetic calls std.temporal_effect.stall_budget_verdict
- change kind projects from std.change.KeyedDiffHunk — no second added/modified/removed enum
- glyphs extend std.symbols + extdeps.render.glyphs rows (the one table), never a fork
- module_path/source_path carry std's existing representation (std.decl_ref's), with
  convergence to QualifiedName/SourceRef declared, not assumed

Derived, never hand-set: AttentionLevel from a supplied basis (the signed clamp
constants — no threshold is invented in this module); BlockedOn from SchedulerHold,
which is held in lockstep with the seed governor's HoldReason by execution; T from the
heartbeat period the seed actually sleeps, declared a Scaffold with the measured
quiet-time distribution as its dissolve-on.

Construction over validation: the no-op sum is closed (docs-policy | uncovered |
no-decls-touched | generated-artifact | departed-path), so a bare unlabelled "nothing"
is unwritable rather than censused after the fact; uncovered derives a visible nudge,
departed-path is typed as a widen and not a no-op.

Green by execution, with discriminating REDs proven by perturbation:
- 28 model conjuncts + 6 lockstep conjuncts PASS
- orphaned law row (enforced_by names a missing declaration) → RED
- Refused/Failed collapsed onto one glyph → RED (both distinctness and collapse laws)
- glyph-table row perturbed → presentation moves → RED (single authority, by execution)

Compile-clean attributed: the closure's 47 errors are pre-existing in std/measure.dag
(46) and std/effect_grant.dag (1) — identical counts compiling those entries alone;
zero attributable to this change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Addresses the blocking finding on the three coproduct predicates, taking its
stronger alternative (dissolve into the canonical surface) rather than only
its weaker one (add a disposition receipt).

The finding was right about the real defect: observation_class_is_intrinsic_anomaly
was a second hand-written table beside observation_presentation, and a witness
asserted the two agreed. That witness was validation standing exactly where
construction was available — it conceded the tables could disagree and promised
to notice.

Fix: ObservationDensity (RoutineCollapsible | SummaryAlwaysShown | AnomalyExpanded)
is now the one table. collapsible, expands_fully and intrinsic-anomaly are all
derived projections of it, so disagreement is unwritable rather than detected.
The three display states stay distinct — the run summary is neither routine nor
an anomaly, which a single boolean would have forced it to borrow.

Disposition receipts added for the remaining structural readers, matching the
cited materialization_ladder pattern: outcome/class, subject/grain/hold, and
selection no-op. Each states why it is Terminal and names its discriminating
corpus rather than asserting terminality.

Witness roles now separated and both proven by execution:
- w_density_is_the_single_display_authority — the content check; reds when a
  class's density changes (verified: ClassRefused → RoutineCollapsible reds it,
  and reds ONLY it, since the projections cannot disagree)
- w_presentation_projects_density_rather_than_restating_it plus the two collapse
  witnesses — construction guards; red when the presentation stops projecting
  density (verified: hardcoding collapsible: true reds all three)

Full suite green: 30 model conjuncts, 6 lockstep conjuncts. Compile-clean
unchanged — 47 errors, all pre-existing in std/measure.dag (46) and
std/effect_grant.dag (1), zero attributable here.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The finding is correct and the hard-blocker applies: avg10_centi was a
percentage magnitude with a scale carried on bare Nat, and the note beside it
self-justified the conflation rather than tracking it.

Fix consumes an EXISTING carrier rather than minting one, which the corpus
had already asked for in advance. std.measure.basis_point_dissolve_on warns:
"else a third dimensionless-ratio use-case mints a third nickname" — this
module is exactly that third use-case, so minting PerMille or a Percentage
quantity would have walked into the failure the row names. BasisPoint's own
note declares its semantic axis as utilization ratios, which is what a PSI
stall share is.

Resolution is exact rather than truncated: the governor reads one decimal of
a percentage and a basis point is a hundredth of a percentage point, so
37.5 percent is 3750 with nothing lost. Percent (Dimensionless, One) would
have truncated it.

Note rewritten to state the grounding and the deliberate non-mint, replacing
the self-justification. When the Ratio<Scale> unification that dissolve-on
calls for lands, this field follows Percent and BasisPoint onto it with no
change of meaning.

Suite green: 31 model conjuncts, 6 lockstep conjuncts. Compile-clean
unchanged — 47 pre-existing errors in std/measure.dag (46) and
std/effect_grant.dag (1), zero attributable here.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…t list

Per ci-two-tier-placement-redesign.md §9.8 (operator 2026-07-24). Replaces the
hand-set gunbc_ci_floor_batch_wall_budget_seconds list — a scalar wall budget
that conflated workload size (diff-proportional selection), host speed, and
per-unit cost creep — with a per-batch clamp computed at run time:
clamp_ms = overhead_seconds*1000 + runtime_unit_count * per_unit_ms.

The load-bearing row is the discovery witness batch (index 2): 300s + 1000ms per
witness, so a full corpus of ~2316 witnesses clamps at ~44min (under the 55-min
step cap, with headroom over the observed 1344-1629s walls) while a runaway reds
proportionally, instead of the fixed 1320s that redded legitimate hub-file PRs.
Fixed-count gate batches carry rate 0 at their measured basis; index 3 (wet
corpora) stays a declared fixed overhead pending the D2 probe's wet-per-witness
rate.

Authority: gunbc.ci_spec FloorBatchClamp + gunbc_ci_floor_batch_clamp_params
(index-aligned to the 7 batches; the cover-schedule witness pins the alignment)
+ gunbc_ci_floor_batch_clamp_note (carries the raise discipline from the kept
static-era note). The 5s per-WITNESS max is unchanged — still the single
gunbc_ci_fast_lane_eval_budget_ms authority, never redefined here.

claim_executor reads the two index-aligned param lists fail-closed, derives the
per-batch unit count from batch_results (corpus_witnesses for discovery
aggregates, 1 per gate row — the runtime datum the static list ignored), computes
the clamp at enforcement, and refuses over-clamp as a typed FLOOR-BATCH-OVER-BUDGET
(never a widen). The GUNBC_FLOOR_BATCH_BUDGET_TIGHTEN_MS RED-control hook now
lowers the COMPUTED clamp. The receipt emits batch_N_units / batch_N_clamp_ms /
verdict; its unit test is updated. Both run_walk call sites carry the new param.

Verified by execution: build clean; ci_floor_plan_witnesses green (the three new
clamp witnesses + cover-schedule). The receipt verdict unit test and the fixture
RED control (budget_red_control_plan; TIGHTEN_MS=0 -> clamp 0 -> the
FLOOR-BATCH-OVER-BUDGET refusal) are the e2e enforcement confirmations; the
fixture's control witness triggers a whole-tree emit that OOMs alongside a compile
in this container, so both run as a clean post-commit confirmation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
… my redundant D5

Main advanced to 12e2ed5 while this branch was built. #7146 ("Derive the diff
baseline from the CI event; kill the origin/main fork") landed the *exact* purpose
of my D5 independently, and more completely: a dedicated gunbc.diff_baseline module
with a CiDiffEvent-modeled, RED-testable pure resolver that HALTS the floor with a
typed AFFECTED-SET REFUSAL on an unrecognized event (fail-closed) rather than
defaulting. It is the single authority now, so my D5 is redundant and dropped.

Conflict resolution (all 8 D5 files): took main's #7146 version wholesale —
floor_diff_observe, merge_admission_produce, roadmap_dispatch_actuator, ci_workflow,
ci_spec_witness_test, floor_diff_observe_witness_test, ci_spec; deleted
ci_diff_defaults.dag (main moved DiffBaseline to gunbc.diff_baseline). My D5's
DiffBaseline/ci_diff_defaults changes are gone; the miscite fix and Piece 3 stay.

Re-applied onto main's ci_spec.dag/ci_workflow.dag the parts that are NOT D5:
- Piece 3 derived clamp (FloorBatchClamp + gunbc_ci_floor_batch_clamp_params +
  clamp_note), replacing main's static gunbc_ci_floor_batch_wall_budget_seconds
  list (which had two operator-signed raises 1320->1440->1680 the clamp supersedes;
  the raise history is kept in the SUPERSEDED gunbc_ci_floor_batch_wall_budget_note).
- The parked miscite fix (rust_tests_removed_disposition ->
  commit_gate_rust_suite_removed_disposition).
- The ci_workflow prose re-point to the clamp authority.

D0 (cli_run.rs retention) + main's #7146 cli_run.rs auto-merged non-overlapping;
D3 (ci_placement.dag) and the rest of Piece 3 (ci_floor_plan.dag, claim_executor.rs,
budget_red_control_plan.dag, ci_floor_plan_witness_test.dag, ci_layer_roots.dag)
carried through.

Verified: ci_floor_plan_witnesses green on the merged tree (346 modules; the three
clamp witnesses + cover-schedule). Rust rebuild + regen follow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
…ned D5 witness

The merge that adopted #7146's landed gunbc.diff_baseline (and dropped my
redundant D5 gunbc.ci_diff_defaults) left two remnants:

- .github/workflows/ci.yml carried an auto-merge artifact — the regen step
  and floor step fetched `origin $GITHUB_BASE_REF` (my dropped D5's bare-var
  form) instead of `origin main` (#7146's authority, which resolves the diff
  baseline at floor eval-time via resolve_diff_baseline, not at fetch time).
  Re-running `gunbc ci` regen re-derives ci.yml from the merged
  ci_workflow.dag, restoring the `origin main` fetch.

- src/v2/test/claim/ci_diff_baseline_witness_test.dag imported the deleted
  gunbc.ci_diff_defaults module (my D5 authority), which would break the
  corpus compile. Its 6 witnesses are strictly superseded by #7146's landed
  dag/test/claim/diff_baseline_witness_test.dag (11 witnesses, with stronger
  fail-closed semantics on PR absent-base). Deleted as dead weight.

Co-Authored-By: Claude <noreply@anthropic.com>
…ance

Second phase of the atomic P0-P3 observation PR (operator ruling: only
finished work merges; a landed event model with no renderer is vocabulary
nobody can see).

gunbc.observation_ci_render projects the std.observation stream into
append-only log lines. It computes nothing and holds no telemetry source —
every number it prints arrives in an event or a heartbeat sample the process
already had — which is precisely what makes replaying a real captured run
possible rather than a synthetic fixture.

FLAGSHIP ACCEPTANCE, green by execution: the fixture is run 30044816605's
actual log, not a reconstruction. Its heartbeat at t=33m carried
current=16107200512 swap=34359738368 psi_some_avg10=9.01 and named no subject
at all, while the process sat inside v2.compiler.normalized_tree for 606984ms
and disclosed that only at walk end. Re-rendered through the escalation law
the same window produces named activity: identity-first heartbeats in human
units (15.0 GiB, not the raw byte dump), the quiet module surfaced at T, and
the memory-reclaim cause surfaced at 2T.

Contracts from section 6b in force: plain-sentence tone, real emojis from the
one glyph authority with the clock pulse, identity before vitals, durations on
every outcome line, refusals restated at the end so log truncation cannot hide
them, and relayed subject text neutralized through the existing GitHub guard
so a child's stderr cannot mint workflow commands in the parent run.

Law 4 made structural: line placement is DERIVED from attention, so a refusal
cannot be written into a collapsed group — the group is exactly where a reader
will not look. Escalation has two rates: reveal depth grows linearly (one tree
level per threshold) while emission points double (T, 2T, 4T), so a window
that stays quiet escalates without becoming a per-minute drumbeat, bounded by
construction.

Three REDs proven by perturbation, as the ruling requires:
- planted silent phase (escalation never emits) reds responsiveness
- an orphaned Begin reds the watchdog
- a Refused placed inside a collapsed group reds

Review 42203 (three findings, all correct, all fixed):
- ci_gibibyte_tenths respelled the GiB scale factor as a literal; it now
  consumes std.measure.gibibyte_scale_factor_bytes, and the duration helper
  consumes seconds_per_minute plus a new milliseconds_per_second added beside
  its siblings in that authority. A unit authority forked inside a formatting
  helper is easy to miss because it looks like arithmetic.
- the run summary picked the refused glyph whenever refusals+failures>0, so a
  failures-only run rendered as refused — collapsing at the last line exactly
  what the outcome sum exists to establish. Failures now dominate the glyph,
  refusals keep their own, both counts stay in the text.
- an unavailable duration silently vanished from concluded lines, breaking the
  model's own rule that an absent measurement names its cause. It now says so.
Each fix carries a witness; the summary fix carries its own RED.

Suite green: 31 model, 6 lockstep, 18 renderer conjuncts. Compile-clean
unchanged at 47 pre-existing errors, zero attributable here.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rriers

Third phase of the atomic P0-P3 observation PR.

gunbc.observation_tty_render projects the SAME std.observation stream the CI
renderer projects — a sibling, not a successor and not a second model. The two
differ only where the medium differs: a terminal can be repainted, so routine
progress overwrites one line in place and stays quiet; a CI log cannot, so it
appends. Everything they share — the event vocabulary, the density authority,
the glyph table, the duration/byte/percent projections, the hold-cause text —
is imported from the CI renderer or the model, never re-derived. A witness
proves the sibling property by execution: the same event drives both surfaces
and moves together.

The three upgrades over the reference implementation are INHERITED from the
shared carriers, not re-earned: outcome lines carry durations, Refused is
distinct from Failed, and dwell escalation is recursive. The reference has none
of the three; the TTY renderer gets them for free by projecting the same model.

Law 4's asymmetry, expressed here as cursor action rather than group placement:
repaint-vs-scroll is DERIVED from attention, so a refusal cannot be repainted
away — overwriting it would erase it the instant the next line arrived, the
terminal form of burying it in a collapsed group. Required preamble (no
anonymous process), BlockedOn inline with named remaining (a bounded estimate
prints the time; an unknown one prints why, never a fabricated ETA), and the
reward animal on Final drawn deterministically from the one glyph authority so
replay is preserved and a non-emoji terminal degrades to a word.

Also in this commit: the self-host regen of the seed. P1 added
milliseconds_per_second to dag/std/measure.dag, a seed-emitted module, so
src/v1/stage0/src/std_measure.rs is regenerated to match — the required
same-PR regen for a generated-artifact source edit. Fixed point verified by
rebuilding regen_stage0 from the new seed and re-running to zero drift.

Suite green: 31 model, 6 lockstep, 18 CI-renderer, 10 TTY-renderer conjuncts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fourth and final phase of the atomic P0-P3 observation PR.

gunbc.observation_emit_census is the census authority. Every place the floor
emits a progress line is either a projection of the observation event stream
or a counted frontier row with a reason and a dissolve-on — the same
discipline the site lane uses for unthemed colours. EmitSiteDisposition is a
closed sum, so a site cannot be half-classified, and there is no third arm for
a site the census has not looked at: the roster's completeness is what the
witness checks against the seed.

The roster carries the structured-tag emit families that exist regardless of
the CI rework: [floor-memory], [typecheck-attribution], [gantt], [governor],
[measurement]. The named negative example the operator called out — the
[floor-memory] raw byte dump — is a rostered frontier row, so the census
already carries the very site it exists to kill, with its dissolve-on naming
the P1 heartbeat projection that replaces it.

Sequencing per the ruling and design section 6b: the CI two-tier rework
rewrites the floor's emit sites, so the exhaustive per-print wall over the ~75
raw eprintlns in claim_executor is a declared frontier gated on this PR
rebasing over that rework and re-censusing. Censusing sites about to be
rewritten is the double-churn the operator ruled out. What lands now is the
census model, the roster, and the executable hygiene witness — never a hidden
zero: five families migrated-pending, the raw-print residue counted, and the
witness holding the roster against the seed so it cannot rot into a lie.

Executable, not inert: the witness reads the live seed and reds when a rostered
marker has vanished (staleness — proven by a RED control) or when a frontier
row lacks a real dissolve-on. The [floor-memory] shape is checked positively —
still present, still classified frontier — so the census cannot quietly drop it.

This completes P0-P3. Full suite green by execution: 31 model, 6 lockstep,
18 CI-renderer, 10 TTY-renderer, 6 census conjuncts, each with discriminating
REDs proven by perturbation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ition, 2026-07-24)

The 1000ms aggregate coefficient now records its basis in gunbc_ci_floor_batch_clamp_note:
host class (srv arm64 self-hosted, capped) x the adaptive governor's realized worker
width, denominated against the observed 0.58-0.70 s/witness (the 1344-1629s full-corpus
fleet envelope over ~2316 witnesses). Naming the basis makes a future width or fleet
change a deliberate re-sign of the constant, never a rediscovered fleet-wide red; the
~1.4-1.7x headroom over the observed top rate is exactly the >=~1.6x runaway the clamp
catches, with sub-threshold creep owned by the gauntlet's per-cadence s/unit receipt.

Co-Authored-By: Claude <noreply@anthropic.com>
…timings

Instruments claim_executor with write_gate_warm_cost_receipt — one row per gate/claim
(eval wall + resolve + combined warm_ms) and a discovery row carrying the per-witness
rate — derived from the ClaimResult timings the walk already records (operator ruling
2026-07-24: instrument the existing floor, no throwaway probe workflow). Written to
target/floor-gate-warm-cost-receipt.tsv and mirrored to the log as [gate-warm-cost] rows
so the placement probe lifts it from get_job_logs on a fleet run. This is the placement
roster's measurement basis: a gate rides PrTier only if its measured warm cost is within
the 5s fast-lane budget, else fail-closed to Gauntlet (v2.workflow.ci_placement). Every
floor run now auto-emits it; run cold-then-warm on >=2 hosts and the roster records value
+ host basis. Verified green-by-execution locally (single-claim row); the discovery-row
path verifies in the next full-corpus CI floor. Fail-closed on a write error, consistent
with the other floor receipts; never a verdict term.

Co-Authored-By: Claude <noreply@anthropic.com>
The operator's "show me": proven-by-witness without a visible sample is the
fluent-but-unseen trap. dag/test/claim/observation_crawl_replay_test.dag
renders the captured crawl window of run 30044816605 through the P1 CI renderer
as one assembled block and asserts it by execution:

- names the module where the capture was silent ("still in witness discovery:
  entry 214 of 602, now typecheck v2.compiler.normalized_tree", surfaced at T,
  the memory-reclaim cause at 2T)
- uses human units, never the raw byte dump (15.0 GiB, not 16107200512)
- ends in a named refusal summary, not a silent 55-minute timeout

observation_crawl_after_block() is the exact function the PR body's after-sample
is produced from, so the pasted before/after is a projection of a green run
rather than prose. Every input number is read off the real log.

The earlier gunbc/observation_crawl_demo.dag (a run-entry that returned a String
and so errored on the ProcessExit contract) is replaced by this witness — a
green check is worth more than a run-entry that prints then fails.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… kill the [file] firehose

The floor's [file] read firehose (2265 lines / ~99% of the log, measured by execution)
was the pre-plan naming-hygiene walk reading the whole source tree at the OutputDecision
Full default, because install_output_policy ran AFTER the walk (claim_executor.rs order).
gunbc.output_policy already models Instrumentation => Suppressed at Normal (CI's default
verbosity) and ShellTrace => Condensed — the walk just never saw the policy.

Fix: install the policy (and group syntax) FIRST, before the naming walk and every
subsequent corpus read, so all host-effect traces are funnelled per the .dag authority.
Verified by execution on the minimal smoke plan: [file] read 2265 -> 0, total log
2613 -> 24 lines, claim still PASS (exit 0). The Ambient semantics hold — the policy's
divergence rule (ExpectedOutcome/ObservedOutcome) still expands a captured stream on
failure, so a red effect is never silenced; only the green firehose is.

This is the highest-leverage lever of the observation-emit census flip (the echo class
the census targets). Follow-on commits route the display families ([floor-memory],
[gantt], [governor], [measurement], [t+..]) through the observation stream as Ambient
projections (the ✅/🕐/🚫 format matching #7168's "after" block).

Co-Authored-By: Claude <noreply@anthropic.com>
…uthority

Step 2 of the flip (format), after step 1 (the [file] firehose, volume). The
prelude phase marks are the visible display class in the short regen job's log;
they now render through the single-authority observation renderer instead of a
raw [t+…] byte string the seed would fork the format into.

  before: claim_executor: [t+86.1s] naming-hygiene walk complete
  after:  ✅ naming-hygiene walk done in 48 seconds

- New seed→.dag boundary gunbc.observation_seed_render: primitive args in, a
  rendered line out — exactly as cli_run.install_output_policy calls
  output_policy.resolve_channel_policy. A phase concluding is modelled as a
  Concluded event on a PhaseSegment subject, projected by
  ci_event_line ∘ ci_render_line, so the FORMAT stays single-authority in
  gunbc.observation_ci_render and the seed constructs no format of its own.
- The raw [t+{:.1}s] eprintln is DELETED, not suppressed (grep-clean for the
  print). §5: on a renderer-unreachable failure the arm names the degradation
  loudly and never reproduces the old marker.
- Per-phase walls (delta since the last mark), not a running t+, so the log
  itemizes which prelude phase is slow — the step toward the per-phase receipt
  keys the ci_spec prelude-coverage-hole follow-up (row a) calls for.
- Green by execution: phase_mark_renders_through_the_observation_render_authority
  resolves the adapter through a real interpreter and asserts human units + the
  completed glyph + NO [t+ marker (the discriminating RED). The seed→.dag
  resolve is memoized, so the renderer resolves once and later marks are cache
  hits. Rust-called-.dag-unimported has precedent (output_policy.dag).

Next in the series: the rostered census families. floor-memory (the flagship
byte dump) needs its subject feed plumbed first so it renders honestly (entry X
of Y, never a fabricated 0 of 0), then gantt/governor/typecheck-attribution,
each flipping its census row (CountedFrontierSite → MigratedToObservation) with
the witness restructured to assert the raw marker is gone — the "witness fixes"
step of flip → witness fixes → roster.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
…ld_residue)

The progress-and-observation merge (#7168) added observation_ci_render.dag,
whose ci_hold_cause_text names the two memory-pressure SchedulerHold variants
specifically and gives the other five a generic cause via a top-level wildcard
arm — a non_fold_residue site. It landed unrostered because per-PR affected-set
selection predict-skips the corpus-read nfr witness (the masking class the
roster's dated rows document), so it reds only on a cold whole-corpus sweep
(falsifier / merge-to-main), not on the selected PR floor. That is the census
wall doing its job on its own author.

Roster it (gunbc.non_fold_residue, one FrontierRow, reason + dissolution trigger
toward a total match), matching the established masking-class fix and preserving
the observation author's design.

Green by execution: observation_hold_cause_wildcard_is_rostered asserts the live
roster now carries dag/gunbc/observation_ci_render.dag::ci_hold_cause_text via
the same host reader the corpus scan uses — reds if the row's key drifts from
the scan's {rel}::{fn} key or the hand edit malformed the 126-row list.

design_register_lift_parity (the other cold-red thought to be surfaced by the
merge) is NOT touched: this branch's gunbc.site.* inputs are byte-identical to
main and recent main-push runs are green cold, so it is green here too — not
attributable to this PR.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
… strings

Foundation for migrating the [floor-memory] byte dump to the observation heartbeat.
Adds gunbc.observation_seed_render.seed_heartbeat_line: the seed→.dag boundary that
takes the primitives the heartbeat thread has (elapsed, batch label, entry position,
memory vitals) and projects them through the one renderer (ci_heartbeat_line ∘
ci_render_line) — identity first, human units, no raw byte dump. The subject is
batch-grain by construction: the floor walks entries in parallel, so there is no
single active module to name, and the primitive interface carries none — never a
fabricated per-module "now typecheck X".

Green by execution: seed_heartbeat_line_renders_identity_first_in_human_units pins
the exact bytes for two samples through the real interpreter:

  🕐 33 minutes in — still in witness discovery: entry 214 of 602. memory 15.0 GiB, swap 32.0 GiB, pressure 9.0%
  🕐 500ms in — still in self-host fixed-point: entry 0 of 2. memory unreadable (cgroup field unreadable), swap 0.0 GiB, pressure unreadable (cgroup field unreadable)

The first is the captured crawl window re-rendered from the seed's own vitals (raw
byte value absent); the second proves an unreadable cgroup field names its cause,
never a fabricated zero (observation law 2 / §5). These golden strings are the oracle
the Rust mirror is proven byte-equal to in 4b.

Why a Rust mirror next, not an interpreter call: the heartbeat runs on a detached
liveness thread in a memory-constrained context — resolving the renderer there would
build a duplicate module index, consuming the very memory it watches (§2), and the
thread exists to stay alive when the main interpreter is busy. 4b adds that mirror
(proven == this oracle), plumbs the subject feed, wires it, deletes the byte dump,
and flips the census row.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
…ort-decomposition lane)

Operator-directed finding (2026-07-24), do-not-fix-here. Records in the residual-shell
census (§0b) a class distinct from that doc's shell-EMISSION axis: modeled ops whose
interface shape is right but whose single hardwired transport is a shell escape where a
NATIVE in-process handler is correct — the verbatim §3(b) N×M-adapter tell.

shell.Env.Get (extdeps/shell/shell.dag:42) reads an env var the process already holds
in its own environment by spawning `printenv` (wet_env_var, v1_interpreter.rs:5096).
Reading your own environment is not a host effect; std::env::var is the native handler,
chosen when locality is OnTarget, with shell/ssh reserved for a var on another host.
Sibling: shell.Which.Check (`command -v`), already in the census. One root, three lanes.

Not a floor-time lever (~ms/spawn); filed so the deficit is counted and prioritizable
(§6), never absorbed into "it's only a few ms." Its native read is the lane's cheapest
first consumer (a pure in-process read, no host_effect_apply even).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
…maly self-describing

The [shell]/$ echo class still printed at Normal after the firehose fix: it is the
ShellTrace channel at Condensed, not the Instrumentation channel that [file] read rode.
But naive "suppress ShellTrace at Normal" is a §5 fail-open — the failure stderr block
rides the SAME channel via trace_emit(), so Suppressed would silence failures too. That
Condensed was load-bearing.

Root (operator's naming): one channel carrying two content classes with OPPOSITE
attention — routine scaffolding (Ambient) and failure evidence (Anomaly) — a
state-space conflation at the channel grain, exactly what the observation model
dissolves by deriving attention per event, not per channel (law 4: routine collapses,
anomaly expands). The fix uses the two EXISTING mechanisms, each governing its class —
no third decision mechanism:

- Routine ($ argv pre-spawn echo + [shell] done exit=… count) → the ShellTrace CHANNEL
  → Suppressed at Normal (Instrumentation's debug-only shape), Full at Verbose.
- Failure evidence (stderr block) → the effect_stream DISPOSITION (SurfaceContent)
  ALONE, not the channel, so suppressing the routine echo cannot silence a failure.

Two upgrades the disposition-gated block gains, both §5-correct now that the count is
silent at Normal:
1. SELF-DESCRIBING — the block carries its own `$ <argv>`, so the failing command never
   scrolls away from its stderr (the pre-spawn echo it used to borrow from is gone at
   Normal). Strictly better than what suppression would have taken away.
2. SURFACES ON EMPTY STDERR — the block names the exit even when the command wrote
   nothing, because the routine count that used to carry the exit is now silent.

Proven by execution: four-corner effect-stream suite kept; new discriminating RED
at_normal_a_failing_effect_surfaces_its_command_a_passing_one_is_silent (passing →
None; failing → `$ <argv>` + stderr) + stderr_block_surfaces_on_surface_content_even_with_empty_stderr.
Channel witness updated (w_shell_trace_routine_is_debug_only: Suppressed at Normal).
Convergence named in output_policy.dag: when shell effects become observation events,
trace_emit(channel) stops being the gate and derived attention replaces this split.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
… unbreak the branch

This reverts commit 60a4496. Two defects, the second fatal to the approach:

1. Parse break (caught late): the witness carried `//` comments, but daglang has NO
   line-comment syntax — documentation is `data …_note: String` only. build_module_path_index
   scans every .dag at install_output_policy startup, so the parse error panicked the whole
   floor, not just that witness. LESSON: verify .dag by execution before pushing; a Rust-lib
   test does not exercise the .dag parse/resolve path.

2. The approach itself was wrong (the real reason for the full revert). Making ShellTrace
   Suppressed at Normal does not just silence the routine echo — effect_stream_disposition is
   GATED BY channel_decision:

     match channel_decision(channel, verbosity) {
       Suppressed => StreamSuppressed          // failures silenced
       Condensed  => divergence_disposition(…) // divergence surfaces, agreement counts
       Full       => SurfaceContent
     }

   So Condensed-at-Normal is load-bearing TWICE (trace_emit AND the divergence disposition),
   and host-effect grouping keys on the same channel. Suppressing it is a §5 fail-open
   (a real failing effect's stderr goes silent at Normal); the Rust test passed only because
   it read the hardcoded EFFECT_STREAM_POLICY_FALLBACK, masking the installed-policy break.
   The alternative (route routine → Instrumentation, keep ShellTrace Condensed) leaves empty
   `##[group]` brackets and buries the failure block inside the collapsed section.

FINDING for the redo: the channel↔disposition↔grouping coupling IS the "one channel, two
content classes" conflation the operator named — and there is no clean immediate fix that
does not touch it. The correct fix decouples the failure disposition from the routine
channel verbosity (the "bigger lift" flagged as needing a design steer), which lands back
at the operator's "Hold — I'll steer". The self-describing failure-block design (carries its
own argv, surfaces on empty stderr) is sound and preserved in 60a4496's history for reuse.

Branch returns to the green b35a4b3 state. Shell-echo goes back to HELD pending the
disposition-decoupling design decision.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
…mirror

Flagship of the observation wiring flip: replace the [floor-memory] raw byte
dump with the identity-first 🕐 heartbeat, proven byte-equal to the 4a seed
oracle (seed_heartbeat_line).

- render_heartbeat_line_mirror: pure Rust mirror of ci_heartbeat_line ∘
  ci_render_line — the heartbeat thread cannot call the interpreter (duplicate
  module index under the memory envelope it watches). Discriminating RED
  render_heartbeat_line_mirror_matches_seed_oracle pins byte-equality on the
  crawl-window and unreadable-field goldens.
- HeartbeatFeed (cli_run): process-global batch label + entries done/total,
  armed only when entry_total is known and non-zero (never a fabricated
  0-of-0). Updated at batch-enter and at the existing
  index_schedule_entry_completed per-entry point (SingleClaim path increments
  per claim result). Discovery fills the total once the roster's entry-group
  count is known.
- Delete the byte dump; keep the regime-disclosure line (marker stays for
  census hygiene). Flip floor_memory_site → MigratedToObservation; restructure
  census/lockstep witnesses (frontier 5→4, dump shape asserted gone).
- Also: strip invalid // comments from output_policy_witness_test.dag that the
  shell-echo §5 commit left (dag has no // comments — parse Slash).

Co-Authored-By: Cursor <cursoragent@cursor.com>

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…e-clean diags

Resolve cli_run.rs three-way conflict in resolved_graph_from_sources_with_index:

- Keep ResolvedGraphMemoShare { Memoize, Ephemeral } from this branch (D0.1 —
  compile-clean whole-tree graph must not pin the process share).
- Adopt main's compile_clean_diags 3-tuple return +
  compile_clean_diags_from_resolved_stages helper (#7179 policy fork).
- Adopt main's disk-cache hit refusal scaffold (diag union absent from v1
  artifacts); Ephemeral still gates the in-process memo install.

Green by cargo check --lib.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
CI build failed at the fmt --all --check gate (assert_eq! wrapping +
HeartbeatFeed Mutex.lock() chain). No behavior change.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…ction

Compile-path trace_mark and GUNBC_FLOOR_GANTT emit through
phase_begin_line / phase_concluded_line mirrors (byte-equal to the seed
oracle; interpreter render from inside compile would recurse). Census
row MigratedToObservation; raw t_ms/rss_mib shapes gone. Frontier 4→3.
Verified via claim_batch on observation_emit_census_witnesses.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…ion projection

HoldReason emits through seed_governor_hold_line (mirror
render_governor_hold_line_mirror); hard/creep/receipt/startup lines lose
the raw [governor] key=value shape. Census MigratedToObservation;
frontier 3→2. Mirror↔oracle byte equality for PsiPressure and
CurrentHighWater. Verified via claim_batch + memory_governor unit tests.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
claude added 2 commits July 25, 2026 23:43
… calls

Traced all three remaining "untraced" census entries to their ISSUING fn
rather than counting occurrences in the witness file, per the srv3 lesson.
Two of the three turned out to be helper-mediated, not direct.

CONVERTED — grep.Grep.MatchesFixedString in
install_media_remaster_ensure_grub_cmdline. grep exits non-zero when the
pattern is ABSENT, and absence is exactly the question: it is the idempotence
probe deciding whether to substitute or leave the file alone. Fresh image =
missing, insert; re-run = present, no-op. Both answers ordinary. Guard holds
on the belt_program_available shape — the Bool is the branch discriminator,
never discarded.

LEFT LOUD, deliberately, as the same class the operator ratified for cargo:

  claim_executor.Executor.VerifyBuildArtifacts (verify_artifacts_typed ->
  Bool). Its non-zero exit means the build artifact is CORRUPT. In the
  corruption probe that is the expected answer, but on the production path
  it is a genuine fault someone wants shouted — the sccache-truncation
  class this very check exists to catch. Same shape as the cargo build:
  guard's letter admits it, spirit does not.

  shell.Exec.Run in host_build_cache_provision's read-back. The witness doc
  says the modeled binary answers non-zero BY DESIGN so the reconcile must
  be NotConverged — so that call is a genuine observation. But the SAME
  operation is used two lines up for chmod, where failure is a real fault.
  One operation, two roles, and they are not separable by an annotation on
  the shared op — this is task #15's call-node-versus-enclosing-fn problem
  showing up a second time, now on a single op rather than a single fn.

Both need an operator call, and both have their trace recorded rather than
being silently converted to make a count reach zero. Zeroing them would be
the disease this arc exists to cure: trading a fake anomaly for a hidden
real one.

Verified: the srv3_seeded witness still true with no glyph.

Running total 19 of ~24. Genuinely remaining: host_effect_plan_apply (the
option-(a) site) plus the three deliberate loud ones (cargo, verify, chmod).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GELyMsZrGgZRrxte2TCsk
…ant row

Two conflicts, opposite resolutions again.

non_fold_residue.dag: main renamed BOTH FrontierRow fields — `unit: String`
-> `subject: PathSubject { path }` and `dissolve_on: String` -> `trigger:
TriggerProse { text }`. Took main's shape and carried my ci_hold_cause_text
row into it. Worth noting the trap: converting only the field the conflict
marker showed would have left `unit:` on my row, which main no longer has
anywhere (zero occurrences), so it would have typechecked as nothing.

commit_workflow.dag: main's empty side was DELIBERATE. It removed the
doc_reachability CommitCheckEnrollment while keeping the data row, and its
new project_local_tidy_checks derives the pre-push list FROM the roster — so
the row was a second admission path for a file per-PR discovery already
covers (the floor log shows doc_graph_has_no_orphan_docs running there).
Took main's removal. That is the reverse of 9037507, where an empty side
really was absence; three merges in, the only reliable method is to check
what main did with the symbol, never to apply a side-preference rule.

Verified after rebuilding all three bins with CI's flags:
ci_floor_plan_witnesses green, witness_exclusion_frontier_reconciliation
green, and gauntlet_lane_rehome_is_never_bare_deenrollment_holds green —
that last one matters, since taking main's removal had to not read as a bare
de-enrollment.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GELyMsZrGgZRrxte2TCsk
@briansrls
briansrls merged commit 95e4bba into main Jul 26, 2026
5 checks passed
@briansrls
briansrls deleted the claude/pr-7162-debug-logs-9f7h53 branch July 26, 2026 01:28
briansrls added a commit that referenced this pull request Jul 26, 2026
…ker (#7265)

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* Fix sccache emit if-branch semantics and commit regenerated ci.yml.

Multi-statement if/then bodies must be semicolon-joined in a single Run
(the if-else grammar inserts then_body verbatim without braces). The heal
job failed because ci.yml drifted and the bot lacks workflows permission to
push workflow files — commit the regenerated ci.yml and falsifier.yml here.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fold bucket-D census into arc census; delete orphan doc.

The standalone bucket-d-foreign-executor-emit-census.md had zero inbound
refs and would red the falsifier after merge. True-up §4.E/4.I and add
§4.J punch-list to the existing shell-to-dag-residual census (reachable
via design_document.dag) — single authority, no bind row needed.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Repoint ci_sccache_opportunistic_detect scaffold to emit module.

ci_sccache_provider_shell_injection moved to v2.workflow.ci_materialization_emit
in this PR; host_build_cache_provision's scaffold bind still pointed at the
deleted gunbc.ci_materialization declaration (review 43048).

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix merge-admission emit golden: hand-authored bytes, no trailing NL.

ci_floor_disposition_marker_init_emit_matches_concat_golden_holds failed
on CI because the concat-reconstructed golden carried a trailing newline
after the echo redirect that orch_emit_pipeline does not emit. Switch to
the #6467 hand-authored golden pattern (matches committed ci.yml).

Co-authored-by: Cursor <cursoragent@cursor.com>

* Mark ci_sccache_bound_branch semijoin as declared Scaffold.

Three bound-branch Runs are semicolon-folded because multi-Do then_
inside realize_if_else inline binding is unguarded by the if-band
corpus and byte-diverged on first ci.yml regen — not a carriage bug.
Dissolution: emit-lane construction refusal for multi-step then_ at
inline if_else bind, or block-bodied if_else row (emit lane, not D).

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add missing Present import to ci_materialization_emit.

Present is used for redirect and else_ arms but was not in the import
list; golden tests executed green via compilation (review 43241).

Co-authored-by: Cursor <cursoragent@cursor.com>

* Roster ct_render_rust_applied_type_qualified_base_test for scaffold index.

#7269 added the hand assertion blob after #7272 landed the inventory witness;
merge main exposed compiler_tests_rust_blobs_are_all_rostered red (27 declared, 26 rostered).

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* Rework bucket D PR1: dissolve semijoin, extract shared emit plumbing.

Replace semicolon-folded sccache bound branch with three Do steps so
block-bodied if_else (#7277) emits multi-line workflow text; re-golden
and regen ci.yml/falsifier.yml. Route both new emit modules through
orchestration_bash_emit_support (run/do/emit_pipeline); pre-existing
ci_*_emit forks migrate in PR2.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* Fix CI drift gate: regen ci.yml from emit authority; drop duplicate roster.

Remove duplicate ct_render_rust_applied_type_qualified_base_test row (main
already carries it after #7272/#7288); revert language_source_scaffold_index
to main placement. Regenerate ci.yml/falsifier.yml via main_wet — block if
then/else body lines use emit indentation (10-space), not hand-indented
12-space; matches heal job 89806546636 output the bot could not push.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* Remove duplicate ct_render_rust roster row from #7265 merge.

Main already owns this entry via #7288; the branch copy made rostered exceed declared (27/28).

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls added a commit that referenced this pull request Jul 27, 2026
…ec.ExitStatus (#7293)

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* Refuse inert TeeTo on retry; name emit-time string-wall dissolve-on.

Review 43497: admitting TeeTo while emit discards it codified silent
loss. ci_retry_body_run is now Absent/Absent (bytes unchanged — tee
stays in hardcoded bash rows); retry admits only Absent redirect+capture.
Parent: path/binder/comment alphabet checks get a typed-carrier dissolve-on.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* Note orch_retry_body Absent conflation with named dissolve-on.

Three causes (empty body / non-Do head / Do with redirect|capture) share
^orch_emit_retry_body_not_run; file the state-space conflation rather than
churning reason symbols this close to the merge bar (parent).

Co-authored-by: Cursor <cursoragent@cursor.com>

* Mark floor_stamp IntNe/Exit Run.command residue as declared PR2b scaffold.

Review 43514 correctly names medium-as-string on the if/exit lines; those
are intentional PR2a deferrals with a named dissolve-on, not unmarked
authority. Louden the scaffold note rather than pulling PR2b carriers.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* Fail-closed IntNe operand alphabet before test emit.

Review 43539: raw String operands could escape [ … -ne … ].
Refuse outside orch_shell_test_operand_alphabet (^orch_emit_int_ne_operand_invalid);
Exit status reuses the same alphabet. Injection RED added.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls added a commit that referenced this pull request Jul 27, 2026
…log source) (#7303)

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* PR2b: refuse silent retry emit drops (multi-step, redirect, capture, log source)

Multi-step retry bodies and Present redirect/capture were narrowed without a diagnostic; LogMatches.source was ignored while templates hardcode BUILD_LOG/RETRY_LOG. Refuse each with a typed reason and honest Absent on ci_retry_body_run.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Keep Present import in ci_spec after PR2b redirect/capture honesty fix.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Resolve #7293 merge: keep PR2b Outcome<Run> retry extract, exhaust Comment/Exit.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: shell→dag bucket D — foreign-executor emit cluster (gate #7216 now MERGE

* Refuse 3+ escalation retry emit: level1.env was silently dropped.

review 43629: multilevel reused the 1level template and skipped level1.env
(and the final level's LogMatches). Fail closed until a faithful N-level
template exists; replace the golden that enshrined the drop with a RED.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants