Files
spoon/docs/superpowers/plans/2026-07-10-spoon-implementation-plan-index.md
T
Gabriel Brown 8aa9140191 docs: multi-phase implementation plan (63 tasks across 5 phases)
Phase 1 Stabilize (13), Phase 2 Runtime unification (12),
Phase 3 Dev-box surface (11), Phase 4 Sync correctness (12),
Phase 5 Notifications & polish (15), plus index.
2026-07-10 15:18:51 -04:00

6.2 KiB
Raw Blame History

Spoon: Stabilize → Unify → Build — Implementation Plan Index

For agentic workers: Execute the phase plans in order. Each phase is a standalone plan that ships working, tested software on its own. Use superpowers:subagent-driven-development (fresh subagent per task, review between tasks) or superpowers:executing-plans (batched with checkpoints).

Spec: ../specs/2026-07-10-spoon-stabilize-unify-build-design.md Design review: Gib, 2026-07-10 (tenancy = owner + trusted friends; runtimes = Codex + OpenCode + Claude Code, all in the per-user box; all four feature tracks; ordering = stabilize → unify → build).

Phases

# Plan Tasks Scope
1 phase1-stabilize 13 Critical/High bug fixes on the current architecture: home-deletion data loss, box lifecycle races/leaks, symlink escape, job-lifecycle recovery (heartbeat/timeout/cancel), auto-sync gating, terminal sizing, workspace shell keying, not-found handling.
2 phase2-runtime-unification 12 AgentRuntime adapter interface; Codex/OpenCode/Claude Code all exec into the box; delete the legacy per-job OpenCode container; runtime picker + queue-time validation; Fedora image + smoke; secrets hygiene.
3 phase3-dev-box-surface 11 /machine page (box status/lifecycle + full-page terminal + home file browser); user-scoped /box/* worker routes + HMAC tokens; persistent workspace terminal (survives tab switch); terminal QoL.
4 phase4-sync-correctness 12 Correct head-SHA (branch ref, not truncated compare); stable maintenance-thread dedup; GitHub webhooks (push + installation lifecycle); Octokit retry/throttle + rate_limited status; bound unbounded queries; surface needs_reauth.
5 phase5-notifications-polish 15 notifications + notificationPreferences tables, in-app bell, preference-gated UseSend email; polish sweep (skeletons, error handling, form re-sync, auth copy, workspace UX, a11y, dead-code removal); docs rewrite.

Total: 63 tasks, each ending in an independently testable, committed deliverable.

Cross-phase dependencies

  • Phase 1 → 2, 3. Phases 2 and 3 consume the Phase-1 box-lifecycle API: export type BoxHandle = { boxName: string; release: () => void } and acquireUserBox(args: { username; workdir; containerHome }) => Promise<BoxHandle> (idempotent release, per-username mutex, --init, startup reconcile of spoon-box-*). Both later plans carry a fallback note for the pre-Phase-1 Promise<string> + releaseUserBox(username) signature — build Phase 1 first and the BoxHandle form is what lands.
  • Phase 1 → 5. Phase 5's agent_turn_finished / agent_needs_input notifications emit at the job-status transitions that Phase 1 hardens (updateStatus, applyMaintenanceDecision).
  • Phase 4 → 5. Phase 5's connection_needs_reauth email emits where the Phase-4 webhook sets gitConnections.status = needs_reauth; Phase 5 Task 3 marks that emit point defensively if Phase 4 hasn't landed.
  • Phase 4 depends on Phase 1's auto-sync gating (autoSyncEnabled etc. land in Phase 1 Task 8) and layers head-SHA/dedup/webhooks on top.

Phases 3 and 4 are otherwise independent and could be reordered or parallelized after Phases 12. The recommended sequential order matches the spec.

Deliberate deferrals (documented by the plan authors)

These are called out inline in the plans, not gaps:

  • Phase 1: updateStatus implements the terminal-state guard (the cancel-revert fix) rather than a full forward-only transition matrix — no illegal transition is otherwise exercised. Stale-job recovery times out rather than requeues (requeue-with-attempt-limit needs a new claimAttempts field — deferred). requireAiLowRiskForSync is scoped to Phase 4 (the AI-review→merge path it guards doesn't exist yet).
  • Phase 2: exact opencode run / claude -p flags and the @anthropic-ai/claude-code version pin are reconciled at implementation time via the extended scripts/smoke-agent-container (--help probes + npm view), since the live CLIs aren't available while planning.
  • Phase 3: dotfiles re-materialization for the /box surface is out of scope (the persistent home already carries dotfiles from prior job runs); box start only ensures a login-shell .bash_profile. Docker-touching code is verified by documented manual steps; only pure logic is unit-tested.
  • Phase 4: the webhook route test cannot assert the scheduled 'use node' refresh ran in-process (convex-test VM limitation) — covered by the manual checklist. Octokit plugin versions may need a bump on bun install.
  • Phase 5: (app)/error.tsx + not-found handling lives in Phase 1 (finding #14), not here.

Testing

Every task is test-first where a test is meaningful. Test surfaces:

  • Worker (apps/agent-worker/tests/unit/, vitest): box-registry mutex/handle semantics, path containment incl. symlinks, terminal resize-message parsing, runtime-adapter fixture-stream parsing.
  • Backend (packages/backend/tests/unit/, convex-test): claim validation/rollback, heartbeat-timeout cron, transition guard incl. cancel-vs-worker race, auto-sync gating matrix, maintenance-thread dedup, webhook signature verification, notification emit/preferences.
  • Next (apps/next/tests/component, jsdom + testing-library): terminal fit-on-fonts-ready + resize, workspace shell remount on job switch, form re-sync, not-found states, notification bell.
  • Docker-touching worker code (box --init, dockerode TTY exec, /box lifecycle) uses documented manual verification — needs a live daemon.

How to run each phase

Subagent-driven (recommended): one fresh subagent per task, two-stage review between tasks.
Inline: superpowers:executing-plans, batched with checkpoints.

Start with Phase 1, Task 1 (cleanupOrphanedWorkspaces layout-awareness) — it closes the highest-severity bug (a cleanup call deletes every user's home).