Fix status-lifecycle false positives from shared values and negated requires (#18)#34
Merged
Merged
Conversation
…equires (#18) Two fixes to the status state-machine checker, applied to both the Rust analyzer and the TypeScript extension analyzer: - Type rule `when:` bindings from the surface `provides:` declaration of the command they subscribe to, matched positionally. Previously a status value shared by several entities made the binding unresolvable and silently dropped the rule's assignments and transition edges, producing spurious unreachableValue/noExit warnings. - Expand `requires: x.status != v` to the complement of the entity's status enum so every other value gains an exit edge. Previously only `=` comparisons produced exit edges. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Fixes #18.
allium checkemitted falseallium.status.unreachableValueandallium.status.noExitwarnings in two scenarios where the lifecycle was fully specified by rules. Both are fixed in the Rust analyzer and in the TypeScript extension analyzer (which also servesallium-lsp).Fix 1 — surface parameter types disambiguate shared status values
The checker now builds a map of command name → positional parameter entity types from surface
provides:declarations (CancelSubscription(admin, sub: Subscription)) and uses it to type a rule's positionalwhen:bindings (when: CancelSubscription(admin, sub)typessubasSubscription).Previously binding entity resolution fell back to inferring the entity from the status value, which fails when a value is shared across entities (e.g. two entities both declaring
active) — silently dropping the rule's status assignments and transition edges.collect_command_param_types/augment_binding_types_from_commandscollectCommandParamTypes/augmentBindingTypesFromCommandsFix 2 — negated requires expand to the complement set
requires: x.status != vnow records an exit edge for every other value of the entity's status enum (guarded onvbelonging to the enum). Previously only=comparisons produced exit edges, so e.g.Order.approvedwas reported as having no exit even thoughReactivateOrdercovers it.NotEqarm invisit_status_comparisonsfindStatusStateMachineIssuesNot included
The issue's stretch suggestion (type annotations in rule
when:clauses as explicit disambiguation) is a grammar change that overlaps with #24, so it is left out here.Verification
field.unusedinfos remain)cargo test --workspace,npm run test, andnpm run lintall passdocs/project/specs/allium-extension-behaviour.alliumanddocs/project/rust-checker-parity.md🤖 Generated with Claude Code