# Rule territory 64 rules, a three-file diff: which ones concern you? `runward rules --for` answers per path, citing the declaration that bit. Three declared states, never silence. ## The problem: 64 rules, a three-file diff The [catalog](https://runward.dev/docs/en/reference/rules/) holds 64 craft rules. Your change touches three files. Which ones concern you? Without an answer, only two behaviours remain, and both are bad. Re-read all 64 every time, which nobody sustains. Or read none and trust the green gate, which confuses "the evidence holds" with "the code is good". The gate verifies that a decision is traced to evidence that resolves. It never claimed to read your code. ```bash runward rules --for src/entry.serve.ts src/db/migrations/003_add_index.sql ``` The command answers, per path, which rules have that file in their territory — and **why**. ## Three declared states, never silence A rule is always in one of three states. The third is the one that matters. - **Declared territory**: the rule names the paths it governs, by globs (`appliesTo`) or by a category a mission binds to its files (`governs`). 14 rules of 64. - **No territory, declared as such**: the rule states openly that it has no file territory, and says why. A pre-production checklist gates the system as a whole, not a class of files. 50 rules of 64. - **Unreviewed**: nobody has ruled yet. Today: zero. That is the whole point. **Writing nothing is not the same as declaring there is nothing to write.** An empty field reads as "we don't know", "we didn't get to it", or "there is nothing" — all three at once, so none of them. Which is why the catalog renders the three states as three distinct things, and why the unreviewed counter is published even when it is zero. The day it stops being zero, it will show. ## Where a match comes from, and why it is rendered runward never infers from the content of your files. A match comes from a declaration, and the declaration is cited. **1. The rule itself.** It carries its globs. A match shows the glob that bit, on the `git check-ignore -v` model: not "this file is ignored", but "that line, in that file, ignores it". **2. Derivation from a deployment manifest.** A `wrangler.jsonc`, `wrangler.json` or `wrangler.toml` declares an execution topology: an entry module, a cron, a queue consumer. runward reads it and derives a category. ``` async-job-guardrails HIGH governs=background-work ← wrangler.serve.jsonc triggers.crons ``` That is a manifest you wrote, not your code. An unknown framework yields no derivation — never a guess. **3. The mission map.** Because a deployment manifest describes a topology and **never the nature of the code behind it**. An entry module that derives a token from an environment secret: no `wrangler.toml` can say that. You can. ## `runward/territory.md` Four columns, inside a `## Territory` section (any heading level works). ```markdown ## Territory | Pattern | Category | Effect | Why | |---|---|---|---| | `src/entry.*.ts` | `secret-boundary` | declare | derives a token from an environment secret | | `src/entry.browser.ts` | `background-work` | remove | the framework's browser bundle runs nothing in the background | ``` Precedence is **named in three places rather than inferred**: the last matching row wins, per (path, category); and the order is derivation < map < a rule's own `appliesTo`, **which the map may never narrow**. The map corrects what runward *guessed*; never what the maintainer *decided*. `remove` is a column rather than a `!` prefix, for a precise reason: a character that inverts the meaning of a line disappears in a diff. **Every refused row is named with its line number.** An invented category, an empty `why`, a path escaping the project — each is reported, never silently dropped. A row the operator believes is working and runward ignored is the worst state of all. And if the whole file is unreadable, the output says so **first**, above everything else: ``` This map was not read ✗ runward/territory.md: no `Territory` heading — the map needs a `## Territory` section (any heading level) above its table Everything below is derivation only — your declarations had no effect. ``` > **runward never writes this map.** `init` does not scaffold it, `update` does not refresh it. A file the tool rewrites is a file the operator stops owning, and that ownership is what makes a stale row visible in a diff. ## Maps rot: the measure lives in `status` A map maintained in a repository goes stale. That is documented, not assumed: an FSE 2025 study of static-analysis suppressions measures **50.8% of suppressions inert**, monotonic growth, and stale suppressions masking future warnings. So [`runward status`](https://runward.dev/docs/en/operating/maintain/) reports coverage, writing nothing: ``` Territory coverage 1 of 109 walked file(s) carry a category · background-work 1 · secret-boundary 1 runward/territory.md: 1 row(s) declared. ! 1 row(s) matched no walked file: territory.md:7 src/legacy/*.ts → startup A row that affects nothing today. Dead or merely early is your call, not the tool's. ``` A row that touches no file is named, with its line number. runward does not rule between "dead" and "merely early": that judgement is yours. A one-row map describing a reality beats a thirty-row map describing an intention. ## What it does not do - **It never reads your project's code.** Only declarations: a rule's globs, a deployment manifest you wrote, your map. - **It does not change the gate.** `runward check --strict` returns exactly the verdict it returned before. Territory tells you what to confront *at the point of action*, not how to cross a step. - **An unknown category is not a guess.** The vocabulary is closed (eight categories). A rule governing a category that no declaration binds to your files does not surface — and it is not counted as evaluated either: `runward rules --for --json` files it under `unresolved`, distinct from rules genuinely ruled out. The difference between "does not apply" and "cannot be decided" is kept, not smoothed over. ## See also - [Rule catalog](https://runward.dev/docs/en/reference/rules/) - [Maintain & diagnose](https://runward.dev/docs/en/operating/maintain/) - [Evidence & integrity](https://runward.dev/docs/en/concepts/evidence/) - [Concepts: the deterministic gate](https://runward.dev/docs/en/concepts/the-gate/)