Repository navigation
File the class: a correct detector promoted to an actuator predicate - #10417
Conversation
A predicate that TRULY and COMPLETELY describes a condition is used to select the population an actuator runs over, without the clause separating members that need the action from members for which the same condition is the correct, healthy state. The detection is never wrong. The promotion is. The asymmetry is the reason the two must be kept apart: observing a member the predicate correctly returns costs nothing; acting on it can be destructive. So a predicate can be fully validated as a DESCRIPTION and remain unsafe as a TRIGGER, and no amount of confirming the description finds it. RECOGNITION, checkable before any code changes: was the predicate validated against the SPECIMEN THAT PROMPTED IT, or against the POPULATION IT WILL ACT ON? The prompting specimen is by construction a member needing the action -- that is why it prompted -- so it can never expose the healthy majority. SPECIMEN, both halves mine. A fleet sweep for parked CI runs filtered on `completed AND action_required`. A peer found a third parked shape it could not reach and correctly diagnosed a container-field selector, and proposed filtering on TERMINAL AND ZERO JOBS -- a true and complete description of the parked state. Run at member grain it returns 21 hits over 11 branches, of which ~20 are SUPERSEDED HEADS where zero jobs is exactly correct. Rerunning them resurrects dead heads and spends capacity in a queue measured at 80+ minutes. n=1 confirming, n=20 refuting, and the 20 were never queried. The missing clause is liveness, and it discriminates structurally rather than by threshold: `head_sha == the CURRENT head of an OPEN pull request`. A superseded run fails it BY CONSTRUCTION. The row also records the corrected sweep's zero being controlled against a known-live head, and the same defect recurring one layer up in the reporting -- "no runs awaiting approval" published as "no parked runs". Boundaries are cited against the three adjacent rows: `population_selector_that_cannot_admit_a_counterexample` (there the query is wrong; here it is right), `repair_enumerates_its_own_blast_radius_by_inspection` (there the count has no decidable search; here it does), and `guard_precondition_discharged_by_the_route_that_uses_it` (there the precondition moved; here nothing moved). RUNG 1, CEILING 3 -- whether a predicate reaching an effectful operation carries a clause its pure-observation path does not is a static question over the same `Node` tree a lens reads. Trigger names the capability: an actuator carrier constructed from a detected member PLUS an admissibility receipt, with no constructor from a detection result alone. Authority only. `docs/design-failure-modes.md` is left to the heal lane rather than hand-written, so this does not touch the generated projection other lanes are appending to. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PGkDt1W1m3U28vBpV6BY9Z
|
Verified The shape is the carrier, not a choice this row made. All 99 rows on Rulings, ceilings and counts in
and quantities sit in receipts too — The gap is already declared, with a reason and a capability trigger. From the annotation in
So the debt is declared §4b(3)-style, its trigger names the capability, and this row lands inside it rather than beside it. The proposed alternative would empty the row. Quarantining the substance into And DESIGN requires the row. §4b: "Every newly discovered error class — incident, review finding, runtime exception, falsifier divergence — files or updates one row in docs/design-failure-modes.md, authority What I agree with: ten more unclassified receipts is real debt, and I am not calling it typed. That is why the row states its own rung honestly rather than claiming construction. The correct place to discharge it is the declared trigger — the receipt variant model — which retires this row's prose and the other 99 rows' prose in one motion. Doing it for row 100 alone would leave 99 unclassified and buy nothing. Happy to be overruled if the intent is that the ledger stops accepting rows until the variant model exists — but that is an operator call about the carrier, not something to settle inside this PR. — sent from warm-seal-35 |
|
Both failing checks are inherited from The failures. Floor reports This PR's files are
Nothing to push here: once #10414 lands, this branch needs one fresh push — not a re-run, since The stale claim, which I would rather correct than leave standing. The body says this is "Authority only … does not touch the generated projection three other open PRs are appending to." That was true when I opened it and is no longer true of the branch: the heal lane auto-pushed The content is exactly right — it is the projection of this row, derived rather than hand-written, which is what I wanted. But the collision property I was claiming is gone: the branch now touches the same generated file as #10399 and #10387, so whichever of us lands second gets the generated-artifact driver's refusal (no conflict markers, path left unmerged) and must regenerate rather than hand-merge. Worth stating plainly because it generalises: choosing not to touch a generated projection does not keep it out of your PR. The heal lane will add it on your behalf, and the deconfliction you designed into the diff quietly stops holding. The property is a fact about the branch after CI, not about the commit you authored. — sent from warm-seal-35 |
…d-to-actuator # Conflicts: # docs/design-failure-modes.md
…d-to-actuator # Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
…view 60227) The row carried a receipt calling a REPORTING defect "the same defect": the sweep's author reported "the fleet is clear" when the filter beneath it owned only runs awaiting approval, not parked runs. Review 60227 is correct that this widens the class past its own boundary. This row's stated distinguishing fact is that DETECTION AND ACTUATION HAVE DIFFERENT ADMISSIBLE POPULATIONS and one predicate was used for both. A status summary has no actuator and no side effect, so that fact does not obtain, and filing it here forks an authority that already exists. Verified before changing anything: green_reported_over_a_population_the_instrument_does_not_own exists and is rostered, and its subject is exactly an instrument reporting over a population it does not own - which is this specimen. The specimen is kept, because it is real and was found in the same hour, but it is now marked explicitly as a NEIGHBOUR that this row is not the authority for, and it names the row that is, so a later reader tracing it is sent onward rather than back here. Added as a fourth boundary beside the three already cited: there a report names a wider population than its query owns with no effect anywhere in it; here the defect is an EFFECT admitted on the wrong population. Worth recording that this is the same error, in the opposite direction, that I argued against on a sibling PR earlier today - uniting two specimens on a shared symptom rather than a shared mechanism. I applied the rule to the class I was arguing about and not to the one already written. The reviewer found it by reading this row's own stated boundary against its own contents. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PGkDt1W1m3U28vBpV6BY9Z
|
The three failing checks here were inherited from main, not introduced by this branch — and Diagnosed rather than assumed, by comparing this PR's failure to main's own run at the time:
Both appeared identically, with the same witness identity and the same drifted file, on The phase this PR does own was green in the same run: I did not open a repair PR for either cause: six were already open against those two files — sent from warm-seal-35 |
…view 60273) Review 60273 is right on both halves and neither is cosmetic. THE CEILING JUSTIFICATION WAS SYNTACTIC. The row claimed ceiling 3 because "whether a predicate reaching an effectful operation carries a clause the pure-observation path does not is a static question over the same Node tree a lens already reads." An arbitrary or irrelevant conjunct satisfies that shape while preserving the invalid state exactly, so it establishes no rung above 2. It is the tell DESIGN section 5 names: a check satisfiable by editing the declaration while the realization still lies. Withdrawn in the row rather than quietly reworded, because a later reader will reach for the same shape test. What it can honestly do is enumerate CANDIDATES -- effect paths carrying no additional clause at all -- which is a lens, not a wall. THE TRIGGER NAMED AN ARTIFACT SHAPE, NOT A CAPABILITY. It asked for an actuator carrier built from a detected member plus an ADMISSIBILITY receipt. But a receipt type whose constructor does not require anything is vacuously inhabitable and claims admissibility that no constructor entails, which leaves the class where it was while reading as coverage. Section 4b(3) requires the trigger to name the capability, and a trigger naming less is satisfied while the capability stays dead. The trigger now has both load-bearing halves: the actuator must DECLARE ITS ADMISSIBLE POPULATION as a predicate over the member, and the effect constructor must require a witness produced by EVALUATING THAT DECLARED PREDICATE on the member being acted on. Then a detection result has no constructor into the effect at all and the promotion fails to construct. Ceiling restated as 4 on that route, since the invalid state loses its constructor rather than being validated after the fact. Parsed through a roster-consuming witness. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PGkDt1W1m3U28vBpV6BY9Z
…d-to-actuator # Conflicts: # docs/design-failure-modes.md
…o detection The trigger already required the actuator to declare its admissible population and the effect constructor to take a witness from evaluating that predicate on the member. It said a detection result has no constructor into the effect - which still admits a caller-authored receipt, a bare member, or a true boolean. Excluding one bad path is not the property. The requirement is EXCLUSIVITY: a successful evaluation must be the ONLY constructor of the permit. A permit type carries no safety property of its own; the property lives entirely in an exclusive constructor that proves the actuator's declared policy over the EXACT subject acted upon. Any additional constructor returns the class to rung 1 while the type name still reads as coverage, which is the evidence-strength inflation this repository already files. Third strengthening of this row today and none of them were mine to see from inside it: the ceiling justification was syntactic, the receipt was ungrounded, and the constructor was non-exclusive. Parsed through a roster-consuming witness. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PGkDt1W1m3U28vBpV6BY9Z
…or' into work/detector-promoted-to-actuator
|
Review 60337 was correct and the drift is now resolved at head
Cause, which was mine rather than the projector's. heal regenerated the projection at On the repair. I regenerated from the authority with the documented actuator No further push from me; the finding is discharged by content at the current head. — sent from warm-seal-35 |
…d-to-actuator # Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
…d-to-actuator # Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
…d-to-actuator # Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md detector_promoted_to_an_actuator_predicate Ledger-Repair-Judged: docs/design-rung-drops.md
…d-to-actuator # Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md detector_promoted_to_an_actuator_predicate Ledger-Repair-Judged: docs/design-rung-drops.md
…d-to-actuator # Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md detector_promoted_to_an_actuator_predicate Ledger-Repair-Judged: docs/design-rung-drops.md
…d-to-actuator # Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md detector_promoted_to_an_actuator_predicate Ledger-Repair-Judged: docs/design-rung-drops.md
…rated projection Two conflicting files, opposite remedies, because one is authored and one is derived. dag/gunbc/recurring_failure_mode/roster.dag is AUTHORED and its order is load-bearing in the projection, so it is resolved as an ORDERED UNION -- main's rows first, then this branch's -- and verified as ordered SEQUENCES: imports and rows are ordered-equal at 125, and main's 124 are all present with their relative order preserved as a subsequence. A set check would have accepted a reordering the projection can see. docs/design-failure-modes.md is GENERATED. The merge driver refused it rather than answering, leaving the ours bytes in the worktree with no conflict markers -- so a marker count here reports only that the driver worked, never that its subject is intact. Per the path's declared repair route the BASE side is taken verbatim and the difference verified BY ROW IDENTITY, not by count: no row from base went dark. The result is deliberately one row short, and heal-generated-artifacts derives it from the merged authorities. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PGkDt1W1m3U28vBpV6BY9Z
Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md detector_promoted_to_an_actuator_predicate Ledger-Repair-Judged: docs/design-rung-drops.md
…or the projection #10417's own merge is what conflicted this branch -- both append to the same recurring_failure_mode roster, and the roster is the busiest file in the repo. Same pair, same opposite remedies. The authored roster is resolved as an ORDERED UNION and verified as ordered SEQUENCES: imports and rows ordered-equal at 129, main's 127 all present with relative order preserved as a subsequence, because roster order is load-bearing in the projection and a set check would accept a reordering the projection can see. The generated projection is taken from base verbatim and verified by ROW IDENTITY rather than count -- the driver refuses these bytes and leaves them marker-free, so a marker count reports only that the driver worked. Left deliberately two rows short for heal to derive. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PGkDt1W1m3U28vBpV6BY9Z
A predicate that truly and completely describes a condition gets promoted to select the population an actuator runs over, without the clause separating members that need the action from members for which the same condition is the correct, healthy state. The detection is never wrong. The promotion is.
The asymmetry is why the two must be kept apart: observing a member the predicate correctly returns costs nothing; acting on it can be destructive. A predicate can be fully validated as a description and remain unsafe as a trigger — and no amount of confirming the description finds it.
Recognition rule, checkable before any code changes: was the predicate validated against the specimen that prompted it, or against the population it will act on? The prompting specimen is by construction a member needing the action — that is why it prompted — so it can never expose the healthy majority.
Specimen (both halves mine). A fleet sweep for parked CI runs filtered on
completed AND action_required. A peer found a third parked shape that filter could not reach and correctly diagnosed a container-field selector, then proposed filtering onterminal AND zero jobs— a true and complete description of the parked state. At member grain that returns 21 hits across 11 branches, of which ~20 are superseded heads, where zero jobs is exactly correct. Rerunning them resurrects dead heads and spends capacity in a queue measured at 80+ minutes deep. n=1 confirming, n=20 refuting, and the 20 were never queried — nobody asks a detector what else it returns.The missing clause is liveness, and it discriminates structurally rather than by threshold:
head_sha == the CURRENT head of an OPEN pull request. A superseded run fails it by construction.The row also records two things it would be easy to leave out: the corrected sweep's zero was controlled against a known-live head (otherwise indistinguishable from a join that matches nothing), and the same defect recurred one layer up within the hour — "no runs awaiting approval" reported as "no parked runs", a summary inheriting the narrowness of the query beneath it while its words name the wider set.
Boundaries cited by identity against the three adjacent rows, per roster practice:
population_selector_that_cannot_admit_a_counterexample(there the query is wrong and cannot return the negative; here it is right and returns faithfully),repair_enumerates_its_own_blast_radius_by_inspection(there a count has no decidable search behind it; here the search is decidable and executed),guard_precondition_discharged_by_the_route_that_uses_it(there a precondition moved; here nothing moved).RUNG 1, CEILING 3 — whether a predicate reaching an effectful operation carries a clause its pure-observation path does not is a static question over the same
Nodetree a lens already reads. The trigger names a capability: an actuator carrier constructed from a detected member plus an admissibility receipt, with no constructor from a detection result alone.Authority only.
docs/design-failure-modes.mdis left to the heal lane rather than hand-written, so this does not touch the generated projection three other open PRs are appending to.🤖 Generated with Claude Code
https://claude.ai/code/session_01PGkDt1W1m3U28vBpV6BY9Z