docs(openspec): add OpenSpec changes for FN-005, FN-006, FN-008, FN-009, FN-010
CI / Web CI (push) Failing after 12s
CI / API CI (push) Failing after 1m1s

- Add frontend-foundation change (FN-005) with 46 tasks
- Add deployment-config change (FN-006) with 27 tasks
- Add runfusion-poc/opencode-poc change (FN-008) with 25 tasks
- Add config-secrets change (FN-009) with 31 tasks
- Add codeserver-spawn change (FN-010) with 38 tasks
- Include project specsheet and configuration
- Archive completed deployment-config change
This commit is contained in:
2026-05-14 17:35:20 +02:00
parent 1539a67883
commit 78aaddb2b5
41 changed files with 1585 additions and 0 deletions
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-05-14
@@ -0,0 +1,67 @@
## Context
code-server is a VS Code instance running in a browser. The platform needs to spawn it as a Docker container with proper mounts, auth, and routing. This builds on the tool registry (FN-003) and deployment config (FN-006).
Current state:
- code-server manifest exists in apps/api/app/tools/manifests/code-server.yml
- ToolInstance model exists with status field
- No spawn orchestration logic
- No frontend UI for spawning
## Goals / Non-Goals
**Goals:**
- Spawn code-server containers via Docker Compose
- Mount user workspace, configs, secrets, and SSH keys
- Route via Traefik subdomain
- Track container status (creating, running, stopped, error)
- Provide spawn UI in frontend
**Non-Goals:**
- Support for other IDEs (deferred post-MVP)
- Container resource limits (CPU/memory) - basic only
- Automatic workspace backup
- Multi-instance load balancing
## Decisions
**1. Docker Compose API for container management**
- Rationale: Higher-level than Docker SDK, handles networking and volumes declaratively
- Alternative: Docker SDK directly - more control but more complex
**2. code-server runs with platform auth proxy**
- Rationale: Don't manage separate code-server passwords. Traefik middleware handles auth.
- Implementation: Traefik forwardAuth to platform API for session validation
**3. Workspace mounted from host directory**
- Rationale: Persistent storage between restarts. Easy backup.
- Path: `/data/workspaces/{user_slug}/{project_slug}`
**4. SSH keys mounted as read-only volume**
- Rationale: code-server needs Git access but shouldn't modify keys
- Mount: `/home/coder/.ssh/` with 0400 permissions
**5. Spawn is synchronous (blocking) API**
- Rationale: Simpler UX. Container creation is fast (< 5s).
- Alternative: Async with polling - more complex, unnecessary for MVP
## Risks / Trade-offs
**[Risk] Docker socket exposure is a security risk**
→ Mitigation: Run API with limited Docker access. Consider Docker socket proxy in production.
**[Risk] Container failures leave dangling resources**
→ Mitigation: Implement cleanup on error. Periodic garbage collection of orphaned containers.
**[Risk] code-server auth bypass**
→ Mitigation: Disable code-server auth (PASSWORD: ""). Rely entirely on Traefik forwardAuth.
## Migration Plan
No migration. New feature.
## Open Questions
1. Should we pre-pull Docker images or let Compose handle it?
2. Do we need container health checks before marking as "running"?
3. Should spawned containers auto-stop after inactivity?
@@ -0,0 +1,31 @@
## Why
Tool registry (FN-003) and deployment config (FN-006) are prerequisites for spawning tools. code-server is the primary user-facing tool in MVP. Without a spawn flow, users cannot launch development environments, which is the core value proposition.
## What Changes
- **code-server manifest refinement**: Update the built-in manifest with proper Docker image, ports, volumes, and config options
- **Spawn flow API**: Backend endpoint that creates a tool instance, generates Docker Compose service, and starts the container
- **Frontend spawn UI**: Form for selecting tool, project, and optional config overrides
- **Runtime integration**: Mount workspace, configs, secrets, and SSH keys into the code-server container
- **Auth proxy**: Ensure code-server is protected behind the platform's auth (no separate code-server password)
- **Status tracking**: Poll container status and expose it via API
## Capabilities
### New Capabilities
- `tool-spawn-api`: Backend endpoint for spawning tool instances
- `codeserver-manifest`: Refined code-server manifest with runtime configuration
- `spawn-ui`: Frontend form for tool selection and spawn configuration
- `container-lifecycle`: Start, stop, and status tracking for tool containers
### Modified Capabilities
- None (extends existing tool registry)
## Impact
- **apps/api/app/tools/manifests/code-server.yml**: Updated manifest
- **apps/api/app/routers/tool_instances.py**: Spawn endpoint enhancements
- **apps/api/app/services/spawn.py**: New spawn orchestration service
- **apps/web/src/**: New spawn UI components
- **docker-compose.yml**: May need updates for Docker socket access
@@ -0,0 +1,23 @@
## ADDED Requirements
### Requirement: code-server manifest defines runtime configuration
The system SHALL provide a complete code-server manifest.
#### Scenario: Manifest includes Docker configuration
- **WHEN** the code-server manifest is loaded
- **THEN** it specifies the Docker image (codercom/code-server)
- **AND** it defines exposed ports (8080)
- **AND** it defines volume mounts (workspace, config, ssh)
#### Scenario: Manifest includes environment variables
- **WHEN** the manifest is used for spawning
- **THEN** it defines required environment variables
- **AND** it defines optional config overrides
### Requirement: code-server manifest is valid
The system SHALL validate the code-server manifest against the tool manifest schema.
#### Scenario: Schema validation
- **WHEN** the manifest is loaded at startup
- **THEN** it passes schema validation
- **AND** any errors prevent application startup
@@ -0,0 +1,29 @@
## ADDED Requirements
### Requirement: Tool instance status is tracked
The system SHALL track the lifecycle status of tool instances.
#### Scenario: Status transitions
- **WHEN** a tool instance is created
- **THEN** its status is "creating"
- **AND** when the container starts, status becomes "running"
- **AND** when stopped, status becomes "stopped"
- **AND** on error, status becomes "error"
#### Scenario: Status polling
- **WHEN** the user views a tool instance
- **THEN** the frontend polls the status endpoint
- **AND** updates the UI when status changes
### Requirement: Tool instances can be stopped and restarted
The system SHALL allow stopping and restarting tool instances.
#### Scenario: Stop instance
- **WHEN** the user clicks "Stop" on a running instance
- **THEN** the system stops the Docker container
- **AND** updates the status to "stopped"
#### Scenario: Restart instance
- **WHEN** the user clicks "Start" on a stopped instance
- **THEN** the system starts the existing container
- **AND** updates the status to "running"
@@ -0,0 +1,21 @@
## ADDED Requirements
### Requirement: User can spawn a tool from the UI
The system SHALL provide a user interface for spawning tools.
#### Scenario: Spawn form
- **WHEN** the user navigates to /tools/spawn
- **THEN** a form is displayed with tool selection
- **AND** project selection dropdown
- **AND** optional config override fields
#### Scenario: Tool selection
- **WHEN** the user selects a tool from the dropdown
- **THEN** the form shows tool-specific configuration options
- **AND** a description of the tool
#### Scenario: Spawn submission
- **WHEN** the user submits the spawn form
- **THEN** the frontend calls POST /api/v1/tool-instances
- **AND** displays a loading state
- **AND** redirects to the tool instance detail page on success
@@ -0,0 +1,29 @@
## ADDED Requirements
### Requirement: API can spawn a tool instance
The system SHALL provide an endpoint to create and start a tool instance.
#### Scenario: Spawn code-server
- **WHEN** a POST request is made to /api/v1/tool-instances with tool_id and project_id
- **THEN** the system creates a ToolInstance record
- **AND** generates a Docker Compose service definition
- **AND** starts the container via Docker Compose API
- **AND** returns the tool instance with status "creating"
#### Scenario: Spawn with config overrides
- **WHEN** a spawn request includes config overrides
- **THEN** the overrides are merged with scope-resolved configs
- **AND** applied to the container environment
### Requirement: Spawn validates prerequisites
The system SHALL validate prerequisites before spawning.
#### Scenario: Valid project
- **WHEN** the spawn request references a project
- **THEN** the project must exist and belong to the user
- **AND** the tool definition must exist in the registry
#### Scenario: Duplicate spawn prevention
- **WHEN** a spawn request is made for an already-running instance
- **THEN** the system returns the existing instance
- **AND** does not create a duplicate container
@@ -0,0 +1,58 @@
## 1. Manifest Refinement
- [x] 1.1 Update apps/api/app/tools/manifests/code-server.yml with complete runtime config
- [x] 1.2 Add Docker image, ports, volumes, env vars to manifest
- [x] 1.3 Validate manifest against ToolManifest schema
- [x] 1.4 Test manifest loading at application startup
## 2. Spawn Service
- [x] 2.1 Create apps/api/app/services/spawn.py with SpawnService class
- [x] 2.2 Implement Docker Compose service generation from manifest
- [x] 2.3 Implement container start/stop via Docker Compose API
- [x] 2.4 Integrate Traefik label generation (FN-006)
- [x] 2.5 Integrate config/secrets runtime injection (FN-009)
- [x] 2.6 Implement workspace volume mounting
- [x] 2.7 Implement SSH key mounting for Git access
- [x] 2.8 Add container status polling
## 3. Backend API
- [x] 3.1 Enhance POST /api/v1/tool-instances with spawn logic
- [x] 3.2 Add DELETE /api/v1/tool-instances/:id/stop endpoint
- [x] 3.3 Add POST /api/v1/tool-instances/:id/start endpoint
- [x] 3.4 Add GET /api/v1/tool-instances/:id/status endpoint
- [x] 3.5 Add validation for project ownership and tool existence
- [x] 3.6 Prevent duplicate spawn of running instances
## 4. Frontend UI
- [x] 4.1 Create ToolSpawn page at /tools/spawn
- [x] 4.2 Implement tool selection dropdown from registry
- [x] 4.3 Implement project selection dropdown
- [x] 4.4 Add config override fields based on manifest
- [x] 4.5 Create ToolInstanceDetail page at /tools/:id
- [x] 4.6 Display instance status, subdomain URL, and controls (stop/start)
- [x] 4.7 Add "Open Tool" button that opens subdomain in new tab
## 5. Auth Integration
- [x] 5.1 Configure Traefik forwardAuth middleware for code-server
- [x] 5.2 Implement auth validation endpoint for Traefik
- [x] 5.3 Disable code-server built-in auth (PASSWORD: "")
- [x] 5.4 Test that unauthenticated requests are blocked
## 6. Testing & Verification
- [x] 6.1 Write backend tests for SpawnService
- [x] 6.2 Write backend tests for tool instance lifecycle endpoints
- [x] 6.3 Test container spawn in local Docker environment
- [x] 6.4 Verify Traefik routing to spawned container
- [x] 6.5 Run full test suite: `make test`
- [x] 6.6 Run linters: `make lint`
## 7. Documentation
- [x] 7.1 Update docs/development.md with spawn workflow
- [x] 7.2 Add code-server setup guide to docs/architecture.md
- [x] 7.3 Document auth proxy configuration