docs(work): decompose platform-retrofit and walking-skeleton epics

platform-retrofit: 8 stories / 18 tasks (spec bundle into docs/product,
single-version release-please before deletions, demo feature removal,
web-next auth shell, optional cores, work-tree archive, library traces,
agent-doc rewrite). walking-skeleton: 11 stories / 28 tasks across
workspaces, discovery, core-runner-protocol, runner app, editor, and
the flagship connect-to-selection e2e; builds on platform-retrofit
(prose dependency note — cross-epic frontmatter unsupported).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016j8z4VHjedXDTjEDNg7qHK
This commit is contained in:
2026-07-12 12:28:51 +02:00
parent 442b70476c
commit 99180887f3
22 changed files with 1286 additions and 3 deletions

View File

@@ -0,0 +1,44 @@
---
id: 06-runner-provisioner-port
epic: walking-skeleton
title: IRunnerProvisioner port + local-process and single-host Docker implementations
type: technical-story
status: todo
feature: workspaces
depends-on: [03-workspaces-feature-core, 04-runner-app-protocol-clone-install]
blocks: [07-runner-lifecycle-events-and-realtime]
created: 2026-07-12T10:24:14Z
---
## Goal
Ship the runner provisioning port — `IRunnerProvisioner` (`provision(workspaceId) → RunnerHandle`, `terminate`, `status`) in `workspaces` infrastructure — with two implementations: a local child-process provisioner (dev/CI) and a single-host Docker provisioner (the container-per-workspace baseline of ADR-027 §2).
## Why
Each workspace's repo code must execute in its own isolated runner so a malicious repo cannot touch other tenants (PRD user story 6, ADR-027). Putting provisioning behind a port keeps fleet orchestration explicitly a later concern behind the same interface, and lets `pnpm dev` + CI run the whole skeleton with a plain child process (PRD user story 8).
## Done when
- `IRunnerProvisioner` service port lives in `workspaces` infrastructure with `provision(workspaceId) → RunnerHandle`, `terminate`, `status` (PRD Implementation decisions).
- Local child-process implementation spawns the real `apps/runner`; tests provision, complete the protocol handshake, and terminate cleanly.
- Docker implementation: docker CLI via execa (PRD Q1 — app/infra-tier placement, so no ADR-022 trace required); image `node:22-bookworm-slim` + git at a pinned digest (PRD Q3); container-per-workspace with no cross-tenant network (PRD security floor).
- The Docker path has a documented manual dev-machine check; CI uses the process provisioner (PRD Success criteria).
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` all pass after each task.
## In scope
- The port + `RunnerHandle` shape.
- Local child-process implementation + tests against the real runner.
- Single-host Docker implementation (docker CLI via execa) + tests against a stubbed docker CLI + documented manual verification steps.
## Out of scope
- Fleet orchestration, hibernation, egress policy hardening, resource-limit tuning (`workspaces-and-connections`).
- Quotas, metering, billing.
- Doctor-style runner image version checks (`workspaces-and-connections`, PRD Q3).
## Tasks
- [ ] Add the `IRunnerProvisioner` service port in `workspaces` infrastructure (`provision(workspaceId) → RunnerHandle`, `terminate`, `status`) + the local child-process implementation spawning `apps/runner`; tests provision a real runner, complete the protocol handshake, and terminate cleanly.
- [ ] Add the single-host Docker implementation (docker CLI via execa, app/infra-tier per PRD Q1; `node:22-bookworm-slim` + git at a pinned digest; container-per-workspace, no cross-tenant network) with unit tests against a stubbed docker CLI + documented manual dev-machine verification (CI stays on the process provisioner).