Contracts

pack-schema.md

Contract: Glossary Pack file schema + doctrine integration

> Naming (squad M4/M5): package/dir/accessor/plural = glossary_packs; built-in dir uses the > canonical built-in/ (hyphen). Enum value + URN prefix = singular glossary_pack.

1. Pack file format — *.glossary-pack.yaml

Built-in location: src/doctrine/glossary_packs/built-in/<id>.glossary-pack.yaml.

# round-trip: skip: illustrative glossary-pack schema example, not a round-trippable contract fixture
# spec-kitty-core.glossary-pack.yaml
id: spec-kitty-core
provenance: built-in
description: Canonical Spec Kitty terminology (migrated from spec_kitty_core.yaml).
terms:
  - surface: work package
    definition: A unit of implementable work within a mission, tracked as WP##.
    confidence: 0.95            # FLOAT (seed uses 0.6/0.75/0.9/0.95/1.0), never a string
    status: active
    see_also: null              # carried from seed (present on ≥1 term)
    introduced_in_mission: null # carried from seed (present on ≥2 terms)
    synonyms_to_avoid: null     # carried from seed (populated on 3 terms)
    aliases: null               # present, unwired in Mission A (Mission B populates)
    banned_synonyms: null       # present, unwired in Mission A
  # ... 103 more terms

Rules

introduced_in_mission, synonyms_to_avoid, aliases, banned_synonyms optional, default None.

finds — no seed field may be dropped (standing parity test, NFR-002).

  • id, provenance, terms required; terms non-empty.
  • Each term: surface, definition, confidence (float), status required; see_also,
  • surface values unique within a pack (duplicate → load error).
  • The migration reads .kittify/glossaries/spec_kitty_core.yaml and carries every field it
  • Loading is deterministic; no network, no code execution (contrast Mission D's executable ASSET).

2. DRG node + resolution contract

prefix == kind.value assertion (NFR-001).

(drg/migration/extractor.py) — NOT by _KIND_MAP (which is for edge targets only).

src/doctrine/glossary_pack.graph.yaml (alongside the other 10) because load_built_in_graph globs *.graph.yaml there non-recursively. A fragment nested under the package is invisible (the NFR-003 trap). The fragment is regenerated by the extractor and committed, not hand-authored.

  • Node kind: NodeKind.GLOSSARY_PACK.
  • URN: glossary_pack:<id>underscore. The hyphenated form is rejected by the URN regex +
  • The pack's own nodes are emitted by a new per-kind block in extract_artifact_edges
  • The generated DRG fragment ships at the doctrine package root as

3. Doctrine-service integration contract

a BaseDoctrineRepository), resolving _built_in_dir("glossary_packs").

"glossary_packs") in _ALLOWED_KINDS, _BUILTIN_ARTIFACT_KINDS, and the org-pack alias map; it is NOT in _NON_AUGMENTATION_ELIGIBLE_KINDS.

  • DoctrineService.glossary_packs returns the loaded GlossaryPack[*] (via GlossaryPackRepository,
  • ArtifactKind.GLOSSARY_PACK is charter-activatable and appears (as the plural string
  • Operator token glossary-pack → canonical glossary_pack via from_operator_token (enum-derived).

4. Activation contract

three-state None default + _BUILTIN_ARTIFACT_KINDS membership + the root graph fragment. No manual charter activate, no config.yaml entry, no suggests/requires edge.

plus a positive default-on assertion.

  • Charter activation records activated packs in PackContext.activated_glossary_packs.
  • The built-in spec-kitty-core pack is activated by default via the named mechanism:
  • charter activate/deactivate glossary-pack <id> [--cascade …] operate through generic DRG edges.
  • The lockstep drift-guard is extended to a three-way equality (incl. _BUILTIN_ARTIFACT_KINDS)

5. Doctor contract

_doctrine_health.py, which is profile-centric today).

synthetic invalid-pack fixture.

  • spec-kitty doctor doctrine --json includes glossary-pack counts and health (new code in
  • A pack with an invalid member is reported unhealthy (never silently healthy) — proven with a

6. Non-goals for Mission A (explicit)

import-boundary test forbids any src/glossary import from src/doctrine/glossary_packs/ (C-002).

(Mission C / B). The seed spec_kitty_core.yaml is read for migration/parity but not modified.

  • NO enforcement: the enforcement fields are inert (Mission B wires them).
  • NO seeding into runtime src/glossary/ (the #1418 pack_seed_loader.py ACL is dropped); an
  • NO retirement of the runtime glossary or repoint of test_glossary_canonical_terms.py