Data Model: One meaning for an unclassified mission artifact (#5697)

This mission changes a classification taxonomy, so the "data model" is the authoritative path → kind → partition table (the change's real contract) and the invariants that bind it. There are no persisted schema changes.

Entities

MissionArtifactKind (enum, src/mission_runtime/artifacts.py)

Gains four new members, all PRIMARY:

New memberValueClassifies
RESEARCH_OUTPUTresearch_outputfindings.md, report.md, methodology.md, synthesis.md, literature-review.md
OCCURRENCE_MAPoccurrence_mapoccurrence_map.yaml
MISSION_GOALSmission_goalsgoals.md
RELEASE_RECORDrelease_recordrelease.md

Classifier maps (src/mission_runtime/artifacts.py)

  • _MISSION_FILE_KIND_BY_BASENAME: gains findings.md, report.md, methodology.md, synthesis.md, literature-review.md → RESEARCH_OUTPUT; gap-analysis.md, audit-report.md → ANALYSIS_REPORT; occurrence_map.yaml → OCCURRENCE_MAP; goals.md → MISSION_GOALS; release.md → RELEASE_RECORD; meta.json → PRIMARY_METADATA.
  • _COORD_RESIDUE_DIRS: gains research → RESEARCH (dir-anchored, any depth — mirrors contracts/decisions).

Partition frozensets

  • _PRIMARY_ARTIFACT_KINDS: gains the four new members. _PLACEMENT_ARTIFACT_KINDS is unchanged. Every classified file is PRIMARY (C-002).

Authoritative classification table (post-change)

Path / dir (under kitty-specs/<slug>/)KindPartitionChange
research/** (subtree)RESEARCHPRIMARYnew (dir-anchored)
findings.mdRESEARCH_OUTPUTPRIMARYnew
report.mdRESEARCH_OUTPUTPRIMARYnew
methodology.mdRESEARCH_OUTPUTPRIMARYnew
synthesis.mdRESEARCH_OUTPUTPRIMARYnew
literature-review.mdRESEARCH_OUTPUTPRIMARYnew
gap-analysis.mdANALYSIS_REPORTPRIMARYnew (reuse)
audit-report.mdANALYSIS_REPORTPRIMARYnew (reuse)
occurrence_map.yamlOCCURRENCE_MAPPRIMARYnew
goals.mdMISSION_GOALSPRIMARYnew
release.mdRELEASE_RECORDPRIMARYnew
meta.json (mission root)PRIMARY_METADATAPRIMARYnew (gap close)
lint-report.jsonNone—unchanged (excluded; .kittify/)
docs/**None—unchanged (excluded; repo root)
answers.yamlNone—unchanged (excluded; .kittify/)
mission-events.jsonlNone—unchanged (excluded; #5669)
spec.md / plan.md / data-model.md / research.md / quickstart.md / tasks.md / wps.yaml / lanes.json / contracts/ / decisions/ / tasks/ / checklists/ / analysis-report.md / retrospective.yaml(existing)PRIMARYunchanged
status.{events.jsonl,json} / issue-matrix.{md,json} / acceptance-matrix.json / decisions.events.jsonl / traces/* / tasks/<wp>/review-cycle-.md(existing)COORDunchanged

Invariants

  • P-1 (partition total + disjoint): _PRIMARY_ARTIFACT_KINDS and _PLACEMENT_ARTIFACT_KINDS are disjoint and jointly cover every MissionArtifactKind member. assert_partition_invariant must pass with the four new members (all added to PRIMARY).
  • Inverse-map honesty (FR-013): mission_file_basenames_for_kind(kind) returns exactly the basenames mapped to kind in _MISSION_FILE_KIND_BY_BASENAME — no basename is mapped to a kind that misdescribes it.
  • One meaning for None (NFR-002): kind_for_mission_file(path) is None is interpreted by exactly one authority (is_coordination_kind_file → not-coord); no consumer branches locally on None → coord.
  • Coordination carry-forward preserved (NFR-004): the projection still carries traces/*, decisions.events.jsonl, and tasks/<wp>/review-cycle-.md forward (they classify to coord kinds → is_coordination_kind_file True).

State transitions

None. Classification is a pure function of the path (and optional mission_slug).