Files
torben 2c4c2b1c7c
CI / verify (push) Failing after 57s
Release / release (push) Successful in 37s
stack: TOC-Pflicht fuer Referenzdateien ueber 100 Zeilen (docs toc); session-setup.md/gates.md nennen die tatsaechliche Budget-Ausnahmeliste (schliesst #73, #76)
Files changed:
- AGENTS.md
- CHANGES.md
- VERSION
- instructions/CONTRACT.md
- instructions/capture-session.md
- instructions/claude-code-model-selection.md
- instructions/dev/issue-tracking.md
- instructions/dev/testing-conventions.md
- instructions/dev/version-parts.md
- instructions/evolve-subtypes.md
- instructions/gates.md
- instructions/german-terminology.md
- instructions/ingest-large-tree.md
- instructions/kb-profiles.md
- instructions/link-taxonomy.md
- instructions/mcp-read-server.md
- instructions/migrate-corpus.md
- instructions/migrations/3.0.0-authoring-conventions.md
- instructions/migrations/4.0.0-link-taxonomy.md
- instructions/private-instance.md
- instructions/session-setup.md
- instructions/setup-instance.md
- kb/CONTRACT.md
- kb/CONVENTIONS.md
- kb/concepts/COLLECTION.md
- raw/CONTRACT.md
- tools/CONTRACT.md
- tools/chemenu/commands/docs_verify.py
- tools/chemenu/commands/instructions_cmd.py
- tools/chemenu/tests/test_docs_verify.py
- tools/chemenu/tests/test_instructions_cmd.py
- tools/chemenu/tests/test_toc.py
- tools/chemenu/toc.py
- types/type-spec.md
2026-09-09 20:38:42 +02:00

6.3 KiB

type, name, description, manual
type name description manual
types/instruction.md evolve-subtypes Extend or drain a page type's subtype vocabulary - entity_type, concept_type, or source_type - once real material has outgrown it, and the invariants that keep the resulting values honest. true

Extend a subtype vocabulary, or drain its catch-all

A subtype field (entity_type, concept_type, source_type) partitions one page type into areas via that type-spec's layout: - types/type-spec.md has the anatomy. Every one of these three enums is instance-owned content, not stack vocabulary: entity.md, concept.md and source.md all carry root: kb and ship only as .template, so an instance's own list of values is exactly as much its own decision as its collection contracts are (kb-profiles.md is the palette that seeds it). This instruction is the procedure for changing that list once it is running, not for choosing it the first time - setup-instance.md does that.

The tooling for this loop already exists end to end; this file only names the sequence and the two rules that keep it from repeating what created kb/sources/'s old notes catch-all in the first place: a schema default: that the compiler applied whenever nobody disagreed, silently turning the least specific value into the collection point for everything unclear.

Contents

When to run

  • A wikitool lint advisory finding reports pages sitting in a subtype's catch-all value (for source, that is unclassified - visible in the catalog, carrying no default) and there are now enough of them to warrant a real value.
  • A real ingest keeps producing pages that do not fit any existing value for a subtype field, and forcing them into the nearest existing one would misclassify them.
  • The catch-all itself needs draining after a value was added, so it does not become a second, quieter collection point.

Not for renaming or removing a value that pages already carry under - that moves pages and is a corpus migration (migrate-corpus.md), not this loop. Not for the one-time choice of an instance's starting vocabulary - that is setup-instance.md's KB-language step, seeded from kb-profiles.md.

Steps

  1. See what has actually collected in the catch-all, before touching anything:

    tools/wikitool lint
    tools/wikitool search --field source_type=unclassified   # or the equivalent <x>_type
    

    Read every page the search returns. A count alone does not say whether the pages share one real category or three - that judgment is the reason this step exists rather than being folded into the next one.

  2. Apply the value-and-sweep rule: a new value is added and populated in the same pass, never one without the other. A declared value that no page carries yet is a category that invites a guess the next time someone has to pick between it and the catch-all - which is exactly how the old notes default absorbed 22 of 29 source pages before anyone noticed. So:

    1. Count real candidates first: tools/wikitool search --field <x>_type=<candidate-guess> will find nothing yet, so count by reading the catch-all's pages from step 1 instead.

    2. Apply the ≥3-page admission threshold. A value is admitted after it has proven itself against real material, never in expectation of some. spec and image are the cautionary case: both were added to source_type ahead of any matching page, both sat at zero for a year, and both were eventually removed again unused. A smaller count is only ever an operator's explicit, named exception (tracker survived that same cleanup at two pages, kept because the corpus was expected to grow into it from ongoing issue ingests) - never a reason to lower the threshold itself.

    3. Add the enum value in the type-spec's schema (types/<t>.schema.yaml) and its layout: entry (types/<t>.md) in the same edit - a value with no layout: line has nowhere to be moved to.

    4. Reclassify every candidate page in the same pass:

      tools/wikitool touch --page "<Title>" --set <x>_type=<new-value>
      tools/wikitool move --reconcile
      
    5. Rebuild and check:

      tools/wikitool index rebuild
      tools/wikitool migrate verify --from HEAD --fail-on-error
      tools/wikitool lint --fail-on-error
      

      migrate verify on a subtype sweep should report moved pages and zero findings - a <x>_type change alone touches no wikilink, citation, footnote or H1.

  3. Draining the catch-all is the same loop, run without step 2.2's threshold - a page sitting in unclassified (or the equivalent) already has an intended home; the only question is which existing value it belongs to, which step 1's read-through already answered. Skip straight to reclassifying it (step 2.4) and rebuilding (step 2.5).

  4. Record it with tools/wikitool log append, describing what moved and why, the same way any other corpus change is logged.

Decision points

  • The catch-all is empty and lint reports nothing? Nothing to do - an empty catch-all is the success state, not a problem this instruction exists to fix.
  • A candidate page could plausibly fit two existing values? Resolve it by rereading the collection's COLLECTION.md for the distinguishing rule (for sources, authorship decides analysis vs. document) before inventing a third value - a genuine gap in the existing values is rarer than an under-read contract.
  • More than one subtype field needs the same treatment? Run this loop once per field; do not try to batch an entity_type change and a source_type change into one pass, since their admission thresholds are independent judgments about unrelated material.

Scope

Covers entity_type, concept_type and source_type - the three subtype fields with both subtype_field: and layout: declared. comparison has neither and is out of scope by construction. Does not cover the stack-owned capture fields fidelity/authority on source pages: those are fixed vocabulary the stack defines, not an instance's taxonomy - see types/source.md.