Execution Lanes
Spec Kitty uses a lane-based execution model.
finalize_taskscomputeslanes.jsonfrom dependencies, ownership, and predicted surfaces.- Each lane gets exactly one git worktree and one lane branch.
- Sequential work packages in the same lane reuse that same worktree.
- Independent lanes can run in parallel in separate worktrees.
Core Rules
- Planning happens in the primary repository checkout.
spec-kitty agent action implement WP## --agent <name>requires a validlanes.json.- The runtime chooses the lane worktree. Agents do not pick a base branch manually.
- If a feature computes one lane, the feature uses one worktree.
- Merge always follows
lane branches -> mission branch -> target branch.
Naming
As of mission 083-mission-id-canonical-identity-migration, every mission carries a ULID
identity (mission_id), and branch and worktree names embed the first 8 characters of
that ULID (mid8) to guarantee collision-free naming even when two missions share the
same human slug.
- Mission branch:
kitty/mission-<human-slug>-<mid8> - Lane branch:
kitty/mission-<human-slug>-<mid8>-lane-a - Lane worktree:
.worktrees/<human-slug>-<mid8>-lane-a/
Example, for a mission with mission_slug=my-feature and
mission_id=01J6XW9KQT7M0YB3N4R5CQZ2EX (so mid8=01J6XW9K):
- Mission branch:
kitty/mission-my-feature-01J6XW9K - Lane branch:
kitty/mission-my-feature-01J6XW9K-lane-a - Lane worktree:
.worktrees/my-feature-01J6XW9K-lane-a/
Legacy (pre-083) forms such as kitty/mission-001-my-feature-lane-a and
.worktrees/001-my-feature-lane-a/ remain readable by current tooling but
are no longer the form produced by implement. Upgrade via the
mission identity migration runbook.
Why This Replaced Per-WP Worktrees
Per-work-package worktrees allowed overlapping work packages to run in parallel and collide at merge time. Execution lanes eliminate that by forcing dependent or overlapping work packages into the same lane, branch, and worktree.
Parallelism Preservation
finalize-tasks assigns WPs to lanes based on two criteria:
- File ownership overlap — WPs that declare no files in common are placed in separate lanes and run in parallel.
- Explicit dependencies — If WP B lists WP A in its
dependenciesfield, they are assigned to the same lane and run sequentially (A then B).
When neither criterion forces a merge, the pipeline keeps WPs in separate lanes to maximise parallelism. When a merge is forced, it is recorded in lanes.json under the collapse_report field:
{
"collapse_report": [
{
"merged_wps": ["WP02", "WP03"],
"reason": "overlapping owned files: src/foo.py"
}
]
}
Each entry in collapse_report lists the WPs that were merged into a single lane and the reason (file overlap or explicit dependency). Inspect this field after finalize-tasks to understand why two WPs share a lane.
Lane-Specific Test Database Isolation (FR-006)
Two parallel SaaS / Django lanes used to share a single test database when their per-lane test runners booted concurrently, which produced flaky failures. Each lane workspace now exposes a lane-suffixed identifier via LaneWorkspaceResult.lane_test_env, which sets SPEC_KITTY_TEST_DB_NAME=test_<safe-mission>_<safe-lane>. Test settings modules (Django and otherwise) should read that env var when constructing their per-lane test database name; the helpers lane_test_db_name() and lane_test_env() in specify_cli.lanes.lane_env are the canonical entry points and guarantee distinct DB names for distinct (mission_slug, lane_id) pairs.