# Ownership and Templates Chemenu ships two kinds of files side by side, and at a glance they look the same: both are plain markdown, both sit in the repo root or under `kb/`, both get read at session start. But a stack upgrade treats them completely differently. Some - [AGENTS.md](../AGENTS.md), [kb/CONTRACT.md](../kb/CONTRACT.md), the per-stage contracts - are identical in every instance that runs this stack and can simply be overwritten by the next release. Others - `USER.md`, `SOUL.md`, `kb/CONVENTIONS.md`, `ENVIRONMENT.md` - describe one particular instance, and overwriting them would silently erase a choice someone made on purpose. ## Two different kinds of truth The stack-owned files describe how the tool works. `kb/CONTRACT.md` opens by saying it holds what `tools/wikitool` enforces or what follows mechanically from how it operates - see [kb/CONTRACT.md](../kb/CONTRACT.md), lines 10-13. That kind of statement doesn't vary by instance: the compiler behaves the same way regardless of who is running it, so the sentence describing that behavior can be copied byte-for-byte into every checkout without becoming wrong anywhere. The instance-owned files describe a choice: which language pages are written in, what tone the agent takes, who the operator is, which git remote is authoritative, which MCP servers are reachable. None of that follows from the tool's mechanics - two instances of the identical stack can answer all of these differently and both be correct. [AGENTS.md § Personalization](../AGENTS.md#personalization) frames the split the same way for `kb/CONTRACT.md` versus `kb/CONVENTIONS.md`: "the split is by who may change the sentence, not by what it is about." A rule about page structure could in principle have been written per-instance too, but then every instance answering "not German" to setup would be hand-editing a file the stack also ships, and the next `dist export` merge would hand the instance's own file back to it, discarding the customization. ## Why silent overwrite is the failure being designed against A stack update is meant to be a routine, low-risk operation: pull the latest release, get whatever fixes and features shipped since the last one. That only stays low-risk if the update knows which files it's allowed to touch. If `USER.md` or `kb/CONVENTIONS.md` were treated the same as `AGENTS.md` - shipped and periodically re-copied - an upgrade would quietly replace a description of *this* operator, in *this* language, with whatever placeholder or default the stack maintainers wrote. The damage wouldn't be loud: nothing crashes, the files still parse, the agent just starts acting on the wrong premises until someone notices the voice or the language changed. Keeping the boundary at the file level, rather than trying to merge changes within a shared file, means an upgrade never has to guess which lines are "stack" and which are "instance" - the file itself already answers that. ## Why the boundary is a predicate rather than a list For a while the boundary was written down as a list of paths - once in `dist_cmd.py`, once in the merge procedure a private instance was told to run by hand, and once in the check that procedure ended with. Three copies of one fact, which is the shape [AGENTS.md](../AGENTS.md) invariant 8 exists to forbid, and they drifted exactly as predicted: the hand-run procedure was still naming three paths after the collection contracts had moved to the instance's side of the line, so it discarded upstream changes to files it had never heard of, while its own final check excluded the same three paths and therefore reported success. `chemenu/ownership.py` replaced the lists with one question - is this path, under a content stage, the stack's or the instance's? - answered by shape rather than by enumeration: `/CONTRACT.md`, and anything ending `.template`. Both consumers ask it, so `dist export` and `wikitool upstream merge` cannot disagree, and a machinery file added under a content stage tomorrow is recognised by both without either being edited. The deeper point is not the deduplication: a list has to be maintained by whoever remembers it exists, and the failure mode when nobody does is silence, because a path the list has never heard of simply looks like content. ## Why a `.template`, not just an absent file The mechanism for instance-owned content is a `.template` file the distribution ships instead of the real one - `USER.md.template`, `SOUL.md.template`, `kb/CONVENTIONS.md.template`, `ENVIRONMENT.md.template`. An alternative would have been to ship nothing at all and let a brand-new instance start from a blank page. The template exists because a blank page doesn't tell [instructions/setup-instance.md](../instructions/setup-instance.md) what shape the answer should take, and it gives nothing for a validator to check afterward. A template carries a placeholder value - a sentinel - in the fields that need a real answer. Setup interviews the operator and replaces the sentinel with what they actually said. That gives `doctor` a mechanical way to tell "personalized" from "not yet": a file that still contains the sentinel hasn't been through setup, regardless of whether the file exists. That's also why `ENVIRONMENT.md` only warrants a WARN rather than a FAIL when absent - see [AGENTS.md § Environment](../AGENTS.md#environment) - while a missing or unfilled `USER.md`/`SOUL.md`/`kb/CONVENTIONS.md` is a harder failure: `ENVIRONMENT.md` describes one checkout among possibly several and is gitignored for that reason, so its absence is a normal state rather than a sign setup was skipped. ## The consequence in practice Running a stack upgrade against an existing instance boils down to: overwrite the verbatim files, leave the `.template`-sourced files alone. The verbatim files are safe to replace wholesale because they were never instance-specific to begin with - identical content going back in changes nothing an instance actually decided. The template-sourced files were filled in once, by a person, for a reason, and nothing about a newer release of the stack's mechanics gives it standing to override that.