Rule
inconsistent-keyed-state-guard
Consumer co-membership is checked on only some successful histories of a keyed insert.
Specimen 82 of 96 · Other active opt-ins / State and collections
- Severity
- info
- Confidence
- high
- Maturity
- experimental
- Selection
- Opt-in
- Policy intent
- not required
- Release
- v0.1.1
- Engine facts used
collection-observationssuccessful-predicatessuccessful-historiesstate-writesruntime-operationscompleted-entries
Selection and scope#
Not selected by default. Select it with --detectors or the detectors list in nightshade.json. Either one replaces profile selection, so list every rule you want.
./.nightshade/node_modules/.bin/nightshade ./contracts --detectors inconsistent-keyed-state-guard
./.nightshade/node_modules/.bin/nightshade detector show inconsistent-keyed-state-guardThe first command runs only this rule; --detectors takes a comma-separated list. The second prints the rule's metadata from your installed version.
Severity is review priority. It does not express exploitability or impact. Confidence is detector metadata, not a probability. All built-in rules are experimental.
Compiler scope: the engine supports the pinned profiles 0.28.0, 0.29.0, 0.30.0, 0.31.1, 0.33.0-rc.2, 0.34.0, 0.35.0-rc.1 and 0.35.0, with ZKIR2 by default. Support for this rule can be narrower; the rule documentation below states any narrower scope.
Corpus checks#
Synthetic corpus checks for this rule in the 0.1.1 proof run. A check counts only with compiler acceptance and complete analysis.
| Positive detected | Corrected quiet | Lookalike quiet | Other negative quiet | Incomplete |
|---|---|---|---|---|
| 2/2 | 2/2 | 2/2 | 0/0 | 0 |
No deviations were recorded for this rule.
These are behavior checks on synthetic fixtures, not a precision or recall estimate. See evaluation.
Rule documentation#
From docs/detectors/inconsistent-keyed-state-guard.md at v0.1.1.
Availability: opt-in with --detectors inconsistent-keyed-state-guard. Severity: info. Confidence: high for the structural observation. No policy required.
The rule reports a final keyed insertion reached by some successful histories with a prerequisite membership check and others without it. A downstream entry must require both collections to contain the same exact key on every modeled successful history. Collection identity comes from resolved ledger declarations; collection names and assertion messages do not affect matching.
This is a review obligation. Consumer checks do not prove that surplus entries are invalid. Intentional preauthorization or independent storage may explain the pattern. Findings leave invariant intent, cross-transaction feasibility and exploitability unproven. Confirm the application's intended relationship before requiring membership on every successful insertion.
Analysis schedules one shared pass of exact successful histories, all predicates and ordered collection observations, including helper calls and cached transfers. Whole entries form dependency components through every canonical ledger root they may read or write, including ordinary key, control and value dependencies. Resolved source bodies, helper closures and zero-iteration callbacks participate. Every entry in a component containing Map/Set membership or insertion is included, even when that entry only removes an element or reads ordinary state. Unchanged assertions after an insertion still constrain its atomic success. Only unchanged, preexisting revision-zero prerequisite receivers are supported. Any prerequisite-root mutation or later target-root mutation prevents a finding. Map lookup alone does not establish the consumer relationship in this version. Unknown required keys, unsupported Boolean relations, incomplete histories or exhausted budgets produce diagnostics. These gaps never establish a clean rule result. A resolved absence of reachable Map/Set membership and insertion establishes not-applicable coverage without a dedicated collection-history observation pass. Resolved callback and helper edges participate in this bounded certificate. Unknown callable bodies, unknown external-contract effect scope or unfinished dependency traversal prevent all disjointness certificates and diagnose. Excluded entries and component dependencies are revalidated before relation analysis; Program.entries is never changed. Preparation and detector traversal work appear in ruleObservationWork metrics and consume the shared observation work/value allowance. Complete relevant histories remain required for every entry in the related component. A completed component can report beside an incomplete disjoint component. Unrelated branches inside a writer still make that whole entry incomplete; partial histories are never sliced into completed relation evidence. Shared work/value exhaustion can withhold proof even for previously completed histories. The independent baseline scan and overall report still retain their analysis gaps. Unscoped engine issues are conservatively associated with all incomplete components; these scopes do not identify an exact failure origin.
Suppress a match#
If a match is intentional, suppress it on the line before with the exact rule ID and a reason of at least eight characters:
// nightshade-disable-next-line inconsistent-keyed-state-guard -- Reason this match is intentionalDiagnostics cannot be suppressed, and an unmatched directive for a selected rule makes analysis incomplete. See configuration for fingerprint suppressions and baselines.