Repository navigation
Correct a stale C0 status: deliverable (c) merged as #7841 but the plan still reads OPEN - #7900
Conversation
…7895) signed_accent_render was a second StarlightRender literal carrying fields byte-identical to g_render twelve lines above it in the same file — hue 45, sat 26, light 87, name "g-starlight" — so one decided colour was authored twice and held in agreement by nobody. Row 4 signed a CLASS, and a selection is a reference, so signed_accent_render is now g_render. The failure this closes is not hypothetical: retuning the G projection against the cited chromaticity would have moved g_render and left the SIGNED row behind, and the site would have kept painting a colour the signature no longer described while every witness stayed green. witness_signed_accent_is_g_and_live repeated witness_g_class_is_the_live_night_ figure's three field comparisons verbatim — the same expression twice once the rows are one value — so it collapses to the part that is still falsifiable: which class the signature selects. Renamed witness_signed_accent_selects_the_g_class. ONE FORK REMAINS AND IS NOT PAPERED OVER: gunbc.design.theme warm_starlight carries the same three numbers a third time under its own name, and witness_g_class_is_the_live_night_figure holds it in agreement with this projection by comparison rather than derivation — validation standing where construction was available (DESIGN §5). accent_signed_note now records that, and names the open question it waits on: whether the site-independent register library may take its accent from a site-layer projection, or whether night_theme is a site instance that should be assembled at the site layer. Not decided unilaterally — design.theme has two consumers (the site and the srv1 roadmap dashboard). Green by execution: the four affected witnesses PASS (selection, live-night figure, no-green in source and projection, study page emits). RED control verified by execution — re-pointing signed_accent_render at k_render FAILs witness_signed_accent_selects_the_g_class. The collapse is value-identical by construction (the literals were byte-identical), so no emission can change. Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
classification_matches_fact joins a roster row to a DeclFact on BARE NAME, while DeclFact carries qualified_name and kind and could key exactly. That is sound only while every top-level declaration of v1.compiler.complexity has a distinct name, and nothing in the carrier makes that true -- it is a property of the subject module, not a wall this carrier erects. Measured over src/v1/complexity.dag: 201 top-level declarations (171 fn, 26 type, 4 data, 0 let), zero duplicate names. So the join is correct today. But a measurement of the current tree is not an oracle (DESIGN section 5), so the precondition is now EXECUTED rather than assumed. The gap this closes is real and none of the four existing totality witnesses covers it: a duplicate name in the DERIVED population still classifies, still matches a roster row, and leaves no stale row, so one roster row can silently answer for two declarations while every count agrees. roster_names_distinct does not cover it either -- it constrains the AUTHORED side only, and the duplicate here would be on the derived side. Added population_names_distinct beside the existing roster_names_distinct, reusing name_already_seen rather than minting a second distinctness fold. Green by execution, all three run through claim_batch against the real tree: PASS w_population_decl_names_are_distinct (live population) PASS w_distinctness_fold_reds_on_a_planted_duplicate (discriminating RED) PASS w_distinctness_fold_accepts_a_distinct_control (positive control) The RED matters: a distinctness fold that cannot fail proves nothing, so a planted same-name pair must come back false or the live green is empty. Dissolve-on is named on the carrier: the roster carrying exact DeclFact identity (qualified_name, or name plus kind) makes the join exact by construction and retires the precondition. That is a 201-row re-authoring and is deliberately not bundled here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…I fixed (review 49289)
Review 49289 caught three more instances of exactly the defect this PR exists
to remove, and it was right: I corrected one occurrence and did not sweep for
the class -- the same shortcut I would send back on someone else's diff.
Fixed, all verified against main rather than recalled:
section 7 C0(c) bullet still called the split "the next implementation
slice" while the C0 summary said DELIVERED
section 9 operator ruling same, so a reader of section 9 could still treat
C0(c) as open
section 2 table still listed a single lens_contract_complexity row
carrying RatchetForever. That row does not exist on
main. Replaced with the two rows that do --
derived_kernel (WallAfterGrounding) and optimality
(RatchetForever, the genuinely undecidable residue)
Two the review did not name, found by sweeping for the class instead of the
reported lines:
section 4 asserted in the present tense that lens_contract_complexity
carries RatchetForever. Marked RESOLVED by #7841 and kept as the
argument the split rests on, rather than deleted -- the reasoning
is why the split has the shape it has
section 8 a discriminating control named the deleted contract. Re-pointed
at both split rows, where the mode/consumer disagreement is
actually checkable
status blockquote said one carrier "currently" declares it permanent
Remaining bare mentions at lines 119, 143 and 147 are deliberate historical
references ("the mixed row", "as written then") describing the pre-split state
in explicitly past tense, not live claims about the tree.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…sfiable condition (review 49307) Third catch of the same class, and this one was more than a stale name -- the retirement criteria were unsatisfiable as written. Clause 1 required that "lens_contract_complexity's boundary class distinguishes the genuinely undecidable residue from the decidable capability". That is precisely what #7841 delivered, so the clause is SATISFIED and now says so, naming the two rows that replaced the mixed one. Clause 2 required that "lens_contract_complexity has a live consumer witness and has flipped off AuditOnly". Read onto the split, that can never be true. lens_contract_complexity_optimality is RatchetForever and stays permanently AuditOnly by the plan's own section 7 C0(c) ruling -- so a retirement condition demanding it flip would make this doc unretirable BY CONSTRUCTION. Re-scoped to lens_contract_complexity_derived_kernel, which is the half that can legitimately flip, and the clause now states explicitly why optimality is excluded so nobody re-adds it later. That second half is the part worth noticing: a dissolution trigger that cannot fire is a scaffold with no exit, which is the failure DESIGN section 6 asks a named trigger to prevent. The stale name would have been cosmetic; the unsatisfiable condition was not. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nstead Reviews caught this plan stale in four separate places, each claim true when written and false a day later. The common shape was a merge-event assertion -- "DELIVERED ON MERGE of #7841", "both rows are on main" -- which rots without anyone touching it, because nothing in the tree can decide it. Replace the class, not the four lines. Every delivery claim now names the carrier SYMBOL a reader can resolve (DESIGN section 3, cite-the-symbol), so it is decidable by grep rather than by remembering which PR merged when. Verified: all seven cited symbols resolve; zero PR numbers and zero merge-event phrases remain in the carrier. Also fixes a real dangling reference the C0(c) split created: the census note in gunbc.v1_complexity_capability_census cited lens_contract_complexity, a row that no longer exists. Re-pointed at lens_contract_complexity_derived_kernel, which is the one a consumer surface would actually move -- optimality is AuditOnly permanently.
|
CI caught a real defect in this branch, and it is worth stating plainly because the failure mode is the one this repo cares most about. The floor refused batch 3 with The fix is not three more long-lane rows. Two of the three are synthetic two-element fixtures that author their own input and their own expected answer — they pay no That is the decomposition DESIGN requires of a live-population claim: small discriminating mechanism fixtures per PR plus the irreducible census on an enrolled cadence — the census may be irreducible, the mechanism never is. Coverage strictly improves. The discriminating RED moves from a cadence to per-PR, so a broken distinctness fold now reds on every PR instead of waiting for a cadence window. The census keeps its scan. Verified by execution: both moved witnesses PASS at 0ms in the fast lane (budget 5s); the pre-existing fast-lane sibling still passes at 138ms, so the added imports disturbed nothing; and the long-lane file's six The second line in that CI failure — the unscheduled — sent from proud-bear-834 |
The floor worker died exit 101 with no terminal receipt on
witness_admission_entry_function_keys_from_source: WINDOW is a 400-BYTE budget
applied to UTF-8 prose via after.len().min(WINDOW), so whenever byte 400 lands
inside a multi-byte char the slice panics and takes the whole run down. The row
that exposed it simply happened to put an em dash across that offset.
Every other slice in that function takes its offset from find/split_once, which
return char boundaries; this fixed offset was the only unguarded one. It now
walks down to the nearest boundary, so an over-long row is truncated rather than
fatal. Note the comment directly above already recorded an earlier panic in this
same function, so the failure mode has form.
Fixing the string instead of the scanner was the tempting move and it is the
unmarked workaround DESIGN section 5 forbids: it would leave the defect armed for
the next author who writes prose with an em dash in it. So the em dash stays in
the row, and the scanner is what changed.
PROVEN DISCRIMINATING BY EXECUTION, both directions:
- unfixed: panics "byte index 400 is not a char boundary; it is inside em dash
(bytes 398..401)" -- the production failure reproduced exactly
- fixed: passes
The fixture puts entry: and function: FIRST, mirroring real rows, because the
scanner deliberately panics when entry: falls outside the window and that refusal
is correct behaviour rather than the bug under test -- an earlier draft of this
fixture tripped that arm and would have tested the wrong thing. The prose is a
run of em dashes shifted by 0/1/2 ASCII bytes, covering every residue class mod
3, so at least one iteration is GUARANTEED to put the window edge strictly inside
a character. The test deliberately does not model where the scanner sets
search_from; pinning that offset would make the fixture fail for the wrong reason
the moment the scanner moves.
v2-complexity-capability-parity§7 marked C0 deliverable (c) as OPEN. It merged on2026-08-05 as #7841.
Verified on
origin/mainby content rather than from the merge notification:v2.lens.enforcement.contractcarrieslens_contract_complexity_derived_kernelandlens_contract_complexity_optimalitylens_contract_complexityrow is gone — a split, not an in-place class flip,which was the operator constraint on that slice
With (a) signed, (b1) and (b2) delivered, and (c) now correct, all three C0 deliverables are on
main and C0's stated Accept condition is met. The row says so, and names C1 as the next slice.
Why a stale status is worth a PR
This is the same class the rest of this arc has been removing, pointed the other way. An
overstated status inflates a rung; an understated one misroutes the next lane — a reader of the
plan would think C0 was still open and that C1 was blocked behind it. Both are the plan failing to
describe the tree, and DESIGN §4b's rung-honesty obligation is symmetric.
Generated artifact
docs/plans/v2-complexity-capability-parity.mdis generated from the carrier and is notregenerated in this commit:
generated_artifact_gate main_wetis reproducibly OOM-killed(exit 137) in this worktree against the current corpus. That path is not a workflow path, so the
heal job is expected to regenerate and push it. If heal does not, the drift gate will say so and
I will regenerate it another way rather than hand-editing the projection.