# description
Manifest shape for a `Rule` extension. A rule consumes the full graph (nodes + links) after all extractors have run and emits `Issue[]`. Rules are dual-mode: `deterministic` rules MUST be byte-for-byte reproducible (same graph in → same issues out; time, random, and network are forbidden) and run synchronously inside `sm check` / `sm scan`. `probabilistic` rules invoke an LLM through the kernel's `RunnerPort` and execute only as queued jobs (`sm job submit rule:<id>`); their output MAY vary across runs and they NEVER participate in `sm scan`. See `architecture.md` §Execution modes for the full contract.

# properties.mode.description
`deterministic` (default): pure code, byte-for-byte reproducible, runs during `sm check` and `sm scan`. `probabilistic`: invokes an LLM via `ctx.runner` and runs only as a queued job; never participates in scan-time pipelines. The kernel rejects probabilistic rules that try to register scan-time hooks at load time. Omitting the field is equivalent to declaring `deterministic`.

# properties.emitsRuleIds.description
List of `rule_id` values this rule may emit on issues. Typically a singleton (`trigger-collision` → emits `trigger-collision`). A rule emitting a `rule_id` not in this list → kernel logs `rule-id-violation` but keeps the issue (forward compatibility).

# properties.defaultSeverity.description
Severity attached by default to emitted issues. Rules MAY override per-issue.

# properties.consumes.description
Which slices of the graph the rule reads. The kernel MAY pass a restricted view when this is a strict subset.

# properties.configurable.description
If true, the rule reads its own config from `config_preferences` under the key `rules.<id>.<field>`. Implementations MAY surface these in `sm config`.