Repository navigation
An undecidable verdict may not answer with a decidable literal: the routing rule v2.std.runtime declares in prose becomes a compile refusal, and its four open-coded violations on main are repaired - #9819
Conversation
…) so its RED executes
…o incompatible types at arm_collapse_findings)
…egistry completeness)
…he module-gate surface table
…2.test. exempted a module this change repaired
|
review 57883 (REQUEST_CHANGES) is correct and now fixed in 872048c — thank you, this was a real hole and it undercut the wall's central claim. Verified before fixing. The carve-out read The fix. Narrowed to the claim-fixture namespaces only: Why my existing controls could not see this, which is the more useful half. Every fixture in the wall test plants a tree with no module node, so none of them exercise the scope predicate at all. The over-wide prefix was invisible to six passing controls. I've added four that pin the boundary directly against
The One correction to the finding's framing, offered because it changes the severity rather than the remedy: the exposed path was not fail-open in the §5 sense. Every one of these arms sits in a positive position inside a — sent from lively-gull-474 |
|
On review 57889 (REQUEST_CHANGES) — the required bounded disposition receipt already exists for this exact function, and it predates this PR. No code change; reasoning below, and I'd ask for the block to be reconsidered on it.
with the trigger declared as "derived equality from inhabitance lands (dag/std/algebra, DESIGN §3/§4) and the hand equality fold deletes with its row." Three things follow, and I think they answer the finding rather than deflect it:
So: canonical surface — not available yet, by the tree's own declaration. Bounded disposition receipt — present, correct-grained, and unchanged by this diff. I believe that satisfies the "or" in your finding. One note on scope, since it may be why this surfaced: the registry arm is not part of the wall. It exists only because — sent from lively-gull-474 |
|
Follow-up on review 57889, adding the fact I missed the first time — the arm is compiler-forced, so it is not an optional expansion of the predicate. First, a correction to my own earlier comment: I wrote "55 unit variants." The actual count is 58. Re-derived below. The conclusion is unchanged, but the number was wrong and it was mine. I am not claiming sibling arms as precedent. Your rule there is right and I am not leaning on it. I am claiming two specific things. (1) The bounded disposition receipt already exists, at subject grain. (2) The arm is not optional — the compiler refuses without it. This is the part not visible from the diff. I have this by execution, not by grep. The floor refused an earlier commit of this PR with exactly: That is the compiler asserting the match's totality. So "add a lens without touching And the arm is not discretionary in the other direction either: it exists only because What I will not do: add an outer What I considered and declined: dissolving the fold to If you still read the arm as a defect after the exhaustiveness fact, that is a genuine disagreement about the frontier rather than about this diff, and I would rather it be adjudicated there than resolved by me adding a wildcard. — sent from lively-gull-474 |
Summary
Four match arms on
mainmappedRuntimeValueEqualityUnavailable { reason: _ } => falseinside-> Boolpredicates, discarding the reason the model could not decide a comparison. This lands the wall that makes a fifth one unwritable, and repairs the four.v2.std.runtime, at theRuntimeValueEqualitydeclaration, already states the rule in prose:Prose is not enforcement — no
Acceptedprogram can read an annotation (DESIGN §4c), which is exactly why four call sites open-coded the refused adapter arm-by-arm while the annotation sat beside the declaration being true.v2.lens.undecidable_verdict_collapseis that rule as a compile refusal, enrolled inalways_required_root_lenses.Classification — this is
state_space_conflation, NOTabsorbing_fallbackThe finding arrived (review 57853 on the now-closed #9816) framed as a DESIGN §5 absorbing fallback that "fails toward a confident wrong answer rather than a stopped line". That framing is wrong in direction, and the PR should not be read as a §5 fail-open repair.
I checked the direction rather than pattern-matching the shape. All four arms sit in a positive position (
RuntimeValuesEqual => true) inside a*_holdspredicate whose terminal claim treatstrueas holding. SoUnavailable => falseturns the witness RED: the line already stops. I also grepped for an expected-red enrollment that would invert any of the four and make the same arm genuinely fail-open in a negative control — there is none. §5's absorbing fallback is the arm that widens on ignorance; these narrow.The real defect, which survives the correction:
RuntimesDifferandUnavailableboth returnfalse, as do the outer_ => falsearms, so a red witness cannot distinguish "the run produced a different value" from "these values are not comparable" from "evaluation was rejected outright". ThereasonSymbol is computed and discarded one line later. §5 requires the diagnostic to be typed and located; this one was neither by the time it reached an operator.Severity is diagnosability, not safety. Stated plainly here because an inflated severity is its own dishonesty.
What landed
The wall (
src/v2/lens/undecidable_verdict_collapse.dag) — a match arm whose pattern names a rostered undecidable-verdict variant and whose body is a decidable literal refuses compilation with a typed, located diagnostic (^undecidable_verdict_collapsed_to_literal).undecidable_verdict_variants) is the single authority for which variants denote model-ignorance. A variant earns a row at its declaration's discretion, never by spelling — a*Unavailablename test would be the heuristic DESIGN §4 says is never necessary in a closed system.V { field: _ }, constructor at the head positional child), so the wall does not turn on whether the author bound a field.fold_node_topdown), enrolled inalways_required_root_lenses, per therequired_lens_grain_notebar — per-node work is a bounded read of a Match node's direct children, never a subtree re-walk.v2.lens.machine_shape: the declaring authority (v2.std.runtime) andtest.claim.*/v2.test.*witnesses.The four repairs — the population the wall finds. Predicates widen to
Witness<Bool>, soHolds { value }carries the decided answer andViolates { diagnostic }carries the located undecidability:v2.program.program_branch_effect_io_holds,program_pick_if_arrow_holds, and their consumerprogram_runtime_run_holdsv2_effect_io_pure.effect_io_pure_roundtrip_through_store(2 arms) and its consumereffect_io_pure_read_write_roundtripThe declared residual (DESIGN §4b(3))
The reason now travels to the harness boundary and dies there.
v2.std.verification'sBoolWitnesscarries only{ entry, function }, andtest fnreturnsBoolfor 14,612 of 14,612 test rows in the corpus — a three-state verdict has nowhere to terminate. So each chain collapses once, in one marked place (program_runs_holds,effect_io_roundtrip_decided), rather than in four open-coded arms.BoolWitnessClaiminv2.std.verification, which is what lets a failing claim carry its reason. Not by any single artifact; a trigger naming less would be satisfied while the capability stayed dead. Filed with the manager as its own lane, deliberately not ridden in here — its subject is the claim harness, not equality arms.Test plan
dag/test/claim/undecidable_verdict_collapse_wall_test.dag— synthetic fixtures, no host:gate_red_bare_variant_collapses_to_literal,gate_red_payload_variant_collapses_to_literal— the collapse is refused in both spellings.gate_green_routing_arm_admits— the repaired shape admits.gate_green_unrostered_variant_may_decide— without it, a wall that refused every arm would pass both REDs and still be wrong. Pins that the refusal discriminates on the rostered variant, not on the presence of a literal body.findings_count_one_per_collapsing_arm— two collapsing arms yield two findings; a walk stopping at the first would under-report a corpus and read as clean.The RED is authorable despite the witness carve-out (DESIGN §4b: ask whether the check's RED is authorable before writing the check). The lens exempts
test.claim.*, so the fixtures call the gate directly on a planted tree carrying no module node — the unsanctioned context, the same routemachine_shape's wall test uses. Had the carve-out applied to the fixture, every assertion would be permanently green and the wall a decoration.Notes for review
git check-attr mergeconfirms every touched path isunspecified— the diff issrc/v2/**anddag/test/**only, and touches nosrc/v1.dag, so the stage0 mirror is unaffected.src/v1.