Reuse-First policy hierarchy

Accepted
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 canonical pattern → category → home table.
  • policies/reuse/<category>-first.kmd (sub-policies, 4 of them) — declare inherits_from: reuse-first.kmd in 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:

  1. 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.
  2. 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.
  3. 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.kmd

The 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:

  1. Inheritance link valid. Every file under policies/reuse/ declares inherits_from: policies/reuse-first.kmd in its frontmatter, and the target file exists.
  2. 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).
  3. Category coverage. Every row in the meta pattern → category → home table 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