# Spec Kitty integration
This repository is a Spec Kitty (governed, spec-driven development) project.
Spec Kitty provides the mission runtime, governance/charter machinery, agent
skills, and the git merge drivers that make AI-agent missions reproducible —
and this project dogfoods it twice: tix builds itself through Spec Kitty
missions, and tix itself tracks the resulting Spec Kitty tasks on its own
board. This document explains how the two systems connect and how the pieces
fit together.
## Quick facts
| Spec Kitty CLI | `spec-kitty` (mise-shim at `~/.local/share/mise/shims/spec-kitty`) |
| Runtime version | 3.2.7 (`spec-kitty --version` → `spec-kitty-cli version 3.2.7`) |
| Python runtime | 3.12.3, Linux (`spec_kitty.environment` in `.kittify/metadata.yaml`) |
| Project slug / UUID | `tix` / `0a387a4b-a4b1-4a37-a726-b22690724a6f` |
| Initialized | 2026-09-11 (schema v3; last upgraded 2026-09-13) |
| Enabled mission types | `software-dev`, `documentation`, `research`, `plan` |
| Coding agent | `opencode` (`agents.available` in `.kittify/config.yaml`) |
| Missions | 4 completed in `kitty-specs/` (all `software-dev`, all accepted) |
| Installed agent skills | 55 under `.agents/skills/` (gitignored) |
| Host state | dashboard daemon on `127.0.0.1:9237`; hosted-sync queue non-empty |
| Health | "healthy" (per AGENTS.md orientation block) |
---
## 1. Repository layout
| `.kittify/` | Spec Kitty project home: config, charter, doctrine, event log, runtime/derived state | Only `config.yaml`, `metadata.yaml`, `canonical-events.jsonl`, `charter/charter.yaml`, `charter/synthesis-manifest.yaml`, `doctrine/PROVENANCE.md`; everything else is gitignored |
| `kitty-specs/` | One committed **mission folder per mission** — the audit-grade record | Yes (most artifacts; JSON/events handled by merge drivers) |
| `kitty-ops/` | Dispatched **Op** (invocation) records, one JSONL per invocation | Yes (14 files committed pre-ignore; `kitty-ops/` is gitignored) |
| `.agents/skills/` | Skills installed for the `opencode` agent by Spec Kitty | No (`/agents/skills/` gitignored; tracked via `.kittify/skills-manifest.json`) |
| `.worktrees/` | Mission worktrees | No |
---
## 2. The `spec-kitty` CLI
The runtime is a `mise`-managed binary; run `spec-kitty --help` for the full
surface. The command families actually used in this repo are:
- **Mission lifecycle** — `specify` (scaffold a mission in `kitty-specs/`),
`plan`, `tasks`, `implement`, `next` (advance the mission state machine),
`accept`, `merge`, `review`, `retrospect`, `reconcile`, `materialize`.
- **Governance / charter** — `charter`, `config`, `doctrine` (via skills),
`glossary`, `issue-matrix`.
- **Agent + invocation loop** — `dispatch` (open a governed Op for an ad-hoc
request), `agent`, `invocations`, `profile-invocation`, `profiles`,
`session-start`/`session-stop`.
- **Git integration** — `merge-driver-*` (see §5), `safe-commit`, `spec-commit`,
`ops`, `cutover-guard`.
- **Health / setup** — `doctor`, `verify-setup`, `migrate`, `upgrade`,
`regen`, `validate-encoding`, `lint`.
- **External surface** — `dashboard`, `orchestrator-api`, `sync`, `auth`,
`workflow`, `mission-type`.
The project stores its own wiring in three places:
`.kittify/config.yaml`+`metadata.yaml`, the `charter`, and the skills-manifest.
---
## 3. Governance state in `.kittify/`
- **`config.yaml`** — project identity (uuid, slug, build id), activated
mission types, VCS (`git`), the coding agent (`opencode`),
`auto_commit: true` (the runtime commits its own state transitions), the
activated directives/tactics, and the charter path.
- **`metadata.yaml`** — auto-generated identity; **do not edit**. Tracks
`spec_kitty.version`, `initialized_at` / `last_upgraded_at`,
`schema_version` (3), and the runtime environment (`migrations`).
- **`canonical-events.jsonl`** — append-only aggregate event log
(`ProjectInitialized`, …). This is the source of truth the runtime
replays/materializes derived state from (`spec-kitty materialize`).
- **`charter/charter.yaml`** — the governance charter: directives/tactics
catalog, per-mission-type activations, overrides. Edited via the charter
workflow, never by hand.
- **`charter/synthesis-manifest.yaml`** — record of the last charter synthesis.
- **`doctrine/PROVENANCE.md`** — notes that the project-level doctrine tree is
a *fresh-project seed*: the runtime falls back to the packaged built-in
doctrine until LLM-authored artifacts land under
`.kittify/charter/generated/` and `spec-kitty charter synthesize` is re-run.
- **Gitignored runtime/derived state** — `.kittify/runtime/merge/` (live merge
bookkeeping, incl. `__global_merge__`), `.kittify/derived/<mission>/`
(`status.json`, `progress.json`, `lifecycle.json`, `board-summary.json`),
`.kittify/skills-manifest.json`, `.kittify/sync-state.json`,
`.kittify/workspaces/`, `.kittify/archive/`, `.kittify/logs/`,
`.kittify/events/`, delta chains and dossiers.
---
## 4. Missions in `kitty-specs/`
Each `<mission-slug>/` folder is the full audit trail for one mission. Its
artifacts:
`meta.json` (mission id/slug/number, type, topology, target branch, purpose,
acceptance history) · `status.json` + `status.events.jsonl` (event-sourced
work-package state) · `spec.md`, `plan.md`, `data-model.md`, `tasks.md` ·
`decisions/DM-*.md` + `decisions/index.json` (Decision Moments) ·
`checklists/requirements.md` · `tasks/WP*.md` + per-WP `tasks/WP*/` dirs
(`review-cycle-*.md`, `review-feedback-*.md`, `baseline-tests.json`) ·
`acceptance-matrix.json` · `issue-matrix.json` · `lanes.json` ·
`mission-events.jsonl` · `snapshot-latest.json` · `quickstart.md` ·
`mission-review-report.md`.
Four completed missions:
| `issue-tracker-tui-01M27PTN` | `software-dev` | `lanes` (flattened) | 65 | 6 | yes |
| `tui-issue-edit-commands-01M2DPM6` | `software-dev` | `single_branch` | 36 | 6 | yes |
| `tix-mcp-server-01M2G3FX` | `software-dev` | — (flattened) | 28 | 4 | yes |
| `kanban-config-filtering-01M2MGDA` | `software-dev` | `coord` | 24 | 4 | yes |
`meta.json` records the acceptance trail (`accepted_at`, `accepted_by`,
`accept_commit`, `acceptance_history`) and the mission wiring
(`topology`, `target_branch`, `flattened`, `vcs: git`); the topology value
varies per mission (`lanes`, `single_branch`, `coord`, or absent).
---
## 5. Git integration
### Merge drivers (`.gitattributes` + git config)
Spec Kitty artifacts are mostly one-line JSON/event files that plain `git
merge` would corrupt or lose on parallel worktree lanes. The repo registers
custom merge drivers that shell out to the `spec-kitty` CLI
(`spec-kitty merge-driver-<kind> %O %A %B`):
| `kitty-specs/**/status.events.jsonl` | `merge=spec-kitty-event-log` | union merge of the event log |
| `kitty-specs/**/decisions.events.jsonl` | `merge=spec-kitty-event-log` | union merge of the event log |
| `kitty-specs/**/meta.json` | `merge=spec-kitty-meta` | fallible field merge |
| `kitty-specs/**/traces/*.md` | `merge=spec-kitty-traces` | union merge |
| `kitty-specs/**/acceptance-matrix.json` | `merge=spec-kitty-acceptance-matrix` | filled-side merge |
| `kitty-specs/**/issue-matrix.json` | `merge=spec-kitty-issue-matrix` | row-aware merge |
| `kitty-specs/**/tasks/*/review-cycle-*.md` | `merge=spec-kitty-review-cycle` | verdict-collision refusal |
Generated artifacts are also marked `linguist-generated` (`status.json`,
`lanes.json`, `mission-events.jsonl`, `snapshot-latest.json`,
`acceptance-matrix.json`, `issue-matrix.json`, `occurrence_map.yaml`,
`tasks/`, `research/{evidence-log,source-register}.csv`,
`test-transcripts/`, `baseline/`, `canary-evidence/`), and
`.kittify/workspaces/**` + `.kittify/migrations/**` get `-diff` so they
don't blur review diffs.
The driver registrations live in git config (`git config --get-all
merge.spec-kitty-*.driver`), i.e. the `spec-kitty` executable must be on
`PATH` for merges to work — a missing shim turns these into *not-found*
merge errors.
### Branch topology and commits
- Each mission targets its own feature branch (`feat/<mission-slug>`,
`branch.main.merge=refs/heads/main`); parallel work packages travel on
`kitty/mission-<slug>` merge lanes that fold back into the feature branch,
which then lands on `main` via merge commits. The exact lane shape depends
on each mission's `topology` (`lanes`, `single_branch`, `coord`; see the
missions table in §4).
- `auto_commit: true` — the runtime commits its own transitions:
`chore(spec-kitty): status transition WP04`.
- Acceptance is an explicit, committed gate — the log shows
`Accept <mission>` and `Record acceptance commit for <mission>` commits.
- tix is an active participant: `chore(track): mirror tix issues #37–#50 +
WP04 task state`.
---
## 6. The tix ↔ Spec Kitty integration
There are two tix integration layers: the **`tix init-agents`** generator and
the **spec-kitty task-tracking workflow** on the tix board.
### 6.1 Detection
`tix init-agents` runs from the project root (resolved by
`Config::project_root`) and performs a **single** `.kittify/` existence check
(`std::fs::metadata(cwd.join(".kittify"))`, `src/commands/agents.rs:23`). No
marker probing, no config reads, no network. This is deliberate — NFR-008 /
C-006 keeps the agent-surface generation trivially deterministic.
### 6.2 The AGENTS.md block (`tix init-agents`)
`tix init-agents` writes the AI-usage guidance into `AGENTS.md` as an
idempotent, marker-bounded block:
- Delimited by `<!-- tix:start -->` … `<!-- tix:end -->`.
- Re-runs replace only the content *between* the markers; unrelated AGENTS.md
content is never touched. One dangling marker ⇒ the file is treated as
unrelated and a fresh block is appended. Writes are atomic (temp file +
rename).
- The block is byte-deterministic (no timestamps/hashes) and is locked by
golden tests (`build_section_false_matches_golden_pre_mission_block`).
- Every clap subcommand must appear verbatim in the output (guarded by
`build_section_contains_every_clap_subcommand`).
When a framework is detected, `tix init-agents` prints a **stdout detection line** before
its status messages, mirroring the generated section one-to-one:
```
Detected Spec Kitty (via .kittify/)
```
and, for an `openspec/` root, `Detected OpenSpec (via openspec/)`, and for a
`.specify/` root, `Detected Spec Kit (via .specify/)` (all lines in that fixed
order, produced by `detection_report`; with no framework present, no detection
line is printed).
When the `.kittify/` directory is present (FR-019), the generated block also
splices in a **"Tracking Spec Kitty tasks with tix"** section, placed between
`### Updating` and `### Storage layout`:
```
- Filing a Spec Kitty task/work package → `tix create --title "<wp title>"`
- Opening an issue → `tix list --status "todo"`
- Marking a task done → `tix move <number> done` [+ `--commit <hash>`]
- Commenting on a task issue → `tix edit <number>`
- Linking related task issues → `tix link <a> <b>` [+ `tix unlink <a> <b>`]
- Populating `files` with the task's spec path → `tix edit <number> --files "<path>"`
```
The same mechanism handles OpenSpec projects — an `openspec/` directory at the
root leads to a parallel **"Tracking OpenSpec work with tix"** section
(`--labels openspec`) — and GitHub Spec Kit projects — a `.specify/` directory
leads to **"Tracking Spec Kit work with tix"** (`--labels speckit`). The three
detections are independent and compose (all present ⇒ all three sections, Spec
Kitty then OpenSpec then Spec Kit). See
[`docs/openspec-integration.md`](openspec-integration.md) and
[`docs/spec-kit-integration.md`](spec-kit-integration.md).
### 6.3 What is actually in AGENTS.md right now
The on-disk `AGENTS.md` contains two layers, *neither* of which is bounded by
the tix markers:
1. A **`<!-- spec-kitty:orientation -->` block** owned by the Spec Kitty CLI.
It encodes the project's two invocation patterns for AI agents:
- **Full mission** (spec → plan → tasks → implement → review → merge):
trigger phrases → `/spec-kitty.specify`.
- **Lightweight dispatch** (ad-hoc fix/Q&A, no mission): trigger phrases →
`spec-kitty dispatch "<request verbatim>"`, then close the Op with
`spec-kitty profile-invocation complete`.
2. A **hand-maintained** "Tracking Spec Kitty tasks with tix" section that is
a *superset* of the generated template: it adds the `--labels spec-kitty`
convention, "add the spec/plan to the issue body", and the two **REQUIRED**
rules (use `tix mcp`, mirror every subtask as an issue).
> ⚠️ Operational note: because the current section is *not* wrapped in
> `<!-- tix:start -->`/`<!-- tix:end -->`, running `tix init-agents` today
> would **append** the (shorter, generated) block instead of replacing the
> hand-maintained one. If you want `tix init-agents` to own this text again,
> wrap the hand-maintained section in the marker pair first — subsequent runs
> will then replace only between the markers.
### 6.4 Tracking Spec Kitty tasks with tix (the dogfooding workflow)
The workflow encoded in AGENTS.md and exercised in this repo:
1. **File a task as a tix issue** with `--labels spec-kitty`
(e.g. `tix create --title "<wp title>" --labels spec-kitty`), and put the
concrete spec/plan in the issue body.
2. **Open the board** with `tix list --status "todo"`.
3. **Mark done with the landing commit**: `tix move <number> done
--commit <hash>` (non-interactive; the interactive form prompts).
4. **Comment** for review findings: `tix edit <number>`.
5. **Mirroring (REQUIRED per AGENTS.md)** — after each finished mission/work
package, replicate (1) every spec-kitty subtask (T0xx) as its own tix
issue and (2) every review finding / follow-up item; all labeled
`spec-kitty`; mark matching issues `done --commit <hash>` when the
lane/commit lands.
**Always use `tix mcp` to create/move these issues**, never hand-edited files
or the CLI prompts. The MCP server is wired into this repo via
`opencode.jsonc` (`cargo run --quiet -- mcp`), so agents call the `tix_*`
tools (`create_issue`, `move_issue`, `list_issues`, `get_issue`,
`board_status`, `search_issues`) directly. See `docs/mcp.md`.
**Observed example** — issue `#19` `T007: Minimal tools.rs stub` (mission
`tix-mcp-server-01M2G3FX`): a spec-kitty subtask mirrored as a tix issue with
`labels: [spec-kitty]`, `status: done`, and the landing commit recorded
(`commit: b0b57b7`). The repo's own board holds 50 issues (45 done, 5 todo),
e.g. `docs/issues/herbert-maschke/2026-09-16-t007-minimal-tools-rs-stub.md`.
---
## 7. Agent-harness surface (opencode)
- **Skills** — 55 skills installed under `.agents/skills/` (gitignored) for
the `opencode` agent and recorded in `.kittify/skills-manifest.json`
(name, installed path, content hash, delivery mode). Families:
`spec-kitty` (dispatch/dispatch lifecycle), `spec-kitty-*` mission phase
skills (specify/plan/tasks/implement-review/runtime-next/runtime-review/
mission-review/charter-doctrine/…), `spk-*` (start/admin/run/doctrine/gate/
team/meta), plus `adversarial-squad` and `ad-hoc-profile-load`. The
`spk-doctrine-profile-load` skill is the canonical entry point for
loading agent profiles (identity, boundaries, governance scope).
- **Roles/profiles** — the runtime tracks an agent profile per invocation
(`architect-alphonso`, `implementer-ivan`, `reviewer-renata`, etc.) against
`spec-kitty profiles`, with per-invocation Op records in `kitty-ops/`.
- **MCP** — opencode's `tix` MCP server (`opencode.jsonc`) exposes the tix
issue board to agents; the Spec Kitty CLI in turn exposes `orchestrator-api`
so external harnesses can drive the mission workflow from outside.
---
## 8. Ops trail (`kitty-ops/`)
Each dispatched invocation produces a JSONL Op record
(`kitty-ops/<invocation-id>.jsonl`) with `started`/`completed` events:
profile id, action, request text (`governance_context_hash`,
`governance_context_available`), actor, mode of work, model id, and outcome.
Example — a `plan` step invoked by `opencode` under the `architect-alphonso`
profile, carrying a supply-chain guard check delegation for dependencies being
introduced. The dashboard daemon (`.kittify/.dashboard`, port 9237) offers a
live view over missions, invocations, and state.
---
## 9. Hosted / team sync
`.kittify/sync-state.json` (gitignored) tracks the queue of local commits
waiting for hosted (SaaS) sync: `pending_local_commits` entries carry
`git_hash`, `mission_id`, `build_id`, `project_uuid`, and `changed_files`
(e.g. a `plan.md` committed for `tui-issue-edit-commands-01M2DPM6`).
`last_saas_confirmed_hash` is currently null, so local-first, with sync
pending. Managed via the `spk-team-sync` / `sync` command family.
---
## 10. Day-to-day operation
**For a human operator or an agent:**
| Task | How |
| --- | --- |
| Open the board of spec-kitty tasks | `tix list --status "todo"` or the TUI (`tix`) |
| Start a governed full mission | trigger phrase → `/spec-kitty.specify` |
| Make an ad-hoc governed change | trigger phrase → `spec-kitty dispatch "<request>"` |
| Close a dispatch Op | `spec-kitty profile-invocation complete --invocation-id <id> --outcome <done\|failed\|abandoned>` |
| Advance a mission | `spec-kitty next --mission <slug>` (via the `spec-kitty-runtime-next` skill) |
| Review a WP | `spec-kitty review` / runtime review surface |
| Review the merged mission | `spec-kitty review` / `spk-gate-mission-review` |
| Regenerate AGENTS.md agent section | `tix init-agents` |
| Regenerate derived mission state | `spec-kitty materialize` |
| Health check | `spec-kitty doctor`, `spec-kitty verify-setup`, git merge-driver check |
| Dashboard | `spec-kitty dashboard --open` |
**Maintenance/upgrades** — `spec-kitty migrate` / `upgrade` bump
`.kittify/metadata.yaml` (`last_upgraded_at`, `schema_version`); the project
currently sits on schema v3 with no applied migrations. `kitty-ops/` and
`.agents/skills/` are regenerated by the runtime on demand.
---
## 11. Reference
- This repo's `AGENTS.md` — the orientation block + current task-tracking
section (hand-maintained, see §6.3).
- `.agents/skills/spec-kitty/SKILL.md` — dispatch semantics for agents.
- `.kittify/config.yaml`, `charter/charter.yaml`, `metadata.yaml`,
`doctrine/PROVENANCE.md` — governance state.
- `docs/mcp.md` — the tix MCP server agents use to drive the board.
- `docs/openspec-integration.md` — the OpenSpec analog: `openspec/` detection, the
generated tracking section, and the `openspec` label convention.
- `kitty-specs/<mission>/quickstart.md` + `mission-review-report.md` — per
mission, human-readable entry points.
---
## 12. Known 3.2.7 defects and interim rules
Two defects fixed on Spec Kitty's `main` branch are not present in the pinned
3.2.7 release:
- **Target-side source loss on default squash merge.** Upstream issue
[#4892](https://github.com/spec-kitty/spec-kitty/issues/4892) was fixed by
commit `eaf3b218`, which fails closed on target source conflicts and adds the
conflict forecast.
- **Python-only dead-code review gate.** Upstream issue
[#5283](https://github.com/spec-kitty/spec-kitty/issues/5283) was fixed by
commit `895ce716`, which reports the gate as not applicable to non-Python
change sets.
Until a release containing both commits is adopted:
- Run `spec-kitty merge --strategy merge` whenever the target branch moved after
the mission base. A true merge reports target/source conflicts instead of
silently resolving them in the mission's favour.
- Record the Python-only dead-code finding as not applicable for a Rust change
set. Use the language-owned gate instead:
```sh
cargo clippy --all-targets --all-features -- -D warnings
```
Keep tix #1595 and #1684 open as externally tracked defects until the pinned
Spec Kitty version includes both upstream fixes.
The `v4.0.0rc7` prerelease contains both commits, but the project remains pinned
to the stable `3.2.7` release until `4.0.0` is released and its migration and
merge behavior are validated here.