Files
kandev/docs/plans/kubernetes-executor/plan.md
T
2026-09-02 13:50:03 +00:00

182 lines
8.2 KiB
Markdown

---
spec: ../../specs/kubernetes-executor/spec.md
created: 2026-08-24
status: completed
---
# Implementation Plan: Kubernetes Executor
## Overview
Add Kubernetes as a remote containerized executor through the existing
`ExecutorBackend` boundary. Establish the typed cluster/template contract and
Kubernetes dependency graph first, then implement lifecycle, authorization/API,
and backend parity in disjoint work packets. Build the responsive settings UI
after the API shape is stable, then add real Kind lifecycle coverage, public
documentation, and final integration checks.
The durable ownership and cleanup rules are recorded in
[ADR-2026-08-24-kubernetes-executor-resource-ownership](../../decisions/2026-08-24-kubernetes-executor-resource-ownership.md).
## Backend
### Runtime taxonomy and Kubernetes core
- Add aligned Kubernetes modules to `apps/backend/go.mod` / `go.sum`.
- Extend `apps/backend/internal/agentruntime/runtime.go`,
`internal/agent/executor/executor.go`, and `internal/task/models/models.go`
with the `k8s` remote/containerized runtime.
- Create `apps/backend/internal/agent/kubernetes/` for typed executor/profile
config, strict `PodTemplate` parsing, reserved-field composition, PVC
synthesis, client loading, and narrow exec/port-forward seams.
- Register a lazy backend/preparer in `internal/backendapp/agents.go`; invalid
Kubernetes config fails closed rather than falling back to standalone.
### Lifecycle and recovery
- Implement `KubernetesExecutor` under
`apps/backend/internal/agent/runtime/lifecycle/executor_kubernetes*.go`.
- Create/verify storage, create and watch a Pod, inject agentctl/config/auth
through `pods/exec`, signal the managed bootstrap, bind loopback-only
port-forward, and reuse existing agentctl handshake/client behavior.
- Persist namespace, names, UIDs, storage ownership, platform, port, hashes,
and the validated workload launch snapshot (Pod template, platform, main
container, and storage config; never Kandev-resolved credentials/profile
env, injected files, or scripts) in `executors_running` metadata.
Reconnect validates UID plus full ownership labels and creates a new local
forward; missing-Pod replacement uses the snapshot rather than a later
profile edit.
- Ordinary stop preserves resources; terminal/force cleanup deletes only the
exact Pod and Kandev-created PVC. Existing claims are retained.
- Map Pod/container conditions into `RemoteStatusProvider` without probing a
local PID.
### Service authorization and settings API
- Make executor/profile validation type-aware in
`apps/backend/internal/task/service/service_resources.go`.
- Require an administrator for Kubernetes executor/profile create, update,
delete, and diagnostic tests at the service boundary so HTTP and WebSocket
mutations agree. Keep read/use available to members.
- Add `apps/backend/internal/kubernetes/handlers.go` for connection/RBAC/dry-run
testing and exact active-session status, registered from
`internal/backendapp/helpers.go`.
### Remote/container parity
- Audit exhaustive executor switches in orchestrator credentials/execution,
workspace-source materialization, scripts/placeholders, skill delivery,
Office CLI injection, embedded editor capability, liveness/status, and
metrics.
- Keep `ContainerID` Docker-specific and carry Kubernetes resource identity in
lifecycle metadata.
## Frontend
### Executor and profile settings
- Add the Kubernetes card and dedicated creation route under
`apps/web/app/settings/executors/`.
- Add a cluster connection page for auth mode, kubeconfig path/context,
namespace, connection/RBAC testing, and sanitized active sessions.
- Extend the profile page with focused Pod-template and workspace cards rather
than expanding one monolithic form.
- Add pure config parse/serialize/baseline logic with Vitest coverage, API
client types/calls, icons/descriptions, breadcrumbs, and all executor
capability/filter switches.
### Mobile contract
Desktop keeps the existing settings-card composition. Phone uses direct
settings navigation with vertically stacked cards; the raw YAML surface owns
its internal horizontal scrolling while the document has one vertical scroll
owner. The nearest shipped exemplar is the responsive settings/profile flow
combined with `mobile-menu-sheet.tsx` geometry for any contextual actions.
Primary Save/Test actions stay visible with 44 px touch targets, profile
actions are not hover-only, and member mode renders a readable administrator
boundary. Desktop/mobile share config state, validation, API calls, and save
handlers.
### Localization
Add all new copy to the six `executors.json` catalogs. Persisted enum values,
namespace names, paths, and raw YAML remain untranslated.
## Tests
- **Runtime classification and config:** table-driven Go tests in
`internal/agentruntime`, `internal/task/models`, and
`internal/agent/kubernetes` cover enums, auth modes, strict YAML, reserved
collisions, merge preservation, storage modes, and redaction.
- **Lifecycle:** controllable API/exec/forward fakes in
`executor_kubernetes*_test.go` cover launch, partial failure, reconnect,
container restart, UID/label mismatch, ordinary stop, exact cleanup, and
existing-claim retention. Run concurrency-sensitive forward-state tests with
`-race`.
- **Service/API:** service and handler tests cover admin/member/synthetic
identity, type transitions, field-path errors, RBAC result shaping, dry-run,
and exact session inventory.
- **Parity:** focused table cases cover every explicit executor switch.
- **Frontend:** Vitest covers parse/serialize/default/dirty-state logic and API
response normalization.
- **Integration:** Kind tests cover kubeconfig and in-cluster authentication,
exec/port-forward launch, restart/reconnect, storage retention/deletion,
denied permissions, scheduling/image/PVC failures, and foreign-resource
protection.
## E2E Tests
- `apps/web/e2e/tests/settings/mobile-kubernetes-executor.spec.ts`: an
administrator configures auth/template/storage on Pixel 5, completes Test
and Save, reloads to prove persistence, and has no page horizontal overflow.
The same file verifies member read-only state and touch-visible actions.
- `apps/web/e2e/tests/settings/kubernetes-executor.spec.ts`: desktop creation,
validation feedback, and profile navigation.
- `apps/web/e2e/tests/kubernetes/*.spec.ts`: real Kind launch, reconnect,
stop/resume, cleanup, existing-claim retention, RBAC denial, and failure
status through the user-facing UI.
## Verification Results
Completed on 2026-08-25. Each task records its focused commands and outcomes in
its `## Results`; [Task 08](task-08-integration.md) records the reconciled broad
backend, web, documentation, hygiene, and live-cluster gates.
- The constrained full backend suite, build, lint, race-sensitive Kubernetes
packages, module tidy/verification, and changed-file formatting all passed.
- Web lint, typecheck, complete i18n checks, the new-code ratchet, and the full
13,096-case Vitest catalog passed without unhandled rejections (13,092
passed; 4 skipped).
- A fresh pinned Kind/Kubernetes 1.36.1 build passed all 12 lifecycle cases
without retries. API/agentctl compatibility smoke passed on both 1.34.8 and
1.36.1, and the targeted mobile active-session projection passed.
- All live-test clusters, images, containers, ownership markers, forwards, and
workspace-owned test processes were absent after teardown.
- Public-doc tests passed 61/61, all 41 published pages validated, the opt-in
RBAC manifest passed client dry-run, and `git diff --check` was clean.
## Implementation Waves And Parallel Candidates
Wave 1:
- [x] [task-01-backend-foundation](task-01-backend-foundation.md)
Wave 2 (parallel-safe after Task 01):
- [x] [task-02-lifecycle](task-02-lifecycle.md)
- [x] [task-03-service-api](task-03-service-api.md)
- [x] [task-04-backend-parity](task-04-backend-parity.md)
Wave 3:
- [x] [task-05-frontend-settings](task-05-frontend-settings.md)
- [x] [task-06-kind-e2e-ci](task-06-kind-e2e-ci.md)
- [x] [task-07-docs-rbac](task-07-docs-rbac.md)
Wave 4:
- [x] [task-08-integration](task-08-integration.md)
Tasks marked parallel-safe own disjoint files. The primary session alone
updates this plan and integrates cross-task conflicts.