docs: ausgelieferte Doku zitiert keine Issue-Nummern mehr, docs verify prueft es (schliesst #77)
CI / verify (push) Successful in 59s
Release / release (push) Successful in 37s

Files changed:
- .gitignore
- CHANGES.md
- EVALS.md
- INSTALL.md
- README.md
- VERSION
- docs/pipeline-rationale.md
- instructions/CONTRACT.md
- instructions/bootstrap.md
- instructions/dev/issue-tracking.md
- instructions/evolve-subtypes.md
- instructions/kb-profiles.md
- instructions/mcp-read-server.md
- instructions/wiki-ingest/SKILL.md
- kb/CONTRACT.md
- kb/concepts/COLLECTION.md
- kb/sources/COLLECTION.md
- raw/CONTRACT.md
- tools/.coveragerc
- tools/CONTRACT.md
- tools/README.md
- tools/chemenu/commands/docs_verify.py
- tools/chemenu/tests/test_docs_verify.py
- types/source.schema.yaml
- types/type-spec.md
This commit is contained in:
2026-09-09 18:52:34 +02:00
parent 5820924ffd
commit a51d7a322f
25 changed files with 388 additions and 68 deletions
+14 -12
View File
@@ -13,8 +13,8 @@ from `kb/` is what makes that boundary visible.
## Directory routing: a date shard, not a type
`raw/` addresses a file by **when it was accepted**, never by what kind of document it is
(Gitea #67). A promotion lands under `raw/<YYYY>/<MM>/`, computed from the calendar month of the
`raw/` addresses a file by **when it was accepted**, never by what kind of document it is.
A promotion lands under `raw/<YYYY>/<MM>/`, computed from the calendar month of the
`raw accept` call that promoted it - a pure function of something immutable, so it can never
rebalance: an overflowing bucket would move files and break every `[^cite-id]` anchor pointing at
them, and only a function of a fixed, past fact (the accept date) rules that out entirely. The
@@ -39,19 +39,20 @@ choice into `source_type:` by hand - which is exactly how a bias took hold. `raw
files that landed there, 16 turned out to be transcripts, 4 LLM analyses, 2 tracker exports, and
only 3 actual notes. The catch-all formed in the raw layer and was carried straight into `kb/`.
**Pre-#67 files are not moved.** `raw/`'s directory layout was never versioned anywhere -
`.wikitool-kb.json` describes `kb/`'s shape, and `corpus_diff.py` compares `raw_files:` as a
*value*, never as directory structure - so there is no "two corpus forms at once" to reconcile,
**Files promoted under the old type directories are not moved.** `raw/`'s directory layout was
never versioned anywhere - `.wikitool-kb.json` describes `kb/`'s shape, and `corpus_diff.py`
compares `raw_files:` as a *value*, never as directory structure - so there is no "two corpus
forms at once" to reconcile,
only a shape that was simply never described. `raw/articles/`, `raw/documents/`, `raw/notes/` and
`raw/assets/` keep holding whatever they already held, indefinitely: `raw accept --replaces`
writes back to a file's existing location (the path is the identifier, Gitea #64), so a legacy
writes back to a file's existing location (the path is the identifier), so a legacy
directory stays a valid promotion target as long as anything still lives there. `sources coverage`
walks `raw/` recursively and works unchanged either way.
## Getting a file in: `incoming/`
`raw/` is never chosen by hand. A file to be ingested is dropped into the gitignored top-level
`incoming/` - flat, since Gitea #67: no subdirectory carries any classification any more. A
`incoming/` - flat: no subdirectory carries any classification any more. A
subdirectory is still tolerated if one is used out of habit or by an older script (so an upgrade
never has to touch a caller), but it is **ignored**, never inspected:
@@ -81,12 +82,13 @@ capture date is whatever it always was, and a bundle mixing an old and a new sha
single correct address.
**The names occupied anywhere under `raw/` - file stems and bundle directory names alike - are
unique** (Gitea #64, widened globally by #67 once type directories stopped bounding the check).
unique** - a rule that used to hold only within one type directory, and went global once those
directories stopped bounding it.
Within a bundle, `handbuch.pdf` and `handbuch.md` sit side by side as always; the rule bites one
level up, so a second, unrelated source cannot promote quietly into a bundle it does not belong to
just because its own filename happens not to collide - nor into a same-named bundle sitting in a
different shard, or in a pre-#67 type directory. A promote whose target name is already occupied
is refused, naming both sanctioned ways past it without recommending either:
different shard, or in one of the old type directories. A promote whose target name is already
occupied is refused, naming both sanctioned ways past it without recommending either:
```
ERROR raw/documents/cluster.md already claims the stem "cluster" under raw/.
@@ -125,7 +127,7 @@ of the same subject is `secondhand` + `opinion`; official system documentation a
about the same system are both `published`, but `normative` against `reporting`.
Both are **required, with no default**, at the point a source page first exists - the same
no-guessing posture `source_type:` has (Gitea #66), but without that field's escape hatch: there
no-guessing posture `source_type:` has, but without that field's escape hatch: there
is no `unclassified` catalog slot for a capture field, because a guessed value here would not read
as "unknown", it would read as a claim about the capture that cannot be corrected later (the
knowledge exists only at the drop point). `raw accept --fidelity <value> --authority <value>`
@@ -167,7 +169,7 @@ value nobody ever thought about.
edition is not kept as a file: it is overwritten, and `git log --follow <path>` is the
archive - no `-2026-09-05` suffix, no content-hash filename, no version field, because
`raw_files:` is an identifier (invariant 2) and Git already answers "what did this used to
say" losslessly (Gitea #64).
say" losslessly.
- **Binary and image files still get ingested**, noting their presence and what they show,
even when their content cannot be read directly.
- **Every file is expected to be covered** by some source page, and one source page may cover