Scaffold backend: Hono + Rivet Kit + per-user Docker stack
Backend that provisions per-user OpenCode + Gitea Docker pair via
dockerode and exposes the Grow Agent / sub-agent Rivet Kit actors
described in the PRD. Sub-agent workflows route through the parent
Grow Agent's OpenCode Docker.
- src/docker/manager.ts spawns growqr-gitea-<userId> and growqr-opencode-<userId>
- src/actors/{grow-agent,sub-agent,registry}.ts: Rivet Kit actors
- src/routes/{actors,opencode,git}.ts: PRD section 5.2-5.4 HTTP API
- docker-compose.yml runs rivet-engine + backend (mounts host Docker socket)
- PRD updated to lock in per-user OpenCode/Gitea Docker topology
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
402
docs/PRD.md
Normal file
402
docs/PRD.md
Normal file
@@ -0,0 +1,402 @@
|
||||
# Grow Agent Platform PRD
|
||||
|
||||
## 1. Overview
|
||||
|
||||
GrowQR is a multi-agent development and personal growth platform where every user gets a dedicated master agent called a Grow Agent. The Grow Agent owns the user's long-running context, memory, workflows, files, repositories, execution state, and progress.
|
||||
|
||||
The platform combines:
|
||||
|
||||
- A Slack-like frontend for chat, progress, and sub-agent channels.
|
||||
- A dedicated Grow Agent per user, implemented as a Rivet Kit actor.
|
||||
- Multiple specialized sub-agents per Grow Agent, also implemented as Rivet Kit actors.
|
||||
- Git-backed memory and state using per-user repositories.
|
||||
- A per-user OpenCode Docker container for coding and workflow execution.
|
||||
- A per-user Gitea Docker container for internal Git hosting.
|
||||
- Rivet Kit actors for durable state, orchestration, and actions.
|
||||
- A frontend that pulls the Rivet Kit React/JS SDK to talk to actors directly.
|
||||
- Backend APIs for auth, actor registry, Docker (OpenCode + Gitea) lifecycle management, payments, and product flows.
|
||||
|
||||
## 2. Product Goals
|
||||
|
||||
- Give every user a persistent AI workspace that can remember, plan, execute, and evolve over time.
|
||||
- Store all user agent state in Git so memory, files, decisions, and workflow history are inspectable and versioned.
|
||||
- Let a master Grow Agent orchestrate specialized sub-agents.
|
||||
- Give each sub-agent isolated execution scope, logs, state, and optionally a Slack-style channel.
|
||||
- Provide a frontend where users can talk to the Grow Agent, watch sub-agent progress, and trigger structured quests or pathways.
|
||||
- Support paid access where payment provisions and starts the user's Grow Agent environment.
|
||||
|
||||
## 3. Core Concepts
|
||||
|
||||
### 3.1 User
|
||||
|
||||
A user is the primary account holder. Each user has:
|
||||
|
||||
- One active Grow Agent.
|
||||
- One or more Git repositories for agent memory and workspace files.
|
||||
- Access to a dedicated OpenCode execution environment.
|
||||
- Access to a Slack-like UI with channels for master and sub-agent activity.
|
||||
|
||||
### 3.2 Grow Agent
|
||||
|
||||
The Grow Agent is the user's master agent and orchestration layer.
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- Maintain user-level memory and context.
|
||||
- Decide which sub-agent should handle a task.
|
||||
- Trigger sub-agent workflows, routing every executable workflow through the user's OpenCode Docker.
|
||||
- Track progress and state transitions.
|
||||
- Commit important state changes to the user's Gitea Docker repo.
|
||||
- Coordinate OpenCode sessions for code execution against its dedicated OpenCode Docker.
|
||||
- Expose status to the frontend via the Rivet Kit React SDK.
|
||||
|
||||
The Grow Agent is implemented as a durable Rivet Kit actor. Each Grow Agent owns:
|
||||
|
||||
- Its own OpenCode Docker container (workflows + code execution).
|
||||
- Its own Gitea Docker container (memory + repo storage).
|
||||
- A registry of Rivet Kit sub-agent actors it can spawn and call.
|
||||
|
||||
### 3.3 Sub-Agents
|
||||
|
||||
Sub-agents are specialized Rivet Kit worker actors owned by a Grow Agent. They are orchestrated by the Grow Agent and execute their workflows through the user's OpenCode Docker.
|
||||
|
||||
Examples:
|
||||
|
||||
- Coding agent using OpenCode.
|
||||
- Repo setup agent using the user's Gitea Docker APIs.
|
||||
- Migration agent.
|
||||
- Product flow agent.
|
||||
- Payment/onboarding agent.
|
||||
- Quest/pathway agent.
|
||||
- Backend CRUD agent.
|
||||
- Frontend planning agent.
|
||||
|
||||
Each sub-agent has:
|
||||
|
||||
- A unique Rivet Kit actor identity.
|
||||
- A bounded workspace directory inside the parent Grow Agent's OpenCode Docker.
|
||||
- A bounded set of capabilities.
|
||||
- A dedicated state object.
|
||||
- A channel/thread in the frontend.
|
||||
- Optional backing microservice integration.
|
||||
|
||||
Sub-agent execution rule: every workflow that needs code, shell, file edits, or generated artifacts is executed via the parent Grow Agent's OpenCode Docker session — sub-agents do not get their own container. The Grow Agent multiplexes OpenCode sessions across its sub-agents.
|
||||
|
||||
### 3.4 Git-Backed State
|
||||
|
||||
Every user gets a Git repository that stores:
|
||||
|
||||
- Agent memory files.
|
||||
- User goals and profile context.
|
||||
- Quest/pathway progress.
|
||||
- Plans, summaries, decisions, and task history.
|
||||
- Generated code/files.
|
||||
- Sub-agent outputs.
|
||||
- System state snapshots where appropriate.
|
||||
|
||||
Gitea is used as the internal Git server, and each Grow Agent runs its own Gitea Docker container so per-user repos are physically isolated.
|
||||
|
||||
Repository model:
|
||||
|
||||
- One Gitea Docker container per Grow Agent (per user).
|
||||
- One primary repo inside that Gitea for Grow Agent memory and workspace state.
|
||||
- Optional child repos inside the same Gitea for generated products or user projects.
|
||||
- All writes from agents go through controlled Git actions against the user's own Gitea Docker.
|
||||
- Important state mutations produce commits with structured messages.
|
||||
|
||||
### 3.5 OpenCode Execution
|
||||
|
||||
OpenCode is used as the code execution and workflow-runtime interface for every sub-agent.
|
||||
|
||||
Topology:
|
||||
|
||||
- Each Grow Agent owns its own OpenCode Docker container (one container per user).
|
||||
- All sub-agent workflows are routed through that OpenCode Docker — it is the single execution surface for the Grow Agent's sub-agents.
|
||||
- OpenCode runs with strict directory boundaries scoped to the user's workspace.
|
||||
- The Grow Agent creates OpenCode sessions per sub-agent task, sends prompts, inspects results, and streams progress.
|
||||
- The container is started on Grow Agent provisioning and stopped on suspension to control cost.
|
||||
|
||||
Open decision (still open):
|
||||
|
||||
- Whether to fork OpenCode and add platform-specific management APIs, or wrap the upstream image behind a backend-controlled management layer (suggested direction in §11).
|
||||
|
||||
## 4. System Architecture
|
||||
|
||||
### 4.1 High-Level Components
|
||||
|
||||
- Frontend app: Slack-like UI, chat interface, quests/pathways, progress views. Pulls the Rivet Kit React SDK for actor connectivity.
|
||||
- Backend API: auth, billing, user management, actor registry, OpenCode Docker lifecycle, Gitea Docker lifecycle.
|
||||
- Rivet Kit actor runtime: durable Grow Agent and sub-agent actors.
|
||||
- Per-user Gitea Docker: one container per Grow Agent, hosting that user's repos.
|
||||
- Per-user OpenCode Docker: one container per Grow Agent, executing all sub-agent workflows.
|
||||
- Docker orchestration layer: provisions, starts, stops, and tears down each user's OpenCode + Gitea container pair.
|
||||
- Database: relational app data such as users, auth, billing, actor registry metadata, repo mappings, and container/host assignments.
|
||||
- Queue/event layer: optional event delivery between backend, actors, OpenCode, and frontend.
|
||||
|
||||
Per-user Docker pair (the "Grow Agent stack"):
|
||||
|
||||
```
|
||||
Frontend ──(Rivet Kit React SDK)──▶ Grow Agent Actor (Rivet Kit)
|
||||
│
|
||||
orchestrates sub-agent actors
|
||||
│
|
||||
▼
|
||||
┌──────── User N's stack ────────┐
|
||||
│ OpenCode Docker ◀── workflows│
|
||||
│ Gitea Docker ◀── commits │
|
||||
└────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 4.2 Request Flow
|
||||
|
||||
1. User signs up or logs in.
|
||||
2. Payment or plan check confirms entitlement.
|
||||
3. Backend provisions the user's Grow Agent Rivet Kit actor.
|
||||
4. Backend starts the user's Gitea Docker container and creates the primary memory repo.
|
||||
5. Backend starts the user's OpenCode Docker container and mounts its workspace.
|
||||
6. User sends a message in the frontend (via Rivet Kit React SDK).
|
||||
7. Message is routed to the user's Grow Agent actor.
|
||||
8. Grow Agent updates state, decides whether to spawn/call sub-agent actors, and commits durable context to the user's Gitea Docker when needed.
|
||||
9. Sub-agents run tasks by opening sessions against the user's OpenCode Docker — all workflows flow through this container.
|
||||
10. Progress events stream back to the frontend over the Rivet Kit connection.
|
||||
|
||||
## 5. Backend Requirements
|
||||
|
||||
### 5.1 Auth
|
||||
|
||||
The backend must support:
|
||||
|
||||
- User registration and login.
|
||||
- Session or JWT auth.
|
||||
- Per-user authorization checks for all actor, repo, and OpenCode resources.
|
||||
- Service-to-service auth for actors calling backend APIs.
|
||||
|
||||
Open decision:
|
||||
|
||||
- Auth provider: custom auth, Auth.js/NextAuth, Clerk, Supabase Auth, or another provider.
|
||||
|
||||
### 5.2 Actor Registry API
|
||||
|
||||
The backend needs an actor registry that tracks:
|
||||
|
||||
- User ID.
|
||||
- Grow Agent actor ID.
|
||||
- Sub-agent actor IDs.
|
||||
- Actor type.
|
||||
- Actor status.
|
||||
- Assigned workspace path.
|
||||
- Assigned Gitea repo.
|
||||
- Assigned OpenCode server/workspace.
|
||||
- Last activity timestamp.
|
||||
- Billing entitlement status.
|
||||
|
||||
Initial endpoints:
|
||||
|
||||
- `POST /actors/provision`
|
||||
- `GET /actors/me`
|
||||
- `GET /actors/:actorId`
|
||||
- `POST /actors/:actorId/start`
|
||||
- `POST /actors/:actorId/stop`
|
||||
- `POST /actors/:actorId/message`
|
||||
- `GET /actors/:actorId/events`
|
||||
|
||||
### 5.3 OpenCode Docker Management API
|
||||
|
||||
The backend needs APIs to manage each user's OpenCode Docker container:
|
||||
|
||||
- Provision OpenCode Docker container for a Grow Agent.
|
||||
- Start/stop the OpenCode Docker runtime.
|
||||
- Create coding/workflow sessions inside the container.
|
||||
- Send prompt/action to OpenCode.
|
||||
- Read execution status.
|
||||
- Fetch logs.
|
||||
- Restrict filesystem access to the user's workspace mount.
|
||||
|
||||
Initial endpoints:
|
||||
|
||||
- `POST /opencode/provision`
|
||||
- `GET /opencode/workspaces/:workspaceId`
|
||||
- `POST /opencode/workspaces/:workspaceId/start`
|
||||
- `POST /opencode/workspaces/:workspaceId/stop`
|
||||
- `POST /opencode/workspaces/:workspaceId/sessions`
|
||||
- `POST /opencode/sessions/:sessionId/messages`
|
||||
- `GET /opencode/sessions/:sessionId/events`
|
||||
|
||||
### 5.4 Gitea Docker Management API
|
||||
|
||||
The backend needs APIs for the per-user Gitea Docker container:
|
||||
|
||||
- Provisioning, starting, and stopping the user's Gitea Docker container.
|
||||
- Creating the primary per-user memory repo inside it.
|
||||
- Creating additional project repos inside the same Gitea.
|
||||
- Creating deploy keys or access tokens.
|
||||
- Committing memory/state files.
|
||||
- Reading repository status.
|
||||
- Managing branches.
|
||||
- Creating PRs when needed.
|
||||
|
||||
Initial endpoints:
|
||||
|
||||
- `POST /git/users/:userId/repo`
|
||||
- `GET /git/repos/:repoId`
|
||||
- `POST /git/repos/:repoId/commit`
|
||||
- `POST /git/repos/:repoId/branch`
|
||||
- `POST /git/repos/:repoId/pull-request`
|
||||
|
||||
### 5.5 Payments
|
||||
|
||||
Payment controls whether the user's Grow Agent can be provisioned or run.
|
||||
|
||||
Requirements:
|
||||
|
||||
- Checkout flow.
|
||||
- Webhook handling.
|
||||
- Subscription status.
|
||||
- Entitlement checks before actor startup.
|
||||
- Graceful suspension when payment fails.
|
||||
|
||||
Open decision:
|
||||
|
||||
- Payment provider, likely Stripe.
|
||||
|
||||
## 6. Actor Requirements
|
||||
|
||||
### 6.1 Grow Agent Actor
|
||||
|
||||
State:
|
||||
|
||||
- User profile summary.
|
||||
- Active goals.
|
||||
- Current quest/pathway.
|
||||
- Memory index.
|
||||
- Sub-agent registry.
|
||||
- Active tasks.
|
||||
- Git repo mapping.
|
||||
- OpenCode workspace mapping.
|
||||
- Recent conversation summary.
|
||||
|
||||
Actions:
|
||||
|
||||
- Receive user message.
|
||||
- Update memory.
|
||||
- Start quest/pathway.
|
||||
- Spawn or call sub-agent.
|
||||
- Commit state to Git.
|
||||
- Request OpenCode session.
|
||||
- Emit progress event.
|
||||
|
||||
### 6.2 Sub-Agent Actor
|
||||
|
||||
State:
|
||||
|
||||
- Parent Grow Agent ID.
|
||||
- Task type.
|
||||
- Current task status.
|
||||
- Workspace path.
|
||||
- Tool permissions.
|
||||
- Channel ID.
|
||||
- Logs/progress.
|
||||
|
||||
Actions:
|
||||
|
||||
- Start task.
|
||||
- Pause/resume task.
|
||||
- Run bounded service action.
|
||||
- Run OpenCode action where allowed.
|
||||
- Commit output to Git.
|
||||
- Emit progress event.
|
||||
|
||||
## 7. Frontend Requirements
|
||||
|
||||
The frontend is next, but the backend should be shaped around this UI. The frontend is pulled in as a separate app that consumes the Rivet Kit React/JS SDK to connect directly to the user's Grow Agent actor (chat + streaming events), and uses the backend REST APIs only for auth, billing, and Docker lifecycle controls.
|
||||
|
||||
Primary screens:
|
||||
|
||||
- Master Grow Agent chat.
|
||||
- Slack-like channel list.
|
||||
- Sub-agent channel/thread view.
|
||||
- Quest/pathway launcher.
|
||||
- Task progress timeline.
|
||||
- Files/repo activity view.
|
||||
- Billing/account state.
|
||||
|
||||
UI behavior:
|
||||
|
||||
- User talks primarily to the Grow Agent.
|
||||
- Grow Agent messages can show spawned sub-agent activity.
|
||||
- Each sub-agent gets a visible channel or thread.
|
||||
- Quests/pathways appear as predefined flows that trigger agent prompts and actions.
|
||||
|
||||
## 8. Security and Isolation
|
||||
|
||||
Hard requirements:
|
||||
|
||||
- Every user must have isolated directories.
|
||||
- Actors can only access assigned workspace roots.
|
||||
- OpenCode Docker must run with strict workspace and command restrictions, and each user's container is network-isolated from other users' containers.
|
||||
- Each user's Gitea Docker is reachable only from that user's Grow Agent + sub-agents and the backend.
|
||||
- Backend must verify user ownership on every actor, repo, and OpenCode request.
|
||||
- Sub-agents should receive only the capabilities needed for their task.
|
||||
- Per-user OpenCode and Gitea Docker containers must have CPU/memory limits to prevent noisy-neighbor and runaway-cost issues.
|
||||
|
||||
## 9. MVP Scope
|
||||
|
||||
### MVP Backend
|
||||
|
||||
- User auth.
|
||||
- Actor registry.
|
||||
- One Grow Agent Rivet Kit actor per user.
|
||||
- Basic sub-agent (Rivet Kit) registration under the Grow Agent.
|
||||
- Per-user Gitea Docker provisioning and primary repo creation.
|
||||
- Basic Git-backed memory commits into the user's Gitea Docker.
|
||||
- Per-user OpenCode Docker provisioning + session API.
|
||||
- Message endpoint from frontend to Grow Agent.
|
||||
- Event stream endpoint for progress.
|
||||
|
||||
### MVP Frontend
|
||||
|
||||
- Pulled as a separate app that consumes the Rivet Kit React SDK.
|
||||
- Login.
|
||||
- Master chat interface (Rivet Kit actor connection to the Grow Agent).
|
||||
- Sub-agent progress sidebar.
|
||||
- Basic quest launcher.
|
||||
- Channel-style task logs.
|
||||
|
||||
### MVP Actors
|
||||
|
||||
- Grow Agent actor with memory and routing.
|
||||
- Coding sub-agent using OpenCode.
|
||||
- Repo sub-agent using Gitea.
|
||||
- Quest sub-agent using predefined prompts.
|
||||
|
||||
## 10. Key Open Questions
|
||||
|
||||
Resolved:
|
||||
|
||||
- ~~Should there be one OpenCode container per user or per active coding sub-agent?~~ → One OpenCode Docker container per Grow Agent (per user). Sub-agents share it via separate sessions.
|
||||
- ~~Gitea topology?~~ → One Gitea Docker container per Grow Agent (per user).
|
||||
- ~~Actor framework?~~ → Rivet Kit for both Grow Agent and sub-agents.
|
||||
- ~~How does the frontend connect to actors?~~ → Frontend pulls and uses the Rivet Kit React/JS SDK.
|
||||
|
||||
Still open:
|
||||
|
||||
- Should OpenCode be forked, wrapped, or used as-is behind a management API?
|
||||
- Should the user memory repo and generated product repos be separate (both inside the same per-user Gitea)?
|
||||
- Which auth provider should be used?
|
||||
- Which database should be used for backend metadata?
|
||||
- How much state should live in Rivet actors versus Git versus database?
|
||||
- Should sub-agent channels map to real Slack channels, an internal Slack-like UI, or both?
|
||||
- What is the exact boundary between a sub-agent actor and a microservice wrapper?
|
||||
- What payment provider and pricing model should be used?
|
||||
- Which Docker orchestrator runs the per-user OpenCode + Gitea pair (plain Docker, Docker Compose per user, Nomad, k8s, Fly Machines, etc.)?
|
||||
|
||||
## 11. Suggested Technical Direction
|
||||
|
||||
- Use the backend database for account, billing, registry, and resource mappings (including per-user OpenCode/Gitea container IDs and hosts).
|
||||
- Use Rivet Kit actors for durable runtime state and orchestration; the Grow Agent is the orchestrator actor and sub-agents are child actors.
|
||||
- Use Git/Gitea (per-user Docker) for long-term memory, files, project artifacts, and auditable history.
|
||||
- Use a per-user OpenCode Docker behind a backend-controlled management layer; sub-agent workflows execute via OpenCode sessions, not by spawning their own containers.
|
||||
- Pull the frontend as a separate app that consumes the Rivet Kit React SDK for actor traffic and the backend REST API for control plane.
|
||||
- Start with an internal Slack-like frontend channel model before integrating real Slack.
|
||||
- Avoid forking OpenCode until the wrapper approach proves insufficient.
|
||||
|
||||
Reference in New Issue
Block a user