Data Model: Canonical Context Architecture Cleanup

Feature: 057-canonical-context-architecture-cleanup Date: 2026-03-27

Entity Overview

ProjectIdentity (1) ──────────< MissionIdentity (many)
                                      │
                                      ├──────< WorkPackage (many)
                                      │              │
                                      │              ├── OwnershipManifest (1:1)
                                      │              └── StatusEvent (many) ──▶ StatusSnapshot (derived)
                                      │
                                      ├──────< MissionContext (many, ephemeral)
                                      │
                                      └──────< MergeState (0..1, ephemeral)

Core Entities

ProjectIdentity

Singleton per repository. Assigned at spec-kitty init, never changes.

FieldTypeDescription
project_uuidstr (ULID)Immutable project identity
schema_versionintMonotonically increasing schema version
schema_capabilitieslist[str]Declared capabilities for forward-compat checks
initialized_atstr (ISO 8601)When project was initialized
last_upgraded_atstr (ISO 8601)`When last migration ran

Storage: .kittify/metadata.yaml (tracked)

spec_kitty:
  version: "3.0.0"
  schema_version: 3
  schema_capabilities:
    - canonical_context
    - event_log_authority
    - ownership_manifest
    - thin_shims
  project_uuid: "01HVXYZ..."
  initialized_at: "2026-01-01T00:00:00+00:00"
  last_upgraded_at: "2026-03-27T16:00:00+00:00"

MissionIdentity

One per feature/mission. Assigned at create-feature time. Stored in meta.json.

FieldTypeDescription
mission_idstr (ULID)Immutable mission identity
feature_numberstrDisplay number (e.g., "057")
slugstrKebab-case slug (e.g., "canonical-context-architecture-cleanup")
feature_slugstrFull slug with number (e.g., "057-canonical-context-architecture-cleanup")
friendly_namestrHuman-readable title
missionstrMission type (e.g., "software-dev", "research")
target_branchstrBranch for final merge
vcsstrVersion control system (e.g., "git")
created_atstr (ISO 8601)Creation timestamp

Storage: kitty-specs/<feature_slug>/meta.json (tracked)

{
  "mission_id": "01HVXYZ...",
  "feature_number": "057",
  "slug": "canonical-context-architecture-cleanup",
  "feature_slug": "057-canonical-context-architecture-cleanup",
  "friendly_name": "Canonical Context Architecture Cleanup",
  "mission": "software-dev",
  "target_branch": "main",
  "vcs": "git",
  "created_at": "2026-03-27T16:49:52+00:00"
}

WorkPackage

One per work package. Identity assigned at task finalization.

FieldTypeDescription
work_package_idstr (ULID)Immutable internal identity
wp_codestrDisplay alias (e.g., "WP03")
mission_idstr (ULID)Parent mission reference
titlestrHuman-readable WP title
dependencieslist[str]List of work_package_id ULIDs this WP depends on. Human-readable aliases (wp_code) may appear in tasks.md for readability but are resolved to immutable IDs at finalization.
execution_modestr"code_change" or "planning_artifact"
owned_fileslist[str]Glob patterns for files this WP owns
authoritative_surfacestrPath prefix for this WP's canonical location

Storage: kitty-specs/<feature_slug>/tasks/<wp_code>.md YAML frontmatter (tracked)

All fields are static metadata — set at task finalization, never modified by runtime. No mutable status fields exist in frontmatter.

---
work_package_id: "01HVXYZ..."
wp_code: "WP03"
mission_id: "01HVXYZ..."
title: "Implement MissionContext resolver"
dependencies: ["01HVXYZ-wp01-id...", "01HVXYZ-wp02-id..."]  # Immutable work_package_id ULIDs, not wp_code aliases
execution_mode: code_change
owned_files:
  - "src/specify_cli/context/**"
  - "tests/specify_cli/context/**"
authoritative_surface: "src/specify_cli/context/"
---

## Description
[Human-authored WP description and subtask list]

Ownership Manifest (embedded in WorkPackage)

Not a separate entity — these are the execution_mode, owned_files, and authoritative_surface fields on WorkPackage.

Validation rules:

  • No two WPs within a mission may have overlapping owned_files globs
  • authoritative_surface must be a prefix of at least one owned_files entry
  • execution_mode must be one of: code_change, planning_artifact
  • planning_artifact WPs must have owned_files that include only kitty-specs/ paths or documentation paths

MissionContext

Ephemeral bound-identity object. Created by context resolution, consumed by workflow commands.

FieldTypeDescription
tokenstrOpaque ULID-based token (e.g., "ctx-01HVXYZ...")
project_uuidstr (ULID)From ProjectIdentity
mission_idstr (ULID)From MissionIdentity
work_package_idstr (ULID)From WorkPackage
wp_codestrDisplay alias
feature_slugstrDisplay alias for mission
target_branchstrFrom MissionIdentity
authoritative_repostr (path)Absolute path to repo root
authoritative_ref`str \None`
owned_fileslist[str]From WorkPackage ownership manifest
execution_modestrFrom WorkPackage
dependency_modestr"independent" or "chained"
created_atstr (ISO 8601)When context was resolved
created_bystrAgent name that created this context

Storage: .kittify/runtime/contexts/<token>.json (gitignored, ephemeral)

{
  "token": "ctx-01HVXYZ...",
  "project_uuid": "01HVXYZ...",
  "mission_id": "01HVXYZ...",
  "work_package_id": "01HVXYZ...",
  "wp_code": "WP03",
  "feature_slug": "057-canonical-context-architecture-cleanup",
  "target_branch": "main",
  "authoritative_repo": "/Users/robert/tmp/big-refactor/spec-kitty",
  "authoritative_ref": "057-canonical-context-architecture-cleanup-WP03",
  "owned_files": ["src/specify_cli/context/**", "tests/specify_cli/context/**"],
  "execution_mode": "code_change",
  "dependency_mode": "chained",
  "created_at": "2026-03-27T17:00:00+00:00",
  "created_by": "claude"
}

StatusEvent

Immutable event in the append-only log. Existing model preserved with identity fields added.

FieldTypeDescription
event_idstr (ULID)Unique event identity
mission_idstr (ULID)Parent mission (NEW)
work_package_idstr (ULID)Internal WP identity (NEW)
wp_idstrDisplay alias (wp_code) for backward compat in log format
feature_slugstrDisplay alias
from_lanestrSource lane
to_lanestrDestination lane
atstr (ISO 8601)Event timestamp
actorstrWho caused the transition
forceboolWhether transition was forced
execution_modestrWP execution mode at time of event
evidence`DoneEvidence \null`
reason`str \null`
review_ref`str \null`

Storage: kitty-specs/<feature_slug>/status.events.jsonl (tracked, append-only)


StatusSnapshot (derived)

Materialized from event log via deterministic reduce(). Never read as authoritative input.

FieldTypeDescription
mission_idstr (ULID)Parent mission
work_packagesdict[str, WPSnapshot]Keyed by work_package_id
summarydict[str, int]Count per lane
weighted_progressfloat0.0 to 100.0
last_event_idstrMost recent event processed
event_countintTotal events processed
materialized_atstr (ISO 8601)When snapshot was generated

Storage: .kittify/derived/<feature_slug>/status.json (gitignored, regenerable)


MergeState (ephemeral)

Persisted resume state for merge operations. Scoped per mission.

FieldTypeDescription
mission_idstr (ULID)Mission being merged
feature_slugstrDisplay alias
target_branchstrBranch being merged into
wp_orderlist[str]Ordered WP IDs (work_package_id) to merge
completed_wpslist[str]WPs successfully merged
current_wp`str \null`
has_pending_conflictsboolWhether conflicts need resolution
strategystr"merge", "squash", or "rebase"
workspace_pathstrPath to merge worktree
started_atstr (ISO 8601)When merge began
updated_atstr (ISO 8601)Last state update

Storage: .kittify/runtime/merge/<mission_id>/state.json (gitignored, ephemeral)


AgentShim

Template for generated agent command files. Not a persisted entity — the generator produces files from this model.

FieldTypeDescription
command_namestrSlash command name (e.g., "spec-kitty.implement")
cli_commandstrFull CLI command (e.g., "spec-kitty agent shim implement")
agent_namestrAgent identifier (e.g., "claude", "codex")
is_consumer_facingboolWhether this skill appears in consumer installs

Storage: Generated into agent command directories (e.g., .claude/commands/spec-kitty.implement.md). Not persisted as data.


State Transitions

Lane State Machine (unchanged from current)

planned → claimed → in_progress → for_review → approved → done
                                                          ↑
                                        (force required to leave done)

blocked ← (reachable from: planned, claimed, in_progress, for_review)
canceled ← (reachable from: all non-done, non-canceled lanes)

Alias: doingin_progress (resolved at input boundaries, never persisted).

Terminal lanes: done, canceled (force required to leave).

MissionContext Lifecycle

[raw args from agent]
        │
        ▼
  resolve() ──▶ MissionContext ──▶ persist to .kittify/runtime/contexts/<token>.json
        │                                       │
        ▼                                       ▼
  return token ◀─────────────── lookup by token on subsequent commands
        │
        ▼
  [context expires when WP reaches done/canceled, or on explicit invalidation]

Merge State Machine

  IDLE ──▶ PREFLIGHT ──▶ MERGING ──▶ RECONCILING ──▶ COMPLETE
                │              │              │
                ▼              ▼              ▼
             FAILED     CONFLICT_PAUSED    FAILED
                              │
                              ▼
                          RESUMED ──▶ MERGING (continue)

Tracked vs Derived Boundary (Definitive)

Tracked (committed to git)

ArtifactLocationAuthority
Human-authored specs, plans, taskskitty-specs/<slug>/*.mdHuman
WP frontmatter (static metadata only)kitty-specs/<slug>/tasks/*.mdTask finalization
Mission identitykitty-specs/<slug>/meta.jsoncreate-feature
Canonical event logkitty-specs/<slug>/status.events.jsonlemit_status_transition()
Project identity.kittify/metadata.yamlspec-kitty init / upgrade
Agent configuration.kittify/config.yamlspec-kitty agent config
Skills manifest.kittify/skills-manifest.jsonspec-kitty upgrade
Constitution.kittify/constitution/constitution.mdspec-kitty constitution

Derived (gitignored, regenerable)

ArtifactLocationGenerated from
Status snapshot.kittify/derived/<slug>/status.jsonEvent log via reduce()
Board summary.kittify/derived/<slug>/board-summary.jsonEvent log via reduce()
Weighted progress.kittify/derived/<slug>/progress.jsonEvent log via progress.py
Dossier snapshots.kittify/derived/dossiers/Mission artifacts
Generated prompt surfaces.kittify/derived/prompt-surfaces/Shim templates
Cached manifests.kittify/derived/manifests/WP frontmatter

Runtime (gitignored, ephemeral)

ArtifactLocationPurpose
Context tokens.kittify/runtime/contexts/<token>.jsonBound identity for agent sessions
Merge workspace.kittify/runtime/merge/<mid>/workspace/Git worktree for merge operations
Merge state.kittify/runtime/merge/<mid>/state.jsonResume state for interrupted merges
Merge lock.kittify/runtime/merge/<mid>/lockPrevent concurrent merges
WP workspace contexts.kittify/runtime/workspaces/<slug>-<wp>.jsonRuntime WP workspace state
Operation locks.kittify/runtime/locks/General operation locks