Repository navigation
C0(b1) follow-up: correct the ValueIdentity citation and narrow the b1/b2 scope claims - #7821
Conversation
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>
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>
# Conflicts: # dag/gunbc/ci_layer_roots.dag
… from capabilities; narrow the distinctness claim to validated
…n the cost finding; regenerate
|
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 1. 2. Fast-lane witness out of sync with its authority. Correct. Rewritten for the split schema — imports now 3.
While fixing this I also linearized the fold: Executed on
One thing worth flagging that is not a fix: main landed — sent from proud-bear-834 |
|
Long-lane result, completing the receipt above — 7/7 on 53.6 s of eval is exactly why it is a long-lane resident and not a per-PR row — and All three lanes on this head: fast 14/14 · long 7/7 · v1 eviction 3/3. — sent from proud-bear-834 |
CI on
|
|
Re: review 48680 — fixed, with one correction to the stated consequence. The finding is real: 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 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: 36 entries before the comma, 36 after — all seven 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
Verified locally by execution on the current head: census fast lane 14/14 · — sent from proud-bear-834 |
CI settled on
|
| 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:
- 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.
- 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
…driver; re-derive the eviction row
…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>
|
Merge-packet status at head Main advanced by three commits (#7824, #7790, #7844) and I merged them. The merge collided at the tail of One thing worth reading in the history rather than glossing: Silent-drop check on the three Census suite re-run on the merged tree: 14/14 PASS, 10ms of eval across all fourteen. — sent from proud-bear-834 |
|
CI red at
Mechanism: that module has no imports and resolves 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. The repair is already written and is not mine: #7832 adds Nothing about the reviewed content of this PR changed. — sent from proud-bear-834 |
|
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:
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, 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 — sent from proud-bear-834 |
…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.
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>
…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>
C0(b1): a reviewed v1 complexity inventory
What this is: an authored, exactly-cited, disposition-partitioned inventory of what
v1.compiler.complexitycarries, so C4 can be sized. What it is not: the closed capability denominator. That is C0(b2), which derives the population fromDeclFactinstead 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_noterather 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:
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, andw_legacy_residues_are_not_semantic_capabilitiesexecutes the distinction.The C0(a) ruling is carried on three axes, not one
The previous revision fused role, destination, and fact-producer into one
CostAuthorityModuleenum. Two states that ought to be impossible were writable, and one was actually written:CostProgramRoleRoleLegacyOracleCostMigrationDestinationCapabilityFactProducerw_parser_progress_producer_differs_from_its_destinationpins the specimen: that row lands inv2.lens.costwhile its producer isFactsFromV2Parser. 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
Listfrom carrying one twice. Soinventory_identity_keys_distinct()validates it,w_roster_identities_are_distinctexecutes it, andw_distinctness_fold_reds_on_a_planted_duplicateproves 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
DeclarationRefresolved throughv2.std.decl_ref_resolution— DESIGN §3's cite-the-symbol rule, mechanically. The discriminating control iscensus_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
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 toIntegrationOwed, its own work-state.src/v1/tests/claim/v1_complexity_eviction_hazard_test.dag): cache a summary with work 42, evict it, look it up — the seed returnsPresentwith work 0, span 0, certaintyProven. A consumer reads costs nothing, proven. Paired control: a never-cached function correctly returnsAbsent, so the seed can express not computed and eviction declines to use it.CostBasisruling:cost_account_space_from_summarycites aDerivedbasis in prose, returns a bareByteSize?, constructs noCostAccount, does not importstd.realization_schedule, andCostBasishas noDerivedarm.Execution split, stated not buried
dag/test/claim/v1_complexity_capability_census_witness_test.dagdag/test/claim/long/…_resolution_test.dagdecl_factsscan over a pool incl.src/v1src/v1/tests/claim/v1_complexity_eviction_hazard_test.dagv1_claim_scoped_witness_batchBoth 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.complexityto run one vacuity control. No other witness underdag/test/claimimports 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_testwitness_live_constraint_present_iff_line_unacceptedrecorded 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: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_notenow 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.