From c30df1ed60dd296d437144c17e35b03696e1e68b Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 May 2026 15:40:51 -0400 Subject: [PATCH 01/18] Add spec for feature workspace-runtime-contract-01KRC8WY --- kitty-specs/workspace-runtime-contract-01KRC8WY/spec.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 kitty-specs/workspace-runtime-contract-01KRC8WY/spec.md diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/spec.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/spec.md new file mode 100644 index 0000000..e69de29 From bf64bbba53ecb213a3f79c318a5789d45eba8649 Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 May 2026 15:40:51 -0400 Subject: [PATCH 02/18] Add meta for feature workspace-runtime-contract-01KRC8WY --- .../workspace-runtime-contract-01KRC8WY/meta.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json b/kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json new file mode 100644 index 0000000..ee5e1b2 --- /dev/null +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json @@ -0,0 +1,10 @@ +{ + "created_at": "2026-05-11T19:40:51.106806+00:00", + "friendly_name": "workspace runtime contract", + "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", + "mission_number": null, + "mission_slug": "workspace-runtime-contract-01KRC8WY", + "mission_type": "software-dev", + "slug": "workspace-runtime-contract-01KRC8WY", + "target_branch": "spec-workspace-runtime-contract" +} From 75ebede1394bfe860647b37c743f0b13756fe46a Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 May 2026 15:52:25 -0400 Subject: [PATCH 03/18] Add plan for feature workspace-runtime-contract-01KRC8WY --- .../plan.md | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 kitty-specs/workspace-runtime-contract-01KRC8WY/plan.md diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/plan.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/plan.md new file mode 100644 index 0000000..bc59470 --- /dev/null +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/plan.md @@ -0,0 +1,108 @@ +# Implementation Plan: [FEATURE] +*Path: [templates/plan-template.md](templates/plan-template.md)* + + +**Branch**: `[###-feature-name]` | **Date**: [DATE] | **Spec**: [link] +**Input**: Feature specification from `/kitty-specs/[###-feature-name]/spec.md` + +**Note**: This template is filled in by the `/spec-kitty.plan` command. See `src/specify_cli/missions/software-dev/command-templates/plan.md` for the execution workflow. + +The planner will not begin until all planning questions have been answered—capture those answers in this document before progressing to later phases. + +## Summary + +[Extract from feature spec: primary requirement + technical approach from research] + +## Technical Context + + + +**Language/Version**: [e.g., Python 3.11, Swift 5.9, Rust 1.75 or NEEDS CLARIFICATION] +**Primary Dependencies**: [e.g., FastAPI, UIKit, LLVM or NEEDS CLARIFICATION] +**Storage**: [if applicable, e.g., PostgreSQL, CoreData, files or N/A] +**Testing**: [Project-specific test approach or NEEDS CLARIFICATION] +**Target Platform**: [e.g., Linux server, iOS 15+, WASM or NEEDS CLARIFICATION] +**Project Type**: [single/web/mobile - determines source structure] +**Performance Goals**: [domain-specific, e.g., 1000 req/s, 10k lines/sec, 60 fps or NEEDS CLARIFICATION] +**Constraints**: [domain-specific, e.g., <200ms p95, <100MB memory, offline-capable or NEEDS CLARIFICATION] +**Scale/Scope**: [domain-specific, e.g., 10k users, 1M LOC, 50 screens or NEEDS CLARIFICATION] + +## Charter Check + +*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* + +[Gates determined based on charter file] + +## Project Structure + +### Documentation (this feature) + +``` +kitty-specs/[###-feature]/ +├── plan.md # This file (/spec-kitty.plan command output) +├── research.md # Phase 0 output (/spec-kitty.plan command) +├── data-model.md # Phase 1 output (/spec-kitty.plan command) +├── quickstart.md # Phase 1 output (/spec-kitty.plan command) +├── contracts/ # Phase 1 output (/spec-kitty.plan command) +└── tasks.md # Phase 2 output (/spec-kitty.tasks command - NOT created by /spec-kitty.plan) +``` + +### Source Code (repository root) + + +``` +# [REMOVE IF UNUSED] Option 1: Single project (DEFAULT) +src/ +├── models/ +├── services/ +├── cli/ +└── lib/ + +tests/ +├── contract/ +├── integration/ +└── unit/ + +# [REMOVE IF UNUSED] Option 2: Web application (when "frontend" + "backend" detected) +backend/ +├── src/ +│ ├── models/ +│ ├── services/ +│ └── api/ +└── tests/ + +frontend/ +├── src/ +│ ├── components/ +│ ├── pages/ +│ └── services/ +└── tests/ + +# [REMOVE IF UNUSED] Option 3: Mobile + API (when "iOS/Android" detected) +api/ +└── [same as backend above] + +ios/ or android/ +└── [platform-specific structure: feature modules, UI flows, platform tests] +``` + +**Structure Decision**: [Document the selected structure and reference the real +directories captured above] + +## Complexity Tracking + +*Fill ONLY if Charter Check has violations that must be justified* + +| Violation | Why Needed | Simpler Alternative Rejected Because | +|-----------|------------|-------------------------------------| +| [e.g., 4th project] | [current need] | [why 3 projects insufficient] | +| [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] | From bf100f3dee071018c053f67d8a432f5be059f7c7 Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 May 2026 15:56:23 -0400 Subject: [PATCH 04/18] Add tasks for feature workspace-runtime-contract-01KRC8WY --- .../status.events.jsonl | 3 + .../status.json | 42 ++++++++++++ .../tasks.md | 35 ++++++++++ .../tasks/.gitkeep | 0 .../tasks/README.md | 64 +++++++++++++++++++ .../tasks/WP01-openspec-proposal-scaffold.md | 55 ++++++++++++++++ .../tasks/WP02-runtime-contract-delta-spec.md | 57 +++++++++++++++++ .../tasks/WP03-cross-link-and-draft-pr.md | 58 +++++++++++++++++ 8 files changed, 314 insertions(+) create mode 100644 kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl create mode 100644 kitty-specs/workspace-runtime-contract-01KRC8WY/status.json create mode 100644 kitty-specs/workspace-runtime-contract-01KRC8WY/tasks.md create mode 100644 kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/.gitkeep create mode 100644 kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/README.md create mode 100644 kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md create mode 100644 kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md create mode 100644 kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl new file mode 100644 index 0000000..3fa5c63 --- /dev/null +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl @@ -0,0 +1,3 @@ +{"actor": "finalize-tasks", "at": "2026-05-11T19:56:22.993859+00:00", "event_id": "01KRC9SCJH85MZASQG17059R7Y", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "planned", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "canonical bootstrap", "review_ref": null, "to_lane": "planned", "wp_id": "WP01"} +{"actor": "finalize-tasks", "at": "2026-05-11T19:56:23.601699+00:00", "event_id": "01KRC9SD5HNAXWXBXE1ZY00Q8J", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "planned", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "canonical bootstrap", "review_ref": null, "to_lane": "planned", "wp_id": "WP02"} +{"actor": "finalize-tasks", "at": "2026-05-11T19:56:23.646662+00:00", "event_id": "01KRC9SD6YAW6BGB30RAVV3Z0S", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "planned", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "canonical bootstrap", "review_ref": null, "to_lane": "planned", "wp_id": "WP03"} diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json new file mode 100644 index 0000000..d5d16f3 --- /dev/null +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json @@ -0,0 +1,42 @@ +{ + "event_count": 3, + "last_event_id": "01KRC9SD6YAW6BGB30RAVV3Z0S", + "materialized_at": "2026-05-11T19:56:23.646662+00:00", + "mission_number": "", + "mission_slug": "workspace-runtime-contract-01KRC8WY", + "mission_type": "software-dev", + "summary": { + "approved": 0, + "blocked": 0, + "canceled": 0, + "claimed": 0, + "done": 0, + "for_review": 0, + "in_progress": 0, + "in_review": 0, + "planned": 3 + }, + "work_packages": { + "WP01": { + "actor": "finalize-tasks", + "force_count": 1, + "lane": "planned", + "last_event_id": "01KRC9SCJH85MZASQG17059R7Y", + "last_transition_at": "2026-05-11T19:56:22.993859+00:00" + }, + "WP02": { + "actor": "finalize-tasks", + "force_count": 1, + "lane": "planned", + "last_event_id": "01KRC9SD5HNAXWXBXE1ZY00Q8J", + "last_transition_at": "2026-05-11T19:56:23.601699+00:00" + }, + "WP03": { + "actor": "finalize-tasks", + "force_count": 1, + "lane": "planned", + "last_event_id": "01KRC9SD6YAW6BGB30RAVV3Z0S", + "last_transition_at": "2026-05-11T19:56:23.646662+00:00" + } + } +} diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks.md new file mode 100644 index 0000000..fd7b133 --- /dev/null +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks.md @@ -0,0 +1,35 @@ +# Work Packages: workspace-runtime-contract-01KRC8WY + +_Generated by finalize-tasks from wps.yaml. Do not edit directly._ + +--- + +## Work Package WP01: Author OpenSpec proposal scaffold for add-workspace-runtime-contract + +**Dependencies**: None +**Requirement Refs**: FR-001, FR-006, C-001, C-004 +**Owned Files**: openspec/changes/add-workspace-runtime-contract/proposal.md, openspec/changes/add-workspace-runtime-contract/design.md, openspec/changes/add-workspace-runtime-contract/tasks.md +**Subtasks**: T001, T002, T003, T004 +**Prompt**: `tasks/WP01-openspec-proposal-scaffold.md` + +--- + +## Work Package WP02: Author workspace-runtime delta spec with INV-1..INV-9 + drift catalog + +**Dependencies**: WP01 +**Requirement Refs**: FR-002, FR-003, FR-004, FR-005, C-004, C-005 +**Owned Files**: openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md +**Subtasks**: T005, T006, T007, T008, T009 +**Prompt**: `tasks/WP02-runtime-contract-delta-spec.md` + +--- + +## Work Package WP03: Cross-link mission to OpenSpec change and open draft PR + +**Dependencies**: WP01, WP02 +**Requirement Refs**: FR-006, FR-007, FR-008, FR-009, FR-010, C-002, C-003 +**Owned Files**: kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json +**Subtasks**: T010, T011, T012, T013, T014 +**Prompt**: `tasks/WP03-cross-link-and-draft-pr.md` + +--- diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/.gitkeep b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/README.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/README.md new file mode 100644 index 0000000..f97195c --- /dev/null +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/README.md @@ -0,0 +1,64 @@ +# Tasks Directory + +This directory contains work package (WP) prompt files. + +## Directory Structure (v0.9.0+) + +``` +tasks/ +├── WP01-setup-infrastructure.md +├── WP02-user-authentication.md +├── WP03-api-endpoints.md +└── README.md +``` + +All WP files are stored flat in `tasks/`. Status is tracked in `status.events.jsonl`, not in WP frontmatter. + +## Work Package File Format + +Each WP file **MUST** use YAML frontmatter: + +```yaml +--- +work_package_id: "WP01" +title: "Work Package Title" +dependencies: [] +planning_base_branch: "spec-workspace-runtime-contract" +merge_target_branch: "spec-workspace-runtime-contract" +branch_strategy: "Planning artifacts were generated on spec-workspace-runtime-contract; completed changes must merge back into spec-workspace-runtime-contract." +subtasks: + - "T001" + - "T002" +phase: "Phase 1 - Setup" +assignee: "" +agent: "" +shell_pid: "" +history: + - timestamp: "2025-01-01T00:00:00Z" + agent: "system" + action: "Prompt generated via /spec-kitty.tasks" +--- + +# Work Package Prompt: WP01 – Work Package Title + +[Content follows...] +``` + +## Status Tracking + +Status is tracked via the canonical event log (`status.events.jsonl`), not in WP frontmatter. +Use `spec-kitty agent tasks move-task` to change WP status: + +```bash +spec-kitty agent tasks move-task --to +``` + +Example: +```bash +spec-kitty agent tasks move-task WP01 --to doing +``` + +## File Naming + +- Format: `WP01-kebab-case-slug.md` +- Examples: `WP01-setup-infrastructure.md`, `WP02-user-auth.md` diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md new file mode 100644 index 0000000..4fec1d0 --- /dev/null +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md @@ -0,0 +1,55 @@ +--- +work_package_id: WP01 +title: Author OpenSpec proposal scaffold for add-workspace-runtime-contract +dependencies: [] +requirement_refs: +- C-001 +- C-004 +- FR-001 +- FR-006 +planning_base_branch: spec-workspace-runtime-contract +merge_target_branch: spec-workspace-runtime-contract +branch_strategy: Planning artifacts for this feature were generated on spec-workspace-runtime-contract. During /spec-kitty.implement this WP may branch from a dependency-specific base, but completed changes must merge back into spec-workspace-runtime-contract unless the human explicitly redirects the landing branch. +subtasks: +- T001 +- T002 +- T003 +- T004 +history: [] +authoritative_surface: openspec/changes/add-workspace-runtime-contract/ +execution_mode: doc_change +owned_files: +- openspec/changes/add-workspace-runtime-contract/proposal.md +- openspec/changes/add-workspace-runtime-contract/design.md +- openspec/changes/add-workspace-runtime-contract/tasks.md +tags: [] +--- + +# WP01 — Author OpenSpec proposal scaffold for `add-workspace-runtime-contract` + +## Goal + +Create the OpenSpec change scaffold (proposal, design, tasks) for `add-workspace-runtime-contract`. No spec deltas are written here — that is WP02. No code under `image/`, `*/template.tf`, `*/scripts/`, or `Makefile` is touched. + +## Inputs + +- Mission spec: `kitty-specs/workspace-runtime-contract-01KRC8WY/spec.md` +- Research: `kitty-specs/workspace-runtime-contract-01KRC8WY/research.md` +- Data model: `kitty-specs/workspace-runtime-contract-01KRC8WY/data-model.md` +- Existing proposal runbook: `.agent/workflows/openspec-proposal.md` +- Existing OpenSpec guidance: `openspec/AGENTS.md` + +## Subtasks + +- **T001** — Create directory `openspec/changes/add-workspace-runtime-contract/`. +- **T002** — Write `proposal.md` summarizing why the contract exists, what it codifies (INV-1…INV-9), explicit non-goals (no code, no drift remediation), and a "Spec Kitty Mission" cross-link to `workspace-runtime-contract-01KRC8WY`. +- **T003** — Write `design.md` covering the descriptive-first approach, OpenSpec/Spec Kitty cohabitation rule, the cross-link convention (`meta.json` ↔ proposal), and the known-drift catalog as future-attachment points. +- **T004** — Write `tasks.md` enumerating the proposal-stage work items (authoring spec, validating, cross-linking, opening draft PR) as `- [ ]` checkboxes; mark them complete only after the corresponding WPs are done. + +## Success Criteria + +- Three files present under `openspec/changes/add-workspace-runtime-contract/`. +- `proposal.md` references the mission slug and the nine invariants. +- `design.md` justifies descriptive-first + cohabitation. +- `tasks.md` is in OpenSpec's expected checkbox format. +- No file outside `openspec/changes/add-workspace-runtime-contract/` is modified. diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md new file mode 100644 index 0000000..4ec6ba4 --- /dev/null +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md @@ -0,0 +1,57 @@ +--- +work_package_id: WP02 +title: Author workspace-runtime delta spec with INV-1..INV-9 + drift catalog +dependencies: +- WP01 +requirement_refs: +- C-004 +- C-005 +- FR-002 +- FR-003 +- FR-004 +- FR-005 +planning_base_branch: spec-workspace-runtime-contract +merge_target_branch: spec-workspace-runtime-contract +branch_strategy: Planning artifacts for this feature were generated on spec-workspace-runtime-contract. During /spec-kitty.implement this WP may branch from a dependency-specific base, but completed changes must merge back into spec-workspace-runtime-contract unless the human explicitly redirects the landing branch. +subtasks: +- T005 +- T006 +- T007 +- T008 +- T009 +history: [] +authoritative_surface: openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md +execution_mode: doc_change +owned_files: +- openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md +tags: [] +--- + +# WP02 — Author the runtime-contract delta spec + +## Goal + +Write the OpenSpec delta spec for capability `workspace-runtime` with nine `## ADDED Requirements`, the boot-sequence and forbidden-behavior requirements, and an informational `## Known Drift` block. + +## Inputs + +- WP01 outputs (proposal, design, tasks). +- Mission spec.md (FRs). +- Mission data-model.md (INV-1…INV-9 entities, coverage matrix). +- Mission research.md (drift D-1…D-6). +- Existing OpenSpec delta-spec examples under `openspec/changes/*/specs/*/spec.md`. + +## Subtasks + +- **T005** — Create directory `openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/`. +- **T006** — Write `spec.md` opening (purpose, scope, derivation, dependency note). +- **T007** — Write nine `## ADDED Requirements` blocks (INV-1…INV-9). Each requirement: clear "shall" statement + at least one `#### Scenario:` describing a verifiable observation in the running workspace. +- **T008** — Write the boot sequence and forbidden-behavior requirements (the §3/§4 of the drafted contract) as scenario-bearing requirements. +- **T009** — Write the `## Known Drift` block enumerating D-1…D-6 as informational (not enforced); each entry names the affected invariant. + +## Success Criteria + +- File at `openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md`. +- `openspec validate add-workspace-runtime-contract --strict` is green. +- Each `ADDED Requirement` has at least one `#### Scenario:`. +- Drift block is clearly labeled informational and cites the relevant source files. diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md new file mode 100644 index 0000000..2e3fdfd --- /dev/null +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md @@ -0,0 +1,58 @@ +--- +work_package_id: WP03 +title: Cross-link mission to OpenSpec change and open draft PR +dependencies: +- WP01 +- WP02 +requirement_refs: +- C-002 +- C-003 +- FR-006 +- FR-007 +- FR-008 +- FR-009 +- FR-010 +planning_base_branch: spec-workspace-runtime-contract +merge_target_branch: spec-workspace-runtime-contract +branch_strategy: Planning artifacts for this feature were generated on spec-workspace-runtime-contract. During /spec-kitty.implement this WP may branch from a dependency-specific base, but completed changes must merge back into spec-workspace-runtime-contract unless the human explicitly redirects the landing branch. +subtasks: +- T010 +- T011 +- T012 +- T013 +- T014 +history: [] +authoritative_surface: kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json +execution_mode: doc_change +owned_files: +- kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json +tags: [] +--- + +# WP03 — Cross-link mission to OpenSpec and open draft PR + +## Goal + +Bind the Spec Kitty mission and the OpenSpec change with bidirectional references, verify pre-push gates, and open a **draft** pull request against `ddev/coder-ddev:main`. + +## Inputs + +- WP01 and WP02 completed outputs. +- `CLAUDE.md` pre-push checklist (terraform fmt/validate/test). +- `gh` CLI with `upstream` remote pointing at `ddev/coder-ddev`. + +## Subtasks + +- **T010** — Update `kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json`: extend `source_description` to reference the OpenSpec change-id `add-workspace-runtime-contract` (without breaking schema). +- **T011** — Re-confirm `openspec/changes/add-workspace-runtime-contract/proposal.md` carries the "Spec Kitty Mission: `workspace-runtime-contract-01KRC8WY`" cross-link added in WP01. +- **T012** — Run `openspec validate add-workspace-runtime-contract --strict`; remediate any failures by editing only WP02 outputs. +- **T013** — Run `terraform fmt -check -recursive` and confirm zero changes (defensive — no HCL touched). +- **T014** — Open a draft PR with `gh pr create --draft --repo ddev/coder-ddev --base main --head jonesrussell:spec-workspace-runtime-contract --title "spec: workspace-runtime-contract (foundational spec)" --body-file ` where `` references the OpenSpec change-id, the Spec Kitty mission slug, the descriptive-first nature of the change, and the known-drift catalog. Confirm PR is in draft state. + +## Success Criteria + +- `meta.json` references the OpenSpec change-id. +- `openspec validate add-workspace-runtime-contract --strict` is green. +- `terraform fmt -recursive` clean. +- Draft PR exists on `ddev/coder-ddev:main`. PR URL captured in the WP completion notes. +- No file under `image/`, `*/template.tf`, `*/scripts/`, or `Makefile` in the PR diff. From 6d1c36db3702c05d0005eb7b7812c0acd25e8d3d Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 May 2026 15:57:31 -0400 Subject: [PATCH 05/18] Add tasks for feature workspace-runtime-contract-01KRC8WY --- .../lanes.json | 54 +++++++++++++++++++ .../tasks/WP01-openspec-proposal-scaffold.md | 2 +- .../tasks/WP02-runtime-contract-delta-spec.md | 2 +- .../tasks/WP03-cross-link-and-draft-pr.md | 2 +- 4 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 kitty-specs/workspace-runtime-contract-01KRC8WY/lanes.json diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/lanes.json b/kitty-specs/workspace-runtime-contract-01KRC8WY/lanes.json new file mode 100644 index 0000000..63b69ed --- /dev/null +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/lanes.json @@ -0,0 +1,54 @@ +{ + "version": 1, + "mission_slug": "workspace-runtime-contract-01KRC8WY", + "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", + "mission_branch": "kitty/mission-workspace-runtime-contract-01KRC8WY", + "target_branch": "spec-workspace-runtime-contract", + "lanes": [ + { + "lane_id": "lane-a", + "wp_ids": [ + "WP01", + "WP02", + "WP03" + ], + "write_scope": [ + "kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json", + "openspec/changes/add-workspace-runtime-contract/design.md", + "openspec/changes/add-workspace-runtime-contract/proposal.md", + "openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md", + "openspec/changes/add-workspace-runtime-contract/tasks.md" + ], + "predicted_surfaces": [ + "artifact-rendering", + "workspace" + ], + "depends_on_lanes": [], + "parallel_group": 0 + } + ], + "computed_at": "2026-05-11T19:57:31.318291+00:00", + "computed_from": "dependency_graph+ownership", + "planning_artifact_wps": [], + "collapse_report": { + "events": [ + { + "wp_a": "WP02", + "wp_b": "WP01", + "rule": "dependency", + "evidence": "WP02 depends on WP01" + }, + { + "wp_a": "WP03", + "wp_b": "WP01", + "rule": "dependency", + "evidence": "WP03 depends on WP01" + } + ], + "total_merges": 2, + "independent_wps_collapsed": 0, + "by_rule": { + "dependency": 2 + } + } +} diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md index 4fec1d0..d67f67c 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md @@ -17,7 +17,7 @@ subtasks: - T004 history: [] authoritative_surface: openspec/changes/add-workspace-runtime-contract/ -execution_mode: doc_change +execution_mode: code_change owned_files: - openspec/changes/add-workspace-runtime-contract/proposal.md - openspec/changes/add-workspace-runtime-contract/design.md diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md index 4ec6ba4..d70fdac 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md @@ -21,7 +21,7 @@ subtasks: - T009 history: [] authoritative_surface: openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md -execution_mode: doc_change +execution_mode: code_change owned_files: - openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md tags: [] diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md index 2e3fdfd..665c60a 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md @@ -23,7 +23,7 @@ subtasks: - T014 history: [] authoritative_surface: kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json -execution_mode: doc_change +execution_mode: code_change owned_files: - kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json tags: [] From 3634d6663736aef7a45502b30a2594f209a146ba Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 May 2026 15:58:02 -0400 Subject: [PATCH 06/18] chore: planning artifacts for workspace-runtime-contract-01KRC8WY Auto-committed by spec-kitty before creating the lane worktree for WP01 --- .../data-model.md | 79 ++++++++ .../mission-events.jsonl | 9 + .../plan.md | 177 ++++++++++-------- .../research.md | 58 ++++++ .../research/evidence-log.csv | 28 +++ .../research/source-register.csv | 15 ++ .../spec.md | 82 ++++++++ .../wps.yaml | 63 +++++++ 8 files changed, 430 insertions(+), 81 deletions(-) create mode 100644 kitty-specs/workspace-runtime-contract-01KRC8WY/data-model.md create mode 100644 kitty-specs/workspace-runtime-contract-01KRC8WY/mission-events.jsonl create mode 100644 kitty-specs/workspace-runtime-contract-01KRC8WY/research.md create mode 100644 kitty-specs/workspace-runtime-contract-01KRC8WY/research/evidence-log.csv create mode 100644 kitty-specs/workspace-runtime-contract-01KRC8WY/research/source-register.csv create mode 100644 kitty-specs/workspace-runtime-contract-01KRC8WY/wps.yaml diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/data-model.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/data-model.md new file mode 100644 index 0000000..7218808 --- /dev/null +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/data-model.md @@ -0,0 +1,79 @@ +# Data Model — Workspace Runtime Contract + +This document enumerates the durable entities of the runtime contract. Each entity is one invariant (INV-1…INV-9) plus its attributes and the relationships that bind it to other invariants. + +## Entities + +### INV-1 — SysboxRuntime +- **Attributes:** `runtime = "sysbox-runc"`, `privileged = false`, `apparmor = unconfined`, `seccomp = unconfined`. +- **Source of truth:** `user-defined-web/template.tf` (`docker_container.workspace` block). +- **Host precondition:** Sysbox installed and registered as a Docker runtime. + +### INV-2 — WorkspaceIdentity +- **Attributes:** username `coder`, UID `1000`, primary group `coder`, supplementary group `docker` (default GID `988`, overridable via `var.docker_gid`). +- **Established by:** image `usermod -l coder` + HCL `user = "coder"` + `group_add` + agent env `HOME=/home/coder`. + +### INV-3 — SudoPosture +- **Attributes:** entry `coder ALL=(ALL) NOPASSWD:ALL`, sudoers file mode `0440`, `DEBIAN_FRONTEND` preserved. +- **Source of truth:** `image/Dockerfile` sudoers RUN block. +- **Threat-model assumption:** workspace boundary = Sysbox; in-container UID separation is not a defense. + +### INV-4 — DockerdLifecycle +- **Attributes:** in-container daemon, started by agent (`sudo dockerd &`), log at `/tmp/dockerd.log`, socket at `/var/run/docker.sock`, socket widened to `chmod 666` after readiness, optional `/etc/docker/daemon.json` registry mirror. +- **Forbidden:** host docker socket mount; systemd-as-PID-1 path. + +### INV-5 — VolumeModel +- **Attributes:** + - Home: host bind `/coder-workspaces/-` → `/home/coder`. + - DinD: named volume `coder---dind-cache` → `/var/lib/docker`. + - No other persistent mounts; no host docker.sock. +- **Persistence semantics:** both volumes survive container stop/start; home is host-managed; DinD is Docker-managed. + +### INV-6 — HydrationModel +- **Attributes:** staging dir `/home/coder-files/` (outside the bind mount), policy "copy-if-missing, append-if-missing", first-boot marker `~/.bashrc absent`, every step idempotent. +- **Consumed files (today):** `WELCOME.txt`, `.vscode/settings.json`, `.gitconfig`, `.gitignore_global`. Drift D-2 enumerates files staged but uncopied. + +### INV-7 — RoutingModel +- **Attributes:** `ddev-router` globally omitted, project web container binds `localhost:80`, single project per workspace, external access only via Coder reverse tunnel + `coder_app.ddev-web` (subdomain). +- **Deviation:** the `freeform` template runs ddev-router and has its own contract; this spec does not govern freeform. + +### INV-8 — CleanupModel +- **Attributes:** stop tears down container (count-gated), preserves both volumes; destroy must remove `/coder-workspaces/-/` via `null_resource.workspace_cleanup` invoking host-side `coder-delete-workspace-dir`. Stop is graceful: `SIGINT`, `stop_timeout = 180s`, `destroy_grace_seconds = 60s`. Two shutdown hooks run `ddev poweroff` (agent + `coder_script` with `run_on_stop=true`). +- **Host precondition:** `/usr/local/bin/coder-delete-workspace-dir` installed with passwordless sudo for the daemon user. + +### INV-9 — IdentitySourceModel +- **Authoritative source:** `coder_agent.env` injects `CODER_WORKSPACE_{ID,NAME,OWNER_NAME,OWNER_EMAIL}`. +- **Forbidden as source:** container `hostname` (it is `-`; container name is `coder-`; mismatch makes hostname parsing unreliable). +- **Used by:** git config injection, DDEV project naming, dashboard metadata. + +## Relationships + +| From | Relation | To | +|------|----------|-----| +| INV-1 | enables safe execution of | INV-4 | +| INV-2 | required by | INV-3, INV-4, INV-5 | +| INV-3 | required by | INV-4 (dockerd launch), INV-5 (chown), INV-6 (hydration writes) | +| INV-4 | persists state via | INV-5 (`/var/lib/docker` volume) | +| INV-5 | shadows image content, necessitating | INV-6 | +| INV-6 | populates state in scope of | INV-2 (user-owned files) | +| INV-7 | exposed to users via | `coder_app.ddev-web` | +| INV-8 | depends on host-side helper named in | charter §"Important Constraints" | +| INV-9 | consumed by every step that names a workspace, including | INV-6 (git identity), INV-7 (DDEV project naming) | + +## Invariant Coverage Matrix + +| Invariant | Image enforces | HCL enforces | Script enforces | +|----------:|:--------------:|:------------:|:---------------:| +| INV-1 | | yes | | +| INV-2 | yes | yes | yes (chown) | +| INV-3 | yes | | yes (uses) | +| INV-4 | yes (binary) | yes (no socket mount) | yes (start) | +| INV-5 | | yes | | +| INV-6 | yes (stages) | | yes (hydrate) | +| INV-7 | yes (ddev install) | yes (coder_app) | (relies on DDEV global config) | +| INV-8 | | yes | yes (shutdown) | +| INV-9 | | yes (env) | yes (uses) | + +## Drift Catalog (informational) + +See `research.md` §"Known Drift" for D-1…D-6. They are **not** modeled as entities here; they are flagged anomalies that will become OpenSpec change proposals in their own missions. diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/mission-events.jsonl b/kitty-specs/workspace-runtime-contract-01KRC8WY/mission-events.jsonl new file mode 100644 index 0000000..e048094 --- /dev/null +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/mission-events.jsonl @@ -0,0 +1,9 @@ +{"mission": "software-dev", "payload": {"action": "research", "agent": "claude", "decision_kind": "step", "mission_state": "discovery", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-11T19:42:30.006862+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "specify", "agent": "claude", "decision_kind": "step", "mission_state": "specify", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-11T19:51:38.466826+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "plan", "agent": "claude", "decision_kind": "step", "mission_state": "plan", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-11T19:52:19.800712+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "tasks-outline", "agent": "claude", "decision_kind": "step", "mission_state": "tasks_outline", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-11T19:53:10.957267+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "tasks-outline", "agent": "claude", "decision_kind": "step", "mission_state": "tasks_outline", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-11T19:53:42.321882+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "tasks-outline", "agent": "claude", "decision_kind": "step", "mission_state": "tasks_outline", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-11T19:53:47.918194+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "tasks-packages", "agent": "claude", "decision_kind": "step", "mission_state": "tasks_packages", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-11T19:56:30.947002+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "tasks-finalize", "agent": "claude", "decision_kind": "step", "mission_state": "tasks_finalize", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-11T19:56:37.906018+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP01"}, "timestamp": "2026-05-11T19:57:39.984042+00:00", "type": "MissionNextInvoked"} diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/plan.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/plan.md index bc59470..3870fa2 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/plan.md +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/plan.md @@ -1,108 +1,123 @@ -# Implementation Plan: [FEATURE] -*Path: [templates/plan-template.md](templates/plan-template.md)* +# Implementation Plan: Workspace Runtime Contract - -**Branch**: `[###-feature-name]` | **Date**: [DATE] | **Spec**: [link] -**Input**: Feature specification from `/kitty-specs/[###-feature-name]/spec.md` - -**Note**: This template is filled in by the `/spec-kitty.plan` command. See `src/specify_cli/missions/software-dev/command-templates/plan.md` for the execution workflow. - -The planner will not begin until all planning questions have been answered—capture those answers in this document before progressing to later phases. +**Branch**: `spec-workspace-runtime-contract` | **Date**: 2026-05-11 | **Spec**: `kitty-specs/workspace-runtime-contract-01KRC8WY/spec.md` +**Input**: Mission specification + descriptive-first contract synthesized from `image/Dockerfile`, `user-defined-web/template.tf`, and the inlined `startup_script`. ## Summary -[Extract from feature spec: primary requirement + technical approach from research] +Deliver the foundational `workspace-runtime-contract` as **proposal artifacts only**. The work consists of three coordinated outputs: (1) the Spec Kitty mission artifacts (spec.md, plan.md, research.md, data-model.md), already in flight; (2) the OpenSpec change `add-workspace-runtime-contract` with proposal, design, tasks, and a delta spec under `openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md`; (3) a cross-link layer joining the two systems via `meta.json` and the OpenSpec proposal body. No code under `image/`, `*/template.tf`, `*/scripts/`, or `Makefile` is touched. ## Technical Context - - -**Language/Version**: [e.g., Python 3.11, Swift 5.9, Rust 1.75 or NEEDS CLARIFICATION] -**Primary Dependencies**: [e.g., FastAPI, UIKit, LLVM or NEEDS CLARIFICATION] -**Storage**: [if applicable, e.g., PostgreSQL, CoreData, files or N/A] -**Testing**: [Project-specific test approach or NEEDS CLARIFICATION] -**Target Platform**: [e.g., Linux server, iOS 15+, WASM or NEEDS CLARIFICATION] -**Project Type**: [single/web/mobile - determines source structure] -**Performance Goals**: [domain-specific, e.g., 1000 req/s, 10k lines/sec, 60 fps or NEEDS CLARIFICATION] -**Constraints**: [domain-specific, e.g., <200ms p95, <100MB memory, offline-capable or NEEDS CLARIFICATION] -**Scale/Scope**: [domain-specific, e.g., 10k users, 1M LOC, 50 screens or NEEDS CLARIFICATION] +**Language/Version**: Markdown (specs), JSON (mission metadata), Terraform HCL (already in place — not modified). +**Primary Dependencies**: `spec-kitty-cli` 3.1.8, `openspec` CLI, `gh` CLI, `terraform` ≥ 1.5. +**Storage**: Filesystem (mission dir, openspec/changes dir), git (auto-committed by Spec Kitty + manual commits for OpenSpec). +**Testing**: `openspec validate add-workspace-runtime-contract --strict`; `terraform fmt -check -recursive`; mission `status.json` lane invariants. +**Target Platform**: WSL2 / Linux host running the agent; PR targets `ddev/coder-ddev:main` on GitHub. +**Project Type**: Documentation/governance change. No source code modifications. +**Performance Goals**: N/A. +**Constraints**: No edits outside `kitty-specs/workspace-runtime-contract-01KRC8WY/`, `openspec/changes/add-workspace-runtime-contract/`, and the eventual PR body. Draft PR only. +**Scale/Scope**: One foundational spec, nine invariants, six drift items, one OpenSpec change. ## Charter Check -*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* +Charter directive #1 (respect risk boundaries) identifies image, template, and startup-script changes as high-risk. This mission **does not modify** any of those surfaces; it only describes them. Charter directive #2 (keep documentation synchronized) is partially satisfied: the spec captures the current contract, but `CLAUDE.md` reconciliation is deferred to a follow-up change (FR-010). No charter gate is violated. -[Gates determined based on charter file] +**Quality gates (from charter):** +- All changes via PR — satisfied. +- `terraform fmt -check` — satisfied (no HCL touched). +- `terraform validate` — satisfied (no HCL touched). +- `terraform test` — N/A (no HCL touched). +- Staging integration tests — N/A (no runtime behavior changes). ## Project Structure -### Documentation (this feature) +### Documentation (this mission) ``` -kitty-specs/[###-feature]/ -├── plan.md # This file (/spec-kitty.plan command output) -├── research.md # Phase 0 output (/spec-kitty.plan command) -├── data-model.md # Phase 1 output (/spec-kitty.plan command) -├── quickstart.md # Phase 1 output (/spec-kitty.plan command) -├── contracts/ # Phase 1 output (/spec-kitty.plan command) -└── tasks.md # Phase 2 output (/spec-kitty.tasks command - NOT created by /spec-kitty.plan) +kitty-specs/workspace-runtime-contract-01KRC8WY/ +├── spec.md # Mission specification (filled) +├── plan.md # This file +├── research.md # Decisions + drift catalog (filled) +├── data-model.md # INV-1…INV-9 entities + coverage matrix (filled) +├── research/ +│ ├── evidence-log.csv # Invariant → file/line evidence (filled) +│ └── source-register.csv# Source files used in synthesis (filled) +├── tasks.md # WP manifest (next phase output) +├── wps.yaml # Work package list (next phase output) +├── lanes.json # Lane allocation (next phase output) +├── tasks/ # Per-WP prompt files (next phase output) +├── meta.json # Mission identity + OpenSpec cross-link +└── mission-events.jsonl # Append-only event log ``` -### Source Code (repository root) - +### Change artifacts (OpenSpec — created during implement phase) ``` -# [REMOVE IF UNUSED] Option 1: Single project (DEFAULT) -src/ -├── models/ -├── services/ -├── cli/ -└── lib/ - -tests/ -├── contract/ -├── integration/ -└── unit/ - -# [REMOVE IF UNUSED] Option 2: Web application (when "frontend" + "backend" detected) -backend/ -├── src/ -│ ├── models/ -│ ├── services/ -│ └── api/ -└── tests/ - -frontend/ -├── src/ -│ ├── components/ -│ ├── pages/ -│ └── services/ -└── tests/ - -# [REMOVE IF UNUSED] Option 3: Mobile + API (when "iOS/Android" detected) -api/ -└── [same as backend above] - -ios/ or android/ -└── [platform-specific structure: feature modules, UI flows, platform tests] +openspec/changes/add-workspace-runtime-contract/ +├── proposal.md +├── design.md +├── tasks.md +└── specs/workspace-runtime/spec.md # The delta spec (ADDED Requirements x9) ``` -**Structure Decision**: [Document the selected structure and reference the real -directories captured above] +**Structure Decision**: This is a *documentation-and-governance* mission. There is no source-code structure to choose. The two artifact homes (`kitty-specs/...` and `openspec/changes/...`) are joined by cross-references; no third location is introduced. -## Complexity Tracking +## Phases + +### Phase 0 — Discovery (complete) +- Research artifacts populated from prior architectural analyses. +- Drift items D-1…D-6 cataloged as informational, not remediated here. + +### Phase 1 — Specify (complete) +- Mission `spec.md` written with FR-001…FR-010 and C-001…C-005. +- Cross-link plan recorded in research (mission → OpenSpec change-id via `source_description` plus link in `proposal.md`). + +### Phase 2 — Plan (this document) +- Confirm charter gates. +- Decide WP allocation (Phase 3 input). + +### Phase 3 — Tasks (next) +The mission needs three work packages, each scoped to a non-overlapping artifact tree: + +| WP | Title | Owned files | Depends on | +|----|-------|-------------|-----------| +| WP01 | Author OpenSpec proposal scaffold | `openspec/changes/add-workspace-runtime-contract/proposal.md`, `design.md`, `tasks.md` | — | +| WP02 | Author runtime-contract delta spec | `openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md` | WP01 | +| WP03 | Cross-link mission to OpenSpec + draft PR | `kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json` (extend `source_description`), PR body | WP01, WP02 | -*Fill ONLY if Charter Check has violations that must be justified* +Each WP carries an FR ref set drawn from FR-001…FR-010 above. None modifies image, template, script, or Makefile. + +### Phase 4 — Implement +- WPs executed sequentially (small dependency chain; parallelism not worthwhile). +- Each WP commits via Spec Kitty auto-commit on the mission branch. + +### Phase 5 — Review and Accept +- `openspec validate add-workspace-runtime-contract --strict` must pass. +- `terraform fmt -check -recursive` must pass (defensive — no HCL touched, but enforced). +- Spec Kitty `accept` step validates lane state. + +### Phase 6 — Merge (out of scope for this mission) +- A draft PR is opened against `upstream/main` (`ddev/coder-ddev:main`). +- Spec Kitty `merge` is **not** invoked — the PR remains draft until human reviewer approval. + +## Complexity Tracking | Violation | Why Needed | Simpler Alternative Rejected Because | |-----------|------------|-------------------------------------| -| [e.g., 4th project] | [current need] | [why 3 projects insufficient] | -| [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] | +| Two governance systems active (OpenSpec + Spec Kitty) | Repo already has both initialized; unifying would itself be a larger change | Forcing a single system now would block on a decision this mission is not authorized to make | +| Three WPs for a documentation-only mission | Each artifact tree must be edited independently; lane `write_scope` prevents overlap | Bundling would obscure provenance and break the lane model | + +## Risks + +- **Auto-commit conflicts** — Spec Kitty's `auto_commit: true` interacts with manual commits for OpenSpec artifacts. Mitigation: stage OpenSpec files explicitly before invoking Spec Kitty steps to keep auto-commits scoped. +- **CLI/project version drift** — already encountered (3.1.7 vs 3.1.8). Mitigation: upgrade resolved; document in research. +- **PR base** — branch was created from `upstream/main`; PR must target `ddev/coder-ddev:main`, not `jonesrussell/coder-ddev:main`. Mitigation: explicit `-R ddev/coder-ddev` in `gh pr create`. +- **Existing live mission** (`github-org-gated-signup-01KR1P4G`) is concurrent. Mitigation: separate branch (`spec-workspace-runtime-contract`) isolates auto-commits. + +## Done When + +- All three WPs in `done` or `approved` lane in `status.json`. +- `openspec validate add-workspace-runtime-contract --strict` is green. +- Draft PR open against `ddev/coder-ddev:main` with body referencing change-id and mission slug. +- No file under `image/`, `*/template.tf`, `*/scripts/`, or `Makefile` in the PR diff. diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/research.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/research.md new file mode 100644 index 0000000..6bbaa80 --- /dev/null +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/research.md @@ -0,0 +1,58 @@ +# Research — Workspace Runtime Contract + +## Purpose + +Synthesize the foundational runtime invariants of a `coder-ddev` workspace from three existing artifacts — `image/Dockerfile`, `user-defined-web/template.tf`, and the inlined `startup_script` — into a single descriptive-first spec named `workspace-runtime-contract`. + +This research is the **basis of evidence** for OpenSpec change `add-workspace-runtime-contract` and the Spec Kitty mission `workspace-runtime-contract-01KRC8WY`. No new behavior is proposed; every invariant maps to existing code. + +## Method + +1. Read each governing source end-to-end (image, template HCL, startup script, governance scaffolding) and produce per-source analyses. +2. Cross-reference the three sources for each candidate invariant. +3. Reject candidates that exist in only one source or that are aspirational rather than enforced. +4. Promote the remaining cross-referenced invariants into INV-1…INV-9. +5. Catalog known drift (cases where prose docs disagree with code) as D-1…D-6 — these are **not** part of the contract; they are tracked attachment points for follow-up changes. + +## Key Decisions + +| ID | Decision | Rationale | +|----|----------|-----------| +| D-RUNTIME | Adopt Sysbox-runc as the only supported container runtime for workspaces. | The HCL pins `runtime = "sysbox-runc"`; the script's manual `sudo dockerd &` only works safely under Sysbox; `--privileged` is explicitly avoided. | +| D-IDENT | Identity = `coder` (UID 1000), docker GID = 988 (parametric). | Image renames `ubuntu` → `coder`; HCL sets `user = "coder"` and `group_add = [tostring(var.docker_gid)]`; agent env forces `HOME=/home/coder`. | +| D-SUDO | NOPASSWD sudo is load-bearing, not optional. | Required by `dockerd &`, `chown /home/coder`, `tee /etc/docker/daemon.json`, `chmod /var/run/docker.sock`. Removing it breaks every boot. | +| D-DAEMON | dockerd is started manually by the agent (`sudo dockerd &`), not by systemd-as-PID-1. | Image enables the systemd unit but the container's PID 1 is `sh -c $CODER_AGENT_INIT_SCRIPT`. Two start models coexist; only the manual path is exercised. | +| D-VOLUMES | Two-volume model: host bind for `/home/coder` + named volume for `/var/lib/docker`. No host docker socket mount. | HCL `volumes` + `mounts` blocks; comment explicitly forbids socket mount; named volume survives container replacement, bind survives workspace restart. | +| D-HYDRATION | "Copy-if-missing, append-if-missing" hydration from `/home/coder-files`. | Bind mount shadows image content; idempotent boot is required because the script re-runs every start; user state must survive. | +| D-ROUTING | Direct-bind on `localhost:80`, ddev-router globally omitted, one project at a time. | Documented in CLAUDE.md and reflected in `coder_app.ddev-web`; `freeform` template is the explicit deviation and has its own contract. | +| D-CLEANUP | Workspace delete must remove `/coder-workspaces/-` via host-side `coder-delete-workspace-dir` invoked from `null_resource.workspace_cleanup`. | Otherwise host directories orphan; Docker named volume is auto-cleaned by Terraform; bind dir is not. | +| D-IDSRC | Workspace identity is sourced from `coder_agent.env`, not the container hostname. | Hostname = `-`; container name = `coder-`. Script's hostname heuristic is defense-in-depth only. | + +## Known Drift (D-1…D-6) — Tracked, Not Resolved Here + +| ID | Drift | Where | +|----|-------|-------| +| D-1 | `image/scripts/.ddev/global_config.yaml` referenced by CLAUDE.md but missing from image tree. | `CLAUDE.md` "Architecture" + `image/scripts/.ddev/` listing | +| D-2 | `.ddev/commands/host/{launch,coder-routes,coder-setup}` shipped but never copied by `user-defined-web` startup. | `image/scripts/.ddev/commands/host/` vs. `user-defined-web/template.tf:295-340` | +| D-3 | `coder-setup` lacks explicit `chmod 755` in image build. | `image/Dockerfile:189-195` | +| D-4 | Dual dockerd-start models (manual + systemd unit enabled). | `image/Dockerfile:118` + script `dockerd &` | +| D-5 | `chmod 666 /var/run/docker.sock` is broader than needed given `group_add = 988`. | Script line ~422 | +| D-6 | `image_version` is a single tag across all four templates; per-template pinning unsupported. | `VERSION` + template `local.image_version` | + +## Open Questions (carried into planning) + +- Should D-1 (`global_config.yaml`) be remediated in a follow-up OpenSpec change `restore-ddev-global-config` or rolled into a broader `template-contract` change? +- Should the systemd-as-init code path (D-4) be removed in a single image change or kept until a runtime contract v2 explicitly retires it? +- For Spec Kitty / OpenSpec linkage: persist `openspec_change_id` in mission `meta.json` (preferred) or only in `proposal.md` (lower coupling)? Recommendation: both. + +## Outputs + +- `kitty-specs/workspace-runtime-contract-01KRC8WY/spec.md` — mission spec describing this work. +- `kitty-specs/workspace-runtime-contract-01KRC8WY/data-model.md` — entities representing the 9 invariants. +- `openspec/changes/add-workspace-runtime-contract/` — proposal, tasks, design, delta spec (created in the `tasks` step). + +## Risks + +- **Spec text becomes stale** if `CLAUDE.md` or HCL drift after archive. Mitigation: descriptive-first language + Phase 4 CI drift check (out of scope here). +- **Pilot mission collision**: existing `github-org-gated-signup-01KR1P4G` mission is open. Spec Kitty allows concurrent missions but auto-commits may interleave. Mitigation: this mission runs on its own branch `spec-workspace-runtime-contract` from `upstream/main`. +- **Two governance systems** (OpenSpec + Spec Kitty) cohabit without enforcement. Mitigation: cross-link via `meta.json` and proposal body; CI gating reserved for Phase 4. diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/research/evidence-log.csv b/kitty-specs/workspace-runtime-contract-01KRC8WY/research/evidence-log.csv new file mode 100644 index 0000000..27ddaf2 --- /dev/null +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/research/evidence-log.csv @@ -0,0 +1,28 @@ +invariant,source_file,line_or_block,observation +INV-1,user-defined-web/template.tf,docker_container.workspace,runtime = "sysbox-runc" pinned; privileged = false; security_opts = ["apparmor:unconfined","seccomp:unconfined"] +INV-2,image/Dockerfile,user rename block,usermod -l coder -d /home/coder -m ubuntu; UID 1000 preserved +INV-2,user-defined-web/template.tf,docker_container.workspace,user = "coder"; group_add = [tostring(var.docker_gid)]; default 988 +INV-2,user-defined-web/template.tf,coder_agent.env,HOME = "/home/coder" forced +INV-3,image/Dockerfile,sudoers RUN,echo "coder ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/coder; chmod 0440 +INV-3,user-defined-web/template.tf,startup_script,uses sudo for chown/tee/dockerd/chmod without prompts +INV-4,image/Dockerfile,docker-ce install,docker-ce + docker-ce-cli + containerd.io installed; systemctl enable docker (unused at runtime) +INV-4,user-defined-web/template.tf,startup_script,sudo dockerd > /tmp/dockerd.log 2>&1 &; polls /var/run/docker.sock; chmod 666 on success +INV-4,user-defined-web/template.tf,docker_container.workspace,host /var/run/docker.sock is NOT mounted (explicit comment) +INV-5,user-defined-web/template.tf,docker_container.volumes,host_path /coder-workspaces/- -> /home/coder +INV-5,user-defined-web/template.tf,docker_container.mounts,named volume coder---dind-cache -> /var/lib/docker +INV-6,image/Dockerfile,COPY scripts /home/coder-files,stages WELCOME.txt vscode/settings.json gitconfig gitignore_global ddev/commands/host/* +INV-6,user-defined-web/template.tf,startup_script hydration block,copy-if-missing for WELCOME .vscode .gitconfig .gitignore_global +INV-7,image/Dockerfile,ddev install,DDEV from pkg.ddev.com (no global config baked) +INV-7,user-defined-web/template.tf,coder_app.ddev-web,url = http://localhost:80; subdomain = true; healthcheck on / +INV-7,CLAUDE.md,Template Architecture Overview,user-defined-web direct-bind port 80; ddev-router omitted globally +INV-8,user-defined-web/template.tf,null_resource.workspace_cleanup,destroy provisioner: sudo /usr/local/bin/coder-delete-workspace-dir '' +INV-8,user-defined-web/template.tf,docker_container.workspace,stop_signal SIGINT; stop_timeout 180; destroy_grace_seconds 60 +INV-8,user-defined-web/template.tf,coder_script.ddev_shutdown,run_on_stop = true; ddev poweroff with docker-socket race guard +INV-9,user-defined-web/template.tf,coder_agent.env,CODER_WORKSPACE_{ID NAME OWNER_NAME OWNER_EMAIL} injected +INV-9,user-defined-web/template.tf,docker_container.workspace,name = coder-; hostname = - (deliberately inverted) +D-1,CLAUDE.md,Architecture section,references image/scripts/.ddev/global_config.yaml which does not exist on disk +D-2,user-defined-web/template.tf,startup_script,does not copy /home/coder-files/.ddev/commands/host/* into ~/.ddev/commands/host/ +D-3,image/Dockerfile,chmod block after COPY scripts,coder-setup omitted from explicit chmod 755 list +D-4,image/Dockerfile,systemd + systemctl enable docker,dual dockerd start models coexist; only manual path used +D-5,user-defined-web/template.tf,startup_script socket section,chmod 666 broader than necessary given group_add 988 +D-6,VERSION + template.tf locals,image_version single source,no per-template image pinning supported diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/research/source-register.csv b/kitty-specs/workspace-runtime-contract-01KRC8WY/research/source-register.csv new file mode 100644 index 0000000..7755772 --- /dev/null +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/research/source-register.csv @@ -0,0 +1,15 @@ +source_id,path,kind,role +S-001,image/Dockerfile,repo file,Base image build; provides UID/GID identity sudo posture daemon binaries hydration staging +S-002,image/scripts/,repo dir,/home/coder-files staging tree (WELCOME settings gitconfig gitignore_global ddev/commands/host/*) +S-003,user-defined-web/template.tf,repo file,Terraform HCL: container resource agent script coder_app cleanup +S-004,user-defined-web/template.tf:startup_script,inline HEREDOC,Agent boot pipeline executed as coder on each start +S-005,CLAUDE.md,repo file,Authoritative developer/operator prose; source for routing model and conventions +S-006,openspec/project.md,repo file,Project conventions and constraints (Sysbox requirement diagnostic transparency) +S-007,.kittify/charter/charter.md,repo file,Project charter; testing standards quality gates risk boundaries +S-008,scripts/coder-delete-workspace-dir.sh,repo file,Host-side cleanup helper invoked by null_resource on destroy +S-009,Makefile,repo file,Image build push template push; VERSION propagation +S-010,drupal-core/template.tf,repo file,Cross-template reference: same runtime + hydration pattern +S-011,drupal-contrib/template.tf,repo file,Cross-template reference: same runtime + hydration pattern (port 8080) +S-012,freeform/template.tf,repo file,Deviation from INV-7: keeps ddev-router on 8080 with Host-header dispatch +S-013,coder-ddev README.md,repo file,Public template descriptions and deployment commands +S-014,VERSION,repo file,Single image tag source; per-template pinning not supported (D-6) diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/spec.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/spec.md index e69de29..3eb1166 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/spec.md +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/spec.md @@ -0,0 +1,82 @@ +# Workspace Runtime Contract + +## Summary + +Establish `workspace-runtime-contract` as the foundational Spec Kitty / OpenSpec specification for the `coder-ddev` repository. The contract codifies the nine load-bearing invariants of a Coder workspace provisioned from a `coder-ddev` template: Sysbox isolation, UID/GID identity, sudo posture, in-container `dockerd` lifecycle, two-volume persistence model, copy-if-missing hydration from `/home/coder-files`, single-project direct-bind web routing, host-aware cleanup, and env-sourced workspace identity. + +This mission delivers the contract as **proposal artifacts only** — no image, template, or script behavior changes. The spec is **descriptive-first**, extracted from current behavior in `image/Dockerfile`, `user-defined-web/template.tf`, and the inlined `startup_script`. It is the precondition for every later governance change in this repo. + +**Related work:** + +- OpenSpec change (drafted in this PR): `add-workspace-runtime-contract`. +- Charter directive #1 ("respect risk boundaries") names the surfaces this contract covers as high-risk. +- Known drift items D-1…D-6 are tracked inside `research.md` and remediated in **follow-up** OpenSpec changes, not in this mission. + +## Goals + +- Land the OpenSpec change `add-workspace-runtime-contract` with a full delta spec under `openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md`. +- Make `workspace-runtime-contract` the named dependency of every future template, image, or runtime spec. +- Document known drift (D-1…D-6) inside the research/spec so follow-up changes have a registered place to attach. +- Establish the convention that a Spec Kitty mission wraps an OpenSpec change (cross-linked via mission `meta.json` and the OpenSpec proposal body). + +## Non-Goals + +- No changes to `image/Dockerfile`, any `template.tf`, the inlined `startup_script`, or `Makefile`. +- No CI gate is added in this mission. CI integration is reserved for Phase 4 of the broader Spec Kitty adoption plan. +- No remediation of known drift items D-1…D-6; each gets its own OpenSpec proposal once the foundational spec is archived. +- No removal of the systemd-as-init code path in the image (forbidden by INV F-9 but retained pending a follow-up change). +- No reconciliation of `CLAUDE.md` architecture prose with the new spec; that follows after archive. + +## User Scenarios & Testing + +These scenarios describe agent and reviewer behavior the spec must enable, not workspace runtime behavior (which is already in place). + +**Scenario 1 — proposal author scaffolds compliantly:** +An agent invokes the `openspec-proposal` workflow with a change that modifies `image/Dockerfile`. The agent reads `workspace-runtime-contract`, identifies which invariants are touched, and writes a delta spec referencing the affected requirements by ID. + +**Scenario 2 — reviewer audits a template change:** +A reviewer opens a PR that edits `user-defined-web/template.tf`. The PR body links the OpenSpec change-id and the Spec Kitty mission slug. The reviewer reads the linked spec text and confirms each invariant is preserved or explicitly modified. + +**Scenario 3 — drift remediation is filed against the spec:** +A contributor notices that `image/scripts/.ddev/global_config.yaml` is missing (drift item D-1). They open a follow-up OpenSpec change `restore-ddev-global-config` that cites `workspace-runtime-contract` D-1 and adds a `MODIFIED Requirements` delta. + +**Scenario 4 — agent declines to write code at proposal stage:** +An agent receives this mission's WP01 prompt. It produces only `proposal.md`, `tasks.md`, `design.md`, and the spec delta — no edits to `image/`, `*/template.tf`, or `startup_script`. `openspec validate add-workspace-runtime-contract --strict` passes. + +**Scenario 5 — draft PR is created, not merged:** +The mission's final WP opens a **draft** pull request against `upstream/main`. The PR body links both the OpenSpec change-id and the Spec Kitty mission slug. No spec archive happens until the PR is merged. + +## Functional Requirements + +| ID | Requirement | Status | +| ---- | ------------- | -------- | +| FR-001 | An OpenSpec change directory `openspec/changes/add-workspace-runtime-contract/` exists with `proposal.md`, `tasks.md`, `design.md`, and a delta spec at `specs/workspace-runtime/spec.md`. | Approved | +| FR-002 | The delta spec defines nine `## ADDED Requirements` corresponding to invariants INV-1…INV-9 (Sysbox runtime, UID/GID identity, sudo posture, dockerd lifecycle, volume model, hydration model, routing model, cleanup model, identity model). Each requirement has at least one `#### Scenario:`. | Approved | +| FR-003 | The delta spec captures the required boot sequence and the forbidden-behavior set as scenario-bearing requirements. | Approved | +| FR-004 | The delta spec captures known drift items D-1…D-6 as a `## Known Drift` block (informational, not enforced), so follow-up OpenSpec changes have a registered attachment point. | Approved | +| FR-005 | `openspec validate add-workspace-runtime-contract --strict` passes. | Approved | +| FR-006 | The Spec Kitty mission `meta.json` carries a cross-link to `add-workspace-runtime-contract` (in `source_description`), and `proposal.md` carries a "Spec Kitty Mission" link pointing at this mission's slug. | Approved | +| FR-007 | No file under `image/`, `*/template.tf`, `*/scripts/`, or `Makefile` is modified by this mission. | Approved | +| FR-008 | `terraform fmt -recursive` reports no changes (the working tree must remain format-clean even though no HCL is touched). | Approved | +| FR-009 | A draft pull request is opened against `upstream/main`. The PR body references the OpenSpec change-id and the Spec Kitty mission slug. The PR is explicitly `--draft`, not ready-for-review. | Approved | +| FR-010 | `CLAUDE.md` is not modified in this mission. It is reconciled in a follow-up change after the foundational spec is archived. | Approved | + +## Constraints + +| ID | Constraint | +| ---- | ----------- | +| C-001 | The mission is **proposal-stage only**. No implementation work happens here. `.agent/workflows/openspec-proposal.md` is the governing runbook. | +| C-002 | The branch base is `upstream/main`, not `origin/main` (per `CLAUDE.md`). | +| C-003 | The PR is a draft. Merging is blocked until human review approves the spec text. | +| C-004 | The spec text is descriptive-first: every invariant must cite the file/block where it is currently enforced. No invariant may describe behavior that does not already exist in the repo. | +| C-005 | Drift items must be enumerated, never silently corrected. Remediation is out of scope. | + +## Acceptance + +The mission is acceptable when: + +1. `openspec validate add-workspace-runtime-contract --strict` is green. +2. `terraform fmt -recursive` reports zero changes. +3. The draft PR exists on `origin/spec-workspace-runtime-contract` targeting `ddev/coder-ddev:main`, body referencing the change-id and mission slug. +4. The Spec Kitty mission `status.json` reflects all WPs in the `approved` or `done` lane. +5. No file in `image/`, `*/template.tf`, `*/scripts/`, or `Makefile` is included in the PR diff. diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/wps.yaml b/kitty-specs/workspace-runtime-contract-01KRC8WY/wps.yaml new file mode 100644 index 0000000..f956f7c --- /dev/null +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/wps.yaml @@ -0,0 +1,63 @@ +work_packages: + - id: WP01 + title: "Author OpenSpec proposal scaffold for add-workspace-runtime-contract" + dependencies: [] + owned_files: + - "openspec/changes/add-workspace-runtime-contract/proposal.md" + - "openspec/changes/add-workspace-runtime-contract/design.md" + - "openspec/changes/add-workspace-runtime-contract/tasks.md" + requirement_refs: + - FR-001 + - FR-006 + - C-001 + - C-004 + subtasks: + - T001 + - T002 + - T003 + - T004 + prompt_file: "tasks/WP01-openspec-proposal-scaffold.md" + + - id: WP02 + title: "Author workspace-runtime delta spec with INV-1..INV-9 + drift catalog" + dependencies: + - WP01 + owned_files: + - "openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md" + requirement_refs: + - FR-002 + - FR-003 + - FR-004 + - FR-005 + - C-004 + - C-005 + subtasks: + - T005 + - T006 + - T007 + - T008 + - T009 + prompt_file: "tasks/WP02-runtime-contract-delta-spec.md" + + - id: WP03 + title: "Cross-link mission to OpenSpec change and open draft PR" + dependencies: + - WP01 + - WP02 + owned_files: + - "kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json" + requirement_refs: + - FR-006 + - FR-007 + - FR-008 + - FR-009 + - FR-010 + - C-002 + - C-003 + subtasks: + - T010 + - T011 + - T012 + - T013 + - T014 + prompt_file: "tasks/WP03-cross-link-and-draft-pr.md" From 19fa30617772aefe982690fd10a0fbd7dbd16a87 Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 May 2026 15:58:03 -0400 Subject: [PATCH 07/18] chore: WP01 claimed for implementation --- .../meta.json | 4 +++- .../status.events.jsonl | 2 ++ .../status.json | 18 +++++++++--------- .../tasks/WP01-openspec-proposal-scaffold.md | 4 ++++ 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json b/kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json index ee5e1b2..788739d 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json @@ -6,5 +6,7 @@ "mission_slug": "workspace-runtime-contract-01KRC8WY", "mission_type": "software-dev", "slug": "workspace-runtime-contract-01KRC8WY", - "target_branch": "spec-workspace-runtime-contract" + "target_branch": "spec-workspace-runtime-contract", + "vcs": "git", + "vcs_locked_at": "2026-05-11T19:58:02.673303+00:00" } diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl index 3fa5c63..4241411 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl @@ -1,3 +1,5 @@ {"actor": "finalize-tasks", "at": "2026-05-11T19:56:22.993859+00:00", "event_id": "01KRC9SCJH85MZASQG17059R7Y", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "planned", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "canonical bootstrap", "review_ref": null, "to_lane": "planned", "wp_id": "WP01"} {"actor": "finalize-tasks", "at": "2026-05-11T19:56:23.601699+00:00", "event_id": "01KRC9SD5HNAXWXBXE1ZY00Q8J", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "planned", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "canonical bootstrap", "review_ref": null, "to_lane": "planned", "wp_id": "WP02"} {"actor": "finalize-tasks", "at": "2026-05-11T19:56:23.646662+00:00", "event_id": "01KRC9SD6YAW6BGB30RAVV3Z0S", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "planned", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "canonical bootstrap", "review_ref": null, "to_lane": "planned", "wp_id": "WP03"} +{"actor": "implement-command", "at": "2026-05-11T19:58:02.716037+00:00", "event_id": "01KRC9WDYWG4W44PT6YRFSZYNS", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "planned", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP01"} +{"actor": "implement-command", "at": "2026-05-11T19:58:03.194268+00:00", "event_id": "01KRC9WEDT713EQD53DGHAPMQZ", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "claimed", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP01"} diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json index d5d16f3..3f46cb6 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json @@ -1,7 +1,7 @@ { - "event_count": 3, - "last_event_id": "01KRC9SD6YAW6BGB30RAVV3Z0S", - "materialized_at": "2026-05-11T19:56:23.646662+00:00", + "event_count": 5, + "last_event_id": "01KRC9WEDT713EQD53DGHAPMQZ", + "materialized_at": "2026-05-11T19:58:03.194268+00:00", "mission_number": "", "mission_slug": "workspace-runtime-contract-01KRC8WY", "mission_type": "software-dev", @@ -12,17 +12,17 @@ "claimed": 0, "done": 0, "for_review": 0, - "in_progress": 0, + "in_progress": 1, "in_review": 0, - "planned": 3 + "planned": 2 }, "work_packages": { "WP01": { - "actor": "finalize-tasks", + "actor": "implement-command", "force_count": 1, - "lane": "planned", - "last_event_id": "01KRC9SCJH85MZASQG17059R7Y", - "last_transition_at": "2026-05-11T19:56:22.993859+00:00" + "lane": "in_progress", + "last_event_id": "01KRC9WEDT713EQD53DGHAPMQZ", + "last_transition_at": "2026-05-11T19:58:03.194268+00:00" }, "WP02": { "actor": "finalize-tasks", diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md index d67f67c..ca7dde2 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md @@ -10,11 +10,15 @@ requirement_refs: planning_base_branch: spec-workspace-runtime-contract merge_target_branch: spec-workspace-runtime-contract branch_strategy: Planning artifacts for this feature were generated on spec-workspace-runtime-contract. During /spec-kitty.implement this WP may branch from a dependency-specific base, but completed changes must merge back into spec-workspace-runtime-contract unless the human explicitly redirects the landing branch. +base_branch: kitty/mission-workspace-runtime-contract-01KRC8WY +base_commit: 3634d6663736aef7a45502b30a2594f209a146ba +created_at: '2026-05-11T19:58:02.708020+00:00' subtasks: - T001 - T002 - T003 - T004 +shell_pid: '384815' history: [] authoritative_surface: openspec/changes/add-workspace-runtime-contract/ execution_mode: code_change From 1391d81514ee3ac559926d0ca0f3fedbe96ccc35 Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 May 2026 15:59:37 -0400 Subject: [PATCH 08/18] chore: Move WP01 to for_review on spec workspace [claude] --- .../status.events.jsonl | 1 + .../status.json | 20 +++++++++---------- .../tasks/WP01-openspec-proposal-scaffold.md | 7 ++++++- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl index 4241411..84ea5fe 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl @@ -3,3 +3,4 @@ {"actor": "finalize-tasks", "at": "2026-05-11T19:56:23.646662+00:00", "event_id": "01KRC9SD6YAW6BGB30RAVV3Z0S", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "planned", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "canonical bootstrap", "review_ref": null, "to_lane": "planned", "wp_id": "WP03"} {"actor": "implement-command", "at": "2026-05-11T19:58:02.716037+00:00", "event_id": "01KRC9WDYWG4W44PT6YRFSZYNS", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "planned", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP01"} {"actor": "implement-command", "at": "2026-05-11T19:58:03.194268+00:00", "event_id": "01KRC9WEDT713EQD53DGHAPMQZ", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "claimed", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP01"} +{"actor": "claude", "at": "2026-05-11T19:59:36.776074+00:00", "event_id": "01KRC9Z9T8D25K1BEVAWH0CBQQ", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "in_progress", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "WP01 OpenSpec scaffold complete in worktree", "review_ref": null, "to_lane": "for_review", "wp_id": "WP01"} diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json index 3f46cb6..7c5ae83 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json @@ -1,7 +1,7 @@ { - "event_count": 5, - "last_event_id": "01KRC9WEDT713EQD53DGHAPMQZ", - "materialized_at": "2026-05-11T19:58:03.194268+00:00", + "event_count": 6, + "last_event_id": "01KRC9Z9T8D25K1BEVAWH0CBQQ", + "materialized_at": "2026-05-11T19:59:36.776074+00:00", "mission_number": "", "mission_slug": "workspace-runtime-contract-01KRC8WY", "mission_type": "software-dev", @@ -11,18 +11,18 @@ "canceled": 0, "claimed": 0, "done": 0, - "for_review": 0, - "in_progress": 1, + "for_review": 1, + "in_progress": 0, "in_review": 0, "planned": 2 }, "work_packages": { "WP01": { - "actor": "implement-command", - "force_count": 1, - "lane": "in_progress", - "last_event_id": "01KRC9WEDT713EQD53DGHAPMQZ", - "last_transition_at": "2026-05-11T19:58:03.194268+00:00" + "actor": "claude", + "force_count": 2, + "lane": "for_review", + "last_event_id": "01KRC9Z9T8D25K1BEVAWH0CBQQ", + "last_transition_at": "2026-05-11T19:59:36.776074+00:00" }, "WP02": { "actor": "finalize-tasks", diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md index ca7dde2..e91fd11 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md @@ -18,7 +18,7 @@ subtasks: - T002 - T003 - T004 -shell_pid: '384815' +shell_pid: "385108" history: [] authoritative_surface: openspec/changes/add-workspace-runtime-contract/ execution_mode: code_change @@ -27,6 +27,7 @@ owned_files: - openspec/changes/add-workspace-runtime-contract/design.md - openspec/changes/add-workspace-runtime-contract/tasks.md tags: [] +agent: "claude" --- # WP01 — Author OpenSpec proposal scaffold for `add-workspace-runtime-contract` @@ -57,3 +58,7 @@ Create the OpenSpec change scaffold (proposal, design, tasks) for `add-workspace - `design.md` justifies descriptive-first + cohabitation. - `tasks.md` is in OpenSpec's expected checkbox format. - No file outside `openspec/changes/add-workspace-runtime-contract/` is modified. + +## Activity Log + +- 2026-05-11T19:59:37Z – claude – shell_pid=385108 – WP01 OpenSpec scaffold complete in worktree From d7868a511f9f45d4fe0f62e50f7a404a58ff7d8b Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 May 2026 15:59:46 -0400 Subject: [PATCH 09/18] chore: Move WP01 to approved on spec workspace [claude] --- .../status.events.jsonl | 2 ++ .../status.json | 16 ++++++++-------- .../tasks/WP01-openspec-proposal-scaffold.md | 1 + 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl index 84ea5fe..7c25613 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl @@ -4,3 +4,5 @@ {"actor": "implement-command", "at": "2026-05-11T19:58:02.716037+00:00", "event_id": "01KRC9WDYWG4W44PT6YRFSZYNS", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "planned", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP01"} {"actor": "implement-command", "at": "2026-05-11T19:58:03.194268+00:00", "event_id": "01KRC9WEDT713EQD53DGHAPMQZ", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "claimed", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP01"} {"actor": "claude", "at": "2026-05-11T19:59:36.776074+00:00", "event_id": "01KRC9Z9T8D25K1BEVAWH0CBQQ", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "in_progress", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "WP01 OpenSpec scaffold complete in worktree", "review_ref": null, "to_lane": "for_review", "wp_id": "WP01"} +{"actor": "claude", "at": "2026-05-11T19:59:45.846191+00:00", "event_id": "01KRC9ZJNPHSJFXA8MF0GV8X3E", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "for_review", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "Self-review: scaffolds match WP01 owned_files; no out-of-scope edits", "review_ref": null, "to_lane": "in_review", "wp_id": "WP01"} +{"actor": "claude", "at": "2026-05-11T19:59:46.267072+00:00", "event_id": "01KRC9ZK2VGD5S0A6T29W489NH", "evidence": {"review": {"reference": "Self-review: scaffolds match WP01 owned_files; no out-of-scope edits", "reviewer": "claude", "verdict": "approved"}}, "execution_mode": "worktree", "force": false, "from_lane": "in_review", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "Self-review: scaffolds match WP01 owned_files; no out-of-scope edits", "review_ref": null, "to_lane": "approved", "wp_id": "WP01"} diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json index 7c5ae83..cbd885c 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json @@ -1,17 +1,17 @@ { - "event_count": 6, - "last_event_id": "01KRC9Z9T8D25K1BEVAWH0CBQQ", - "materialized_at": "2026-05-11T19:59:36.776074+00:00", + "event_count": 8, + "last_event_id": "01KRC9ZK2VGD5S0A6T29W489NH", + "materialized_at": "2026-05-11T19:59:46.267072+00:00", "mission_number": "", "mission_slug": "workspace-runtime-contract-01KRC8WY", "mission_type": "software-dev", "summary": { - "approved": 0, + "approved": 1, "blocked": 0, "canceled": 0, "claimed": 0, "done": 0, - "for_review": 1, + "for_review": 0, "in_progress": 0, "in_review": 0, "planned": 2 @@ -20,9 +20,9 @@ "WP01": { "actor": "claude", "force_count": 2, - "lane": "for_review", - "last_event_id": "01KRC9Z9T8D25K1BEVAWH0CBQQ", - "last_transition_at": "2026-05-11T19:59:36.776074+00:00" + "lane": "approved", + "last_event_id": "01KRC9ZK2VGD5S0A6T29W489NH", + "last_transition_at": "2026-05-11T19:59:46.267072+00:00" }, "WP02": { "actor": "finalize-tasks", diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md index e91fd11..9395013 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP01-openspec-proposal-scaffold.md @@ -62,3 +62,4 @@ Create the OpenSpec change scaffold (proposal, design, tasks) for `add-workspace ## Activity Log - 2026-05-11T19:59:37Z – claude – shell_pid=385108 – WP01 OpenSpec scaffold complete in worktree +- 2026-05-11T19:59:46Z – claude – shell_pid=385108 – Self-review: scaffolds match WP01 owned_files; no out-of-scope edits From 3b5ea170b84d4088c103c0ba62337e2252a836f2 Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 May 2026 16:00:25 -0400 Subject: [PATCH 10/18] chore: planning artifacts for workspace-runtime-contract-01KRC8WY Auto-committed by spec-kitty before creating the lane worktree for WP02 --- .../workspace-runtime-contract-01KRC8WY/mission-events.jsonl | 1 + 1 file changed, 1 insertion(+) diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/mission-events.jsonl b/kitty-specs/workspace-runtime-contract-01KRC8WY/mission-events.jsonl index e048094..8a74a3c 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/mission-events.jsonl +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/mission-events.jsonl @@ -7,3 +7,4 @@ {"mission": "software-dev", "payload": {"action": "tasks-packages", "agent": "claude", "decision_kind": "step", "mission_state": "tasks_packages", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-11T19:56:30.947002+00:00", "type": "MissionNextInvoked"} {"mission": "software-dev", "payload": {"action": "tasks-finalize", "agent": "claude", "decision_kind": "step", "mission_state": "tasks_finalize", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-11T19:56:37.906018+00:00", "type": "MissionNextInvoked"} {"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP01"}, "timestamp": "2026-05-11T19:57:39.984042+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP02"}, "timestamp": "2026-05-11T20:00:05.857224+00:00", "type": "MissionNextInvoked"} From 03fbbfc7acfb08921527998ed3ba1011833378fb Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 May 2026 16:00:27 -0400 Subject: [PATCH 11/18] chore: WP02 claimed for implementation --- .../status.events.jsonl | 2 ++ .../status.json | 18 +++++++++--------- .../tasks/WP02-runtime-contract-delta-spec.md | 1 + 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl index 7c25613..3870441 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl @@ -6,3 +6,5 @@ {"actor": "claude", "at": "2026-05-11T19:59:36.776074+00:00", "event_id": "01KRC9Z9T8D25K1BEVAWH0CBQQ", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "in_progress", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "WP01 OpenSpec scaffold complete in worktree", "review_ref": null, "to_lane": "for_review", "wp_id": "WP01"} {"actor": "claude", "at": "2026-05-11T19:59:45.846191+00:00", "event_id": "01KRC9ZJNPHSJFXA8MF0GV8X3E", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "for_review", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "Self-review: scaffolds match WP01 owned_files; no out-of-scope edits", "review_ref": null, "to_lane": "in_review", "wp_id": "WP01"} {"actor": "claude", "at": "2026-05-11T19:59:46.267072+00:00", "event_id": "01KRC9ZK2VGD5S0A6T29W489NH", "evidence": {"review": {"reference": "Self-review: scaffolds match WP01 owned_files; no out-of-scope edits", "reviewer": "claude", "verdict": "approved"}}, "execution_mode": "worktree", "force": false, "from_lane": "in_review", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "Self-review: scaffolds match WP01 owned_files; no out-of-scope edits", "review_ref": null, "to_lane": "approved", "wp_id": "WP01"} +{"actor": "implement-command", "at": "2026-05-11T20:00:26.596481+00:00", "event_id": "01KRCA0TF4M52TRQN5YTWAX4K9", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "planned", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP02"} +{"actor": "implement-command", "at": "2026-05-11T20:00:26.999050+00:00", "event_id": "01KRCA0TVQ9G6P2W2Z9GJNNPQ7", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "claimed", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP02"} diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json index cbd885c..54bfad1 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json @@ -1,7 +1,7 @@ { - "event_count": 8, - "last_event_id": "01KRC9ZK2VGD5S0A6T29W489NH", - "materialized_at": "2026-05-11T19:59:46.267072+00:00", + "event_count": 10, + "last_event_id": "01KRCA0TVQ9G6P2W2Z9GJNNPQ7", + "materialized_at": "2026-05-11T20:00:26.999050+00:00", "mission_number": "", "mission_slug": "workspace-runtime-contract-01KRC8WY", "mission_type": "software-dev", @@ -12,9 +12,9 @@ "claimed": 0, "done": 0, "for_review": 0, - "in_progress": 0, + "in_progress": 1, "in_review": 0, - "planned": 2 + "planned": 1 }, "work_packages": { "WP01": { @@ -25,11 +25,11 @@ "last_transition_at": "2026-05-11T19:59:46.267072+00:00" }, "WP02": { - "actor": "finalize-tasks", + "actor": "implement-command", "force_count": 1, - "lane": "planned", - "last_event_id": "01KRC9SD5HNAXWXBXE1ZY00Q8J", - "last_transition_at": "2026-05-11T19:56:23.601699+00:00" + "lane": "in_progress", + "last_event_id": "01KRCA0TVQ9G6P2W2Z9GJNNPQ7", + "last_transition_at": "2026-05-11T20:00:26.999050+00:00" }, "WP03": { "actor": "finalize-tasks", diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md index d70fdac..bb25884 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md @@ -19,6 +19,7 @@ subtasks: - T007 - T008 - T009 +shell_pid: '385375' history: [] authoritative_surface: openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md execution_mode: code_change From 0284df0e07ada262ca24fe012c1327ffdf990a47 Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 May 2026 16:02:17 -0400 Subject: [PATCH 12/18] chore: Move WP02 to for_review on spec workspace [claude] --- .../status.events.jsonl | 1 + .../status.json | 20 +++++++++---------- .../tasks/WP02-runtime-contract-delta-spec.md | 7 ++++++- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl index 3870441..485f167 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl @@ -8,3 +8,4 @@ {"actor": "claude", "at": "2026-05-11T19:59:46.267072+00:00", "event_id": "01KRC9ZK2VGD5S0A6T29W489NH", "evidence": {"review": {"reference": "Self-review: scaffolds match WP01 owned_files; no out-of-scope edits", "reviewer": "claude", "verdict": "approved"}}, "execution_mode": "worktree", "force": false, "from_lane": "in_review", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "Self-review: scaffolds match WP01 owned_files; no out-of-scope edits", "review_ref": null, "to_lane": "approved", "wp_id": "WP01"} {"actor": "implement-command", "at": "2026-05-11T20:00:26.596481+00:00", "event_id": "01KRCA0TF4M52TRQN5YTWAX4K9", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "planned", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP02"} {"actor": "implement-command", "at": "2026-05-11T20:00:26.999050+00:00", "event_id": "01KRCA0TVQ9G6P2W2Z9GJNNPQ7", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "claimed", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP02"} +{"actor": "claude", "at": "2026-05-11T20:02:16.508846+00:00", "event_id": "01KRCA45SWTHTRK7CSFZFVWYS9", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "in_progress", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "WP02 delta spec authored, openspec validate --strict green", "review_ref": null, "to_lane": "for_review", "wp_id": "WP02"} diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json index 54bfad1..0f8ec44 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json @@ -1,7 +1,7 @@ { - "event_count": 10, - "last_event_id": "01KRCA0TVQ9G6P2W2Z9GJNNPQ7", - "materialized_at": "2026-05-11T20:00:26.999050+00:00", + "event_count": 11, + "last_event_id": "01KRCA45SWTHTRK7CSFZFVWYS9", + "materialized_at": "2026-05-11T20:02:16.508846+00:00", "mission_number": "", "mission_slug": "workspace-runtime-contract-01KRC8WY", "mission_type": "software-dev", @@ -11,8 +11,8 @@ "canceled": 0, "claimed": 0, "done": 0, - "for_review": 0, - "in_progress": 1, + "for_review": 1, + "in_progress": 0, "in_review": 0, "planned": 1 }, @@ -25,11 +25,11 @@ "last_transition_at": "2026-05-11T19:59:46.267072+00:00" }, "WP02": { - "actor": "implement-command", - "force_count": 1, - "lane": "in_progress", - "last_event_id": "01KRCA0TVQ9G6P2W2Z9GJNNPQ7", - "last_transition_at": "2026-05-11T20:00:26.999050+00:00" + "actor": "claude", + "force_count": 2, + "lane": "for_review", + "last_event_id": "01KRCA45SWTHTRK7CSFZFVWYS9", + "last_transition_at": "2026-05-11T20:02:16.508846+00:00" }, "WP03": { "actor": "finalize-tasks", diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md index bb25884..d9a353e 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md @@ -19,13 +19,14 @@ subtasks: - T007 - T008 - T009 -shell_pid: '385375' +shell_pid: "385715" history: [] authoritative_surface: openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md execution_mode: code_change owned_files: - openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md tags: [] +agent: "claude" --- # WP02 — Author the runtime-contract delta spec @@ -56,3 +57,7 @@ Write the OpenSpec delta spec for capability `workspace-runtime` with nine `## A - `openspec validate add-workspace-runtime-contract --strict` is green. - Each `ADDED Requirement` has at least one `#### Scenario:`. - Drift block is clearly labeled informational and cites the relevant source files. + +## Activity Log + +- 2026-05-11T20:02:17Z – claude – shell_pid=385715 – WP02 delta spec authored, openspec validate --strict green From 93bc0f1f9fba8549dd46e7e0dbd341c0ac600b98 Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 May 2026 16:02:18 -0400 Subject: [PATCH 13/18] chore: Move WP02 to approved on spec workspace [claude] --- .../status.events.jsonl | 2 ++ .../status.json | 16 ++++++++-------- .../tasks/WP02-runtime-contract-delta-spec.md | 1 + 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl index 485f167..2c6d129 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl @@ -9,3 +9,5 @@ {"actor": "implement-command", "at": "2026-05-11T20:00:26.596481+00:00", "event_id": "01KRCA0TF4M52TRQN5YTWAX4K9", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "planned", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP02"} {"actor": "implement-command", "at": "2026-05-11T20:00:26.999050+00:00", "event_id": "01KRCA0TVQ9G6P2W2Z9GJNNPQ7", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "claimed", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP02"} {"actor": "claude", "at": "2026-05-11T20:02:16.508846+00:00", "event_id": "01KRCA45SWTHTRK7CSFZFVWYS9", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "in_progress", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "WP02 delta spec authored, openspec validate --strict green", "review_ref": null, "to_lane": "for_review", "wp_id": "WP02"} +{"actor": "claude", "at": "2026-05-11T20:02:18.268807+00:00", "event_id": "01KRCA47GWMF2HXXM3A10XJZ51", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "for_review", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "Self-review: 9 ADDED reqs, all with scenarios; drift block informational; validation green", "review_ref": null, "to_lane": "in_review", "wp_id": "WP02"} +{"actor": "claude", "at": "2026-05-11T20:02:18.714471+00:00", "event_id": "01KRCA47YT3C9CY607C8N22HWD", "evidence": {"review": {"reference": "Self-review: 9 ADDED reqs, all with scenarios; drift block informational; validation green", "reviewer": "claude", "verdict": "approved"}}, "execution_mode": "worktree", "force": false, "from_lane": "in_review", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "Self-review: 9 ADDED reqs, all with scenarios; drift block informational; validation green", "review_ref": null, "to_lane": "approved", "wp_id": "WP02"} diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json index 0f8ec44..ec3b154 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json @@ -1,17 +1,17 @@ { - "event_count": 11, - "last_event_id": "01KRCA45SWTHTRK7CSFZFVWYS9", - "materialized_at": "2026-05-11T20:02:16.508846+00:00", + "event_count": 13, + "last_event_id": "01KRCA47YT3C9CY607C8N22HWD", + "materialized_at": "2026-05-11T20:02:18.714471+00:00", "mission_number": "", "mission_slug": "workspace-runtime-contract-01KRC8WY", "mission_type": "software-dev", "summary": { - "approved": 1, + "approved": 2, "blocked": 0, "canceled": 0, "claimed": 0, "done": 0, - "for_review": 1, + "for_review": 0, "in_progress": 0, "in_review": 0, "planned": 1 @@ -27,9 +27,9 @@ "WP02": { "actor": "claude", "force_count": 2, - "lane": "for_review", - "last_event_id": "01KRCA45SWTHTRK7CSFZFVWYS9", - "last_transition_at": "2026-05-11T20:02:16.508846+00:00" + "lane": "approved", + "last_event_id": "01KRCA47YT3C9CY607C8N22HWD", + "last_transition_at": "2026-05-11T20:02:18.714471+00:00" }, "WP03": { "actor": "finalize-tasks", diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md index d9a353e..8d1aebf 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP02-runtime-contract-delta-spec.md @@ -61,3 +61,4 @@ Write the OpenSpec delta spec for capability `workspace-runtime` with nine `## A ## Activity Log - 2026-05-11T20:02:17Z – claude – shell_pid=385715 – WP02 delta spec authored, openspec validate --strict green +- 2026-05-11T20:02:18Z – claude – shell_pid=385715 – Self-review: 9 ADDED reqs, all with scenarios; drift block informational; validation green From 00bd4b9f604b401277a57bc4df107369e8e58558 Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 May 2026 16:02:26 -0400 Subject: [PATCH 14/18] chore: WP03 claimed for implementation --- .../status.events.jsonl | 2 ++ .../status.json | 18 +++++++++--------- .../tasks/WP03-cross-link-and-draft-pr.md | 1 + 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl index 2c6d129..6f696f1 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl @@ -11,3 +11,5 @@ {"actor": "claude", "at": "2026-05-11T20:02:16.508846+00:00", "event_id": "01KRCA45SWTHTRK7CSFZFVWYS9", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "in_progress", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "WP02 delta spec authored, openspec validate --strict green", "review_ref": null, "to_lane": "for_review", "wp_id": "WP02"} {"actor": "claude", "at": "2026-05-11T20:02:18.268807+00:00", "event_id": "01KRCA47GWMF2HXXM3A10XJZ51", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "for_review", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "Self-review: 9 ADDED reqs, all with scenarios; drift block informational; validation green", "review_ref": null, "to_lane": "in_review", "wp_id": "WP02"} {"actor": "claude", "at": "2026-05-11T20:02:18.714471+00:00", "event_id": "01KRCA47YT3C9CY607C8N22HWD", "evidence": {"review": {"reference": "Self-review: 9 ADDED reqs, all with scenarios; drift block informational; validation green", "reviewer": "claude", "verdict": "approved"}}, "execution_mode": "worktree", "force": false, "from_lane": "in_review", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "Self-review: 9 ADDED reqs, all with scenarios; drift block informational; validation green", "review_ref": null, "to_lane": "approved", "wp_id": "WP02"} +{"actor": "implement-command", "at": "2026-05-11T20:02:25.676577+00:00", "event_id": "01KRCA4ERC71NHF7137CY3HG9Y", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "planned", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP03"} +{"actor": "implement-command", "at": "2026-05-11T20:02:26.119282+00:00", "event_id": "01KRCA4F67EGXFGSBKAD4XC2JE", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "claimed", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP03"} diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json index ec3b154..6c647e5 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json @@ -1,7 +1,7 @@ { - "event_count": 13, - "last_event_id": "01KRCA47YT3C9CY607C8N22HWD", - "materialized_at": "2026-05-11T20:02:18.714471+00:00", + "event_count": 15, + "last_event_id": "01KRCA4F67EGXFGSBKAD4XC2JE", + "materialized_at": "2026-05-11T20:02:26.119282+00:00", "mission_number": "", "mission_slug": "workspace-runtime-contract-01KRC8WY", "mission_type": "software-dev", @@ -12,9 +12,9 @@ "claimed": 0, "done": 0, "for_review": 0, - "in_progress": 0, + "in_progress": 1, "in_review": 0, - "planned": 1 + "planned": 0 }, "work_packages": { "WP01": { @@ -32,11 +32,11 @@ "last_transition_at": "2026-05-11T20:02:18.714471+00:00" }, "WP03": { - "actor": "finalize-tasks", + "actor": "implement-command", "force_count": 1, - "lane": "planned", - "last_event_id": "01KRC9SD6YAW6BGB30RAVV3Z0S", - "last_transition_at": "2026-05-11T19:56:23.646662+00:00" + "lane": "in_progress", + "last_event_id": "01KRCA4F67EGXFGSBKAD4XC2JE", + "last_transition_at": "2026-05-11T20:02:26.119282+00:00" } } } diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md index 665c60a..9575e0c 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md @@ -21,6 +21,7 @@ subtasks: - T012 - T013 - T014 +shell_pid: '385833' history: [] authoritative_surface: kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json execution_mode: code_change From 52884356c8b667bcff4f3f70eea23181c27c2043 Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 May 2026 16:05:27 -0400 Subject: [PATCH 15/18] chore: Move WP03 to for_review on spec workspace [claude] --- .../status.events.jsonl | 1 + .../status.json | 20 +++++++++---------- .../tasks/WP03-cross-link-and-draft-pr.md | 7 ++++++- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl index 6f696f1..1882708 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl @@ -13,3 +13,4 @@ {"actor": "claude", "at": "2026-05-11T20:02:18.714471+00:00", "event_id": "01KRCA47YT3C9CY607C8N22HWD", "evidence": {"review": {"reference": "Self-review: 9 ADDED reqs, all with scenarios; drift block informational; validation green", "reviewer": "claude", "verdict": "approved"}}, "execution_mode": "worktree", "force": false, "from_lane": "in_review", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "Self-review: 9 ADDED reqs, all with scenarios; drift block informational; validation green", "review_ref": null, "to_lane": "approved", "wp_id": "WP02"} {"actor": "implement-command", "at": "2026-05-11T20:02:25.676577+00:00", "event_id": "01KRCA4ERC71NHF7137CY3HG9Y", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "planned", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP03"} {"actor": "implement-command", "at": "2026-05-11T20:02:26.119282+00:00", "event_id": "01KRCA4F67EGXFGSBKAD4XC2JE", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "claimed", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP03"} +{"actor": "claude", "at": "2026-05-11T20:05:25.916171+00:00", "event_id": "01KRCA9YRWWAVBPF4PC6M02HKF", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "in_progress", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "Force move to for_review", "review_ref": null, "to_lane": "for_review", "wp_id": "WP03"} diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json index 6c647e5..68e1606 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json @@ -1,7 +1,7 @@ { - "event_count": 15, - "last_event_id": "01KRCA4F67EGXFGSBKAD4XC2JE", - "materialized_at": "2026-05-11T20:02:26.119282+00:00", + "event_count": 16, + "last_event_id": "01KRCA9YRWWAVBPF4PC6M02HKF", + "materialized_at": "2026-05-11T20:05:25.916171+00:00", "mission_number": "", "mission_slug": "workspace-runtime-contract-01KRC8WY", "mission_type": "software-dev", @@ -11,8 +11,8 @@ "canceled": 0, "claimed": 0, "done": 0, - "for_review": 0, - "in_progress": 1, + "for_review": 1, + "in_progress": 0, "in_review": 0, "planned": 0 }, @@ -32,11 +32,11 @@ "last_transition_at": "2026-05-11T20:02:18.714471+00:00" }, "WP03": { - "actor": "implement-command", - "force_count": 1, - "lane": "in_progress", - "last_event_id": "01KRCA4F67EGXFGSBKAD4XC2JE", - "last_transition_at": "2026-05-11T20:02:26.119282+00:00" + "actor": "claude", + "force_count": 2, + "lane": "for_review", + "last_event_id": "01KRCA9YRWWAVBPF4PC6M02HKF", + "last_transition_at": "2026-05-11T20:05:25.916171+00:00" } } } diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md index 9575e0c..bf15f86 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md @@ -21,13 +21,14 @@ subtasks: - T012 - T013 - T014 -shell_pid: '385833' +shell_pid: "386142" history: [] authoritative_surface: kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json execution_mode: code_change owned_files: - kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json tags: [] +agent: "claude" --- # WP03 — Cross-link mission to OpenSpec and open draft PR @@ -57,3 +58,7 @@ Bind the Spec Kitty mission and the OpenSpec change with bidirectional reference - `terraform fmt -recursive` clean. - Draft PR exists on `ddev/coder-ddev:main`. PR URL captured in the WP completion notes. - No file under `image/`, `*/template.tf`, `*/scripts/`, or `Makefile` in the PR diff. + +## Activity Log + +- 2026-05-11T20:05:27Z – claude – shell_pid=386142 – Moved to for_review From 8541700c001b1c33fd9cfcc2988584310b3aa910 Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 May 2026 16:05:54 -0400 Subject: [PATCH 16/18] chore: Move WP03 to approved on spec workspace [claude] --- .../status.events.jsonl | 2 ++ .../status.json | 16 ++++++++-------- .../tasks/WP03-cross-link-and-draft-pr.md | 1 + 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl index 1882708..b08ed19 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.events.jsonl @@ -14,3 +14,5 @@ {"actor": "implement-command", "at": "2026-05-11T20:02:25.676577+00:00", "event_id": "01KRCA4ERC71NHF7137CY3HG9Y", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "planned", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP03"} {"actor": "implement-command", "at": "2026-05-11T20:02:26.119282+00:00", "event_id": "01KRCA4F67EGXFGSBKAD4XC2JE", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "claimed", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP03"} {"actor": "claude", "at": "2026-05-11T20:05:25.916171+00:00", "event_id": "01KRCA9YRWWAVBPF4PC6M02HKF", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "in_progress", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "Force move to for_review", "review_ref": null, "to_lane": "for_review", "wp_id": "WP03"} +{"actor": "claude", "at": "2026-05-11T20:05:50.038970+00:00", "event_id": "01KRCAAPAP5KZTDXGA2J9Z5RK1", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "for_review", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "Lane branch cleaned; cross-link will be applied on PR branch (spec-workspace-runtime-contract)", "review_ref": null, "to_lane": "in_review", "wp_id": "WP03"} +{"actor": "claude", "at": "2026-05-11T20:05:54.230327+00:00", "event_id": "01KRCAATDPXBVPZH6SAWPBS5MP", "evidence": {"review": {"reference": "Lane branch cleaned; cross-link will be applied on PR branch (spec-workspace-runtime-contract)", "reviewer": "claude", "verdict": "approved"}}, "execution_mode": "worktree", "force": false, "from_lane": "in_review", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", "mission_slug": "workspace-runtime-contract-01KRC8WY", "policy_metadata": null, "reason": "Lane branch cleaned; cross-link will be applied on PR branch (spec-workspace-runtime-contract)", "review_ref": null, "to_lane": "approved", "wp_id": "WP03"} diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json index 68e1606..9d34d2b 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/status.json @@ -1,17 +1,17 @@ { - "event_count": 16, - "last_event_id": "01KRCA9YRWWAVBPF4PC6M02HKF", - "materialized_at": "2026-05-11T20:05:25.916171+00:00", + "event_count": 18, + "last_event_id": "01KRCAATDPXBVPZH6SAWPBS5MP", + "materialized_at": "2026-05-11T20:05:54.230327+00:00", "mission_number": "", "mission_slug": "workspace-runtime-contract-01KRC8WY", "mission_type": "software-dev", "summary": { - "approved": 2, + "approved": 3, "blocked": 0, "canceled": 0, "claimed": 0, "done": 0, - "for_review": 1, + "for_review": 0, "in_progress": 0, "in_review": 0, "planned": 0 @@ -34,9 +34,9 @@ "WP03": { "actor": "claude", "force_count": 2, - "lane": "for_review", - "last_event_id": "01KRCA9YRWWAVBPF4PC6M02HKF", - "last_transition_at": "2026-05-11T20:05:25.916171+00:00" + "lane": "approved", + "last_event_id": "01KRCAATDPXBVPZH6SAWPBS5MP", + "last_transition_at": "2026-05-11T20:05:54.230327+00:00" } } } diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md index bf15f86..421eb0e 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/tasks/WP03-cross-link-and-draft-pr.md @@ -62,3 +62,4 @@ Bind the Spec Kitty mission and the OpenSpec change with bidirectional reference ## Activity Log - 2026-05-11T20:05:27Z – claude – shell_pid=386142 – Moved to for_review +- 2026-05-11T20:05:54Z – claude – shell_pid=386142 – Lane branch cleaned; cross-link will be applied on PR branch (spec-workspace-runtime-contract) From a8759ba609d165b6236b614d66dbffbcec80bec0 Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 May 2026 16:06:03 -0400 Subject: [PATCH 17/18] feat(kitty/mission-workspace-runtime-contract-01KRC8WY): squash merge of mission --- .../meta.json | 2 +- .../add-workspace-runtime-contract/design.md | 45 ++++ .../proposal.md | 31 +++ .../specs/workspace-runtime/spec.md | 218 ++++++++++++++++++ .../add-workspace-runtime-contract/tasks.md | 24 ++ 5 files changed, 319 insertions(+), 1 deletion(-) create mode 100644 openspec/changes/add-workspace-runtime-contract/design.md create mode 100644 openspec/changes/add-workspace-runtime-contract/proposal.md create mode 100644 openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md create mode 100644 openspec/changes/add-workspace-runtime-contract/tasks.md diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json b/kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json index 788739d..98db2df 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json @@ -2,7 +2,7 @@ "created_at": "2026-05-11T19:40:51.106806+00:00", "friendly_name": "workspace runtime contract", "mission_id": "01KRC8WYGG1KFDFRDA92GCAFGB", - "mission_number": null, + "mission_number": 2, "mission_slug": "workspace-runtime-contract-01KRC8WY", "mission_type": "software-dev", "slug": "workspace-runtime-contract-01KRC8WY", diff --git a/openspec/changes/add-workspace-runtime-contract/design.md b/openspec/changes/add-workspace-runtime-contract/design.md new file mode 100644 index 0000000..ca108d7 --- /dev/null +++ b/openspec/changes/add-workspace-runtime-contract/design.md @@ -0,0 +1,45 @@ +# Design: Workspace Runtime Contract + +## Context + +The `coder-ddev` runtime has nine invariants that are load-bearing today but unspecified anywhere reviewable. The invariants are spread across: +- `image/Dockerfile` — image build (UID/GID, sudo, daemon binaries, hydration staging). +- `user-defined-web/template.tf` — Terraform shape (Sysbox runtime, volumes, agent env, cleanup). +- `user-defined-web/template.tf:startup_script` — inline shell pipeline executed by the Coder agent on each boot (hydration, dockerd start, identity, profile assembly). +- `CLAUDE.md` — prose summary used by AI agents. + +Without a single spec home, reviewers must read three files to confirm an invariant is preserved; agents must re-derive the invariants from prose; and drift items (`global_config.yaml` missing, host commands uncopied, dual dockerd-start models) have no registered attachment point. + +## Approach + +**Descriptive-first.** The spec captures *what is true today*. No requirement may state behavior that does not already exist in the repo. The contract introduces zero runtime changes. + +**One capability, nine requirements.** A single capability — `workspace-runtime` — holds INV-1 through INV-9 as `## ADDED Requirements`, each with a `shall` statement and at least one `#### Scenario:` describing a verifiable observation. Boot sequence and forbidden behaviors are encoded as additional scenario-bearing requirements rather than as a separate capability. + +**Drift catalog as informational appendix.** Items D-1 … D-6 live in a `## Known Drift` block. They are not enforced; they are named so follow-up `MODIFIED` deltas can reference them by ID without re-discovering them. + +**Spec Kitty ↔ OpenSpec join.** The Spec Kitty mission wraps the OpenSpec change. The mission `meta.json.source_description` references the OpenSpec change-id; `proposal.md` carries a `Spec Kitty Mission` link. Spec text lives only in OpenSpec; mission state and event log live only in `kitty-specs/`. No content is duplicated. + +## Decisions + +| ID | Decision | Rationale | +|----|----------|-----------| +| D-1 | One capability per mission, not one capability per invariant. | The nine invariants are cross-cutting; splitting them would obscure relationships (e.g., INV-3 sudo is required by INV-4 dockerd). | +| D-2 | Drift items are informational, not `MODIFIED Requirements`. | They are anomalies in the *implementation*, not changes to the contract. Each will become its own change later. | +| D-3 | The `freeform` template is excluded. | Freeform deviates from INV-7 (keeps ddev-router) and INV-4 (multiple projects per workspace). Its contract is a future sibling capability. | +| D-4 | `CLAUDE.md` is not touched in this change. | Reconciling prose and spec mid-archive would conflate two concerns. A separate proposal will retire duplicated architecture sections after the first archive lands. | +| D-5 | The two systemd-init code paths remain forbidden (INV F-9) but the systemd install in the image stays. | Removing the systemd install is a real image change requiring its own proposal. Documenting it as forbidden behavior is sufficient for this contract. | +| D-6 | Per-template image pinning is not allowed by this contract. | A single `VERSION` is enforced today; per-template variance would require breaking INV-5 or extending it. Tracked as D-6 for the follow-up proposal. | + +## Risks + +- **Stale spec** — if `image/Dockerfile`, any `template.tf`, or the startup script drifts after archive, the spec rots. *Mitigation:* descriptive-first language + a future CI drift check (out of scope here). +- **Cohabitation friction** — OpenSpec and Spec Kitty cohabit with no enforced join. *Mitigation:* bidirectional cross-link convention codified here; CI gating reserved for a future proposal. +- **Pilot mission collision** — the existing Spec Kitty mission `github-org-gated-signup-01KR1P4G` is concurrent and auto-commits. *Mitigation:* this mission runs on its own branch (`spec-workspace-runtime-contract`) based on `upstream/main`. + +## Alternatives Considered + +- **One spec per invariant.** Rejected — fragments the relationships and inflates the cross-reference surface. +- **Promote `CLAUDE.md` to the spec.** Rejected — prose lacks scenarios and validation hooks; OpenSpec format provides both. +- **Skip OpenSpec, use only Spec Kitty.** Rejected — OpenSpec is already initialized with `.agent/workflows/` runbooks; replacing it would itself be a large governance change this proposal is not authorized to make. +- **Defer until drift is remediated.** Rejected — the foundational spec must land first so drift remediations can attach to a stable reference. diff --git a/openspec/changes/add-workspace-runtime-contract/proposal.md b/openspec/changes/add-workspace-runtime-contract/proposal.md new file mode 100644 index 0000000..088fa3f --- /dev/null +++ b/openspec/changes/add-workspace-runtime-contract/proposal.md @@ -0,0 +1,31 @@ +# Change: Add Workspace Runtime Contract + +## Why + +`coder-ddev` enforces nine load-bearing runtime invariants — Sysbox isolation, UID/GID identity, NOPASSWD sudo, in-container `dockerd` lifecycle, the two-volume persistence model, copy-if-missing hydration from `/home/coder-files`, single-project direct-bind web routing, host-aware cleanup, and env-sourced workspace identity. These invariants are scattered across `image/Dockerfile`, `user-defined-web/template.tf` (and its inlined `startup_script`), and prose in `CLAUDE.md`. Nothing in `openspec/specs/` describes them today, so a reviewer cannot confirm that a PR preserves them without re-reading three loosely coupled files. + +This proposal codifies the invariants as a single foundational capability — `workspace-runtime` — that future changes can attach to (or modify) through OpenSpec deltas. The intent is **descriptive-first**: every requirement maps to behavior already enforced in the repo; no new runtime behavior is introduced. + +This proposal also establishes the convention that a Spec Kitty mission *wraps* the OpenSpec change. Bidirectional cross-references between the mission `meta.json` and `proposal.md` keep both governance systems aligned without merging them. + +**Spec Kitty Mission:** [`workspace-runtime-contract-01KRC8WY`](../../../kitty-specs/workspace-runtime-contract-01KRC8WY/spec.md) + +## What Changes + +- **Adds** capability `workspace-runtime` with nine requirements (INV-1 … INV-9) covering the runtime invariants enumerated above. +- **Adds** scenario-bearing requirements for the required agent boot sequence and the forbidden-behavior set (e.g., no host docker.sock mount, no `--privileged`, no hostname-derived identity). +- **Adds** a `## Known Drift` informational block enumerating D-1 … D-6 (missing `global_config.yaml`, uncopied DDEV host commands, missing `chmod 755` on `coder-setup`, dual dockerd-start models, broad socket chmod, single-tag image version). These are **not** remediated by this change; each will become its own follow-up OpenSpec proposal. + +## Impact + +- **Affected specs:** `workspace-runtime` (new capability). +- **Affected code:** **None.** No file under `image/`, `*/template.tf`, `*/scripts/`, or `Makefile` is modified. +- **Affected workflows:** future OpenSpec proposals that touch the image, any template, or the inlined `startup_script` are expected to reference `workspace-runtime` requirements by ID. +- **Affected governance:** establishes the Spec Kitty ↔ OpenSpec cohabitation rule (mission wraps change; spec text lives in OpenSpec; mission state lives in `kitty-specs/`). + +## Non-Goals + +- No edits to `CLAUDE.md` — reconciliation of architecture prose with the new spec is a follow-up after archive. +- No CI gate added in this change. CI integration is reserved for a separate proposal. +- No remediation of drift items D-1 … D-6. +- No introduction of a `freeform` template contract — `freeform` deviates from INV-7 and will be governed by a sibling capability later. diff --git a/openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md b/openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md new file mode 100644 index 0000000..5751940 --- /dev/null +++ b/openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md @@ -0,0 +1,218 @@ +## ADDED Requirements + +### Requirement: Sysbox Container Runtime +Workspace containers SHALL run under the `sysbox-runc` Docker runtime, MUST NOT be privileged, and SHALL set `apparmor:unconfined` and `seccomp:unconfined` security options so that the nested Docker daemon can operate safely without `--privileged`. + +#### Scenario: Workspace container declares Sysbox runtime +- **WHEN** a workspace is provisioned from any `coder-ddev` template +- **THEN** the underlying `docker_container` resource SHALL declare `runtime = "sysbox-runc"` +- **AND** SHALL declare `privileged = false` +- **AND** SHALL declare `security_opts = ["apparmor:unconfined", "seccomp:unconfined"]` + +#### Scenario: Host without Sysbox refuses provisioning +- **WHEN** the Coder host does not have the `sysbox-runc` runtime registered +- **THEN** `terraform apply` SHALL fail with a Docker runtime error +- **AND** no partial workspace container SHALL be created + +--- + +### Requirement: Workspace User Identity +The container SHALL run as the `coder` user (UID 1000), with `HOME=/home/coder` forced through agent environment variables, and SHALL receive the host docker group as a supplementary group via the parametric `docker_gid` variable. + +#### Scenario: Container starts as coder +- **WHEN** a workspace container starts +- **THEN** the container process SHALL run as user `coder` (UID 1000) +- **AND** `HOME` SHALL be `/home/coder` +- **AND** the process SHALL be a member of the supplementary group whose GID equals `var.docker_gid` (default 988) + +#### Scenario: Image identity matches HCL identity +- **WHEN** the base image is built +- **THEN** the image SHALL rename the stock Ubuntu user to `coder` while preserving UID 1000 + +--- + +### Requirement: NOPASSWD Sudo Posture +The `coder` user SHALL have unrestricted passwordless sudo (`coder ALL=(ALL) NOPASSWD:ALL`) so the agent startup script can start `dockerd`, repair home ownership, write `/etc/docker/daemon.json`, and adjust the docker socket without interactive prompts. The privilege boundary SHALL be the Sysbox runtime, not in-container UID separation. + +#### Scenario: Sudoers entry exists with correct mode +- **WHEN** the base image is built +- **THEN** `/etc/sudoers.d/coder` SHALL contain `coder ALL=(ALL) NOPASSWD:ALL` +- **AND** SHALL have mode `0440` +- **AND** SHALL preserve `DEBIAN_FRONTEND` via `Defaults env_keep` + +#### Scenario: Agent script can sudo without prompt +- **WHEN** the agent `startup_script` invokes `sudo dockerd` or `sudo chown` or `sudo tee /etc/docker/daemon.json` +- **THEN** each invocation SHALL succeed without an interactive password prompt + +--- + +### Requirement: In-Container Dockerd Lifecycle +The Docker daemon SHALL run inside the workspace container, SHALL be started by the agent `startup_script` (not by systemd-as-PID-1), SHALL log to `/tmp/dockerd.log`, SHALL expose `/var/run/docker.sock` to the `coder` user, and SHALL persist state under `/var/lib/docker` (backed by the named volume defined in the Volume Model requirement). The host Docker socket MUST NOT be mounted into the workspace. + +#### Scenario: Dockerd is started by the agent on first boot +- **WHEN** the agent `startup_script` runs and `pgrep -x dockerd` returns nothing +- **THEN** the script SHALL invoke `sudo dockerd > /tmp/dockerd.log 2>&1 &` +- **AND** SHALL poll `/var/run/docker.sock` for readiness with a bounded timeout +- **AND** SHALL relax socket permissions so the `coder` user can communicate with the daemon + +#### Scenario: Host docker socket is never mounted +- **WHEN** the `docker_container.workspace` resource is rendered +- **THEN** it MUST NOT declare a `volumes` or `mounts` block whose target is `/var/run/docker.sock` +- **AND** no host path SHALL be exposed at that container path + +#### Scenario: Registry mirror is applied before daemon start +- **WHEN** the agent detects a reachable registry mirror or `var.docker_registry_mirror` is non-empty +- **THEN** the script SHALL write `/etc/docker/daemon.json` with the mirror configuration before invoking `dockerd` +- **AND** subsequent `docker pull` calls SHALL use the mirror + +--- + +### Requirement: Two-Volume Persistence Model +Each workspace SHALL be backed by exactly two persistent surfaces: a host bind mount at `/coder-workspaces/-` mapped to `/home/coder`, and a named Docker volume `coder---dind-cache` mapped to `/var/lib/docker`. No other persistent mounts SHALL be added by the template. + +#### Scenario: Home is a host bind mount +- **WHEN** the workspace container is created +- **THEN** the container path `/home/coder` SHALL be backed by the host directory `/coder-workspaces/-` +- **AND** the bind SHALL be writable + +#### Scenario: Dockerd storage is a named volume +- **WHEN** the workspace container is created +- **THEN** the container path `/var/lib/docker` SHALL be backed by a Docker named volume whose name encodes the workspace owner and slug +- **AND** the volume SHALL survive container replacement (image bump, stop/start) + +#### Scenario: No additional persistent mounts +- **WHEN** the workspace template HCL is rendered +- **THEN** the `docker_container.workspace` resource SHALL declare exactly one `volumes` block (home bind) and exactly one `mounts` block (DinD volume) + +--- + +### Requirement: Copy-If-Missing Home Hydration +On every agent start, the workspace SHALL hydrate `/home/coder` from `/home/coder-files/` (staged outside the bind mount at image build time) using a "copy-if-missing, append-if-missing" policy. User edits MUST NOT be overwritten. Hydration steps SHALL be idempotent. + +#### Scenario: First-boot hydration +- **WHEN** the agent starts and `~/.bashrc` does not exist +- **THEN** the script SHALL seed the home directory from `/etc/skel/` +- **AND** SHALL copy any image-supplied skeleton from `/home/coder-files/` into the user's home + +#### Scenario: Subsequent boot preserves user state +- **WHEN** the agent starts and `~/.bashrc` already exists with user modifications +- **THEN** copy steps SHALL be skipped for any file whose target already exists +- **AND** append steps SHALL be guarded by `grep -q` or equivalent so duplicate entries are not written + +#### Scenario: Missing staging directory is non-fatal +- **WHEN** `/home/coder-files/` is absent from the image +- **THEN** the script SHALL log a warning and continue without aborting + +--- + +### Requirement: Direct-Bind Single-Project Web Routing +For templates governed by this contract (`user-defined-web`, `drupal-core`, `drupal-contrib`), DDEV SHALL be configured globally with `--omit-containers=ddev-router`; the active project's web container SHALL bind directly to `localhost:80` inside the workspace; and external access SHALL flow through Coder's reverse tunnel via a `coder_app` advertisement (with `subdomain = true`). At most one DDEV project SHALL be running per workspace. + +#### Scenario: ddev-router is omitted globally +- **WHEN** the agent has finished initialization +- **THEN** `~/.ddev/global_config.yaml` SHALL declare `omit_containers: [ddev-router]` + +#### Scenario: Dashboard exposes localhost:80 +- **WHEN** the workspace HCL is rendered +- **THEN** a `coder_app` resource SHALL advertise `url = "http://localhost:80"` with `subdomain = true` +- **AND** a healthcheck SHALL be declared against that URL + +#### Scenario: Container publishes no host ports +- **WHEN** the `docker_container.workspace` resource is rendered +- **THEN** it SHALL NOT declare a `ports` block + +--- + +### Requirement: Host-Aware Cleanup +Stopping a workspace SHALL tear down the container while preserving both persistent volumes. Deleting a workspace SHALL also remove the host bind-mount root `/coder-workspaces/-/` via a `null_resource` destroy provisioner that invokes the host-side helper `/usr/local/bin/coder-delete-workspace-dir` with passwordless sudo. Stop SHALL be graceful enough that `ddev poweroff` can complete. + +#### Scenario: Stop preserves volumes +- **WHEN** a workspace transitions to `start_count = 0` +- **THEN** the `docker_container` resource SHALL be destroyed by Terraform +- **AND** the host bind directory SHALL remain +- **AND** the named DinD volume SHALL remain + +#### Scenario: Delete removes the host directory +- **WHEN** a workspace is destroyed via `terraform destroy` or `coder delete` +- **THEN** the `null_resource.workspace_cleanup` destroy provisioner SHALL invoke `sudo /usr/local/bin/coder-delete-workspace-dir` with the host bind path +- **AND** the directory SHALL be removed before the workspace is considered deleted + +#### Scenario: Graceful stop allows ddev poweroff +- **WHEN** a stop is initiated +- **THEN** the container SHALL receive `SIGINT` +- **AND** SHALL be given `stop_timeout = 180s` and `destroy_grace_seconds = 60s` +- **AND** the `coder_script` shutdown hook SHALL run `ddev poweroff` with a docker-socket race guard + +--- + +### Requirement: Env-Sourced Workspace Identity +The authoritative source of workspace identity (`CODER_WORKSPACE_ID`, `CODER_WORKSPACE_NAME`, `CODER_WORKSPACE_OWNER_NAME`, `CODER_WORKSPACE_OWNER_EMAIL`) SHALL be the agent `env` block injected via `coder_agent.env`. Container `hostname` parsing MUST NOT be used as an identity source in new code. + +#### Scenario: Agent env carries identity +- **WHEN** the workspace agent starts +- **THEN** the four `CODER_WORKSPACE_*` environment variables SHALL be exported into every agent-spawned shell +- **AND** git global `user.name` and `user.email` SHALL be set from `CODER_WORKSPACE_OWNER_NAME` and `CODER_WORKSPACE_OWNER_EMAIL` + +#### Scenario: Hostname is not a valid identity source +- **WHEN** a new contributor adds code that derives workspace identity +- **THEN** that code SHALL read from the env variables above +- **AND** SHALL NOT parse the container `hostname` (which is `-`, deliberately distinct from the container `name` `coder-`) + +--- + +### Requirement: Required Agent Boot Sequence +The agent `startup_script` SHALL execute the boot steps in the order: (1) repair home ownership, (2) seed skeleton on first boot, (3) configure GitSSH for the current session, (4) hydrate from `/home/coder-files`, (5) apply git identity, (6) configure registry mirror, (7) start `dockerd` and wait for socket, (8) pre-warm DDEV images, (9) ensure standard directories, (10) assemble shell profile. Each step SHALL be idempotent. The script SHALL use `set +e` so a single failure never aborts boot; failures SHALL be logged. + +#### Scenario: Mirror precedes dockerd start +- **WHEN** the registry mirror configuration is enabled +- **THEN** `/etc/docker/daemon.json` SHALL be written before `dockerd` is launched +- **AND** the first image pull SHALL go through the mirror + +#### Scenario: Hydration precedes shell profile assembly +- **WHEN** the agent boots +- **THEN** files from `/home/coder-files/` SHALL be copied into the home directory before `~/.bash_profile` is assembled +- **AND** `~/.bash_profile` SHALL source `/etc/bash.bashrc` and `~/.bashrc` and display `~/WELCOME.txt` for login shells + +#### Scenario: Best-effort boot +- **WHEN** any individual boot step fails (e.g., dockerd timeout) +- **THEN** the script SHALL log the failure +- **AND** SHALL continue to subsequent steps +- **AND** SHALL exit 0 + +--- + +### Requirement: Forbidden Runtime Behaviors +The following behaviors SHALL NOT appear in any template, image, or agent script governed by this contract: + +- F-1: Mounting the host Docker socket into the workspace. +- F-2: Setting `privileged = true` on the workspace container. +- F-3: Hard-coding UID or GID numerically in scripts (use names `coder` / `docker` and HCL variable `docker_gid`). +- F-4: Persisting `GIT_SSH_COMMAND` to any user dotfile. +- F-5: Overwriting user state in `/home/coder` during hydration. +- F-6: Publishing container ports on the host via the `ports` argument. +- F-7: Adding a new persistent mount without a destroy-time cleanup obligation. +- F-8: Relying on container `hostname` for workspace identity. +- F-9: Starting `dockerd` via `systemd-as-PID-1` (the systemd unit installed by the image is dormant; mixing paths is forbidden). +- F-10: Adding `set -e` to the boot script without re-engineering every failure path. + +#### Scenario: Static check rejects forbidden HCL constructs +- **WHEN** a reviewer inspects a PR that modifies a `template.tf` +- **THEN** the PR SHALL be rejected if it adds a host-socket mount (F-1), sets `privileged = true` (F-2), or publishes container ports (F-6) +- **AND** the reviewer SHALL be able to cite the corresponding F-id in the rejection + +#### Scenario: Script review rejects forbidden patterns +- **WHEN** a reviewer inspects a PR that modifies the inlined `startup_script` +- **THEN** the PR SHALL be rejected if it persists `GIT_SSH_COMMAND` (F-4), parses `hostname` for identity (F-8), or adds `set -e` (F-10) + +--- + +## Known Drift + +The following anomalies exist in the repository at the time this spec lands. They are **informational** and **not enforced** by this contract. Each will become its own follow-up OpenSpec proposal that references the relevant invariant. + +- **D-1** — `image/scripts/.ddev/global_config.yaml` is referenced by `CLAUDE.md` but absent from the image tree. Affects Requirement: Direct-Bind Single-Project Web Routing. Source: `CLAUDE.md` Architecture section vs. `image/scripts/` listing. +- **D-2** — `/home/coder-files/.ddev/commands/host/{launch,coder-routes,coder-setup}` are staged by the image but never copied into `~/.ddev/commands/host/` by `user-defined-web/template.tf`. Affects Requirement: Copy-If-Missing Home Hydration. Source: `image/Dockerfile` `COPY scripts` step vs. `user-defined-web/template.tf` `startup_script` hydration block. +- **D-3** — `coder-setup` is missing from the explicit `chmod 755` list after `COPY scripts /home/coder-files` in `image/Dockerfile`. Affects executability of an image-shipped DDEV host command. +- **D-4** — Two `dockerd` start models coexist in the image (`systemctl enable docker` + manual `sudo dockerd` in the agent script). Forbidden behavior F-9 disallows the systemd path; the systemd install will be retired in a follow-up. +- **D-5** — The agent script applies `chmod 666 /var/run/docker.sock` even though `group_add = 988` already grants the `coder` user write access. Broader than necessary; a follow-up will tighten to `chmod 660` after asserting GID alignment at boot. +- **D-6** — `image_version` is a single tag across all four templates; per-template image pinning is not currently supported. Tracked for a future Volume Model extension. diff --git a/openspec/changes/add-workspace-runtime-contract/tasks.md b/openspec/changes/add-workspace-runtime-contract/tasks.md new file mode 100644 index 0000000..15051de --- /dev/null +++ b/openspec/changes/add-workspace-runtime-contract/tasks.md @@ -0,0 +1,24 @@ +# Tasks: Add Workspace Runtime Contract + +These tasks deliver the proposal-stage artifacts only. No code is changed. + +- [ ] 1. Author `proposal.md`, `design.md`, and `tasks.md` under `openspec/changes/add-workspace-runtime-contract/`. +- [ ] 2. Author delta spec at `openspec/changes/add-workspace-runtime-contract/specs/workspace-runtime/spec.md` with: + - [ ] 2.1. Nine `## ADDED Requirements` (INV-1 … INV-9) — each with a `shall` and at least one `#### Scenario:`. + - [ ] 2.2. Boot-sequence requirements (the ordered steps the agent script must satisfy). + - [ ] 2.3. Forbidden-behavior requirements (no host docker.sock mount, no `--privileged`, no hostname-derived identity, no `set -e`, no overwriting user state during hydration, etc.). + - [ ] 2.4. `## Known Drift` informational block enumerating D-1 … D-6 with the relevant file references. +- [ ] 3. Cross-link mission and change: + - [ ] 3.1. Update `kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json` `source_description` to reference change-id `add-workspace-runtime-contract`. + - [ ] 3.2. Confirm `proposal.md` carries a `Spec Kitty Mission` link to the mission slug. +- [ ] 4. Validate: + - [ ] 4.1. `openspec validate add-workspace-runtime-contract --strict` — green. + - [ ] 4.2. `terraform fmt -check -recursive` — zero changes (defensive; no HCL touched). + - [ ] 4.3. Diff scope check — no file under `image/`, `*/template.tf`, `*/scripts/`, or `Makefile` modified. +- [ ] 5. Open a **draft** pull request against `ddev/coder-ddev:main`. Body references the OpenSpec change-id, the Spec Kitty mission slug, and the descriptive-first stance. + +**Not in scope for this change:** +- Remediating drift items D-1 … D-6. +- Editing `CLAUDE.md` or any architecture prose. +- Adding CI gates. +- Removing the systemd install in the image. From 11096972fdddd29470229b2c898306aeb9442fc3 Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 May 2026 16:06:26 -0400 Subject: [PATCH 18/18] spec(kitty): cross-link mission to OpenSpec change-id Add openspec_change_id and source_description to mission meta.json, binding kitty-specs/workspace-runtime-contract-01KRC8WY to openspec/changes/add-workspace-runtime-contract. --- kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json b/kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json index 98db2df..63b16c9 100644 --- a/kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json +++ b/kitty-specs/workspace-runtime-contract-01KRC8WY/meta.json @@ -5,7 +5,9 @@ "mission_number": 2, "mission_slug": "workspace-runtime-contract-01KRC8WY", "mission_type": "software-dev", + "openspec_change_id": "add-workspace-runtime-contract", "slug": "workspace-runtime-contract-01KRC8WY", + "source_description": "Foundational workspace-runtime-contract spec; wraps OpenSpec change add-workspace-runtime-contract. Descriptive-first capture of nine runtime invariants (Sysbox, identity, sudo, dockerd, volumes, hydration, routing, cleanup, identity source).", "target_branch": "spec-workspace-runtime-contract", "vcs": "git", "vcs_locked_at": "2026-05-11T19:58:02.673303+00:00"