Skip to content

C0(b1) follow-up: correct the ValueIdentity citation and narrow the b1/b2 scope claims - #7821

Merged
briansrls merged 41 commits into
mainfrom
session/proud-bear-834
Aug 6, 2026
Merged

briansrls merged 41 commits into
mainfrom
session/proud-bear-834

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Aug 5, 2026 •

Copy link
Copy Markdown
Contributor

What this head actually delivers (updated 2026-08-06). The substantive C0(b1) carrier —
gunbc.v1_complexity_capability_census, its roster, its fast and long-lane witnesses, and the
v1 eviction-hazard control — already landed on main via #7840, which had merged this
branch before C0(b2) merged. Verified by content on origin/main.

What remains in this diff is four documentation corrections, 5 insertions / 5 deletions:
the false ValueIdentity citation (DESIGN §3 cite-the-symbol), the c0_scope_note and
complexity_capability_id_note scope narrowing so C0(b2) is not misread as the trigger that
closes capability discovery (DESIGN §4b trigger honesty), the closure_cost_note measured
disjoint-range result superseding its earlier "actual size is unknown" wording, and the removal
of a self-referential (see c0_scope_note) citation found by review 49160.

The title was renamed accordingly. Leaving it as the b1 delivery title would have written an
overclaim into main's history through squash-merge — the same class of defect this diff exists
to correct. The original description follows unchanged.


C0(b1): a reviewed v1 complexity inventory

What this is: an authored, exactly-cited, disposition-partitioned inventory of what v1.compiler.complexity carries, so C4 can be sized. What it is not: the closed capability denominator. That is C0(b2), which derives the population from DeclFact instead of authoring it, and it is open.

The title changed from "C0(b): … census" on operator review. "Census" and "C0(b)" both read as a completeness claim this lane does not make; a 26th capability omitted from the roster would not be detected here, and the carrier now says so in c0_scope_note rather than leaving it to be inferred.

Carrier

gunbc.v1_complexity_capability_census — v1_complexity_inventory_roster, 27 rows.

It is an inventory, not a capability roster. Legacy residues are not peers of capabilities:

V1ComplexityInventoryItem
  = SemanticCapabilityItem { capability }
  | LegacyHazardItem       { hazard, of_capability }
  | LegacyRealizationItem  { realization, of_capability }

The eviction hazard and the v1 parser walker are residues that belong to a capability, carried as typed edges. So counting rows (27) and counting capabilities (25) are now different questions with different answers — inventory_semantic_capability_count() answers the second, and w_legacy_residues_are_not_semantic_capabilities executes the distinction.

The C0(a) ruling is carried on three axes, not one

The previous revision fused role, destination, and fact-producer into one CostAuthorityModule enum. Two states that ought to be impossible were writable, and one was actually written:

axis what it says why separate
CostProgramRole what a module is — includes RoleLegacyOracle the ruling assigns v1 a role
CostMigrationDestination where owed work may land — legacy oracle absent "migrate into the deletion target" now has no constructor
CapabilityFactProducer who produces the facts parser-progress facts come from the v2 parser, not the cost lens

w_parser_progress_producer_differs_from_its_destination pins the specimen: that row lands in v2.lens.cost while its producer is FactsFromV2Parser. Under one enum it had to name the lens as its own producer, contradicting its own note.

Identity distinctness: validated, not constructed

Corrected on review. A closed coproduct makes an identity outside the vocabulary unrepresentable; it does not stop a List from carrying one twice. So inventory_identity_keys_distinct() validates it, w_roster_identities_are_distinct executes it, and w_distinctness_fold_reds_on_a_planted_duplicate proves the fold discriminates — a planted duplicate must come back false, or the green means nothing. The carrier and the plan note both say "validated" now. C0(b2)'s derived population supplies the construction wall this list cannot.

Citations resolve; they are not substring matches

Every row carries a typed DeclarationRef resolved through v2.std.decl_ref_resolution — DESIGN §3's cite-the-symbol rule, mechanically. The discriminating control is census_prose_only_name_does_not_resolve: a name that exists only inside a note string does not resolve, which a .contains() check would have accepted.

Findings, each executed

  1. C4 is smaller than the parity note's table implied — but the work is integration, not nothing. std.graph (SCC), std.termination (DescentEvidence), std.computation (LoweringTarget), std.induction (CostBound) are all reached by import from v1 and by none of v2's lens modules. First revision projected these as discharged; corrected to IntegrationOwed, its own work-state.
  2. A migration hazard, proven by execution (src/v1/tests/claim/v1_complexity_eviction_hazard_test.dag): cache a summary with work 42, evict it, look it up — the seed returns Present with work 0, span 0, certainty Proven. A consumer reads costs nothing, proven. Paired control: a never-cached function correctly returns Absent, so the seed can express not computed and eviction declines to use it.
  3. A receipt for the CostBasis ruling: cost_account_space_from_summary cites a Derived basis in prose, returns a bare ByteSize?, constructs no CostAccount, does not import std.realization_schedule, and CostBasis has no Derived arm.

Execution split, stated not buried

lane file runs per-PR?
fast structural dag/test/claim/v1_complexity_capability_census_witness_test.dag yes
exact resolution dag/test/claim/long/…_resolution_test.dag no — needs a decl_facts scan over a pool incl. src/v1
eviction hazard src/v1/tests/claim/v1_complexity_eviction_hazard_test.dag no — v1_claim_scoped_witness_batch

Both non-per-PR lanes are enrolled on executing cadences with named local recipes in gunbc.ci_layer_roots, not on a deferral arm.

A cost finding this PR paid for, recorded rather than quietly fixed — and re-stated with its clock basis

An earlier revision of the fast-lane witness imported v2.lens.cost / v2.lens.complexity to run one vacuity control. No other witness under dag/test/claim imports them, so this file was the first to drag the v2 lens closure into the per-PR witness layer — and the floor measured the consequence on an unrelated witness: roadmap_program_view_witness_test witness_live_constraint_present_iff_line_unaccepted recorded 3901.9ms on green main and 5019ms here, with no change to its own semantic work.

Main landed witness_row_cost_clock_basis_note (#7820) while this PR was open, and it changes what those two numbers may be claimed to mean. Both are wall; the fast-lane cap is enforced on thread CPU. So:

  • 3901.9ms is a real reading. Eval is single-threaded, so a wall figure under the cap proves cpu under it.
  • 5019ms is not a cost. It is a censored measurement — its value is where the kill landed, and the true figure is unbounded above.

The honest claim is therefore weaker in one direction and stronger in the other: the regression is at least 1117ms, its actual size is unknown, and what is decided is only that the row crossed. closure_cost_note now states it that way rather than quoting a delta between two figures on a clock the cap does not enforce.

The imports moved to the long lane with the control that needed them. It stays recorded because it is a measured instance of this program's own subject twice over: a per-witness cost invisible until it lands on somebody else's budget, and a threshold that reports the victim rather than the cause.

Plan-note state

C0(a) signed · C0(b1) delivered on merge of this PR (not "already delivered" — the artifact is the merged carrier) · C0(b2) open · C0(c) open. The stale "parser progress is still unsized" line is gone: the operator ruled that disposition on 2026-08-05 and the census models it as two rows.

gunbc-ci-auto-heal and others added 2 commits August 5, 2026 00:38
Delivers deliverable (b) of the v2 complexity capability parity
program's C0 phase: one typed inventory row per capability that
src/v1/complexity.dag carries, each with a disposition from a closed
sum. Deliverables (a) the authority ruling and (c) the RatchetForever
re-classification are operator decisions and are deliberately absent.

Carrier: gunbc.v1_complexity_capability_census. Every arm carries
required non-empty payloads, so an unjustified disposition is
unwritable rather than lens-caught. Adds a sixth arm,
DispositionDeferred, because the five declared arms had no home for a
capability whose disposition is one of the note's own open questions;
forcing parser-progress into a neighbouring arm would have fabricated
a decision nobody made.

Witness: 15 checks green by execution, including two RED controls. Each
row's v1 symbol resolves against the live seed and each cited
destination symbol against the file its row names, so a stale citation
reds rather than reading plausibly.

Four findings, each executed rather than asserted:

1. C4 is smaller than the parity note's table implied. std.graph,
   std.termination, std.computation and std.induction already carry the
   SCC and descent vocabulary and v1 reaches it by import, while v2's
   lens modules import none of them — owed work is consumption, not
   migration. The v1-AST walkers that produce that vocabulary are the
   real C4 surface.
2. std.induction's CostBound/derive_bound vocabulary was missing from
   the do-not-re-mint list; added.
3. evict_summary overwrites an entry with a zero-cost Proven summary
   instead of removing it, so an evicted function reads as "costs
   nothing, proven" rather than "not computed". Rostered as a hazard
   that must not migrate with the capability.
4. cost_account_space_from_summary's note cites CostAccount.space with
   a Derived basis; it constructs no CostAccount, v1 does not import
   std.realization_schedule, and CostBasis has no Derived arm. Gives
   parity open question 3 a receipt.

Also corrects the sibling note's correction 1, which claimed no
valuation environment existed anywhere in the tree: the seed has one
(eval_cost_expr_concrete, env: Map<String, Int>), and it is
String-keyed. The narrower claim is the useful one — the seam is absent
from v2, and v1's key is the anemic identity parity §6 forbids carrying
across.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot changed the title cost analysis C0(b): v1 complexity capability census — typed rows, executed against the tree Aug 5, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review August 5, 2026 01:00
gunbc-ci-auto-heal and others added 13 commits August 5, 2026 02:17
Reworks the census on operator review. The previous revision proved its
authored rows were well-formed and distinct; it did not prove its
citations resolved or that its dispositions stated the remaining work
honestly. Both are addressed, and the title is narrowed to what is
actually established.

Finding 1 — citations are exact, not substring. CitedSymbol { symbol,
file } is replaced by a typed DeclarationRef resolved through
v2.std.decl_ref_resolution. The file becomes an OBSERVED property of the
resolved declaration (rel_path) rather than a second authored identity.
The discriminating control: "Derived" appears verbatim in a seed note
string, so the old check found it; as a DeclarationRef it is not a
declaration and resolution refuses. Planted absent-declaration and
absent-module refusals accompany it.

Finding 2 — no closed denominator. Retitled C0(b1) "reviewed roster".
Declaration-to-capability totality is now an explicit C0(b2) slice that
derives the population from DeclFact. The 171/201 discrepancy is
resolved as a method identity: 171 counts top-level fn; 201 counts
fn+type+data+let (26 type, 4 data). Both correct; the method was
missing.

Finding 3 — disposition algebra. AvailableInSharedSubstrate projected as
discharged, understating C4; it is now IntegrationOwed with its own
work-state, because v2 must still consume std.graph et al.
DeliberatelyRetired belonged to no partition, so exhaustiveness was
green-by-vacancy; retirement now splits into RetirementOwed (replacement
has not executed) and Retired (discharged), and every arm — including
the two no row inhabits — carries a controlled fixture.
DispositionDeferred is removed per the parser-progress ruling.

Finding 4 — weak controls. Eviction is now proven by EXECUTION: cache a
summary with work 42, evict, look it up; the seed returns work 0, span
0, certainty Proven instead of Absent, while a never-cached function
correctly returns Absent. The constant-true finding uses the module's
own typed VacuousValidation carrier plus execution rather than
asserting the function exists.

Finding 5 — stale contract table: linearity_audit's WallAfterGrounding
boundary restored and complexity_lowering added with its distinct
SingleAuthority dissolution.

Operator rulings recorded: C0(a) signed (carried as the typed
CostAuthorityModule vocabulary, with the atomic-relocation nuance);
C0(c) split ruled as the next slice; parser progress split into
migration + retirement rows; WorkAtom closed-outer/open-identity shape;
CostBasis three-valued per resource axis; span stays in C2; C5 is two
changes never one; no blanket specialized-lens collapse.

Execution split stated rather than buried: exact resolution and the
eviction control need a decl_facts pool including src/v1, so they live
in the long lane and per-PR CI does not run them. The offline recipe is
named in gunbc.ci_layer_roots. Fast structural half: 10/10 green, max
2ms. Long lane: 9/9 green locally.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The floor red on this PR was not the two named witnesses being flaky.
Measured, same runner class: roadmap_program_view_witness_test
witness_live_constraint_present_iff_line_unaccepted ran 3901.9ms on
green main and 5019ms here, breaching the 5s budget without its own
semantic work changing.

Cause is mine. The fast-lane witness imported v2.lens.complexity,
v2.lens.cost and v2.std.refinement to execute the vacuity control, and
no other witness under dag/test/claim imports them — so this file was
the first to drag the v2 lens closure into the per-PR witness layer,
and every discovered entry paid for it.

Fix keeps ownership where it belongs: the control and its imports move
to the long-lane companion, which already pays a large closure. No
other lane's witness is relocated, and the long/ resident count does
not grow for anyone else's code.

Recorded as closure_cost_note rather than silently fixed: it is a
measured instance of this program's own subject — a per-witness cost
invisible until it lands on somebody else's budget, and a wall-clock
threshold that reports the victim rather than the cause.

Fast lane 9/9, long lane 10/10.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The floor refused at the pre-plan naming walk: all_disposition_fixtures
was a plain fn in a *_test.dag unreachable from any test fn — silent
de-enrollment, which the enroll-or-refuse hygiene rightly stops.

Fixed by making it load-bearing rather than deleting it. The new
w_fixture_set_covers_every_work_kind folds over all six arm fixtures
and asserts the set covers every one of the four work kinds, so an arm
added without a fixture now leaves a kind uncovered and reds. The
enumerated per-arm check states which arm maps where; this states the
fixture set is complete over the work-kind space.

Fast lane 10/10.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Compile-clean refused with a precise diagnostic:

  dag/test/claim/long/v1_complexity_capability_census_resolution_test.dag:26:1:
  error: unresolved import: module 'v1.compiler.complexity' not found

The distinction the failure taught, now measured rather than assumed:
reaching v1 through decl_facts POOL ROOTS is fine for a dag/ entry —
pools are read independently of walk source roots — but IMPORTING a v1
module from a dag/ entry does not resolve under compile-clean's scope.

Only the executing eviction control needed the import. It moves to
src/v2/test/manual/v1_complexity_eviction_hazard_test.dag, beside the
existing v1-importing precedent (ownership_movable_test.dag imports
v1.compiler.ownership from that same directory). The resolution census
stays in the dag/ long lane and keeps resolving v1 DeclarationRefs
through pool roots, with no v1 import at all.

Verified in each file's real condition rather than a convenient one:
resolution census 7/7 with only dag + src/v2 as walk roots — exactly
compile-clean's condition, the one that failed; eviction control 3/3
with src/v1 added. Recipe rows updated for the split.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
review 48510: the WitnessExclusionRow reason said the resolution file
"carries the EXECUTING eviction control" and then, two sentences later,
that the control "does NOT live here" and was homed to
src/v2/test/manual/. Both were true at different points in this PR; only
the second is true now. The opening sentence survived the split I made
in the previous commit.

Operators read that row to run the local recipe, so a stale sentence
there misdocuments what the recipe covers — the same stale-prose class
this census exists to make decidable, committed in the row describing
the census. Removed rather than reworded: the correction already states
the fact completely.

Verified the row's --functions list matches the file exactly, 7 for 7.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The floor refused with WITNESS ADMISSION REFUSAL count=10
(10 UnclassifiedPathDeferral): enrolled witnesses excluded from
discovery that name zero executing consumers. As of 2026-08-04 a
directory is no longer an admission answer — moving a file under a
long/ or offline path removes it from per-PR discovery and executes it
NOWHERE.

This is the exact defect this census argues against, committed by the
census. I had said in prose that green CI proves nothing about these
rows unless the local recipe ran; the substrate now refuses to accept
that as an answer, and it is right to.

Two fixes, each verified under the cadence's real source roots rather
than a convenient set:

- The 7 resolution/vacuity witnesses get exact function-grain rows in
  gunbc.explicit_witness_admission on FalsifierSubstrateLongLane — the
  declared lane for SubstrateInputsOnly witnesses over the fast-lane
  budget. Verified 7/7 on dag + src/v2, the lane's roots.
- The 3 eviction witnesses move to src/v1/tests/claim/ and enroll on
  v1_claim_scoped_witness_entries, the only home with an executing
  consumer for a v1-importing witness (batch roots: dag + src/v1).
  Verified 3/3 on exactly those roots, without src/v2.

Both earlier homes were refuted by the floor, not by argument:
dag/test/claim/long/ failed compile-clean at the v1 import line, and
src/v2/test/manual/ compiled but was refused by this admission wall.

Also deletes the per-file OfflineLocalRecipe path row the exact
admissions supersede — precedence is total (a function with an exact
admission is decided by it), so keeping both would be the dual
representation that carrier exists to remove.

Fast 10/10, long 7/7, v1-scoped 3/3.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot changed the title C0(b): v1 complexity capability census — typed rows, executed against the tree C0(b1): reviewed v1 complexity inventory — typed rows, executed against the tree Aug 5, 2026
gunbc-ci-auto-heal added 3 commits August 5, 2026 06:43
@gunbai-bot

gunbai-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Re: review 48593 — all three findings were real, and all three are fixed. They were caught mid-recut: the schema split landed in one commit and the follow-through in the next, and an autocommit published the intermediate state. Verified against 7d29d83, not asserted:

1. MigrationOwed.producer omitted on almost every row. Correct — the field insertion matched once. Now on all 20 MigrationOwed rows (grep -c "producer: FactsFrom" → 20, grep -c "disposition: MigrationOwed" → 20). Nineteen carry FactsFromCostLens; parser_progress_fact_production carries FactsFromV2Parser, which is the whole point of splitting the axis and is pinned by w_parser_progress_producer_differs_from_its_destination.

2. Fast-lane witness out of sync with its authority. Correct. Rewritten for the split schema — imports now CostProgramRole / CostMigrationDestination / CapabilityFactProducer, V1ComplexityInventoryRow, SemanticCapabilityItem / LegacyHazardItem / LegacyRealizationItem, MigrateTo*, SummaryEvictionHazard, ParserProgressV1WalkerRealization. All fixtures construct V1ComplexityInventoryRow with item:.

3. inventory_item_key defined but never called — specification without execution. The sharpest of the three, and correct as written. Three witnesses now execute it:

  • w_roster_identities_are_distinct — folds distinctness over the live roster
  • w_distinctness_fold_reds_on_a_planted_duplicate — the discriminating control, without which the green above means nothing; it also asserts the same hazard against two different capabilities yields two distinct keys
  • w_legacy_residues_are_not_semantic_capabilities — pins the inventory/capability split

While fixing this I also linearized the fold: inventory_identity_keys_distinct was recomputing the key list inside its own body (O(n³) at n=27). Now the list is built once and keys_are_distinct / key_occurrence_count are shared with the witness. Small n, but DESIGN §6's bare-minimum-cost rule says a proven cost-shape defect is fixed regardless of realized n.

Executed on 7d29d83, local, all green:

  • fast lane, 14/14 (dag + src/v2), max row 50 ms
  • v1 eviction hazard, 3/3 (dag + src/v1)
  • long-lane exact resolution — running; result to follow

One thing worth flagging that is not a fix: main landed gunbc.witness_row_cost witness_row_cost_clock_basis_note (#7820) while this PR was open, and it changes what my own cost finding may claim. The fast-lane cap is enforced on thread CPU; the recorded column is wall. So the 3901.9 ms baseline is a real reading (eval is single-threaded, so wall under the cap proves cpu under it), but the 5019 ms figure is a censored measurement — its value is where the kill landed, so the true figure is unbounded above. closure_cost_note now says the regression is at least 1117 ms with unknown actual size, rather than quoting a delta between two figures on a clock the cap does not enforce.

— sent from proud-bear-834

@gunbai-bot

gunbai-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Long-lane result, completing the receipt above — 7/7 on 7d29d83 (dag + src/v2 walk roots; the census pool roots add src/v1 via decl_facts(pool_roots:), which is why this cannot be a fast-lane row):

PASS census_every_declaration_ref_resolves_exactly
PASS census_absent_declaration_refuses
PASS census_absent_module_refuses
PASS census_prose_only_name_does_not_resolve
PASS census_resolved_identity_carries_observed_path
PASS census_shared_substrate_carrier_resolves
PASS census_complexity_admission_predicate_is_vacuous_by_execution
7 witness(es) in 53615ms

53.6 s of eval is exactly why it is a long-lane resident and not a per-PR row — and census_prose_only_name_does_not_resolve is the one that earns the cost: a name that exists only inside a note string does not resolve, which a substring check would have accepted.

All three lanes on this head: fast 14/14 · long 7/7 · v1 eviction 3/3.

— sent from proud-bear-834

@gunbai-bot

gunbai-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

CI on a05bc26: regen fixed, ci reached witness discovery, two real defects found

regen passed. The previous failure was mine and now understood: adding a .dag under src/v1/** puts it in the v1 self-host closure, so stage0_emit_plan_generated.dag and .gitattributes both grew a row for v1_tests_claim_v1_complexity_eviction_hazard_test.rs — but the generated .rs itself was never emitted. regen_verify_gate_passes recomputed the fixed point, found a declared-but-absent output, and correctly returned false.

Cause of my miss: there are two regenerators and I ran one. generated_artifact_gate main_wet covers ci.yml / docs/plans / .gitattributes / the emit plan; regen_stage0 covers the 127 src/v1/stage0/src/*.rs outputs, and it is the one the self-host gate recomputes. Running regen_stage0 produced exactly two changes — the missing file and a one-line lib.rs module row — confirming the fixed point was otherwise intact.

The timing receipt

ci reached witness discovery for the first time on this branch:

✓ witness_live_constraint_present_iff_line_unaccepted
  (dag/test/claim/roadmap_program_view_witness_test.dag leg=InterpretedLeg)  4191.9ms

The arc for the closure regression this PR caused and then fixed: 3901.9 ms on green main → 5019 ms censored → 4191.9 ms passing.

Stated with its limit: both figures are wall, the cap is thread CPU, and I will not claim the +290 ms against main's baseline is attributable. One measurement per side does not separate my corpus growth from host noise on a host whose own receipts move between repeats of an identical entry.

Four ci failures — two inherited, two mine

Inherited from main (red at its last five commits, not touched here): falsifier_cold_control_steps_follow_floor_in_job_order and red_floor_workflow_fixture_cold_controls_still_execute, both undefined variable: job_id.

Mine, 1 — a §3 name collision, which is the finding worth reading. RetirementTrigger already exists in the tree as a variant: gunbc.stage0_rust_lifecycle_totality LifecycleTotalityUnderivedAxis, and again in gunbc.stage0_rust_honest_frontier_projection. This census declared it as a top-level type, shadowing the variant and breaking lifecycle_totality_counts_retirement_trigger_as_underived_axis with an undefined-variable refusal — in a module this PR never touched.

Renamed to CapabilityRetirementTrigger, with the reasoning recorded on the carrier rather than only here, because the non-action matters more than the rename:

  • It is accidental homonymy, not a fork. Theirs is an axis label for a fact the stage0 rust lifecycle cannot yet derive; mine is the trigger carrier that discharges a capability retirement obligation. Different subjects — unifying them would be false unification, which is the mirror error of the one §3 warns about.
  • This census does not discharge lifecycle_totality_retirement_trigger_dissolve_on. That row waits for a RetirementTrigger carrier in gunbc.stage0_rust_source_lifecycle_scaffold, for the stage0 rust source lifecycle subject. A future reader finding a modeled retirement trigger here must not close that row against this one, so the carrier says so explicitly.

The irony is not lost: the PR whose subject is cite exactly, do not re-mint names re-minted a name. It was caught by CI, not by inspection — which is the argument for the gate, not against the census.

Mine, 2 — a stale count gate. witness_v1_claim_scoped_batch_is_file_grain_and_batch_owned asserts length(xs: v1_claim_scoped_witness_entries) == 3; the eviction witness makes it 4. Updated.

Flagging without fixing, deliberately: that literal is the change-detector shape DESIGN §5's oracle rule names — it is measured from the same tree it checks, and automating its update collapses the clause to measure() == measure(). The surrounding clauses in that witness are real property checks (source roots, scan dirs, selection mode, clamp), so the file is not worthless; but this one clause counts the entries someone remembered to author. Redesigning another module's witness is outside this PR's scope, so it is named here rather than done.

— sent from proud-bear-834

@gunbai-bot

gunbai-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Re: review 48680 — fixed, with one correction to the stated consequence.

The finding is real: dag/gunbc/ci_layer_roots.dag line 1183 was } with no comma before the first appended census row, inconsistent with all 35 other rows in falsifier_substrate_long_lane_rows. Comma added.

The predicted effect did not occur, and I checked rather than assumed because the difference matters. The review says it "should fail compile/parse for gunbc.ci_layer_roots". It does not — and the evidence was already on the table before I looked: CI compile-clean passed on this head, regen passed, ci ran 6,849 discovery witnesses, and my local ci_floor_plan_witness_test run read v1_claim_scoped_witness_entries out of that very module and passed. A module that failed to parse could not have done any of that.

So the question worth answering was not "does it break the build" but "does it silently drop my seven rows" — a truncation would be worse than a parse error, because the long-lane enrollment would read as present while executing nothing. Measured by evaluating the projection:

gunbc run --source-root dag --source-root src/v2 \
  --entry dag/gunbc/ci_layer_roots.dag --function falsifier_substrate_long_lane_entries

36 entries before the comma, 36 after — all seven v1_complexity_capability_census_resolution_test rows present in both, ending with census_complexity_admission_predicate_is_vacuous_by_execution. The separator is tolerated at that position and nothing was lost.

Fixed regardless, for the reason that survives the correction: resting a load-bearing enrollment roster on an undocumented parser tolerance is not something to leave in place, and one row formatted unlike its 35 siblings is a reader trap even when the evaluator does not care.

Worth noting as a repo observation rather than a claim about this PR: an optional list separator is a position where a genuine typo cannot be caught by the parser. I have not chased whether that is deliberate, and it is outside this PR.

Also fixed since the last CI run, both found by ci reaching witness discovery for the first time on this branch:

  • RetirementTrigger renamed to CapabilityRetirementTrigger — it collided with an existing variant of that name in gunbc.stage0_rust_lifecycle_totality and gunbc.stage0_rust_honest_frontier_projection, breaking a witness in a module this PR never touched. Detail and the deliberate non-unification in the comment above.
  • witness_v1_claim_scoped_batch_is_file_grain_and_batch_owned entry count 3 to 4.

Verified locally by execution on the current head: census fast lane 14/14 · stage0_rust_lifecycle_totality_witness_test 7/7 including the witness the collision broke · ci_floor_plan_witness_test 2/2 · long lane 7/7 · v1 eviction 3/3.

— sent from proud-bear-834

@gunbai-bot

gunbai-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

CI settled on 5029e77 — every defect of mine is gone; the two reds are main's

build                      success
heal_generated_artifacts   success
regen                      success
ci                         failure  (2 of 6849 discovery witnesses)

The two failures:

falsifier_cold_control_steps_follow_floor_in_job_order   runtime error: undefined variable: job_id
red_floor_workflow_fixture_cold_controls_still_execute   runtime error: undefined variable: job_id

Both in dag/test/claim/falsifier_workflow_witness_test.dag, which this PR does not touch. Main's last two completed runs fail with the identical pair. This branch runs 6,849 discovery witnesses against main's 6,835 — 14 added, zero new failures.

Three defects that CI found on earlier heads are fixed and verified by execution, not inspection:

defect fix verified
stage0 output declared but never emitted ran regen_stage0 regen green on three consecutive heads
RetirementTrigger §3 name collision renamed to CapabilityRetirementTrigger stage0_rust_lifecycle_totality_witness_test 7/7
stale entry-count gate (3 → 4) updated ci_floor_plan_witness_test 2/2

The timing receipt, with a second reading

run figure
green main (baseline) 3901.9 ms
this PR, before the closure fix 5019 ms — censored
this PR, reading 1 4191.9 ms ✓
this PR, reading 2 4106.4 ms ✓

What can be said: the closure regression is closed — the witness is back under the cap with roughly 800–900 ms of headroom, and both readings pass.

What cannot: whether the ~200–290 ms above main's baseline is real. My two readings differ by 85.5 ms, so the gap to main does exceed my own observed spread — suggestive of a small genuine increase. But main's baseline is a single measurement with no spread estimate, and per witness_row_cost_clock_basis_note these are wall figures while the cap is thread CPU. I am recording it as likely a small real increase, not established, rather than picking whichever reading tells a nicer story.

Main's break, diagnosed but deliberately not fixed here

fn falsifier_job_steps(job_id: String) -> List<Step> {
  fold(falsifier_workflow.jobs, init: [], f: fn(acc, j) {
    if j.id == job_id { j.steps } else { acc }
  })
}

The lambda does not capture the enclosing function's parameter. The sibling ci_job_steps() survives only because it inlines a literal "ci" rather than referencing a parameter.

Two observations, the second being the one worth acting on:

  1. The tempting patch — inline the literal, as the sibling does — is DESIGN §5's unmarked workaround verbatim: it routes around a language-layer defect and zeroes the defect's frequency so it never ranks for fixing.
  2. An unbound variable in a lambda body is structurally decidable at compile time, yet this surfaces as a runtime undefined variable. That is a §4b rung inversion: a class sitting at mitigatable that the closed substrate should be able to place at structurally guaranteed. Whichever way the capture question is resolved — lambdas capture, or they are refused — the refusal belongs at compile time.

Not touched here because it is outside this PR and fixing it would widen the diff into a module I have no mandate over. Flagged for routing.

Merge readiness — one thing I cannot verify

dashboard-ops reviews gunbc#7821 returns no data: null head, null mergeable, null checks, empty provider lists. Not "zero approvals" — no record at all, and the same for #7841. GitHub's own review list is empty because these are dashboard-only artifacts.

So I have no authoritative read on the tally, and I am not converting the notification stream into one. What I can state on my own evidence: mergeable: MERGEABLE, open, not draft, head 5029e77, and CI red solely on two witnesses identical to main's.

Per the temporary policy I am not merging this myself.

— sent from proud-bear-834

gunbc-ci-auto-heal and others added 12 commits August 5, 2026 13:49
…bsolete roadmap long-lane row and mark its citation historical
The merge of main (#7824, #7790, #7844) into this branch collided at the
tail of falsifier_substrate_long_lane_rows — my seven C0(b1) census rows
and main's two new rows append at the same list position. Both sides are
kept; 39 rows, no duplicate (entry, function) pair, every entry file
present on disk.

The conflicted file was committed and pushed with markers intact by the
autocommit path before this resolution, so this commit is the repair of
that state, not a fresh merge.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Merge-packet status at head c43428efaa8.

Main advanced by three commits (#7824, #7790, #7844) and I merged them. The merge collided at the tail of gunbc.ci_layer_roots falsifier_substrate_long_lane_rows — my seven C0(b1) census rows and main's two new rows append at the same list position. Both sides are kept: 39 rows, no duplicate (entry, function) pair, every entry file present on disk.

One thing worth reading in the history rather than glossing: 05096abf5dc ("WIP: cost analysis") carries the conflict markers. The autocommit path committed and pushed the conflicted file before I resolved it, and it left no MERGE_HEAD, so the tree read as a completed merge. c43428efaa8 is the repair of that state. Nothing between the two was ever green, and no reviewed content changed — the resolution is purely the two row sets concatenated.

Silent-drop check on the three merge=generated-artifact files ran after the merge, per the hazard that bit this PR earlier today: stage0_emit_plan_generated.dag, src/v1/stage0/src/lib.rs, and .gitattributes all still carry main's rows plus this branch's one new registration. No regeneration was needed — the branch-vs-main file set is exactly the fifteen files this PR authors.

Census suite re-run on the merged tree: 14/14 PASS, 10ms of eval across all fourteen.

— sent from proud-bear-834

@gunbai-bot

gunbai-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

CI red at c43428e, and the failure is not in this diff. Recording it here because the automated notice attributes it to this PR.

build, regen, and heal_generated_artifacts are green. The ci floor fails at dag_compile_clean_gate_passes, with ~100 hard diagnostics all in one file this PR does not touch:

dag/gunbc/plans/branch_merge_admission_model.dag:15:15: error: function 'row' not found in scope
dag/gunbc/plans/branch_merge_admission_model.dag:15:27: error: function 'cell' not found in scope

Mechanism: that module has no imports and resolves cell/row as bare references. gunbc.plans.md_helpers defines cell(text:) -> MarkdownTableCell and row(cells:) -> MarkdownTableRow. Main tip 4f9112965af (#7824) added a second module-scope pair in dag/gunbc/roadmap_instrument_sandbox.dag — cell(s: String) -> Fragment and row(cells: List<Fragment>) -> Fragment. Two candidates, no import, resolution refuses. This is the Class B shape DESIGN's open threads describe, with the pool-membership coincidence broken by a homonym rather than by a stripped import.

Confidence, stated rather than implied: I have the before/after (one such definition pair in the tree before #7824, two after) but I have not run a control that flips only that variable. deep-bat-181 reports verifying the same mechanism independently before landing their fix, and narrows the affected population to exactly two plan modules — this one and merge_admission_gate_shape_proposal — with every other md_helpers consumer already importing the definer.

The repair is already written and is not mine: #7832 adds import gunbc.plans.md_helpers { h2, h3, p, li, ul, quote, cell, row } to both files. I am not pushing a duplicate of it into another lane's file to unstick my own PR — a byte-identical race would only churn their branch. This PR is blocked on #7832 landing, after which I will merge main and rerun the floor.

Nothing about the reviewed content of this PR changed.

— sent from proud-bear-834

@gunbai-bot

gunbai-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Correction to my previous comment. The causal story I gave for the compile-clean red is not established, and the control I said would close it did not.

What I got wrong:

  1. I said main would red with the same diagnostic. Main did red on 4f9112965af, but on a different failure: WITNESS ADMISSION REFUSAL cause=FrozenPathDeferralGrew count=14 (gunbc.witness_deferral_freeze gained identities relative to its diff baseline). Main compile-clean passed.

  2. It passed because main ran compile-clean at affected-set scope — 396 entries, module_rows=578 — so it never compiled branch_merge_admission_model.dag. This PR ran whole-tree, module_rows=1490, because merging main pulled compiler-infra .rs changes into the diff and forced the whole-tree baseline. This PR-s own pre-merge run was also affected-set (350 entries, module_rows=526).

  3. A local test cuts against the homonym mechanism. Resolving the module directly with both md_helpers and roadmap_instrument_sandbox under the source roots evaluated cleanly and returned a MarkdownBlock — no cell not found. So the homonym does not break resolution at that pool breadth, and my "two candidates, resolution refuses" account does not hold as stated.

What still stands, and what it now means: the failing file is unchanged by this PR, and the difference between passing and failing is compile-clean scope, not content. So the breakage is latent on main and exposed by this PR-s whole-tree scope. Whether it arrived with #7824 is circumstantial (that module was added there, md_helpers is unchanged since #6927, exactly two module-scope cell/row pairs exist) and I have not isolated it.

I am not spending a whole-tree local compile to attribute the cause. #7832-s repair is explicit imports, which resolve a bare-reference failure whichever module created the ambiguity, so the fix does not depend on the attribution being right.

Also upstream of this PR: main is currently red on FrozenPathDeferralGrew, so merging main again pulls that in too. Both reds are external to this change, and nothing about its reviewed content has moved.

— sent from proud-bear-834

@gunbai-bot gunbai-bot Bot mentioned this pull request Aug 5, 2026
1 of 2 tasks
gunbc-ci-auto-heal and others added 6 commits August 5, 2026 21:30
…ation in parity section 6

The generated-artifact merge driver resolved .github/workflows/ci.yml to this
branch's stale side when main was merged, silently dropping #7856's
[ ! -f X ] -> ! [ -f X ] transposition at two floor-peak cgroup ascent sites.
That form was already present at the merge base, so this was a revert rather
than the branch being behind. Re-running the registered regeneration
(generated_artifact_gate main_wet) restores it; ci.yml now differs from main by
exactly the one AUTHORED_CONFLICTS entry this PR legitimately adds for its own
generated eviction-hazard test.

No rebuild was involved: the projection is interpreted from .dag at run time,
so the existing binary emits the current form. The drift was solely the merge
resolution never being followed by a regeneration.

Also corrects a section 6 citation the C1 lane caught. ValueIdentity was cited
as something the G1 cited-symbol work 'already makes resolvable'. It resolves
to no declaration anywhere in the corpus -- it exists only inside the sibling
note's proposed CostSubject / CostJustification code blocks. True of
DeclarationRef, false of ValueIdentity: the DESIGN section 3 cited-symbol
class, decidable by grep, sitting false in an authority doc while the mechanism
it described stayed correct. Edited in the carrier; the md is regenerated.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ranch's three corrections

An autocommit committed conflict markers from the origin/main merge and pushed
them (64c0af2). This replaces that content with a real resolution; the merge
commit itself is kept, so no history rewrite and no force-push.

C0(b2) merged to main first, so main is authoritative for every shared carrier
and this branch is stale on all of them. Resolution was therefore per hunk, not
per side:

  v1_complexity_capability_census.dag - main wholesale, then re-apply the two
      note strings this branch corrected (c0_scope_note and
      complexity_capability_id_note: capability discovery is closed by NEITHER
      b1 nor b2). b2's algebra import, inventory_row_semantic_capability and
      concat rewrite are all kept.
  plans/v2_complexity_capability_parity.dag - main wholesale (it correctly
      records b2 DELIVERED ON MERGE and drops the now-closed C0(c) OPEN), then
      re-apply only the ValueIdentity citation correction.
  v1_complexity_capability_census_witness_test.dag - one differing line; this
      branch's measured disjoint-range cost result supersedes main's older
      its-actual-size-is-unknown wording.
  ci_layer_roots.dag - main wholesale. Verified by extracting (entry, function)
      pairs from both sides: the only rows this branch has that main lacks are
      the five direct_rust_door rows #7814 deliberately consolidated. Taking
      both sides would have duplicated seven b1 census rows that had already
      reached main through #7840.

Three files were also silently reverted and are restored to main. The merge
dropped #7865's std_unicode_types from the stage0 crate partition, and a
regeneration run reverted #7864's witness_report_line from claim_batch.rs plus
its instrument witness. claim_batch.rs is an emitted-code artifact whose
generation runs through the emit path baked into the binary, and this binary
predates #7864. Only the parity md needed regenerating, and that is an
interpreted projection, so it is correct.

Net diff against main is four files, five insertions, five deletions.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
c0_scope_note carried the parenthetical (see c0_scope_note) inside its own
declaration. It resolved to nothing a reader could follow: the citation names
the note containing it, and the capability-discovery explanation it points at
is already spelled out a few sentences later in the same string.

That is the DESIGN section 3 cited-symbol class -- a name-level claim a grep
decides -- landing in the one note whose subject is honest, resolvable scope.
The same PR fixes that class for ValueIdentity in the parity carrier, so
leaving it here would have been inconsistent on the exact point the note makes.

Dropped rather than repointed: the following sentences ARE the explanation, so
a forward reference would restate the structure the string already has, and a
positional pointer (see below) is the other half of what section 3 refuses.

Swept the other two carriers in this PR for the same shape -- a data note whose
body names its own declaration -- and found none.
@gunbai-bot gunbai-bot Bot mentioned this pull request Aug 6, 2026
8 of 9 tasks
@gunbai-bot gunbai-bot Bot changed the title C0(b1): reviewed v1 complexity inventory — typed rows, executed against the tree C0(b1) follow-up: correct the ValueIdentity citation and narrow the b1/b2 scope claims Aug 6, 2026
@briansrls
briansrls merged commit 2be8433 into main Aug 6, 2026
5 checks passed
@briansrls
briansrls deleted the session/proud-bear-834 branch August 6, 2026 03:11
gunbai-bot Bot pushed a commit that referenced this pull request Aug 6, 2026
Retrofits LsFilesStageZ/CatFileBlob to the extdeps.git *InRepo family
(repo: FilePath, git -C {repo} ...) so commit_writer_heal_admission_gate
is exercisable against a throwaway git repo, and threads repo: FilePath
through the full observation chain to heal_admit (which still passes ".").

Adds a wet real-execution witness file exercising the gate against a real
repo: an ordinary-case control, the unmerged-index/no-markers discriminator
(the #7870/#7821 shape), and the unclaimed-blob-with-markers RED control for
the absence-arm classification.

Documents, per operator analysis, that this gate does NOT discharge
CommitWriterHealSkewConflictArm's full obligation: it closes the
failed-resolution arm (unmerged stages / live conflict markers) but the
arm's provisional-ours-commit-before-regen defect (the #7870 shape
reproduced by the guard's own two-commit design) remains open as a
separate, load-bearing CI flow change requiring its own design pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
briansrls pushed a commit that referenced this pull request Aug 7, 2026
…d/unclaimed-and-marked blobs (#7905)

* WIP: Refuse autocommit while index has unmerged stages

* Add structural witness for the pre-commit unmerged-index recheck

review 49321 flagged that STILL_UNMERGED and its guard could be
deleted from ci_heal_skew_conflict_arm without CI going red — the
gate had no executing consumer (DESIGN §5). Pins the emitted
STILL_UNMERGED bind, its `if [ -n "$STILL_UNMERGED" ]` guard, and the
refusal diagnostic ahead of `git commit`, plus a RED control showing
the assertions fail against script text that lacks the recheck.

* Regenerate ci.yml: heal skew guard unmerged-index recheck

The GitHub App cannot push .github/workflows/**, so the heal job
regenerated correctly and uploaded the repair as an artifact
(heal-author-commit-required) instead of pushing it. Applying that
artifact here.

* WIP: Refuse autocommit while index has unmerged stages

* Wire commit_writer admission gate into the heal skew guard's commit arm

Adds git.Core.LsFilesStageZ/CatFileBlob transport operations, a fold
in dag/gunbc/commit_workflow.dag that observes the real staged index
and blobs and calls admit_commit_writer, and invokes it via
`gunbc run --entry ... --function heal_admit` immediately before the
conflict-arm's commit step in ci_heal_skew_guard_emit.dag, relying on
the pipeline's existing FailFast to refuse before the commit runs.

* Real-execution admission gate witnesses + provisional-bytes residue note

Retrofits LsFilesStageZ/CatFileBlob to the extdeps.git *InRepo family
(repo: FilePath, git -C {repo} ...) so commit_writer_heal_admission_gate
is exercisable against a throwaway git repo, and threads repo: FilePath
through the full observation chain to heal_admit (which still passes ".").

Adds a wet real-execution witness file exercising the gate against a real
repo: an ordinary-case control, the unmerged-index/no-markers discriminator
(the #7870/#7821 shape), and the unclaimed-blob-with-markers RED control for
the absence-arm classification.

Documents, per operator analysis, that this gate does NOT discharge
CommitWriterHealSkewConflictArm's full obligation: it closes the
failed-resolution arm (unmerged stages / live conflict markers) but the
arm's provisional-ours-commit-before-regen defect (the #7870 shape
reproduced by the guard's own two-commit design) remains open as a
separate, load-bearing CI flow change requiring its own design pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Fix stray brace interpolation in commit_workflow.dag prose note

The transport note for commit_writer_complete_staged_index_blob_observation_transport
quoted `git -C {repo}` inside a String literal; .dag interpolates {X} in strings,
and repo is not in scope at that data declaration, producing
"error: undefined variable 'repo'" at compile. Rephrased without braces.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* WIP: Refuse autocommit while index has unmerged stages

* Regenerate ci.yml to wire the heal-admission gate into the skew-conflict step

Review 49409 (Finding A) found the admission check landed in .dag
source but was never regenerated into the production ci.yml, and
(Finding B) that its argv used bare `gunbc` instead of the
$ROOT/target/release/gunbc pattern every other step in this job uses.
Finding B's source fix already landed; this regenerates the emitted
workflow so the admission-check step actually executes before the
heal commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Fix git ls-files/ls-tree -z wire decoding; declare empty module_storage policy for heal-admission gate

Two changes, both green by real execution:

1. object_store.dag: git_decode_ls_files_stage_z / git_decode_ls_tree_z were
   splitting each NUL-terminated record on every NUL, not on the real wire
   delimiters (SP SP TAB for the header fields, TAB before the path, NUL only
   as the record terminator). Replaced the quartet fold with a
   GitNulRecordSplitState state machine that awaits first-SP, second-SP, then
   TAB before treating the remainder as the path/name field, matching real
   `git ls-files -z --stage` / `git ls-tree -z` output. Four pre-existing pure
   witness fixtures had been hand-built with all-NUL-delimited headers, which
   only "passed" against the old buggy decoder; rewrote them to real wire
   format and added a new witness
   (witness_git_ls_files_stage_z_path_containing_space_and_tab_survives_intact)
   proving a path whose own bytes contain a literal space and tab is preserved
   intact rather than mis-splitting the record.

2. commit_workflow.dag: observe_complete_staged_commit previously called
   module_storage_bindings_for_source_roots(["dag", "src/v2"]) and refused on
   Rejected. That scaffold always rejects (no live host dispatch), and the
   manifest-overlay-supply alternative doesn't work here either:
   discover_source_root_ingest mints ^-prefixed identifiers from source-file
   basenames with no keyword-escaping, so scanning dag/ mints ^capability,
   ^module, ^import for dag/extdeps/bmc/capability.dag,
   dag/extdeps/languages/go/module.dag, and dag/std/import.dag respectively —
   all reserved .dag keywords — producing syntactically invalid overlay output
   for any scope touching dag/. Both are named findings with receipts, not
   fixed here; carried upward by the parent session as its own lane.

   heal_admit's caller never stages genuine test fixtures (only generated
   artifacts), so the writer now declares heal_writer_claims_no_fixture_exemptions
   = Empty directly at the call site, as policy (see
   heal_writer_claims_no_fixture_exemptions_note in-code) — never reachable via
   a failure/Rejected arm. Every staged blob then falls to the existing
   CommitWriterBlobTextUnclaimed absence arm and still receives the full
   commit_writer_text_marker_refusals conflict-marker scan.

   Named limitation: a staged blob that is genuinely TestClaimArtifact-shaped
   and also contains conflict-marker-looking bytes (a real fixture with
   embedded begin/separator/end tokens) will now falsely refuse under this
   policy, because the empty declaration cannot distinguish it from ordinary
   content. This is a known, accepted false-refusal, not a missed defect.

   Dissolution trigger: this declaration dissolves once
   module_storage_bindings_for_source_roots gains a live host dispatch, or the
   discover_source_root_ingest keyword-collision defect above is fixed and
   re-verified end-to-end — either bounds a real fixture-exemption receipt for
   this writer instead of the empty declaration.

   commit_writer_binding_work (the row) is explicitly NOT discharged by this
   change.

Witness tests updated to assert specific refusal variants
(CommitWriterUnmergedIndexRefusal / CommitWriterConflictMarkerTextRefusal) via
direct calls to observe_complete_staged_commit/admit_commit_writer, plus a new
space-and-tab-named-path wet-execution witness. All 4 commit-writer witnesses
and all 33 git-upstream-model witnesses pass by real execution (--wet /
claim_batch), counted against roster, not FAIL-grepped.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Fail closed on cat-file read failure; enroll space/tab wet witness in CI

commit_writer_observe_staged_blob ignored git.Core.CatFileBlobInRepo's
success flag, classifying read.content even on a failed cat-file call.
Route the failure through the existing
commit_writer_unavailable_classification_receipt refusal instead of
falling through to classification of garbage/empty content, mirroring
the existing LsFilesStageZInRepo success check in the same file
(DESIGN.md §5 fail-closed).

The space_and_tab_named_paths_admit_by_real_execution wet witness
(excluded from hermetic discovery, real-git-effects only) was never
added to bin_witness_wet_entries, so it had zero executing CI
consumer despite being enrolled — exactly the CI floor's Phase 0(b)
admission refusal that failed PR #7905's ci job
(WitnessRed: UnexecutedDeferredWitness). Adding the missing bin_wet
row is the fix; this was the actual root cause of the failing check.

Verified: heal_admit compiles clean (ExitSuccess, 0 problems); all 4
commit-writer heal-admission witnesses PASS 4-for-4 under --wet.

Addresses review 49477 findings 1 and 2.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* ci: re-fire the pull_request trigger

Tree-identical to b4f0da9. That head was pushed by the gunbc-ci-auto-heal
identity and has drawn no pull_request-event run in 7+ hours, while sibling
branches receive them normally; this commit tests whether a push from an
ordinary token fires the trigger.

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.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.

1 participant