From cdd2eba5640f1729fa4bfd080e19c42a98d99341 Mon Sep 17 00:00:00 2001 From: Manas Srivastava Date: Mon, 11 May 2026 09:58:49 +0530 Subject: [PATCH] docs(plan-rollout): SYSTEM.md schema spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The semantic-contract-graph schema. Optional input to /plan-rollout — declares role-level contracts (auth mints session tokens middleware enforces; breaks-if format change without coordinated deploy). Distinct from the import graph (discovered at runtime). Repo-wide, long-lived, hand-authored. This commit lands the spec only. The consuming skill ships in the next commit. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/SYSTEM-MD.md | 217 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 docs/SYSTEM-MD.md diff --git a/docs/SYSTEM-MD.md b/docs/SYSTEM-MD.md new file mode 100644 index 000000000..3fe475bae --- /dev/null +++ b/docs/SYSTEM-MD.md @@ -0,0 +1,217 @@ +# SYSTEM.md — the semantic contract graph + +`SYSTEM.md` is a declarative file at the repo root describing what each +component *is*, what it *owns*, and the role-level contracts it has with +other components. Its consumer is `/plan-rollout`, which uses it to slice +a single large change into an ordered PR stack with reader guides and +deploy-edge awareness. + +`SYSTEM.md` is optional. `/plan-rollout` works without it — falling back +to path heuristics + import-graph discovery — and improves materially +when present. + +## What SYSTEM.md is NOT + +It is not a package manifest. It does not list: + +- Import graphs or symbol-level callers +- npm / Cargo / Gem / Go module versions +- Build dependencies or linker flags +- Test framework wiring + +Everything mechanical is discovered at runtime (AST, grep, package manifests). +Declaring it here would go stale within a week. + +## What SYSTEM.md IS + +The **semantic contract graph**: the relationships between components that +only a human knows. + +| Kind | Example | Lives where | +|------|---------|-------------| +| Role/contract dep | "auth mints session tokens middleware enforces; format change without middleware redeploy breaks sessions" | SYSTEM.md | +| Package/import dep | "`auth.ts` imports `crypto-utils`; `middleware.ts` calls `auth.verify()`" | Discovered (NOT here) | + +`/plan-rollout` reads both. Declared contracts give the *why* (what breaks +under coordinated deploy). Discovered imports give the *what* (which files +move together). Disagreements surface in the decomposition output for human +resolution rather than being silently resolved either way. + +## Schema (v1 — intra-repo) + +```yaml +--- +version: 1 +components: + - name: + path: + kind: component # or: leaf-util | types-only (optional; defaults to 'component') + role: + owns: + - + contracts: + - with: + nature: + breaks-if: + rollout-edge: + note: + rollout-order: +--- + +# System Map + + +``` + +### Field reference + +**`name`** — unique identifier used by other artifacts to reference this +component. Keep it short and stable. Renames cascade to every contract +reference. + +**`path`** — where the component lives in the repo. Can be a file or +directory. Used for component-membership lookups (is `src/auth/session.ts` +in the `auth` component? yes). + +**`kind`** — defaults to `component`. Use: +- `leaf-util` for shared utility dirs (`src/utils/`, `src/helpers/`) that + components import freely without declaring contracts. The skill skips + these when reconciling. +- `types-only` for pure type/interface modules. Skipped likewise. + +**`role`** — one sentence describing what this component is FOR. Not what +it contains, not how it's built. What it does in the system. + +**`owns`** — data surfaces, tables, APIs, or features this component is +the single source of truth for. Two components claiming ownership of the +same surface is a design smell. + +**`contracts`** — the heart of SYSTEM.md. Each contract declares a +role-level relationship with another component. + +- **`with`** — the other component's name. Must match a declared component. +- **`nature`** — plain-English description of the relationship. +- **`breaks-if`** — the specific human action that violates the contract. + This is what `/plan-rollout` reads. "Session payload schema changes + without middleware redeploy" tells the skill these two PRs must ship + as a coordinated stage. +- **`rollout-edge`**: + - `hard` = must deploy together (e.g., a session format change). The + skill places both sides of a hard edge in the same slice or marks + the slice "coordinated deploy required." + - `soft` = can lag (e.g., a logging metric addition). Noted but not + enforced. +- **`note`** (optional): + - `runtime-only` — coupling via DB, message bus, HTTP, or filesystem; + no code-level import edge exists. Suppresses the "contract without + imports" reconcile flag. + - `types-only` — TypeScript types only, not runtime values. + - `legacy` — contract exists but is being phased out. + +**`rollout-order`** — integer. Components with lower numbers ship first. +Equal numbers can ship in parallel. Used as the default ordering for +PR-stack decomposition; users can override per-call. + +## Example + +```yaml +--- +version: 1 +components: + - name: auth + path: src/auth + role: authentication + session lifecycle + owns: + - user table + - session table + - JWT minting + contracts: + - with: middleware + nature: middleware enforces session tokens auth mints + breaks-if: session payload schema changes without middleware redeploy + rollout-edge: hard + rollout-order: 1 + + - name: middleware + path: src/middleware + role: request routing + auth enforcement + owns: + - request context shape + contracts: + - with: gateway + nature: gateway consumes req.user set by middleware + breaks-if: req.user shape changes without gateway redeploy + rollout-edge: hard + rollout-order: 2 + + - name: gateway + path: src/gateway + role: external HTTP surface + owns: + - public API schema + contracts: [] + rollout-order: 3 + + - name: utils + path: src/utils + kind: leaf-util + role: shared helpers — imported freely without contracts + owns: [] + contracts: [] + rollout-order: 0 +--- + +# System Map + +auth and middleware are the security boundary. Any change to session format +or the user-context shape is a coordinated deploy (rollout-edge: hard). We +learned this after the Feb 2025 incident where a session serializer change +shipped 40 minutes ahead of middleware and logged everyone out. + +utils is declared `leaf-util` so the skill doesn't flag the many imports +into it from other components as missing contracts. +``` + +## How /plan-rollout uses it + +`/plan-rollout` reads `SYSTEM.md` (if present) at the start of every run +and applies it three ways: + +1. **File-to-component mapping** — when bucketing changed files into PR + slices, files matching a component's `path` join that component's + slice. No SYSTEM.md ⇒ slices fall back to top-level path heuristics + (one slice per top-level dir of changes). +2. **Slice ordering** — slices are ordered by their components' + `rollout-order`, lowest first. Files in `leaf-util` or `types-only` + components float to slice 0 (foundational; no contracts to honor). +3. **Hard-edge enforcement** — if changed files span both sides of a + `rollout-edge: hard` contract, the skill either merges those slices + into a single coordinated stage or annotates the decomposition with + a deploy-coordination warning. + +Reconciliation is informational in v1. The skill prints flagged +mismatches between declared contracts and discovered imports +(`import-without-contract`, `contract-without-imports`, +`rollout-order-inversion`) so the human can resolve them, but does not +gate output on them. + +## Scaffolding + +`/plan-rollout` does NOT scaffold `SYSTEM.md` for you in v1. Scaffolding +(walking top-level dirs, classifying each, inferring `role` from +README/package.json) is a v2 follow-up. For v1, write the file by hand +or copy the example above and edit it. + +## Relationship to other declarative files + +| File | Purpose | Who writes it | +|------|---------|---------------| +| `CLAUDE.md` | Project-specific instructions for Claude (routing rules, test commands) | Human | +| `CODEOWNERS` | Who reviews changes to which paths | Human | +| `SYSTEM.md` | Semantic contract graph (this file's schema) | Human | +| `decomposition.md` | Per-change PR stack | `/plan-rollout` | + +SYSTEM.md is the long-lived, repo-wide truth. `decomposition.md` is a +per-change artifact that references it.