Decision order: guard the position a checkpoint decides in - #471
Merged
Conversation
Bumps the corpus pin to the five step-position fixes, and re-records everything coupled to a walk: the six snapshots, the corpus stamp they were taken against, and the delivery-cost baseline the gate reads. Two of the fixes are visible in the snapshots. The signing precondition now precedes the repository index, so a repository without signing configured fails before paying for a full index. The build-artifact gate applies to rust-substrate projects, so this walk takes 10 checkpoint round trips instead of 11 — one fewer yield, respond and resume for every project that has no build-dependent artifacts to regenerate. Delivery is 1,297,394 characters, 634 above the previous recording. Those characters are the step that derives the regeneration commands and the project-type clause on the two gates that present them. The fixture description carries the reason, and the gate reads 100.
A step gated on a variable no earlier step could have bound reads nothing, so it is skipped, and the checkpoint that decides that variable runs later with nothing left to apply its answer to. check:decision-order reports the pair. Five exemptions, each because the earlier read has an answer or loses nothing by not firing: a declared default is in the bag from session creation; exists and notExists answer on a missing variable; an announcement that stays quiet costs nothing; an option carrying transitionTo sends the run back through the reader; and gates demanding incompatible values of one variable are never both reached, which is the shape of deriving a value, announcing it when the derivation was confident, and gating it when it was not. Measured on the corpus this lands against: the plain rule finds 14 pairs, 12 of them patterns working as designed, and 2 real ones, both fixed in the corpus commit this adopts. Every exemption is load-bearing — removing any single one puts a pattern back on the report.
m2ux
force-pushed
the
fix/469-step-order
branch
from
August 17, 2026 14:22
efdf92e to
a0a3494
Compare
Bumps the pin to the two adjacent fixes and re-records the five walk snapshots, the corpus stamp and the delivery baseline against it. The snapshots gain one step: the issue-reference detector's second binding, which fires on this walk because the walker never binds a platform. That is the defect the step closes, visible from the runtime side — the platform-gated verification steps were reached with nothing to read. Delivery is 1,302,319 characters, 4,925 above the previous recording. Most of it is one extra get_technique: the detector's second delivery is a full 4,054-character fetch rather than a ledger hit, because a technique bundled into get_activity does not satisfy a later standalone get_technique for the same content. The gate reads 100 against the re-recorded fixture, whose description carries the reason.
A step absent from a walk's executed list is silent about why. Correctly gated out and skipped-for-want-of-a-decision look identical, and the snapshot excluded the variable bag by design, so nothing in the committed artifact distinguished them. That is how the issue-platform ordering defect sat in the baseline: twelve steps gated on a platform no walk binds, recorded as absent and read as correct. The snapshot now carries, per activity, the gates it evaluated with nothing in the bag to read. Two filters keep it to the shape worth seeing. Only positive forms count, because absence answers a negative comparison and a presence test — which is how this corpus spells "not in that mode". And only variables the activity's own checkpoints or set actions bind count, so a technique output a no-agent walker was never going to produce stays out. On the work-package matrix that is 20 entries on start-work-package and none on the other eleven activities. Twelve name the issue platform, which is the defect this branch fixes; eight are the review-mode flag, a boolean with no declared default whose absence its readers take as false. This makes the class visible in review and fails the snapshot when it changes. It is not yet an assertion: a walk cannot reach zero here while technique outputs stay unbound.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A step gated on a variable no earlier step could have bound reads nothing, so the step is skipped. The checkpoint that decides that variable runs later, and its answer arrives with nothing left to apply it to. The run completes, having asked a question that changed nothing.
Nothing reported this class, so it accumulated. This adds a guard that does, and adopts the corpus commit that clears the two instances it finds. Closes the server half of #469; the definition half is #470.
What the guard checks
For each checkpoint, the variables its options bind, against every earlier step in the same activity that is gated on one of them. A hit is a step that runs first and reads nothing.
Five positions are exempt because the earlier read has an answer, or loses nothing by not firing:
defaultValueexists/notExiststransitionToThe last exemption is provable rather than conventional, and it is what makes the corpus's standard way of settling a value legible: a technique derives it, an announcement reports it when the derivation was confident, a checkpoint decides it when the derivation was ambiguous, and the announcement and the checkpoint carry opposite gates on the ambiguity flag.
Gates are read through the repository's own
whenparser rather than by splitting the string, so precedence and parentheses are handled the way the server handles them. Only conjuncts are taken as requirements; anorproves nothing about which branch a run took, so a gate built from one contributes no exclusion — the guard reports rather than assumes.Why the exemptions are the guard
Measured on the corpus this adopts: the rule with its exemptions removed — a checkpoint decides what an earlier step read — finds 14 pairs, and 12 are working patterns. A guard with that ratio does not get run. With the exemptions it finds two, both real, and both fixed in #470: the issue-platform gate in
work-packageand the structural-inventory persist inworkflow-design.Every exemption is load-bearing. Removing any single one puts a working pattern back on the report — the defaults and announcement carve-outs by two each, the presence, re-entry and exclusivity carve-outs by one each.
The guard reports two findings against the parent corpus commit and zero against the adopted one, so a green corpus is evidence the guard can still fire rather than evidence it never could. The fixtures pin both directions and one case per exemption.
Why the smoke suite blessed the defect
Worth stating, because the answer shaped a change here. A step absent from a walk's executed list is silent about why — correctly gated out and skipped-for-want-of-a-decision look identical — and the snapshot excluded the variable bag by design. So the twelve platform-gated steps were recorded as absent and read as correct.
Measured on the six-policy matrix: 103 of 266 steps (39%) execute in zero walks, and 83 of 99 checkpoint options are never exercised.
issue-verificationdeclares nodefaultOption, so every policy falls back to its first option — "Provide existing issue" — and the create path where the platform gate lives is never walked at all.The snapshot now records, per activity, the gates it evaluated with nothing in the bag to read. Two filters keep it to the shape worth seeing: only positive forms (absence answers a negative comparison or a presence test, which is how this corpus spells "not in that mode"), and only variables the activity's own checkpoints or
setactions bind (a technique output a no-agent walker was never going to produce stays out).That is 20 entries on
start-work-packageand none on the other eleven activities — twelve naming the issue platform, eight the review-mode flag. It makes the class visible in review and fails the snapshot when it changes. It is deliberately not an assertion: a walk cannot reach zero while technique outputs stay unbound.Scope of change
One new guard script and its test, one registry entry, one npm script, and a documentation section on where a checkpoint belongs. One new exported helper on the gate-liveness module with six tests, and the walker and snapshot changes that use it. The corpus bump brings seven definition fixes, with the walk snapshots, the corpus stamp and the delivery-cost baseline re-recorded in the same commit as each pointer move.
Acceptance criteria
What the walk shows
Delivery is 1,302,319 characters, 5,559 more than the recording before the adopted fixes. The walk also drops from 11 checkpoint round trips to 10, because a project with no build-dependent artifacts is no longer asked about them.
Most of the increase is one extra
get_technique: the issue-reference detector's second binding delivers a full 4,054 characters rather than a ledger hit, because a technique bundled intoget_activitydoes not satisfy a later standaloneget_techniquefor the same content. The bundled delivery and the standalone answer are recorded under different ledger key shapes, so the content hash never matches. That is a gap in the reference-delivery machinery rather than a definition problem, and it is left open here — the fixture description records the measurement so it does not have to be re-derived.Non-goals
check:checkpoint-entrykeeps its single sentence — a checkpoint may not be an activity's first step. The two rules share a subject but not an id, so a sweep reports which one fired.Investigation detail
Evaluation report and per-dimension analysis
🤖 Generated with Claude Code