Chemenu 2.1.0 - deterministischer Wissenskompiler
CI / verify (push) Failing after 32s
Release / release (push) Successful in 38s

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.
This commit is contained in:
2026-09-01 16:24:34 +02:00
commit 18ae28f918
368 changed files with 50628 additions and 0 deletions
+81
View File
@@ -0,0 +1,81 @@
---
type: types/type-spec.md
name: comparison
description: Strukturierter Typ für Vergleichsseiten, die mehrere Entities oder Ansätze gegenüberstellen
schema: types/comparison.schema.yaml
base_dir: comparisons
page_ref_fields: [entities]
---
# Comparison
`comparison` ist der Typ für Seiten, die mehrere Entities, Werkzeuge, Technologien oder Ansätze systematisch anhand festgelegter Kriterien gegenüberstellen. Vergleichsseiten stützen Entscheidungen und machen Zielkonflikte zwischen Alternativen sichtbar.
## Wann zu verwenden
- Vergleich mehrerer Technologien oder Frameworks für einen konkreten Einsatzzweck
- Analyse der Vor- und Nachteile verschiedener Werkzeuge oder Bibliotheken
- Bewertung alternativer Lösungswege für ein Problem
- Dokumentation eines Entscheidungsprozesses mit mehreren geprüften Optionen
## Wann NICHT zu verwenden
- Für die Dokumentation einer einzelnen Entity oder eines Concepts (dann `entity` bzw. `concept`)
- Für Zusammenfassungen von Quellmaterial (dann `source`)
- Für Seiten, die einen einzelnen Gegenstand behandeln statt mehrere zu vergleichen
## Frontmatter
| Feld | Pflicht | Verwendung |
|---|---:|---|
| `type` | Ja | `types/comparison.md` |
| `tags` | Nein | Navigations-Tags zur Kategorisierung |
| `created` | Ja | Erstellungsdatum (YYYY-MM-DD) |
| `entities` | Ja | Titel der verglichenen Entities |
| `summary` | Ja | Einzeiler für `kb/index.md` |
## Autorenanweisungen
- Ein Titel, der den Vergleich benennt (z. B. "Go vs Rust", "Kubernetes vs Docker Swarm"); er folgt den etablierten Namen der verglichenen Gegenstände, nicht der KB-Sprache (`kb/CONTRACT.md`, Abschnitte "Naming" und "Language")
- Klar darlegen, was verglichen wird und warum
- Eine Vergleichstabelle mit den Kriterien als Zeilen verwenden
- Eine Analyse, die die Tabelle auswertet statt sie zu wiederholen
- Eine Empfehlung, wo eine begründbar ist
## Template
```markdown
# Comparison: {name}
## Überblick
TODO: Kurzer Überblick, was verglichen wird und warum der Vergleich zählt.
## Vergleichstabelle
| Kriterium | {entities|table_header} |
|-----------|{entities|table_sep}|
| TODO | {entities|table_cells} |
## Analyse
TODO: Auswertung des Vergleichs. Welche Muster zeigen sich? Was sind die entscheidenden Unterschiede?
## Empfehlung
TODO: Falls möglich - was wann und für wen zu verwenden ist. Unter welchen Umständen ist welche Option die beste?
```
`# Comparison:` bleibt als Präfix stehen - anders als bei `source` ist es kein `title_prefix`,
sondern reine Template-Konvention, und der Seitentitel selbst (`Go vs Rust`) trägt es nicht.
Fügt `wikitool xref` eine Beziehung hinzu, entsteht `## Siehe auch`; der Name steht in
`tools/chemenu/sections.py`.
---
Ergänzende Hinweise:
- Vergleichsseiten stützen Technologieauswahl und Architekturentscheidungen
- Die verglichenen Entities sollten alle als Wiki-Seiten existieren
- Die Kriterien sollten zur anstehenden Entscheidung passen
- Ein Vergleich bleibt auf einen konkreten Einsatzzweck oder Entscheidungskontext fokussiert
+33
View File
@@ -0,0 +1,33 @@
# YAML Schema for comparison type
type: object
properties:
type:
type: string
const: "types/comparison.md"
description: Must reference the comparison type-spec
tags:
type: array
items:
type: string
description: Navigation tags for categorization
created:
type: string
format: date
pattern: "^\\d{4}-\\d{2}-\\d{2}$"
description: Creation date in YYYY-MM-DD format
entities:
type: array
items:
type: string
description: Entity titles being compared
minItems: 2
summary:
type: string
description: 1-line summary for index.md
minLength: 1
required:
- type
- created
- entities
- summary
additionalProperties: false
+102
View File
@@ -0,0 +1,102 @@
---
type: types/type-spec.md
name: concept
description: Basistyp für Concept-Seiten - Architekturen, Muster, Protokolle, Abläufe, Entscheidungen oder Problemstellungen
schema: types/concept.schema.yaml
subtype_field: concept_type
base_dir: concepts
page_ref_fields: [related, sources]
---
# Concept
`concept` ist der Typ für abstrakte Ideen, Methodiken, Muster und Architekturentscheidungen. Concepts liefern die theoretische und methodische Grundlage, die Entities umsetzen oder befolgen.
## Wann zu verwenden
- Dokumentation eines Architekturmusters oder Entwurfsansatzes
- Erläuterung eines Entwurfsmusters oder einer Programmiermethodik
- Beschreibung eines Kommunikationsprotokolls oder Standards
- Festhalten eines Ablaufs oder Prozesses, der über Projekte hinweg wiederkehrt
- Dokumentation einer Architekturentscheidung (ADR) oder Entwurfsentscheidung
- Analyse eines wiederkehrenden Problems und seiner Lösungen
## Wann NICHT zu verwenden
- Für konkrete Dinge wie Projekte, Systeme oder Werkzeuge (dann `entity`)
- Für Quelldokumente oder eingelesenes Material (dann `source`)
- Für vergleichende Analysen konkreter Gegenstände (dann `comparison`)
## Frontmatter
| Feld | Pflicht | Verwendung |
|---|---:|---|
| `type` | Ja | `types/concept.md` |
| `concept_type` | Ja | Eines von: architecture, pattern, protocol, workflow, decision, problem |
| `tags` | Nein | Navigations-Tags zur Kategorisierung |
| `created` | Ja | Erstellungsdatum (YYYY-MM-DD) |
| `modified` | Ja | Datum der letzten Änderung (YYYY-MM-DD) |
| `related` | Nein | Titel verwandter Concepts und Entities |
| `sources` | Nein | Titel der Source-Seiten, die die Aussagen dieser Seite stützen |
| `confidence` | Nein | Abgeleitete Konfidenz (0.0-1.0), neu berechnet von `wikitool confidence decay` |
| `confidence_base` | Nein | Unverfallene Konfidenz zum Zeitpunkt der letzten Bestätigung - bei einer Neubewertung dieses Feld ändern, nicht `confidence` |
| `provenance` | Ja | sourced, general oder mixed |
| `summary` | Ja | Einzeiler für `kb/index.md` |
## Autorenanweisungen
- Der Titel ist der kanonische Name des Concepts und folgt der etablierten Fachbezeichnung, nicht der KB-Sprache (`kb/CONTRACT.md`, Abschnitte "Naming" und "Language")
- Mit einer klaren Definition beginnen: was das Concept ist
- Beispiele geben, wo sie das Verständnis tragen
- Auf Entities verlinken, die das Concept umsetzen oder verwenden
- Bei `provenance: sourced` oder `mixed` harte Fakten inline mit einer `[^cite-id]`-Fußnote belegen -
`tools/wikitool cite add --page "<Title>" --source "Source - X"` erzeugt Id und Definition
- Wikipedia-Tonfall: sachlich, neutral, keine Werbesprache
## Template
```markdown
# {name}
**Typ:** {concept_type|capitalize}
## Definition
TODO: Klare Definition dessen, was dieses Concept ist.
## Kernpunkte
- TODO: Kernpunkt 1
- TODO: Kernpunkt 2
- TODO: Kernpunkt 3
## Beispiele
- [[Entity 1]] - kurze Beschreibung
- [[Entity 2]] - kurze Beschreibung
## Wann zu verwenden
TODO: Bedingungen und Kontexte, in denen dieses Concept greift
## Wann NICHT zu verwenden
TODO: Anti-Muster, Warnungen oder Situationen, in denen es fehl am Platz ist
## Verwandte Concepts
- [[Related Concept 1]]
- [[Related Concept 2]]
```
Der Wert hinter `**Typ:**` bleibt der englische Enum-Wert - danach filtert `search --field`.
Fügt `wikitool xref` eine Beziehung hinzu, entstehen zusätzlich `## Beziehungen` und
`## Siehe auch`; deren Namen stehen in `tools/chemenu/sections.py`.
---
Ergänzende Hinweise:
- Concept-Seiten tragen den theoretischen Unterbau des Wikis
- Jeder Concept-Typ steht für eine andere Kategorie abstrakten Wissens
- Concepts sollten von den Entities aus verlinkt sein, die sie umsetzen oder verwenden
+65
View File
@@ -0,0 +1,65 @@
# YAML Schema for concept type
type: object
properties:
type:
type: string
const: "types/concept.md"
description: Must reference the concept type-spec
concept_type:
type: string
enum: [architecture, pattern, protocol, workflow, decision, problem]
description: The specific category of concept
tags:
type: array
items:
type: string
description: Navigation tags for categorization
created:
type: string
format: date
pattern: "^\\d{4}-\\d{2}-\\d{2}$"
description: Creation date in YYYY-MM-DD format
modified:
type: string
format: date
pattern: "^\\d{4}-\\d{2}-\\d{2}$"
description: Last modification date in YYYY-MM-DD format
related:
type: array
items:
type: string
description: Related concept and entity titles
sources:
type: array
items:
type: string
description: Source page titles that support claims
confidence:
type: number
minimum: 0.0
maximum: 1.0
default: 0.5
description: Confidence score for the concept's information (derived - recomputed by `wikitool confidence decay` from confidence_base)
confidence_base:
type: number
minimum: 0.0
maximum: 1.0
default: 0.5
description: Undecayed confidence at last confirmation; the input `wikitool confidence decay` decays from. Set this, not `confidence`, when re-assessing a page.
provenance:
type: string
enum: [sourced, general, mixed]
default: general
description: Provenance classification
summary:
type: string
description: 1-line summary for index.md
minLength: 1
required:
- type
- concept_type
- created
- modified
- provenance
- summary
additionalProperties: false
+109
View File
@@ -0,0 +1,109 @@
---
type: types/type-spec.md
name: entity
description: Basistyp für Entity-Seiten - Projekte, Systeme, Werkzeuge, Technologien oder Personen
schema: types/entity.schema.yaml
subtype_field: entity_type
base_dir: entities
page_ref_fields: [related, sources]
layout:
project: {dir: projects, title: Projekte}
system: {dir: systems, title: Systeme}
tool: {dir: tools, title: Werkzeuge}
technology: {dir: technologies, title: Technologien}
person: {dir: people, title: Personen}
---
# Entity
`entity` ist der Typ für konkrete Dinge: Projekte, Systeme, Werkzeuge, Technologien oder Personen. Entities sind die primären Bausteine des Wissensgraphen.
## Wann zu verwenden
- Darstellung eines Softwareprojekts, einer Initiative oder eines Arbeitsvorhabens
- Dokumentation eines betriebenen Systems, Dienstes oder einer Infrastrukturkomponente
- Beschreibung eines CLI-Werkzeugs, Hilfsprogramms oder einer Programmbibliothek
- Festhalten von Informationen zu einer Sprache, einem Framework oder einem Protokoll
- Dokumentation einer Person, eines Teams oder einer Organisation
## Wann NICHT zu verwenden
- Für abstrakte Konzepte, Muster oder Methodiken (dann `concept`)
- Für Quelldokumente oder eingelesenes Material (dann `source`)
- Für vergleichende Analysen (dann `comparison`)
## Frontmatter
| Feld | Pflicht | Verwendung |
|---|---:|---|
| `type` | Ja | `types/entity.md` |
| `entity_type` | Ja | Eines von: project, system, tool, technology, person |
| `tags` | Nein | Navigations-Tags zur Kategorisierung |
| `created` | Ja | Erstellungsdatum (YYYY-MM-DD) |
| `modified` | Ja | Datum der letzten Änderung (YYYY-MM-DD) |
| `related` | Nein | Titel verwandter Seiten (Entities, Concepts, Sources) |
| `sources` | Nein | Titel der Source-Seiten, die die Aussagen dieser Seite stützen |
| `confidence` | Nein | Abgeleitete Konfidenz (0.0-1.0), neu berechnet von `wikitool confidence decay` |
| `confidence_base` | Nein | Unverfallene Konfidenz zum Zeitpunkt der letzten Bestätigung - bei einer Neubewertung dieses Feld ändern, nicht `confidence` |
| `provenance` | Ja | sourced, general oder mixed |
| `summary` | Ja | Einzeiler für `kb/index.md` |
## Autorenanweisungen
- Der Titel ist der kanonische Name der Entity und folgt der etablierten Bezeichnung des Gegenstands, nicht der KB-Sprache (`kb/CONTRACT.md`, Abschnitte "Naming" und "Language")
- Die Hauptbeschreibung steht weit oben
- Auf verwandte Entities und Concepts verlinken, wo Beziehungen bestehen
- Bei `provenance: sourced` oder `mixed` harte Fakten inline mit einer `[^cite-id]`-Fußnote belegen -
`tools/wikitool cite add --page "<Title>" --source "Source - X"` erzeugt Id und Definition
- Wikipedia-Tonfall: sachlich, neutral, keine Werbesprache
## Template
```markdown
# {name}
**Typ:** {entity_type|capitalize}
## Beschreibung
TODO: 1-2 Absätze dazu, was diese Entity ist und wozu sie dient.
## Kerndaten
- **Zweck:** TODO
- **Status:** aktiv, abgelöst, in Planung usw.
- **Version:** TODO (falls zutreffend)
- **Sprache/Technik:** TODO (falls zutreffend)
- **Verantwortlich:** TODO (falls zutreffend)
- **Repository:** TODO (falls zutreffend)
## Beziehungen
- **Hängt ab von:** TODO
- **Verwendet von:** TODO
- **Verwandt mit:** TODO
## Details
TODO: Ausführliche Informationen, nach sinnvollen Abschnitten gegliedert
## Historie
- [{today}] - Page created via wikitool
## Siehe auch
- TODO: Verwandte Seiten
```
`## Beziehungen` und `## Siehe auch` sind toolgeführt: `wikitool xref` schreibt in genau diese
Abschnitte, benannt in `tools/chemenu/sections.py`. Der Wert hinter `**Typ:**` bleibt der
englische Enum-Wert - danach filtert `search --field`.
---
Ergänzende Hinweise:
- Entity-Seiten bilden den konkreten Bestand der Wissensbasis
- Jeder Entity-Typ (project, system, tool usw.) ist eine Ausprägung dieses Basistyps
- Die Beziehungen zwischen Entities tragen die Vernetzung des Wissensgraphen
+65
View File
@@ -0,0 +1,65 @@
# YAML Schema for entity type
type: object
properties:
type:
type: string
const: "types/entity.md"
description: Must reference the entity type-spec
entity_type:
type: string
enum: [project, system, tool, technology, person]
description: The specific category of entity
tags:
type: array
items:
type: string
description: Navigation tags for categorization
created:
type: string
format: date
pattern: "^\\d{4}-\\d{2}-\\d{2}$"
description: Creation date in YYYY-MM-DD format
modified:
type: string
format: date
pattern: "^\\d{4}-\\d{2}-\\d{2}$"
description: Last modification date in YYYY-MM-DD format
related:
type: array
items:
type: string
description: Related page titles
sources:
type: array
items:
type: string
description: Source page titles that support claims
confidence:
type: number
minimum: 0.0
maximum: 1.0
default: 0.5
description: Confidence score for the entity's information (derived - recomputed by `wikitool confidence decay` from confidence_base)
confidence_base:
type: number
minimum: 0.0
maximum: 1.0
default: 0.5
description: Undecayed confidence at last confirmation; the input `wikitool confidence decay` decays from. Set this, not `confidence`, when re-assessing a page.
provenance:
type: string
enum: [sourced, general, mixed]
default: general
description: Provenance classification
summary:
type: string
description: 1-line summary for index.md
minLength: 1
required:
- type
- entity_type
- created
- modified
- provenance
- summary
additionalProperties: false
+95
View File
@@ -0,0 +1,95 @@
---
type: types/type-spec.md
name: instruction
description: Agent-directed procedure held as a flat file under instructions/, loaded by link or on explicit request rather than published as a skill
schema: types/instruction.schema.yaml
root: repo
base_dir: instructions
---
# Instruction
Use `instruction` for a procedure an agent follows: how to operate the tooling, how to recover
from a refused call, how to close out a change. An instruction is *prescriptive* - it tells the
reader what to do, not what is true.
Instances are flat files under `instructions/`. That placement is what keeps them unpublished:
a subdirectory containing a `SKILL.md` is copied into the harness skill directories, while a
flat file is reached only through a link or an explicit request. See
[instructions/CONTRACT.md](../instructions/CONTRACT.md).
## When to Use
- A procedure is repeated across several skills or contracts and should exist once
- An operation is rare enough that a permanently-loaded skill would not earn its context cost
- A refusal, gate, or failure mode needs a documented recovery path
## When NOT to Use
- The procedure is a whole task an agent should be able to invoke by name - write a skill
(`instructions/<name>/SKILL.md`), whose frontmatter belongs to the harness, not to this type
- The content is a fact about a system rather than an action - that is an `entity` or `concept`
page under `kb/`
- The content explains *why* a rule exists - that is a `concept` page, linked from the
instruction
## Frontmatter
| Field | Required | Use |
|---|---:|---|
| `type` | Yes | `types/instruction.md` |
| `name` | Yes | Short identifier, matching the filename stem |
| `description` | Yes | The retrieval wire: the question an agent would ask when it needs this procedure. Not a label for the file |
There is deliberately no `summary`, no `confidence` and no `sources`. An instruction is not a
knowledge claim: it is either correct and in use, or it is wrong and gets fixed. Scoring its
confidence would suggest a middle state that does not exist.
## Authoring Instructions
- Title imperatively - it answers "what does this tell me to do?"
- Frontload: self-contained for an agent with no prior context. Define terms inline.
- Make decision points explicit ("if X, do A; otherwise do B") rather than implied.
- State scope boundaries: when this does *not* apply, and what to do instead.
- Keep reasoning minimal - only enough to decide edge cases. The rest is a concept page.
- Show the exact command. A step an agent has to reconstruct is a step it can get wrong.
## Template
```markdown
# {name}
{One paragraph: what situation this applies to, and what it achieves.}
## When to run
- TODO: the trigger conditions
## Steps
1. **TODO** - what to do:
```bash
TODO: the exact command
```
2. **TODO** - the next step, with its decision points stated.
## Decision points
- **TODO: condition?** TODO: what to do instead.
## Scope
TODO: when this does not apply, and what to use instead.
```
---
Relevant Notes:
- This type declares `root: repo`, so `base_dir: instructions` resolves against the repository
root rather than `kb/`. Instructions are agent-directed material, not compiled knowledge, and
the `raw/` -> `kb/` provenance rules do not apply to them.
- It declares no `page_ref_fields:`: an instruction links with ordinary markdown paths, not
wikilinks, because its targets are contracts and other instructions rather than pages.
+50
View File
@@ -0,0 +1,50 @@
# YAML Schema for instruction type
type: object
properties:
type:
type: string
const: "types/instruction.md"
description: Must reference the instruction type-spec
name:
type: string
minLength: 1
description: Short identifier, matching the filename stem
description:
type: string
minLength: 1
description: >-
The retrieval wire - the question an agent would ask when it needs this
procedure, written to match that query rather than to label the file
manual:
type: boolean
description: >-
True for a rare, deliberate procedure that must never run implicitly.
Exempts it from `instructions verify`'s reference requirement - and,
symmetrically, `verify` then requires it NOT be linked from AGENTS.md
or a skill (the paths an agent loads automatically), since a link
there is exactly how it would stop being deliberate. A mention in a
CONTRACT.md, a COLLECTION.md, or another instruction's prose is fine -
that is documentation a reader opts into, not automatic pickup.
Invoked only by explicit name on request.
migrates_to:
type: string
pattern: "^[0-9]+\\.[0-9]+\\.[0-9]+$"
description: >-
Present on a migration document under `instructions/migrations/`: the
stack version whose content shape this migration produces. `wikitool
migrate status` builds the outstanding chain from these, so the value is
the migration's identity as much as its label. Plain `x.y.z` - no
pre-release suffixes anywhere in this stack.
migration_kind:
type: string
enum: [mechanical, assisted]
description: >-
How the migration is carried out. `mechanical` is deterministic and
scriptable; `assisted` needs a judgment call per page and is therefore an
agent procedure. Today this is a description rather than an execution
promise - there is no `migrate run`.
required:
- type
- name
- description
additionalProperties: false
+68
View File
@@ -0,0 +1,68 @@
---
type: types/type-spec.md
name: lint-report
description: Generated structural health report for the wiki, produced by wikitool lint --markdown
schema: types/lint-report.schema.yaml
---
# Lint Report
A snapshot of the wiki's mechanically-verifiable health at one point in time,
written by `tools/wikitool lint --markdown "reports/Lint Report <date>.md"`.
This type-spec declares no `base_dir:`, so it is **contract only**: it describes
a file format without owning a place under `kb/`, and `wikitool new lint-report`
refuses to scaffold one. A lint report is not a wiki page. It is derived output,
written to `reports/` and gitignored there, because its structural sections are
recomputable from the tree at any commit - committing them would create a second
copy that drifts from what `wikitool lint` answers on demand.
## When to Use
- Recording a full lint pass, per the maintenance schedule in
[tools/CONTRACT.md](../tools/CONTRACT.md) (every 10 sources, or on request)
## When NOT to Use
- Never author one by hand. The structural sections are generated; writing them
manually produces numbers nothing verified.
- Not for a quick status check - `wiki-status` reads `lint` with no flags and
writes nothing.
## Conventions
- Filename: `reports/Lint Report <YYYY-MM-DD>.md`, matching the date in `created:`.
- A report is a dated snapshot, not a living page. Supersede it with a new one
rather than editing an old one; old reports are local scratch and can simply be
deleted.
- The `## Semantic Review` section is the LLM's half, and it is the only part
that cannot be regenerated. Because the file itself is never committed, that
judgment has to leave `reports/` before the pass ends: findings that change a
page go into the page, and the summary of the pass goes into `kb/log.md` via
`tools/wikitool log append --op lint`. Leaving its TODOs unfilled means the
pass is unfinished; leaving them only in `reports/` means the pass is lost.
## Template
```markdown
# Structural Lint Report ({today})
TODO: generated by `wikitool lint --markdown` - do not author this file by hand.
## Semantic Review (LLM to complete)
- Contradictions across pages: TODO
- Stale claims (unconfirmed >6 months): TODO
- Suggested new pages / missing cross-references: TODO
```
---
Relevant Notes:
- The structural sections come from `wikitool lint`'s hard oracles; the semantic
section is judgment and cannot be generated.
- This type declares no `page_ref_fields:`: a report references pages in prose
only, never through frontmatter.
- It also declares no `base_dir:`, which is what keeps `reports/` out of `kb/`
and out of the index.
+21
View File
@@ -0,0 +1,21 @@
# YAML Schema for lint-report type
type: object
properties:
type:
type: string
const: "types/lint-report.md"
description: Must reference the lint-report type-spec
created:
type: string
format: date
pattern: "^\\d{4}-\\d{2}-\\d{2}$"
description: Date the report was generated, in YYYY-MM-DD format
summary:
type: string
description: 1-line summary for index.md
minLength: 1
required:
- type
- created
- summary
additionalProperties: false
+124
View File
@@ -0,0 +1,124 @@
---
type: types/type-spec.md
name: source
description: Strukturierter Typ für Source-Seiten, die eingelesenes Rohmaterial erfassen und zusammenfassen
schema: types/source.schema.yaml
subtype_field: source_type
base_dir: sources
title_prefix: "Source - "
page_ref_fields: [entities, concepts]
---
# Source
`source` ist der Typ für Seiten, die eingelesenes Rohmaterial zusammenfassen und katalogisieren. Source-Seiten sind die Brücke zwischen der `raw/`-Schicht (unveränderliche Quelldateien) und der `kb/`-Schicht (kompiliertes Wissen). Eine Source-Seite steht für **eine logische Quelle**, die mehrere Raw-Dateien umfassen kann.
## Wann zu verwenden
- Zusammenfassung eines einzelnen externen Artikels, Dokuments oder einer Spezifikation
- Erfassung mehrerer zusammengehöriger Notizen oder Gesprächsprotokolle als eine Quelle
- Dokumentation eines eingelesenen PDFs, Handbuchs oder sonstigen Dokuments
- Festhalten von Informationen zu einem Bild oder Diagramm
## Wann NICHT zu verwenden
- Für kompiliertes Wissen (dann `entity` oder `concept`)
- Für vergleichende Analysen (dann `comparison`)
- Für originären Wiki-Inhalt, der nicht aus Rohmaterial abgeleitet ist
## Frontmatter
| Feld | Pflicht | Verwendung |
|---|---:|---|
| `type` | Ja | `types/source.md` |
| `source_type` | Ja | Eines von: article, document, notes, spec, image |
| `author` | Ja | Urheber des Quellmaterials |
| `raw_files` | Ja | Raw-Dateipfade, die diese Quelle **besitzt** - siehe "Eine Raw-Datei, ein Besitzer" unten |
| `source_url` | Nein | Ursprungs-URL bei externen Quellen |
| `source_language` | Nein | ISO-639-1-Code der Sprache des Rohmaterials, z. B. `de`, `en`, `fr` |
| `date` | Ja | Veröffentlichungs- oder Erstellungsdatum (YYYY-MM-DD) |
| `tags` | Nein | Navigations-Tags zur Kategorisierung |
| `entities` | Nein | Titel der in dieser Quelle erwähnten Entities |
| `concepts` | Nein | Titel der in dieser Quelle erwähnten Concepts |
| `summary` | Ja | Einzeiler für `kb/index.md` |
## Autorenanweisungen
- Der Titel beginnt mit "Source - ", gefolgt vom Namen der Quelle
- `raw_files` listet jede Raw-Datei, die diese Quelle abdeckt (eine Source-Seite pro logischer Quelle, nicht pro Datei)
- Bei externen Artikeln immer `source_url` auf die Ursprungs-URL setzen
- `source_language` auf die Sprache des Rohmaterials setzen, nicht auf die der Seite
- Die Seite wird in der KB-Sprache geschrieben, unabhängig von der Sprache der Quelle; wörtliche Passagen werden im Original zitiert (`kb/CONTRACT.md`, Abschnitt "Language")
- Kernaussagen im Abschnitt Summary zusammenfassen
- Handlungsbedarf in den Abschnitt Action Items
- Bewusst Weggelassenes in den Abschnitt Not Extracted - siehe unten
- Erwähnte Entities und Concepts unter Related Entities/Concepts verlinken
## Not Extracted
Die Entscheidung, dass Material *nicht* übernommen werden soll, ist nicht rekonstruierbar: nichts
im Repository kann sie neu herleiten, und `sources coverage` weiß nur, ob eine Raw-Datei von
irgendeiner Source-Seite beansprucht wird - nie, ob jemand über ihren Inhalt entschieden hat.
Bleibt das unaufgeschrieben, wird dieselbe Quelle bei jedem späteren Durchgang neu verhandelt.
- Jede bewusste Auslassung mit **Begründung** festhalten, nicht nur mit Dateinamen.
- Pflicht, wenn der Ingest als Tree-Ingest lief (siehe `instructions/ingest-large-tree.md`).
Optional bei einer einzelnen kleinen Datei - aber ein leerer Abschnitt ist immer noch besser
als ein fehlender.
- Gehört auf die Source-Seite, nicht in `kb/log.md`: es ist eine Aussage über *diese* Quelle,
und das Log ist chronologisch, nicht quellenbezogen.
## Template
```markdown
# Source: {name}
**Autor:** {author}
**Datum:** {date}
**Raw-Dateien:** {raw_files|join}
**Typ:** {source_type|capitalize}
## Zusammenfassung
TODO: 2-3 Absätze zu den Kernaussagen des Quellmaterials.
## Kernaussagen
- TODO: Kernaussage 1
- TODO: Kernaussage 2
- TODO: Kernaussage 3
## Aufgaben
- [ ] TODO: Aufgabe 1
- [ ] TODO: Aufgabe 2
## Nicht übernommen
- TODO: Was bewusst nicht übernommen wurde, und warum (oder "nichts - die Quelle wurde vollständig erfasst")
## Verwandte Entities
{entities|bullets}
## Verwandte Concepts
{concepts|bullets}
```
`# Source:` bleibt als Präfix stehen - es spiegelt den `title_prefix` und damit den Titel, unter
dem die Seite verlinkt und zitiert wird. Der Wert hinter `**Typ:**` bleibt der englische
Enum-Wert. Fügt `wikitool cite` ein Zitat hinzu, entsteht am Seitenende `## Fußnoten`; der Name
steht in `tools/chemenu/sections.py`.
---
Ergänzende Hinweise:
- Source-Seiten sind der maßgebliche Katalog dessen, was an Rohmaterial eingelesen wurde
- **Eine Raw-Datei, ein Besitzer.** Eine Raw-Datei steht in genau einem `raw_files:` - diese Seite ist dafür verantwortlich, sie zusammengefasst zu halten. Beliebig viele Seiten dürfen sie per `[^cite-id]` **zitieren**; ein Zitat ist Wiederverwendung, `raw_files:` ist eine Wartungszuständigkeit. Bei zwei Anspruchstellern ist undefiniert, welche Seite bei einer Änderung der Raw-Datei nachgezogen werden muss - dann verrotten beide still
- Source-Seiten machen Wissen bis zum ursprünglichen Rohmaterial rückverfolgbar
- `raw_files:` enthält konkrete existierende Dateipfade, nie Verzeichnisse
- Eine `raw_files:`-Liste jenseits von etwa 15 Einträgen zeigt an, dass der Schnitt zu grob war -
die Quelle hätte per `instructions/ingest-large-tree.md` in mehrere Source-Seiten geteilt
werden müssen
+65
View File
@@ -0,0 +1,65 @@
# YAML Schema for source type
type: object
properties:
type:
type: string
const: "types/source.md"
description: Must reference the source type-spec
source_type:
type: string
enum: [article, document, notes, spec, image]
default: notes
description: The category of source material
author:
type: string
description: Author of the source material
minLength: 1
raw_files:
type: array
items:
type: string
description: List of raw file paths this source covers
minItems: 1
source_url:
type: [string, "null"]
description: Upstream URL for external sources
format: uri
source_language:
type: string
pattern: "^[a-z]{2}$"
description: >-
ISO 639-1 code for the language of the raw material, e.g. de, en, fr.
The page itself is written in the KB language regardless; this records
what had to be translated. Optional - absent on pages predating the rule.
date:
type: string
format: date
pattern: "^\\d{4}-\\d{2}-\\d{2}$"
description: Publication or creation date in YYYY-MM-DD format
tags:
type: array
items:
type: string
description: Navigation tags for categorization
entities:
type: array
items:
type: string
description: Entity titles mentioned in this source
concepts:
type: array
items:
type: string
description: Concept titles mentioned in this source
summary:
type: string
description: 1-line summary for index.md
minLength: 1
required:
- type
- source_type
- author
- raw_files
- date
- summary
additionalProperties: false
+157
View File
@@ -0,0 +1,157 @@
---
type: types/type-spec.md
name: type-spec
description: Authoring and validation contract for path-valued Chemenu type specifications
schema: types/type-spec.schema.yaml
---
# Type spec
A type-spec doc is the authoring and validation contract for one Chemenu artifact type. Artifact frontmatter stores the repo-relative path to this doc in `type:`, and this file serves several consumers differently: an author writing a new instance reads it for what to write, someone unfamiliar with the type reads it for what to expect from an instance before opening one, and the validator and the type-conformance reviewer read it to check conformance.
## Required Frontmatter
- `type`: `types/type-spec.md`. The root type spec is self-referential and uses the same value.
- `name`: short human-facing type name. This is also the type's logical "kind" - tooling resolves an instance's `type:` path to this `name` instead of hardcoding a type-path-to-kind mapping.
- `description`: retrieval description for the type contract.
- `schema`: repo-relative path to the `.schema.yaml` file that validates artifacts of this type, or `null` when the type has no schema.
- `subtype_field` (optional): the frontmatter field name on instances of this type that carries a subtype/category (e.g. `entity_type`), or omitted if this type has no such field.
## Validation Contract
Two systems check conformance to a type:
- **The deterministic validator** checks the symbolic half: frontmatter fields, enums, path patterns, and syntactic body shape (required headings, section counts, date formats) — whatever the named `.schema.yaml` can statically specify. It parses structure; it never judges meaning.
- **The type-conformance review gate** checks the semantic half: everything about an instance that is not mechanically checkable — a `description`'s routing quality, a title's claim-shape, whether the body's claims hold up — judged against this file's body, read as natural-language authoring instructions applied by an LLM reviewer.
Do not restate a schema rule in body text. The validator already enforces it, so the restatement adds no protection — it only spends the reviewer's judgment re-confirming something already guaranteed, instead of on the properties only a reviewer can check.
## Writing Shape
- Write the body as a **content contract**: checkable properties of a conforming instance, in a form the type-conformance gate can apply directly. Prefer "what a conforming instance contains or claims" over "how to produce one" — production process is invisible to the reviewer, so it belongs in a skill or instruction, linked rather than embedded.
- State what the type is for and when an author should choose it over a neighboring type.
- Document the frontmatter fields (required and optional) as a reference for authors; the schema is the sole source of truth for requiredness.
- When `schema` is non-null and implies body structure beyond `type`/`name`/`description`, include a `## Template` an authoring agent can copy.
## The type layer
`types/` is the repo's **global type surface**: one set of type-specs serving every collection
under `kb/`. It is deliberately **not a collection** and carries no `COLLECTION.md` — there is
no per-collection type surface, and `tools/wikitool docs verify` fails if a contract appears
here.
**Quality goal:** a type-spec is the single source of truth for its type. No structural fact
about a page type may be restated anywhere else — not in `AGENTS.md`, not in a skill, not in
Python. Adding a type must require no code change.
### Anatomy of a type
Each type is two files:
| File | Owns |
|------|------|
| `types/<name>.md` | The authoring contract: when to use the type, when not to, guidance, and the `## Template` block used to scaffold new pages |
| `types/<name>.schema.yaml` | The machine-checkable half: fields, types, enums, defaults, required-ness, `additionalProperties: false` |
This file is the self-referential root contract that both are validated against.
### Placement frontmatter
Beyond the required fields above, a type-spec declares where its instances are written.
**Never choose a directory by hand** - `root` plus `base_dir` plus `layout` decide placement,
and `tools/wikitool new` writes the file.
| Field | Required | Use |
|-------|----------|-----|
| `base_dir` | Yes for instantiable types | Directory where instances are written, e.g. `entities`. Relative to the root named by `root:` |
| `root` | No | Which root `base_dir` resolves against: `kb` (default, `config.KB_DIR`) or `repo` (`config.ROOT`) |
| `layout` | No | Maps each subtype to its `dir` and index `title` |
| `title_prefix` | No | Prepended to the page title, e.g. `Source - ` |
| `page_ref_fields` | No | Fields whose entries are page titles, e.g. `[related, sources]`. `lint` checks they resolve; `rename`/`rm` rewrite them |
`root: kb` is the default because it is what every knowledge type wants, and because keeping
placement kb-relative is what lets a test point `config.KB_DIR` at a fixture and be certain
nothing can write into the real `kb/`. `root: repo` is opt-in, for types whose artifacts are
legitimately not knowledge: `instruction` is the worked example - an agent-directed procedure
under `instructions/`, outside the `raw/` -> `kb/` provenance rules entirely.
A type-spec **without `base_dir` is a contract only** and cannot be instantiated;
`wikitool new <name>` refuses it. `lint-report` is the worked example: its artifacts are
generated into `reports/`, so it describes a file format without owning a place anything writes
to.
### Adding a type
1. Write `types/<name>.md` with the frontmatter above and a `## Template` fenced block.
2. Write `types/<name>.schema.yaml` declaring every field, with `additionalProperties: false`.
3. Confirm it is discovered: `tools/wikitool types list`, then
`tools/wikitool types describe <name>`.
4. Scaffold with `tools/wikitool new <name> --name "..." --set field=value`.
No Python change is needed at any step; `wikitool` discovers types by scanning this directory.
### Template variables
The `## Template` block is filled from the page's own frontmatter, plus `{name}` and
`{today}`. Filters render structured fields: `{entities|bullets}`, `{tags|join}`,
`{entity_type|capitalize}`, `{entities|table_header}`, `{entities|table_sep}`,
`{entities|table_cells}`. `{field|literal text}` falls back to the literal when the field is
absent.
### Ownership boundary
| Owned here | Owned by `kb/CONTRACT.md` and the collection contracts |
|------------|-----------------------------------------------------------|
| Frontmatter fields, enums, defaults, required-ness | Quality goal and tone |
| Directory placement and title prefix | Naming conventions |
| Body skeleton (template) | Linking policy and relationship vocabulary |
| When to use / not use this type | Provenance and confidence practice |
If a rule would be identical for every type, it belongs in `kb/CONTRACT.md`, not in a
type-spec. If it is identical for every page in one collection, it belongs in that
collection's `COLLECTION.md`.
### What does not belong here
- Page instances. Nothing under `types/` is content.
- A `COLLECTION.md`. `types/` is a framework surface, not a collection.
- Anything already enforced by a `.schema.yaml` restated in prose as if it were separately
authoritative.
## Template
````markdown
---
type: types/type-spec.md
name: {type-name}
description: "{Retrieval description for this type contract}"
schema: {types/{type-name}.schema.yaml or null}
---
# {Type name}
{What this type is for, and when to choose it over a neighboring type.}
## Frontmatter
| Field | Required | Use |
|---|---:|---|
| `type` | Yes | `{this type spec's own repo path}` |
| `name` | Yes | {short human-facing type name} |
| `description` | Yes | {retrieval description for instances of this type} |
| `schema` | Yes | {repo-relative path to schema.yaml or null} |
## Template
```markdown
{a copyable frontmatter + body skeleton matching the schema}
```
````
---
Relevant Notes:
- This is the root type-spec that all other type-specs reference
- Type-specs form the structural backbone of the wiki's type system
- All validation flows through type-spec definitions
+77
View File
@@ -0,0 +1,77 @@
# YAML Schema for type-spec documents
type: object
properties:
type:
type: string
description: Path to parent type-spec or self-reference
pattern: "^types/.*\\.md$"
name:
type: string
description: Short human-facing type name
minLength: 1
pattern: "^[a-z][a-z0-9-]*$"
description:
type: string
description: Retrieval description for this type contract
minLength: 10
schema:
type: [string, "null"]
description: Path to schema file or null
pattern: "^types/.*\\.schema\\.yaml$|^null$"
subtype_field:
type: [string, "null"]
description: Name of the frontmatter field on instances of this type that carries its subtype/category (e.g. entity_type), or null/omitted if this type has no subtype field
pattern: "^[a-z][a-z0-9_]*$"
layout:
type: object
description: >-
Optional map of subtype value -> {dir, title}, declaring where instances
of each subtype are written under wiki/ and what section title/order to
use in wiki/index.md. Only types with subtype-driven directory
placement (e.g. entity) need this; omit for types with a single flat
directory.
additionalProperties:
type: object
properties:
dir:
type: string
minLength: 1
title:
type: string
minLength: 1
required:
- dir
- title
additionalProperties: false
base_dir:
type: string
description: >-
Directory, relative to the wiki root (wiki/), where instances of this
type are written - e.g. `entities`. Required on every instantiable
type; omit only for types that are never instantiated as pages (e.g.
type-spec itself). Combined with `layout:` for subtype-driven
placement, giving wiki/<base_dir>/<layout[subtype].dir>/<Title>.md.
pattern: "^[a-z][a-z0-9/_-]*$"
title_prefix:
type: string
description: >-
Optional prefix prepended to a page's title/filename at scaffold time
(e.g. `Source - ` for source pages). Defaults to no prefix.
minLength: 1
page_ref_fields:
type: array
description: >-
Frontmatter fields on instances of this type whose entries are wiki page
titles (e.g. `related`, `sources`, `entities`). `wikitool lint` checks
every entry resolves to an existing page, and `wikitool rename`/`rm`
rewrite them. Declared here rather than hardcoded in Python so a new
type needs no code change. Omit for types with no page-reference fields.
items:
type: string
pattern: "^[a-z][a-z0-9_]*$"
required:
- type
- name
- description
- schema
additionalProperties: false