18ae28f918
Chemenu kompiliert Rohnotizen zu einem verlinkten, quellengebundenen Wiki: raw/ -> types/ + tools/ -> kb/ -> reports/. Was mechanisch ist, macht tools/wikitool; was Urteil braucht, macht ein Agent unter Contracts, deren Grenzen in Code durchgesetzt sind statt im Prompt. Dieser Commit ist der Startpunkt der oeffentlichen Historie. Die vorherige Entwicklung fand in einer privaten Instanz statt und ist nicht Teil dieses Repositorys; ihre Erzaehlung steht vollstaendig in CHANGES.md, das mit 44 Eintraegen von 0.1.0 bis 2.1.0 erhalten geblieben ist. Der mitgelieferte Korpus ist ein Testbett und eine Demo: 170 Seiten ueber den Stack selbst - Gates, Lint, Versionierung, Suche, das Wiki-Muster. Er dokumentiert das Werkzeug mit den eigenen Mitteln des Werkzeugs. Lizenz: AGPL-3.0 fuer den Stack (tools/, types/), CC-BY-4.0 fuer die Inhalte. Die Grenze zwischen beiden ist der Dateiplan, den dist export berechnet - siehe NOTICE.
240 lines
13 KiB
Markdown
240 lines
13 KiB
Markdown
# kb/ - Knowledge Layer Contract
|
|
|
|
The compiled knowledge layer, and the third stage of the pipeline
|
|
`raw/` -> `kb/` -> `reports/`. Everything here is written and maintained by the LLM from
|
|
material in `raw/`, and is expected to stay correct without being re-derived.
|
|
|
|
**Quality goal:** a page should answer a future question *without* re-reading the source it
|
|
came from. If answering still requires the raw file, the page is incomplete.
|
|
|
|
This file holds the rules that apply in **every** collection. Each `kb/<name>/COLLECTION.md`
|
|
declares that it inherits them and adds only what is local to its own subtree - read this file
|
|
together with the target collection's contract before writing or editing a page.
|
|
|
|
Structural facts (which frontmatter fields exist, which are required, what the body skeleton
|
|
looks like) are *not* here - they belong to the type-specs and are printed by
|
|
`tools/wikitool types describe <type>`. Never hand-write frontmatter; scaffold with
|
|
`tools/wikitool new <type> --name "<Name>" --set field=value ...`.
|
|
|
|
## Collections
|
|
|
|
`kb/` is a **namespace, not a collection**. It carries no `COLLECTION.md` of its own.
|
|
|
|
A directory under `kb/` is a **collection** exactly when it contains a `COLLECTION.md`. That
|
|
file is the local authoring contract for every page in the subtree.
|
|
|
|
- A subdirectory *inside* a collection is an **area**. It inherits the enclosing contract and
|
|
must not carry a `COLLECTION.md` of its own - `kb/entities/systems/` is an area of
|
|
`kb/entities/`.
|
|
- A `COLLECTION.md` nested inside another collection is invalid.
|
|
- `COLLECTION.md` appears **nowhere outside `kb/`**. `raw/`, `types/`, `tools/`, `reports/`
|
|
and `instructions/` are not collections and carry a `CONTRACT.md` or a root type-spec
|
|
instead.
|
|
|
|
`tools/wikitool docs verify` enforces all three.
|
|
|
|
| Collection | Holds | Contract |
|
|
|------------|-------|----------|
|
|
| `kb/entities/` | Concrete things: projects, deployed systems, tools, technologies, people | [entities/COLLECTION.md](entities/COLLECTION.md) |
|
|
| `kb/concepts/` | Architectures, patterns, protocols, workflows, decisions, recurring problems | [concepts/COLLECTION.md](concepts/COLLECTION.md) |
|
|
| `kb/sources/` | One summary page per ingested source, carrying its `raw_files:` provenance | [sources/COLLECTION.md](sources/COLLECTION.md) |
|
|
| `kb/comparisons/` | Structured comparisons of two or more existing pages | [comparisons/COLLECTION.md](comparisons/COLLECTION.md) |
|
|
|
|
**Adding a collection:** `mkdir kb/<name>` and write a `kb/<name>/COLLECTION.md`. Collections
|
|
are discovered by contract presence, so no code change is needed. A collection only becomes
|
|
*writable* once some type-spec declares a matching `base_dir:`.
|
|
|
|
**Where a page goes** is decided by its type-spec, never by hand - see
|
|
[types/type-spec.md](../types/type-spec.md).
|
|
|
|
## Generated files
|
|
|
|
Never hand-edit these; they are produced by `tools/wikitool`:
|
|
|
|
| File | Produced by |
|
|
|------|-------------|
|
|
| `kb/index.md` | `wikitool index rebuild` - the catalog **map**: statistics, counts, links |
|
|
| `kb/<collection>/INDEX.md` and `kb/<collection>/<area>/INDEX.md` | `wikitool index rebuild` - the page tables |
|
|
| `kb/log.md` | `wikitool log append` |
|
|
| `kb/provenance.md` | `wikitool sources rebuild-index` |
|
|
|
|
To *find* a page, search rather than read the catalog: `tools/wikitool search "<text>"`, or
|
|
`tools/wikitool search --field <predicate>` for a structured query over frontmatter.
|
|
|
|
## Naming
|
|
|
|
- Human-readable titles with spaces: `Hybrid Search.md`, `Gitea Actions.md` - not kebab-case.
|
|
- Singular for entities: `ha-core.md`, not `ha-cores.md`.
|
|
- Comparison pages read as a comparison: `Go vs Rust.md`.
|
|
- ADRs are prefixed: `adr-001-use-go-modules.md`.
|
|
- The filename stem *is* the page title, and `[[wikilinks]]` must match it exactly.
|
|
- Prefer readability over convention when the two conflict.
|
|
|
|
What to name a thing: projects use their repository or common name; systems a descriptive
|
|
name; tools the tool's own name; technologies their standard spelling and capitalization;
|
|
people a full name or common handle.
|
|
|
|
## Every page should
|
|
|
|
- [ ] Carry a clear, descriptive title and a summary near the top
|
|
- [ ] Use consistent terminology with the rest of the wiki
|
|
- [ ] Link to every entity and concept it mentions, and be linked to in return
|
|
- [ ] Cite its hard facts (see [Provenance and citation](#provenance-and-citation))
|
|
- [ ] Duplicate no existing page
|
|
- [ ] Appear in the catalog (guaranteed by `wikitool index rebuild`)
|
|
|
|
## Tone
|
|
|
|
Wikipedia style: factual, neutral, specific.
|
|
|
|
- No buzzwords ("bahnbrechend", "hochmodern", "leistungsstark", "revolutioniert").
|
|
- No AI filler ("es sei angemerkt", "es ist wichtig zu betonen", "in der heutigen Zeit").
|
|
- No em-dash asides carrying parenthetical reasoning.
|
|
- At most 2 blockquoted lines per page. `wikitool lint` reports overages as advisory, since
|
|
exceeding the cap can be a legitimate judgment call - but the page should carry the
|
|
knowledge itself, not delegate it to quotations. The cap is about how much of the page you
|
|
let quotes carry; it does not apply to text you are citing verbatim from a source.
|
|
|
|
Good: "MQTT ist ein leichtgewichtiges Publish-Subscribe-Protokoll für Geräte mit knappen
|
|
Ressourcen."
|
|
|
|
Bad: "MQTT ist ein bahnbrechendes, hochmodernes Protokoll, das die IoT-Kommunikation
|
|
revolutioniert - und es sei angemerkt, dass es ein Publish-Subscribe-Muster verwendet."
|
|
|
|
## Language
|
|
|
|
Pages are written in **German**. This binds `kb/` and the authoring surface that shapes it -
|
|
the page type-specs `types/entity.md`, `types/concept.md`, `types/source.md` and
|
|
`types/comparison.md`. `raw/` is untouched ([raw/CONTRACT.md](../raw/CONTRACT.md)), and the
|
|
control plane stays English: AGENTS.md, the stage contracts including this one, `instructions/`,
|
|
and the type-specs for non-page artifacts.
|
|
|
|
Every line of a page is either **prose** or an **identifier**. Only prose is translated.
|
|
|
|
**Prose:** descriptions and definitions, `## Key Information` values, `## Details` body text, a
|
|
source page's Summary / Key Takeaways / Action Items / Not Extracted, and `summary:`.
|
|
|
|
**Identifiers - never translated, in any language:**
|
|
|
|
| Identifier | Why |
|
|
|---|---|
|
|
| Page titles, and the H1 that repeats one | A title is the wiki's only identifier for a page and follows the subject's own established name - see [Naming](#naming). `wikitool lint` reports an H1 that stops matching its title |
|
|
| The subtype value on the generated `**Typ:**` line | It renders a schema enum value (`technology`, `workflow`), which `search --field` filters on. The label is prose; the value is not |
|
|
| `tags:` | Search keys, not prose |
|
|
| Commands, paths, config keys, hostnames, code | They are what they are |
|
|
| Quotations | Quoted verbatim in the source's own language |
|
|
|
|
Established English technical terms stay English inside German prose - "GitOps", "Ownership
|
|
Model", "Reverse Proxy", "Pull Request". Translate a term only where the German one is genuinely
|
|
the more common usage. A coined German equivalent nobody else writes makes the page harder to
|
|
find, not more idiomatic.
|
|
|
|
Which terms those are, which have a settled German form, and the register the prose is written in:
|
|
[instructions/german-terminology.md](../instructions/german-terminology.md). It is lookup material,
|
|
not a second rule - every entry in it is a decision that was made wrong once first.
|
|
|
|
**A source in another language** is still summarized in the KB language: a source page is
|
|
evidence *about* a source, not a substitute for it. Quote verbatim in the original language and
|
|
record the raw file's language in `source_language:`.
|
|
|
|
### Section headings
|
|
|
|
Three headings are a vocabulary the tool owns rather than prose an author picks: `xref add`
|
|
writes into Relationships and See Also, and `cite add` owns the trailing Footnotes block. They
|
|
follow the KB language like everything else - `## Beziehungen`, `## Siehe auch`, `## Fußnoten` -
|
|
and `tools/chemenu/sections.py` is the single place naming them.
|
|
|
|
Each has aliases the tool still *recognizes* but no longer writes, which is what lets the corpus
|
|
be translated page by page: a page still carrying `## Relationships` is found and appended to
|
|
correctly, and `cite sync` leaves an untranslated `## Footnotes` heading alone rather than
|
|
retitling it. Renaming a heading is the translation pass's job, never a side effect of another
|
|
command. Any *other* heading an author adds is ordinary prose and is translated with the rest.
|
|
|
|
## Linking
|
|
|
|
Every page links to what it mentions, in both directions. Cross-references are created with
|
|
`tools/wikitool xref add --a "<A>" --b "<B>" --rel-a "<label>" --rel-b "<label>"`, never by
|
|
hand-editing the `related:` array or the Relationships/See Also bullets.
|
|
|
|
Use a typed relationship label rather than a generic one:
|
|
|
|
`hängt ab von` · `verwendet` · `implementiert` · `erweitert` · `ersetzt` · `steht in Konflikt mit`
|
|
· `benötigt` · `erzeugt` · `konsumiert` · `besitzt` · `pflegt` · `läuft auf` · `verwandt mit`
|
|
(last resort)
|
|
|
|
The labels are prose written into a `- **label:** [[Title]]` bullet; no code matches on them, so
|
|
an untranslated page's English label is stale wording, not a broken reference.
|
|
|
|
A page is expected to have at least one inbound link; `wikitool lint` reports orphans.
|
|
Comparison pages are exempt - they are reached through the catalog.
|
|
|
|
Renaming a page, deleting one, or dropping a single reference are tool operations with their
|
|
own procedure: see [instructions/page-lifecycle.md](../instructions/page-lifecycle.md).
|
|
|
|
## Provenance and citation
|
|
|
|
Every claim is either traceable to a raw file or explicitly marked as not.
|
|
|
|
- **`provenance:`** on every entity/concept page - `sourced` (every substantive claim traces
|
|
to a raw file), `general` (LLM general knowledge, no raw backing), or `mixed` (both; put the
|
|
unsourced part under a `## General Guidance (unsourced)` heading).
|
|
- **`raw_files:`** on every source page - concrete existing file paths under `raw/`, never a
|
|
directory and never a bare URL. For an external article also set `source_url:`, but
|
|
`raw_files:` must still point at the local copy under `raw/articles/`.
|
|
- **One source page may cover many raw files.** A folder of related documents becomes a single
|
|
page listing all of them, not one page per file.
|
|
- **A `[^cite-id]` footnote** appended to any *specific hard fact*: an IP, port, version, path,
|
|
command, or config value. `tools/wikitool cite add --page "<Title>" --source "Source - X"
|
|
[--file <qualifier>]` mints the id, upserts its `[[Source - X]]` (or
|
|
`[[Source - X|storage-model.md]]` for a multi-file source) definition in the page's trailing
|
|
`## Footnotes` block, and adds `Source - X` to `sources:` - it prints the marker to paste at
|
|
the fact; placing it is still manual. Never hand-type a cite-id (AGENTS.md invariant 1). This
|
|
differs from a plain `[[Source - X]]` link, which only means "related to".
|
|
- **Notation inside code is notation, not a reference.** A `[^cite-id]` or a `[[wikilink]]`
|
|
written in backticks or a fenced block is read as an example: the citation does not count and
|
|
the link does not exist. That is what lets a page document this stack's own syntax. It also
|
|
means a marker appended to a line *inside* a fence cites nothing - put it on a
|
|
`Quelle: [^cite-id]` line under the block, where it renders as a footnote instead of
|
|
travelling with the command when someone copies it.
|
|
- A source cited inline must also appear in the page's frontmatter `sources:` list;
|
|
`wikitool lint` checks this in both directions, and hard-errors on a leftover pre-migration
|
|
`^[[...]]` marker, an undefined `[^cite-id]` reference, or an orphaned Footnotes definition.
|
|
`tools/wikitool cite sync` reconciles a page's block after a prose edit changes which ids are
|
|
actually referenced.
|
|
- `tools/wikitool xref link-source --source "Source - X" --entities A,B,C` adds a new source
|
|
to every page it backs in one pass.
|
|
- Every raw file is expected to be claimed by some source page;
|
|
`tools/wikitool sources coverage` lists the ones that are not.
|
|
|
|
If no raw file or existing page backs an answer, say so explicitly rather than synthesizing
|
|
one - and never file the synthesized version back into the wiki.
|
|
|
|
## Confidence
|
|
|
|
`confidence_base` is the undecayed score set when a page's content is last confirmed;
|
|
`confidence` is *derived* from it by `tools/wikitool confidence decay` and must never be
|
|
edited directly.
|
|
|
|
Base score for a single source is 0.5, adjusted by:
|
|
|
|
- **+0.2 per supporting source** (max +0.6)
|
|
- **+0.2** if confirmed <30 days ago, **+0.1** if <90 days
|
|
- **+0.1** for official documentation, **+0.05** for a reputable secondary source
|
|
- **+0.1** if multiple independent sources agree
|
|
|
|
Re-assess a page with `tools/wikitool touch --page "<Title>" --confidence-base <value>`.
|
|
|
|
In prose, hedge according to the score: below 0.6 write "möglicherweise"/"kann"; below 0.4
|
|
write "unsicher"/"unbestätigt".
|
|
|
|
## What does not belong here
|
|
|
|
- Raw source material - it stays immutable under `raw/`.
|
|
- Type definitions, frontmatter contracts, or templates - those live in `types/`.
|
|
- Procedures for operating the tooling - those live in `instructions/`.
|
|
- Rules that apply to only one collection - those belong in that collection's
|
|
`COLLECTION.md`.
|
|
- Hand-edited generated files - see [Generated files](#generated-files).
|
|
- Generated lint reports - they are written to `reports/` and are not pages.
|
|
- Answers with no source behind them.
|