# current-root-policy-mismatch

> An explicitly selected membership guard lacks current-root evidence at enforcement time.

Canonical: https://nightshade.dicksonwu.xyz/rules/current-root-policy-mismatch.html
Release: Nightshade 0.1.1 (v0.1.1)

| Field | Value |
| --- | --- |
| Rule ID | `current-root-policy-mismatch` |
| Severity | medium |
| Confidence | medium |
| Maturity | experimental |
| Selection | Opt-in + policy |
| Policy intent | required |
| Default enabled | no |
| Category | Policy-dependent rules |
| Engine facts used | declared-current-root-policy, all-successful-predicates, native-merkle-queries, ordered-writes |
| Release | v0.1.1 |

## Selection and scope

Not selected by default. Select it with `--detectors` or the `detectors` list in nightshade.json, and declare the matching application intent in `policies`. Selecting it alone does not supply that intent.

```sh
./.nightshade/node_modules/.bin/nightshade ./contracts --detectors current-root-policy-mismatch
./.nightshade/node_modules/.bin/nightshade detector show current-root-policy-mismatch
```

The 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 |
| ---: | ---: | ---: | ---: | ---: |
| 1/1 | 1/1 | 1/1 | 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](https://nightshade.dicksonwu.xyz/evaluation.md#synthetic-corpus).

## Rule documentation

From https://github.com/DicksonWu654/nightshade/blob/v0.1.1/docs/detectors/current-root-policy-mismatch.md at v0.1.1.

Availability: **opt-in policy**. Severity/confidence: **medium/high**. Select with
`--detectors current-root-policy-mismatch` and declare the application requirement:

```json
{"version":1,"policies":{"currentRootMembership":[
  {"circuit":"record","ledger":"permitted"}
]}}
```

The policy applies to positive native `checkRoot` predicates enforced on modeled
successful histories of the selected exported circuit. It requires the checked
root to be current **when that predicate is enforced**. The ledger selector is
an unambiguous canonical ledger ID or name; all native Merkle receivers below
that root are selected, including nested Maps. Helpers retain their actual
invocation operands and sites. This policy does not infer freshness intent.
Equivalent repeated queries list every candidate invocation; the report never
silently identifies an unused call as the saved Boolean's exact occurrence.

```compact
import CompactStandardLibrary;
ledger permitted: HistoricMerkleTree<2,Field>;
export ledger accepted: MerkleTreeDigest;
export circuit record(root: MerkleTreeDigest): [] {
  assert(permitted.checkRoot(disclose(root)), "membership");
  accepted = disclose(root);
}
```

Historic trees accept previous roots. An application that promises latest-snapshot
acknowledgment should use `MerkleTree`, or establish a recognized current-only
invariant with `resetHistory`/`resetToDefault` and perform a fresh query. Query-time
proof alone is insufficient: saving a positive check, inserting into its tree,
then asserting the saved Boolean does not certify the tree at that guard.
Ordered real writes are checked between query and enforcement. Exact sibling
writes preserve certification; possible aliases and ancestor replacements remove
it. No comparison between Merkle epochs and ledger revisions supplies a proof.
Native current trees remain exclusive for dynamic receivers too.

The diagnostic reports a missing guard-time certificate under the explicit
policy. It does **not** establish that historical roots are actually stored, that
an overlapping write changes the root, that a stale root is accepted at runtime,
or that a modeled history is feasible. Intentional historical membership is a
known policy-dependent review shape: leave this policy unset. Negative checks,
mere optional queries, and tautologies do not become required positive membership.
A true branch does enforce membership on its own successful history.

Later-effect freshness is outside this contract: a fresh guard followed by an
insertion is quiet even if an effect happens afterward. Missing membership guards
are also outside this rule; see `merkle-membership-not-enforced`. Independently
bound current roots and unmodeled application invariants can make a reported
certificate gap intentional. Nonliteral Boolean equality chains, lost predicate
structure, unavailable/checkpoint-projected positions and exhausted budgets give
explicit rule/entry-scoped incomplete diagnostics, never clean policy results.
Boolean-to-numeric encodings in enforced predicates are also explicitly
unavailable; conversions cannot erase a native check into apparent clean absence.
Opaque native digest/commitment relations involving observed check Booleans
retain a loss marker and are unavailable too; hashing is not decoded as Boolean
equality or positive membership evidence.
No successful invocation supplies no complete guard evidence.

## 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:

```compact
// nightshade-disable-next-line current-root-policy-mismatch -- Reason this match is intentional
```

Diagnostics cannot be suppressed, and an unmatched directive for a selected rule makes analysis incomplete. See [configuration](https://nightshade.dicksonwu.xyz/configuration.md#suppress-an-intentional-match) for fingerprint suppressions and baselines.

## References

- [Rule source document at v0.1.1](https://github.com/DicksonWu654/nightshade/blob/v0.1.1/docs/detectors/current-root-policy-mismatch.md)
- [Catalog entry in rules.json](https://nightshade.dicksonwu.xyz/rules.json)
- [All rules](https://nightshade.dicksonwu.xyz/rules.md#policy-dependent-rules)
- [Limitations](https://nightshade.dicksonwu.xyz/limitations.md)
