Reuse-First policy hierarchy
| Field | Value |
|---|---|
| Status | Accepted (2026-05-02) — defaults ratified: reuse-first (meta name), reuse/ (sub-policy dir), single inheritance, code-first stays sibling, ≥3 categorical rules gate. |
| Author(s) | Rodrigo (with Claude as scribe) |
| Date | 2026-05-02 |
| Affects | meta/docs/stack/policies/sdk-first.kmd (rename + split), policies/code-first.kmd (sibling, untouched), commands/k-sdkify.md, commands/k-housekeep.md, RFC-001-spec-encapsulation-across-platforms.md, refs in CLAUDE.md |
| Depends on | monorepo-RFC-009-meta-internal-split.md (location of policies/), engines/sdk/koder_kit/docs/rfcs/RFC-001-spec-encapsulation-across-platforms.md (the policy this hierarchy enforces) |
1. Summary
Replace the single policies/sdk-first.kmd with a two-level hierarchy:
policies/reuse-first.kmd(meta) — single source of truth for the cross-cutting decision tree, the pre-Write protocol, the promotion pipeline, and the canonicalpattern → category → hometable.policies/reuse/<category>-first.kmd(sub-policies, 4 of them) — declareinherits_from: reuse-first.kmdin frontmatter and add only the rules that are categorically distinct (versioning, breaking-change discipline, testing thresholds, build determinism, wire compatibility, etc.).
The decision tree is never duplicated — it lives only in the meta. Sub-policies extend, they do not reimplement. sdk-first.kmd becomes a redirect stub for one or two release cycles, then is removed.
2. Motivation
The current sdk-first.kmd carries three problems that compound as the Stack grows:
- Naming is narrower than scope. The policy covers UI framework, runtime libs, build-time CLIs and protocol clients — but the name suggests "API client SDK only". New engineers (and AI sessions) underestimate which patterns are in scope.
- Categorical rules are implicit. Today you discover that a runtime lib should follow strict SemVer or that a build-time tool must be hash-stable only by reading other policies (
releases.kmd,code-first.kmd) or by tribal knowledge. Nothing forces these rules at the source where they apply. - The flat 15-row table will not scale. As the Stack adds patterns (e.g. shared ML model artefacts, kernel extensions, codec engines) the table inflates and category-specific search becomes manual.
A flat split into four independent policies was considered (and rejected — see §9): it would duplicate the decision tree four times, exactly the cross-LLM drift code-first.kmd warns against.
The hierarchy proposed here avoids both ends: the decision tree stays unique; the categorical content gets first-class location.
3. Design
3.1 Two-level structure
meta/docs/stack/policies/
├── reuse-first.kmd ← meta (replaces sdk-first.kmd)
├── code-first.kmd ← sibling, untouched
└── reuse/ ← sub-policy directory
├── ui-framework-first.kmd
├── runtime-lib-first.kmd
├── build-tooling-first.kmd
└── protocol-first.kmdThe meta policy is one file; sub-policies are one file each, scoped to a single category. Adding a fifth category later (e.g. ml-asset-first) is a single-file addition; no policy needs to grow.
3.2 Frontmatter schema
The meta reuse-first.kmd keeps its current frontmatter shape (name, type: policy, mandatory: true, triggers, references).
Sub-policies declare an extra field:
---
name: UI Framework First
type: policy
inherits_from: policies/reuse-first.kmd
mandatory: true
category: ui-framework
audit:
applicable_to:
- "engines/sdk/koder_kit
app/**/*.dart"
script: ./ui-framework-first-audit.sh
severity: strict
summary: |
…categorical rules only…
---inherits_from is structurally validated: a sub-policy that does not declare it (or declares an invalid path) fails koder-spec-audit reuse. Sub-policies must NOT redeclare the decision tree, the protocol, or the promotion pipeline.
3.3 Layout — what goes where
| Content | Lives in | Rationale |
|---|---|---|
| 3-question decision tree | meta only | DRY across categories |
| Pre-Write protocol (3 questions answered in chat) | meta only | Same tree, same audit signal |
Promotion pipeline (sdk/<name>/backlog/pending/NNN-promote-…) |
meta only | Mechanism is identical |
Canonical pattern → category → home table |
meta only | Single index; sub-policies link to it |
Anti-patterns ("default to local copy", "encode if the LLM thinks", …) |
meta only | Behavioural, not categorical |
| Category-specific rules (SemVer tier, a11y baseline, hash stability, wire compat, …) | sub-policy | Substantive distinction per category |
| Category-specific audit script | sub-policy audit.script |
Targets only relevant tree |
Category-specific commands (/k-ui-audit, /k-protocol-audit, …) |
sub-policy references |
Discoverability |
3.4 Audit
koder-spec-audit reuse (a new sub-command of the existing koder-spec-audit binary tracked in KSTACK-101) performs three structural checks:
- Inheritance link valid. Every file under
policies/reuse/declaresinherits_from: policies/reuse-first.kmdin its frontmatter, and the target file exists. - No duplicated content. Sub-policies do not contain the decision tree (heuristic: no h2/h3 with text matching
Decision (tree|protocol),When this applies,Promotion pipeline). - Category coverage. Every row in the meta
pattern → category → hometable cites a category that has an existing sub-policy.
The audit is strict for sub-policy structural validity and advisory for table coverage (a new category may exist briefly before its sub-policy is written).
4. Categorical content preview
Each sub-policy is justified only if it carries at least three substantive categorical rules that the meta cannot express. The four below clear that bar.
4.1 ui-framework-first.kmd
Applies to: `enginessdkkoder_kit