Skip to main content
sourceSource: corpus/docs/adrs/0045-overlays-are-project-owned.mdModified: 2026-06-23

type: adr id: 0045-overlays-are-project-owned status: superseded created: 2026-06-05 updated: 2026-06-06 supersedes: superseded_by: 0049-minimal-install-no-mount-no-imposed-workspace

Superseded by ADR-0049. There is no overlays directory: project conventions now live in AGENTS.md. The reasoning below (project rules must survive a framework upgrade) still holds — under 0049 it holds because the bootloader an agent reads is project-owned and an upgrade only re-copies corpus's named skill files.

ADR-0045: Overlays are project-owned and live outside the replaceable kernel payload

Context

Overlays are the project-local rule layer (architecture conventions, extra refusals, local command bindings) a repository adds on top of the kernel (overlays reference). They are project-authored content. Yet the kernel payload model placed them inside the framework-owned tree: docs/model/workspace.md listed overlays/ as a sub-directory of .corpus/kernel/ (the installed payload) and the producer seed shipped at starter-kit/.agents/overlays/ (which mirrors .corpus/kernel/).

That nesting is an upgrade footgun. The kernel-upgrade model (0044) replaces .corpus/kernel/ wholesale from a newer payload. With overlays nested inside it, a naive payload swap deletes the project's overlays — the one directory under .corpus/kernel/ a project is expected to author. The workspace table even said "Framework-owned; project edits belong in overlays/," i.e. it marked a project-owned island inside a framework-owned, replace-on-upgrade tree — exactly the ownership conflation that makes upgrades unsafe.

Decision

Overlays are project-owned and live at a top-level .corpus/overlays/ — a sibling of .corpus/kernel/, outside the replaceable payload — not at .corpus/kernel/overlays/.

  1. .corpus/overlays/ is a top-level workspace category (alongside sources/, status/, memory/, ledger/, archive/), project-owned and committed. A kernel upgrade replaces .corpus/kernel/ wholesale and never touches .corpus/overlays/.
  2. The producer seed moves out of the payload mirror: starter-kit/.agents/overlays/starter-kit/overlays/ (a workspace seed, not part of the starter-kit/.agents/.corpus/kernel/ mirror), so 0044's "starter-kit/.agents/ mirrors .corpus/kernel/" invariant stays honest. The stdlib ships it empty (a README).
  3. The ownership boundary is now positional: everything under .corpus/kernel/** is framework-owned and replaced on upgrade; .corpus/overlays/ (with the root AGENTS.md, .corpus/config.yaml, and the data workspace) is project-owned and preserved. This is the same boundary the upgrade story relies on.
  4. The overlay contract is unchanged (overlays reference): an overlay is SOFT, additive, lazily-loaded-by-name guidance that MUST NOT override an approved obligation or redefine kernel semantics. Only its location and ownership tagging change.

Refines 0040 (the kernel payload directory) and supports 0044 (the self-contained, replaceable payload). This is a precondition for a safe kernel upgrade and for the static adoption bundle.

Alternatives considered

AlternativeWhy rejected
Keep overlays under .corpus/kernel/overlays/, preserve them on upgrade by a special stash/restore stepMakes the upgrade special-case a project-owned subdir of a framework-owned tree; ownership-by-exception is exactly the conflation that caused the footgun. Positional ownership (location = owner) is simpler and safe by construction.
Keep the producer seed at starter-kit/.agents/overlays/Breaks 0044's mirror invariant (starter-kit/.agents/.corpus/kernel/): the coherence gate would expect it to install under .corpus/kernel/overlays/. The seed must leave the payload mirror.
Put project rules in the root AGENTS.md instead of overlaysAGENTS.md is always-loaded persistent facts; overlays are lazily-loaded, pass-scoped rule bundles — a different lifecycle (overlays reference §"where does a rule belong"). They are not interchangeable.

Consequences

Positive

  • A kernel upgrade is safe by construction: replacing .corpus/kernel/ cannot delete project overlays.
  • Ownership is positional and unambiguous: .corpus/kernel/** framework-owned/replaced; everything else the project's.
  • Aligns overlays with the other project-owned, upgrade-surviving surfaces (the root AGENTS.md, config.yaml).

Negative

  • The .corpus/ workspace grows from eight to nine top-level categories; adopters learn one more directory.
  • Existing prose and the producer layout that named starter-kit/.agents/overlays/ / .corpus/kernel/overlays/ must be updated (this ADR + workspace.md + overlays.md + the starter-kit/AGENTS.md/README.md pointers).

Neutral / tradeoffs

  • The overlay contract, the dependency-chain position (most-downstream), and the SOFT/additive boundary are unchanged — this is a relocation + ownership-tagging decision, not a semantic change. No canonical closed set changes.

Status

Accepted (v0.1).

Affected obligations / constraints

  • Adds: .corpus/overlays/ as a project-owned, upgrade-surviving top-level workspace category; the positional ownership boundary (.corpus/kernel/** framework-owned/replaced vs .corpus/overlays/ project-owned/preserved).
  • Modifies: the workspace partition (eight → nine categories); the producer seed location (starter-kit/.agents/overlays/starter-kit/overlays/); the starter-kit/AGENTS.md and starter-kit/README.md overlay pointers; the "Where overlays live" contract in docs/library/overlays.md.
  • Refines: 0040. Supports: 0044.
  • Does NOT change: the overlay contract, the dependency chain, the SOFT/additive boundary, or any canonical count.

Ready to run the loop on your own repo? Get started — copy the kit and write your first spec.