types/: Seiten-Type-Spec-Anleitungsprosa in stackeigene guidance-Datei ausgelagert (schliesst #104)
CI / verify (push) Failing after 43s
Release / release (push) Successful in 34s

Files changed:
- AGENTS.md
- CHANGES.md
- VERSION
- docs/ownership-and-templates.md
- instructions/migrations/6.0.0-type-guidance-split.md
- instructions/setup-instance.md
- tools/CONTRACT.md
- tools/chemenu/commands/dist_cmd.py
- tools/chemenu/commands/types_cmd.py
- tools/chemenu/tests/test_dist_cmd.py
- tools/chemenu/tests/test_dist_upgrade.py
- tools/chemenu/tests/test_type_resolver.py
- tools/chemenu/tests/test_types_cmd.py
- tools/chemenu/type_resolver.py
- tools/chemenu/types_core.py
- types/comparison.guidance.md
- types/comparison.md
- types/concept.guidance.md
- types/concept.md
- types/entity.guidance.md
- types/entity.md
- types/source.guidance.md
- types/source.md
- types/type-guidance.md
- types/type-guidance.schema.yaml
- types/type-spec.md
This commit is contained in:
2026-09-15 18:23:38 +02:00
parent 90ce41964f
commit d49513bda6
26 changed files with 789 additions and 238 deletions
+41 -25
View File
@@ -16,7 +16,7 @@ overwriting them would silently erase a choice someone made on purpose.
- [Why silent overwrite is the failure being designed against](#why-silent-overwrite-is-the-failure-being-designed-against)
- [Why the boundary is a predicate rather than a list](#why-the-boundary-is-a-predicate-rather-than-a-list)
- [Why a `.template`, not just an absent file](#why-a-template-not-just-an-absent-file)
- [Where the file boundary strains](#where-the-file-boundary-strains)
- [Where the file boundary used to strain](#where-the-file-boundary-used-to-strain)
- [The consequence in practice](#the-consequence-in-practice)
<!-- /wikitool:toc -->
@@ -92,36 +92,50 @@ also why `ENVIRONMENT.md` only warrants a WARN rather than a FAIL when absent -
checkout among possibly several and is gitignored for that reason, so its absence is a normal
state rather than a sign setup was skipped.
## Where the file boundary strains
## Where the file boundary used to strain
"The file itself already answers that" holds for every file above except one shape, and it is
worth naming rather than discovering: a `root: kb` type-spec has two audiences inside one file.
"The file itself already answers that" held for every file above except one shape: a `root: kb`
type-spec used to carry two audiences inside one file.
Its authoring guidance - when to use this type, what each frontmatter field means, how to cite -
is instruction to an agent. It reads like the stack's own prose because it *is* the stack's own
prose: a later release that learns something about writing entity pages would want to improve it
everywhere. Its `## Template` block and its `layout:` titles are the opposite: they become the
was instruction to an agent. It read like the stack's own prose because it *was* the stack's own
prose: a later release that learned something about writing entity pages would want to improve it
everywhere. Its `## Template` block and its `layout:` titles were the opposite: they became the
literal headings of pages this instance writes, in the language this instance chose, and no
release has any business touching them.
release had any business touching them.
The same file is where the language question comes apart from this one, and for the same reason:
ownership decides who may change a line, its reader decides what language it is in - which is why
an instance's own type-spec keeps English guidance around a template block in its own language.
[language-boundaries.md](language-boundaries.md) has that argument; the rest of this page is about
ownership alone.
The same file is where the language question comes apart from the ownership one, and for the same
reason: ownership decides who may change a line, its reader decides what language it is in -
which is why a `root: kb` type-spec still keeps English prose around a template block written in
its own language. [language-boundaries.md](language-boundaries.md) has that argument; this page is
about ownership alone.
Ownership is per file, so the instance keeps both halves. The template half is correct that way.
The guidance half pays for it: an instance that adopted its type-specs at setup will never
receive an improvement to them again, because `dist upgrade` writes the `.template` beside the
adopted file and never the file itself. Nothing breaks, and nothing reports it - the instance
simply keeps reading the guidance it was handed the day it was created.
Ownership is per file, so a file carrying both audiences had to give both halves to whoever owned
it. The template half was correct that way. The guidance half paid for it: an instance that
adopted its type-specs at setup never received an improvement to the guidance again, because
`dist upgrade` wrote the `.template` beside the adopted file and never the file itself. Nothing
broke, and nothing reported it - the instance simply kept reading the guidance it was handed the
day it was created.
This is not an argument against the per-file boundary; the boundary is what makes an upgrade
safe at all, and merging inside a shared file is the failure the whole section above is about.
It is an argument that this particular file is cut in the wrong place. Splitting it - the
template block into its own instance-owned file, the guidance staying stack-owned and shipping
verbatim - would put the boundary back where the audiences actually divide, and would cost a
migration for every instance that already adopted one.
That was not an argument against the per-file boundary; the boundary is what makes an upgrade
safe at all, and merging inside a shared file is the failure the whole section above is about. It
was an argument that this particular file was cut in the wrong place - so it was cut again. A
`root: kb` type-spec may now declare `guidance:`, a repo-relative path to a second,
stack-owned file (`types/<name>.guidance.md`) holding exactly the half that used to be stranded:
when to use the type, when not to, and mechanism-level advice that holds for every instance. That
file ships verbatim and upgrades like any other machinery file, whether or not the type-spec that
links it has ever been adopted. `types/type-spec.md` §§ "Who owns a type-spec" and "Anatomy of a
type" hold the current shape; `tools/wikitool types describe <name>` composes both files into one
answer, so an agent asking for a type's contract never needs to know it comes from more than one
file. An instance that adopted its type-specs before this split existed takes it as an *offered*
migration rather than something an upgrade applies on its own - the same reasoning as any other
instance-owned file in the middle category below, spelled out for this one case because it is the
case that motivated the category existing at all.
A type-spec that declares no `guidance:` - one an instance writes entirely for itself - is
unaffected: it is still described from its own body alone, the way every type-spec worked before
`guidance:` existed. The split is optional exactly where there is no stack-owned improvement to
receive.
## The consequence in practice
@@ -129,7 +143,9 @@ An upgrade sorts every shipped path into three categories, not two - and the thi
becomes visible once an upgrade is a command rather than a hand-run copy:
- **Verbatim files** - `AGENTS.md`, `kb/CONTRACT.md`, the per-stage contracts, everything under
`tools/`, `types/` and `instructions/` - are the release's to replace.
`tools/`, `types/` and `instructions/` - are the release's to replace. This is where a `root:
kb` type-spec's optional `types/<name>.guidance.md` sits: verbatim, even though the type-spec
it documents (below) is not.
- **`.template`-sourced files** - `USER.md`, `SOUL.md`, `kb/CONVENTIONS.md`, each
`kb/<name>/COLLECTION.md`, `ENVIRONMENT.md`, the `root: kb` type-specs - are never written by
an upgrade at all. The distribution ships only the `.template` beside them, so the filled file