Date: 2026-07-16 Status: accepted Deciders: Thibault Souris (maintainer) Method: decision-loop — factual audit (no machine surface; the why of a rule locked in markdown bodies), challenge on scope creep, durable position
Context
The audit named two blind spots with one root. No machine surface: the rule set — runward's content moat — is consumable only by reading sixty markdown files; a CI dashboard, an editor extension or a script that wants "the CRITICAL rules mapped to floor, with their signatures" must reimplement frontmatter parsing against an undocumented shape. The why is buried: a rule's rationale lives in its body; the CLI never surfaces it, so the tacit knowledge stays tacit — the onboarding cost is "read the doctrine", and the bus factor concentrates in whoever already has.
The rule set is already the product's data. What is missing is the seam.
Decision
Two read-only, zero-LLM commands over the effective rule set (the mission's runward/rules/ copy when present, else the package's — exactly the gate's own resolution):
runward rules [--json] [--phase <id>]— the deterministic inventory: slug, title, impact, phases, ASI mapping, signature presence.--jsonemits a stable machine envelope —{ runward, source, count, rules: [...] }, rules sorted by slug — treated as a versioned, additive contract (contracts-governanceapplied to ourselves: fields are added, never renamed or repurposed).runward explain <rule> [--json]— the rule's contract surface (title, impact, the why viaimpactDescription, phases, ASI, signature) followed by its full body: the rationale inline, at the point of asking, no doctrine excavation. Unknown slugs answer with the migration record's guidance (ADR-0006) when one exists.
Alternatives discarded
- An HTTP/registry endpoint for rules. runward is never a runtime; the CLI is the seam, scripts compose it.
- A separate rules-data npm package. Splits the rules from the gate that verifies them and doubles the release surface; the mission-copy resolution (operators may edit their rules) would be lost.
- Rendering the doctrine's full rationale into
explain. The rule body already is the operational form of the rationale; duplicating doctrine prose creates a second source of truth that drifts.
Consequences
- Positive. Dashboards, editor extensions and CI annotations get a supported contract instead of scraping; the why of a rule is one command away — the tacit-knowledge tax and the bus factor both shrink; the content moat gains a platform seam.
- Negative, accepted. The JSON envelope is a public contract to honor additively from now on;
explainoutput quality is bounded by rule-body quality (a pressure on rule authoring, accepted as healthy). - On other boundaries.
src/lib/rules.ts(one parser for the full frontmatter shape) +src/commands/rules.ts; README documents the envelope; smoke and unit tests pin determinism, sorting, and the migration answer for renamed slugs.
Reevaluation trigger (mandatory, dated)
Reopen if a consumer needs a field the envelope cannot add additively (a breaking shape change — expand/contract like any port, ADR-0011), or if --json output is observed drifting between runs on an unchanged rule set (a determinism bug, treated as a gate-grade incident).
Trigger set on: 2026-07-16 · Watched via: consumer reports and the release review of the envelope shape.