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
+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