Implements horizontally-scalable worker pool architecture: - claudebox-sidecar: HTTP server for Claude Code, git, and SDLC ops - rdev-worker: standalone worker binary polling rdev-api for tasks - HTTP client adapter for sidecar communication - HPA with custom Prometheus metrics for autoscaling - ServiceMonitor for metrics scraping Code review fixes applied: - URL-encode query parameters in GitStatus (Critical #1) - Remove unused shellQuote function (Critical #2) - Use stdlib strings.Split/TrimSpace (Critical #3) - Add version injection via ldflags (Warning #4) - Add debug logging for swallowed git/sdlc errors (Warning #5, #6) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
59 KiB
Orchard Studio: The Interactive Foundry
Vision: A "Deploy First, Code Later" platform where users build software through conversation with an Architect Agent, watching their application evolve in real-time.
1. The Core Philosophy
Current AI coding tools (Cursor, Copilot) operate at the file level. Deploying is the last step.
Orchard Studio flips this:
- Infrastructure is Day 0. You get a URL and a Database immediately.
- Requirements are Fluid. You don't write a spec document; you have a conversation.
- Agents are Engineers. You don't review PRs line-by-line; you review functionality and intent.
- Plans are Visible. You see what the agent understands, not just what it says.
2. The Three-Pane Interface
The Studio presents three synchronized panes: Chat, Plan, and Preview.
┌─────────────────────────────────────────────────────────────────────────────────┐
│ ORCHARD STUDIO cool-project ● Live │
├───────────────────────┬─────────────────────────────┬───────────────────────────┤
│ CHAT │ PLAN │ PREVIEW │
│ ───────────────── │ ───────────────────────── │ ─────────────────────── │
│ │ │ │
│ You: I want users │ ## Cat Photos │ ┌─────────────────────┐ │
│ to post cat photos │ │ │ │ │
│ │ ### Data Model ✓ │ │ cool-project │ │
│ Architect: Should │ ┌─────────────────────┐ │ │ .threesix.ai │ │
│ these be public or │ │ Post │ │ │ │ │
│ friends-only? │ │ - id: uuid │ │ │ [Live App Here] │ │
│ │ │ - image_url: text │ │ │ │ │
│ You: Public, like │ │ - user_id: uuid │ │ │ │ │
│ Instagram │ │ - created_at: ts │ │ │ │ │
│ │ └─────────────────────┘ │ │ │ │
│ Architect: Got it. │ │ │ │ │
│ I've added a public │ ### API Endpoints ✓ │ │ │ │
│ feed. Do you want │ POST /api/posts │ │ │ │
│ likes or comments? │ GET /api/posts (feed) │ │ │ │
│ │ GET /api/posts/:id │ └─────────────────────┘ │
│ │ │ │
│ │ ### UI Components ✓ │ ┌─────────────────────┐ │
│ │ - PhotoUpload │ │ Activity │ │
│ │ - FeedGrid │ │ ───────────────── │ │
│ │ - PostCard │ │ ● Ready to build │ │
│ │ │ │ │ │
│ │ ### Open Questions ⚠ │ │ │ │
│ │ - Likes/comments? │ │ │ │
│ │ - Max image size? │ │ │ │
│ │ │ └─────────────────────┘ │
│ ┌─────────────────┐ │ ───────────────────────── │ │
│ │ Type message... │ │ [Build It] ← disabled │ [↻ Refresh Preview] │
│ └─────────────────┘ │ "2 open questions remain" │ │
└───────────────────────┴─────────────────────────────┴───────────────────────────┘
Pane Responsibilities
| Pane | Purpose | Updates When |
|---|---|---|
| Chat | Conversation with Architect | User/Architect messages |
| Plan | Architect's structured understanding | Every chat turn |
| Preview | Live deployed application | Build completes |
The Plan as Forcing Function
The Plan pane is not decoration—it's the forcing function that ensures quality:
- Visible Understanding: User sees exactly what the Architect thinks they want
- Explicit Gaps: Open questions are shown, not hidden
- Build Gate: "Build It" is disabled until plan meets completeness criteria
- Correction Loop: User can say "no, not that" before any code is written
Building the Plan Agentively
The transition from loose conversation to structured Blueprint requires judgment, not just extraction.
Principles:
| Principle | What It Means |
|---|---|
| Don't rush to structure | Let the conversation develop naturally before filling in Blueprint sections |
| Show your work | "I'm inferring a 16px spacing scale from the card padding I observe" |
| Invite correction | "Does this match what you had in mind, or should I adjust?" |
| Iterate incrementally | Each conversation turn refines the Blueprint slightly |
| Distinguish confidence | "I'm confident about the layout, less sure about the accent color" |
The Architect is not a form-filler. It's a collaborator that builds shared understanding progressively. The structured Blueprint emerges from the conversation—it's not imposed on it.
3. The User Journey
Phase 1: Genesis (Template Selection)
┌─────────────────────────────────────────────────────────────────┐
│ ORCHARD STUDIO [Sign In] │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Start Building │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ ┌─────┐ │ │ ┌─────┐ │ │ ┌─────┐ │ │
│ │ │ 💼 │ │ │ │ 🌍 │ │ │ │ 📄 │ │ │
│ │ └─────┘ │ │ └─────┘ │ │ └─────┘ │ │
│ │ │ │ │ │ │ │
│ │ SaaS │ │ Social │ │ Empty │ │
│ │ Starter │ │ World │ │ Canvas │ │
│ │ │ │ │ │ │ │
│ │ Auth+API+ │ │ Realtime │ │ Hello │ │
│ │ Billing │ │ +Spatial │ │ World │ │
│ │ │ │ │ │ │ │
│ │ [Spawn] │ │ [Spawn] │ │ [Spawn] │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
User Action: Click "Spawn" on a template.
System Response:
- Creates K8s namespace
cool-project - Provisions CockroachDB database
- Seeds skeleton code from template
- Triggers initial CI/CD deployment
- Creates DNS record
cool-project.threesix.ai
Result: Within 60-90 seconds, user has:
- A live URL showing "Hello World" or template landing
- A database ready for tables
- A git repo with CI/CD configured
- The three-pane Studio interface opens
Phase 2: Consultation (The Architect Conversation)
The Architect's job is requirement elicitation, not coding. It:
- Asks clarifying questions
- Updates the Plan after each exchange
- Identifies gaps and assumptions
- Suggests when ready to build
Example Conversation Flow:
User: "I want users to post cat photos"
Architect: "I'll add photo posting. A few questions:
1. Should photos be public (anyone can see) or friends-only?
2. Do you want likes, comments, or neither for v1?"
[Plan updates with partial data model, marks auth as TBD]
User: "Public feed, no comments, just likes"
Architect: "Got it. I've updated the plan:
- Posts are public with a feed endpoint
- Like count per post (no comment system)
- 5MB max image size (default)
The plan looks complete. Ready to build?"
[Plan shows all sections ✓, Build It enables]
User: "Yes, build it"
[Build phase begins]
Phase 3: Materialization (The Build)
When "Build It" is clicked:
┌─────────────────────────────────────────────────────────────────────────────────┐
│ ORCHARD STUDIO cool-project ● Building │
├───────────────────────┬─────────────────────────────┬───────────────────────────┤
│ CHAT │ PLAN │ PREVIEW │
│ ───────────────── │ ───────────────────────── │ ─────────────────────── │
│ │ │ │
│ Architect: Building │ ## Cat Photos │ ┌─────────────────────┐ │
│ your feature now. │ │ │ │ │
│ I'll update you as │ [Plan content unchanged] │ │ [Current App] │ │
│ I progress. │ │ │ │ │
│ │ │ │ │ │
│ │ │ └─────────────────────┘ │
│ │ │ │
│ │ │ ┌─────────────────────┐ │
│ │ │ │ Build Progress │ │
│ │ │ │ ───────────────── │ │
│ │ │ │ ✓ Creating spec │ │
│ │ │ │ ✓ Designing schema │ │
│ │ │ │ ✓ Writing handlers │ │
│ │ │ │ → Running tests │ │
│ │ │ │ ○ Deploying │ │
│ │ │ │ │ │
│ │ │ │ [Cancel Build] │ │
│ │ │ └─────────────────────┘ │
└───────────────────────┴─────────────────────────────┴───────────────────────────┘
System Actions:
- Blueprint → SDLC Feature Spec
- SDLC Classifier drives:
spec → design → implement → test → deploy - SSE stream sends progress events to UI
- On completion, Preview auto-refreshes
Build Progress Events:
{"phase": "spec", "status": "complete", "message": "Feature spec created"}
{"phase": "design", "status": "in_progress", "message": "Designing database schema..."}
{"phase": "design", "status": "complete", "message": "Schema: posts, likes tables"}
{"phase": "implement", "status": "in_progress", "message": "Writing Go handlers..."}
...
{"phase": "deploy", "status": "complete", "message": "Live at cool-project.threesix.ai"}
Design Inspiration Flow
Users can provide visual references at any point in the conversation:
Two Input Types:
| Type | How It Works | Example |
|---|---|---|
| URL | System screenshots the page automatically via Playwright | "Build something like stripe.com/pricing" |
| Screenshot | User uploads image (Figma export, competitor screenshot) | Drag & drop or paste image |
The Collect → Clarify → Plan → Implement Flow:
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 1. COLLECT │
│ │
│ User: "Build a pricing page like this" + [attaches URL or screenshot] │
│ │
│ System: Screenshots URL (if provided), stores reference with Blueprint │
└──────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 2. CLARIFY │
│ │
│ Architect: "I see a dark theme with 3 pricing tiers in cards, gradient CTAs, │
│ and a 'Popular' badge. A few questions: │
│ - Match exactly or use as inspiration? │
│ - Keep the purple gradient or use your brand colors? │
│ - Include the feature comparison table, or just the cards?" │
│ │
│ User: "Inspiration, our brand colors, just the cards for v1" │
└──────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 3. PLAN (Blueprint updates) │
│ │
│ sections.designSystem: │
│ colors: [{name: "primary", value: "#0066FF"}, ...] │
│ spacing: [8, 16, 24, 32] │
│ borderRadius: "12px" │
│ theme: "light" │
│ inspirationNotes: "Card layout from reference, simplified to 3 tiers" │
│ │
│ sections.uiComponents: │
│ - PricingCard (tier name, price, features, CTA) │
│ - PricingGrid (3-column responsive layout) │
│ │
│ references.items: │
│ - {type: "url", source: "stripe.com/pricing", thumbnail: "/refs/abc.png"} │
└──────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 4. IMPLEMENT │
│ │
│ User: "Build it" │
│ │
│ → Blueprint converted to SDLC spec (includes design system tokens) │
│ → Agent implements with extracted design guidance │
│ → Preview shows result │
└──────────────────────────────────────────────────────────────────────────────────┘
Key Principle: The conversation stays loose and exploratory ("I see a dark theme with rounded cards"). The Blueprint stays structured and precise (borderRadius: "12px"). The Architect bridges the gap.
Phase 4: Evolution (Iteration)
After the feature is live, the user continues the conversation:
User: "The photos are too big. Make them a grid."
Architect: "I'll update the FeedGrid component to show photos in a
3-column masonry layout instead of single-column.
This is a style-only change, no new data needed."
[Plan shows: UI Components section updated, minimal scope]
User: "Do it"
[Smaller build cycle: just frontend changes]
4. The Blueprint Schema
The Plan pane renders a structured Blueprint that the Architect maintains.
Blueprint Data Structure
interface Blueprint {
// Metadata
id: string;
projectId: string;
feature: string;
summary: string;
createdAt: string;
updatedAt: string;
// Conversation state
conversationId: string;
turnCount: number;
// Design references (visual inspiration)
references: {
items: Array<{
id: string;
type: 'screenshot' | 'url' | 'figma';
source: string; // Original URL or upload path
thumbnail: string; // Stored screenshot path
annotations?: string; // User notes ("match this layout")
extractedDescription?: string; // LLM description of what it sees
}>;
};
// Structured sections (what the UI renders)
sections: {
dataModel: {
status: 'empty' | 'partial' | 'complete';
entities: Array<{
name: string;
fields: Array<{name: string; type: string; nullable?: boolean}>;
relationships?: string[];
}>;
};
apiEndpoints: {
status: 'empty' | 'partial' | 'complete';
endpoints: Array<{
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
path: string;
description: string;
auth: 'none' | 'required' | 'optional';
}>;
};
uiComponents: {
status: 'empty' | 'partial' | 'complete';
components: Array<{
name: string;
purpose: string;
location: string; // e.g., "apps/web/src/components/"
}>;
};
dependencies: {
status: 'empty' | 'partial' | 'complete';
services: string[]; // e.g., ["postgres", "redis"]
packages: string[]; // e.g., ["pkg/auth"]
external: string[]; // e.g., ["S3 for images"]
};
designSystem?: {
status: 'empty' | 'partial' | 'complete';
colors: Array<{name: string; value: string; usage?: string}>;
typography: Array<{name: string; font: string; size: string; weight?: string}>;
spacing: number[]; // Scale in px, e.g., [4, 8, 16, 24, 32]
borderRadius: string; // e.g., "8px" or "rounded-lg"
theme: 'light' | 'dark' | 'both';
inspirationNotes?: string; // How references informed these choices
};
};
// Completeness tracking
openQuestions: Array<{
id: string;
question: string;
context?: string;
suggestedOptions?: string[];
}>;
assumptions: Array<{
id: string;
assumption: string;
canOverride: boolean;
}>;
// Build gate
readyToBuild: boolean;
blockers: string[]; // Human-readable reasons if not ready
// Estimates (optional, shown to user)
estimates?: {
complexity: 'trivial' | 'simple' | 'moderate' | 'complex';
newTables: number;
newEndpoints: number;
newComponents: number;
};
}
Completeness Rules
The readyToBuild flag is computed from:
function isReadyToBuild(blueprint: Blueprint): {ready: boolean; blockers: string[]} {
const blockers: string[] = [];
// Must have at least one section with content
const hasContent = Object.values(blueprint.sections)
.some(s => s.status !== 'empty');
if (!hasContent) {
blockers.push("No feature content defined yet");
}
// No open questions allowed
if (blueprint.openQuestions.length > 0) {
blockers.push(`${blueprint.openQuestions.length} open questions remain`);
}
// Critical sections must be at least partial
if (blueprint.sections.dataModel.status === 'empty' &&
blueprint.sections.apiEndpoints.status === 'empty') {
blockers.push("Need at least data model or API endpoints");
}
return {
ready: blockers.length === 0,
blockers
};
}
5. API Design
Blueprint Chat Endpoint
The primary interaction point for the Architect conversation.
POST /projects/{projectId}/blueprint/chat
Request:
{
"blueprintId": "bp_abc123", // null for new conversation
"message": "I want users to post cat photos",
"references": [ // optional: design inspiration
{
"type": "url",
"source": "https://dribbble.com/shots/12345"
},
{
"type": "screenshot",
"source": "data:image/png;base64,..." // or uploaded file path
}
]
}
Response:
{
"blueprintId": "bp_abc123",
"reply": "I'll add photo posting. Should these be public or friends-only?",
"blueprint": {
"feature": "Cat Photos",
"sections": {
"dataModel": {
"status": "partial",
"entities": [
{
"name": "Post",
"fields": [
{"name": "id", "type": "uuid"},
{"name": "image_url", "type": "text"},
{"name": "user_id", "type": "uuid"},
{"name": "created_at", "type": "timestamp"}
]
}
]
},
"apiEndpoints": {"status": "empty", "endpoints": []},
"uiComponents": {"status": "empty", "components": []},
"dependencies": {"status": "partial", "services": ["postgres"], "packages": [], "external": ["image storage"]}
},
"openQuestions": [
{
"id": "q1",
"question": "Should photos be public or friends-only?",
"suggestedOptions": ["Public feed (anyone)", "Friends only", "Private (only owner)"]
}
],
"assumptions": [
{"id": "a1", "assumption": "5MB max image size", "canOverride": true}
],
"readyToBuild": false,
"blockers": ["1 open question remains"]
}
}
Build Trigger Endpoint
Converts a complete Blueprint into an SDLC feature and starts the build.
POST /projects/{projectId}/blueprint/{blueprintId}/build
Request:
{
"blueprintId": "bp_abc123"
}
Response:
{
"operationId": "op_xyz789",
"featureSlug": "cat-photos",
"status": "started",
"streamUrl": "/projects/{projectId}/operations/{operationId}/stream"
}
Build Progress Stream
SSE endpoint for real-time build progress.
GET /projects/{projectId}/operations/{operationId}/stream
Event Stream:
event: phase
data: {"phase": "spec", "status": "complete", "message": "Feature spec created", "timestamp": "..."}
event: phase
data: {"phase": "design", "status": "in_progress", "message": "Designing database schema...", "timestamp": "..."}
event: artifact
data: {"type": "schema", "content": "CREATE TABLE posts (...)", "timestamp": "..."}
event: phase
data: {"phase": "design", "status": "complete", "message": "Schema complete", "timestamp": "..."}
event: phase
data: {"phase": "implement", "status": "in_progress", "message": "Writing handlers...", "timestamp": "..."}
event: progress
data: {"phase": "implement", "step": "handlers", "progress": 0.5, "message": "3 of 6 handlers complete"}
event: phase
data: {"phase": "test", "status": "in_progress", "message": "Running tests...", "timestamp": "..."}
event: test
data: {"passed": 12, "failed": 0, "skipped": 0}
event: phase
data: {"phase": "deploy", "status": "in_progress", "message": "Deploying to cluster...", "timestamp": "..."}
event: complete
data: {"status": "success", "deployedAt": "...", "url": "https://cool-project.threesix.ai"}
Blueprint Management
GET /projects/{projectId}/blueprints # List all blueprints
GET /projects/{projectId}/blueprints/{id} # Get specific blueprint
DELETE /projects/{projectId}/blueprints/{id} # Discard draft blueprint
6. The Architect Agent
Responsibilities
The Architect is a specialized agent persona that:
- Elicits requirements through targeted questions
- Maintains structured state (the Blueprint)
- Identifies gaps before they become problems
- Suggests defaults for common decisions
- Knows when to stop asking and start building
System Prompt (Abbreviated)
You are the Architect, a requirements engineer for Orchard Studio.
## Your Role
- Help users define what they want to build
- Ask clarifying questions to fill gaps
- Maintain a structured Blueprint (provided in context)
- Suggest when the plan is complete enough to build
## Your Constraints
- NEVER write code or implementation details
- NEVER assume requirements—ask when uncertain
- ALWAYS update the Blueprint after each exchange
- KEEP questions focused (1-3 at a time, not 10)
## Handling Design References
When the user provides a URL or screenshot as inspiration:
1. **Describe what you observe** (conversational, natural language):
"I see a dark-themed pricing page with three tiers in cards,
gradient CTA buttons, and a highlighted 'Popular' badge on the middle tier."
2. **Ask clarifying questions about intent**:
- "Should I match this layout exactly, or use it as loose inspiration?"
- "I notice they use purple gradients. Should I match this or use your brand colors?"
- "The cards have subtle shadows. Is this level of polish important for v1?"
3. **Extract structured design tokens into the Blueprint** (machine-readable):
Update `sections.designSystem` with inferred values:
- Colors extracted from the reference
- Spacing patterns observed
- Typography characteristics
- Component patterns identified
4. **Reference the inspiration in your plan**:
Add to `sections.designSystem.inspirationNotes` how the reference informed choices.
The conversation stays loose and exploratory. The Blueprint stays structured and precise.
## Blueprint Sections You Maintain
- Data Model: entities, fields, relationships
- API Endpoints: routes, methods, auth requirements
- UI Components: what the user will see and interact with
- Dependencies: services, packages, external integrations
- Design System: colors, typography, spacing, theme (when references provided)
## Completeness Criteria
A Blueprint is ready to build when:
- At least one section has meaningful content
- No open questions remain
- User has confirmed the plan
## Response Format
Always respond with:
1. A conversational message to the user
2. An updated Blueprint JSON (system will render it)
## Question Strategy
- Start broad: "What are you building?"
- Get specific: "Should X be public or private?"
- Offer defaults: "I'll assume 5MB limit unless you specify"
- Confirm scope: "So no comments for v1, just likes?"
Architect Decision Tree
User message received
│
▼
┌───────────────────────────────────┐
│ Parse user intent │
│ - New requirement? │
│ - Answer to open question? │
│ - Correction to plan? │
│ - Request to build? │
└───────────────────────────────────┘
│
▼
┌───────────────────────────────────┐
│ Update Blueprint │
│ - Add/modify entities │
│ - Add/modify endpoints │
│ - Resolve open questions │
│ - Add new assumptions │
└───────────────────────────────────┘
│
▼
┌───────────────────────────────────┐
│ Evaluate completeness │
│ - Any critical gaps? │
│ - Any open questions? │
│ - Ready to build? │
└───────────────────────────────────┘
│
├─── Gaps exist ──────► Ask 1-2 clarifying questions
│
├─── Ready to build ──► "Plan looks complete. Ready to build?"
│
└─── User said build ─► Confirm and trigger build
7. Technical Architecture
System Components
┌─────────────────────────────────────────────────────────────────────────────┐
│ ORCHARD STUDIO │
│ (Next.js Frontend) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Chat Pane │ │ Plan Pane │ │ Preview │ │ Activity │ │
│ │ │ │ │ │ (iframe) │ │ Feed │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │ │
│ └────────────────┴────────────────┴────────────────┘ │
│ │ │
│ WebSocket / SSE │
└───────────────────────────────────┼─────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────────────────────┐
│ RDEV-API │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Blueprint │ │ Operations │ │ Projects │ │
│ │ Handler │ │ Handler │ │ Handler │ │
│ │ │ │ │ │ │ │
│ │ POST /chat │ │ GET /stream │ │ POST /spawn │ │
│ │ POST /build │ │ GET /{id} │ │ GET /list │ │
│ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Service Layer │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ Architect │ │ Orchestrator │ │ Project │ │ │
│ │ │ Service │ │ Service │ │ Service │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ - Chat loop │ │ - Run trees │ │ - Provision │ │ │
│ │ │ - Blueprint │ │ - Track ops │ │ - Templates │ │ │
│ │ │ - LLM calls │ │ - Stream │ │ - DNS │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Adapter Layer │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Postgres │ │ K8s │ │ Claude │ │ Gitea │ │ │
│ │ │ (state) │ │ (pods) │ │ (LLM) │ │ (git) │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────────────────────┐
│ WORKER PODS (claudebox) │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ SDLC Execution Environment │ │
│ │ - Clone project repo │ │
│ │ - Run `sdlc next --execute` │ │
│ │ - Commit and push changes │ │
│ │ - Stream progress to rdev-api │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────────────────┘
Data Flow: Blueprint to Deployed Feature
1. User types in Chat
│
▼
2. POST /blueprint/chat
│
▼
3. Architect Service
- Load conversation context
- Call Claude API with Architect prompt
- Parse response into reply + blueprint delta
- Persist updated blueprint
│
▼
4. Return {reply, blueprint} to UI
│
▼
5. User clicks "Build It"
│
▼
6. POST /blueprint/{id}/build
│
▼
7. Orchestrator Service
- Convert Blueprint → SDLC Feature Spec
- Create feature via SDLC API
- Start operation tracking
- Dispatch to worker queue
│
▼
8. Worker Pod executes
- sdlc next --execute --stream
- Events sent to rdev-api
│
▼
9. SSE stream to UI
- Phase updates
- Progress indicators
- Completion notification
│
▼
10. Preview iframe refreshes
- User sees deployed feature
Database Schema Additions
-- Blueprint storage
CREATE TABLE blueprints (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
project_id UUID NOT NULL REFERENCES projects(id),
feature_name TEXT NOT NULL,
summary TEXT,
-- Structured content (JSONB for flexibility)
sections JSONB NOT NULL DEFAULT '{}',
open_questions JSONB NOT NULL DEFAULT '[]',
assumptions JSONB NOT NULL DEFAULT '[]',
-- Completeness
ready_to_build BOOLEAN NOT NULL DEFAULT FALSE,
blockers JSONB NOT NULL DEFAULT '[]',
-- Lifecycle
status TEXT NOT NULL DEFAULT 'draft', -- draft, building, built, archived
built_feature_slug TEXT, -- links to SDLC feature after build
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Conversation history
CREATE TABLE blueprint_messages (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
blueprint_id UUID NOT NULL REFERENCES blueprints(id) ON DELETE CASCADE,
role TEXT NOT NULL, -- 'user' or 'architect'
content TEXT NOT NULL,
blueprint_snapshot JSONB, -- state after this message
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Operation tracking (tree runner state in DB)
CREATE TABLE operations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
project_id UUID NOT NULL REFERENCES projects(id),
blueprint_id UUID REFERENCES blueprints(id),
-- What's running
operation_type TEXT NOT NULL, -- 'build', 'deploy', 'tree'
tree_name TEXT,
-- Status
status TEXT NOT NULL DEFAULT 'pending', -- pending, running, complete, failed
current_phase TEXT,
progress JSONB NOT NULL DEFAULT '{}',
-- Results
result JSONB,
error TEXT,
started_at TIMESTAMPTZ,
completed_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Operation events (for replay/audit)
CREATE TABLE operation_events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
operation_id UUID NOT NULL REFERENCES operations(id) ON DELETE CASCADE,
event_type TEXT NOT NULL, -- 'phase', 'progress', 'artifact', 'error', 'complete'
payload JSONB NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_operations_project ON operations(project_id);
CREATE INDEX idx_operations_status ON operations(status) WHERE status = 'running';
CREATE INDEX idx_operation_events_operation ON operation_events(operation_id);
CREATE INDEX idx_blueprints_project ON blueprints(project_id);
8. Environments: Staging and Production
Every project has two environments. Development happens in staging; users see production.
The Environment Model
┌─────────────────────────────────────────────────────────────────┐
│ Project: cool-project │
│ │
│ STAGING PRODUCTION │
│ staging.cool-project cool-project │
│ .threesix.ai .threesix.ai │
│ │
│ • Where development happens • User-facing, stable │
│ • Preview pane shows this • Only updated via "Publish" │
│ • "Build It" deploys here • Production credentials │
│ • Test/sandbox credentials • Enabled after first publish │
│ │
│ "Build It" "Publish" │
│ │ │ │
│ ▼ ▼ │
│ [Staging] ─────────────────► [Production] │
└─────────────────────────────────────────────────────────────────┘
Preview Pane = Staging
The Preview pane always shows the staging environment:
<iframe
src="https://staging.cool-project.threesix.ai"
sandbox="allow-scripts allow-same-origin allow-forms"
/>
This means:
- Development is always isolated from users
- You can break things without affecting production
- "Publish" is an explicit, intentional action
The Publish Flow
┌─────────────────────────────────────────────────────────────────────────────────┐
│ STUDIO: Ready to Publish │
├───────────────────────┬─────────────────────────────┬───────────────────────────┤
│ CHAT │ PLAN │ PREVIEW │
│ │ │ staging.cool-project │
│ Architect: Feature │ ## Photo Feed │ .threesix.ai │
│ is complete and │ │ │
│ deployed to staging. │ Status: ✓ Built │ ┌─────────────────────┐ │
│ │ Tests: ✓ 24 passing │ │ [Feature working] │ │
│ Ready to publish │ Coverage: 87% │ │ │ │
│ to production? │ │ └─────────────────────┘ │
│ │ │ │
│ │ │ ────────────────────── │
│ │ │ Environment: [Staging ▼] │
│ │ │ │
│ │ │ [Publish to Production] │
└───────────────────────┴─────────────────────────────┴───────────────────────────┘
When "Publish" is clicked:
- Validate staging is healthy (deployment running, health checks pass)
- Ensure production has credentials for all services staging uses
- Run any pending database migrations on production
- Deploy the staging image to production
- Health check production
- SSE event:
{"type": "published", "productionUrl": "https://cool-project.threesix.ai"}
Credential Handling
Services may have different credentials per environment:
| Service | Staging | Production |
|---|---|---|
| Test mode (no real sends) | Live sends | |
| Stats | Separate project | Separate project |
| Auth | Test users | Real users |
| Logging | Same (or tagged) | Same (or tagged) |
The platform handles this automatically during provisioning and publish.
9. Platform Services
Projects can connect to shared platform services for common capabilities.
Available Services
┌─────────────────────────────────────────────────────────────────┐
│ PLATFORM SERVICES │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Logging │ │ Email │ │ Stats │ │
│ │ ─────────── │ │ ─────────── │ │ ─────────── │ │
│ │ Loki │ │ Resend │ │ PostHog │ │
│ │ │ │ │ │ │ │
│ │ Centralized │ │ Transaction │ │ Product │ │
│ │ logs │ │ email │ │ analytics │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────┐ │
│ │ Auth │ (More services can be added) │
│ │ ─────────── │ │
│ │ Clerk │ │
│ │ │ │
│ │ User auth │ │
│ │ & identity │ │
│ └─────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Service Rollout Order
Services are added in order of complexity:
| Order | Service | What It Provides |
|---|---|---|
| 1 | Logging | Ship logs to centralized Loki instance |
| 2 | Send transactional emails via Resend | |
| 3 | Stats | Product analytics via PostHog |
| 4 | Auth | User authentication via Clerk |
Adding Services to Projects
For new projects: Select services during template selection or via Architect conversation.
For existing projects: Add services via API or Studio UI.
User: "I need to send password reset emails"
Architect: "I'll add the email service to your project.
This will provision Resend credentials and add
the email client to your codebase.
I'll create a PR with the integration code."
[Blueprint updates: platformServices includes email]
[On build: Resend provisioned, credentials injected, PR created]
How Services Are Integrated
POST /projects/{id}/services
{ "type": "email", "provider": "resend" }
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 1. PROVISION │
│ Create Resend API key for this project │
│ Store encrypted credentials │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 2. INJECT │
│ Add RESEND_API_KEY to K8s secrets │
│ Restart deployment to pick up new env vars │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 3. INTEGRATE │
│ Create PR with: │
│ • resend package in package.json │
│ • Email service client code │
│ • Updated .env.example │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 4. VERIFY │
│ After PR merge and deploy, verify service is working │
│ (send test email, check logs appearing, etc.) │
└─────────────────────────────────────────────────────────────────┘
Blueprint Integration
The Architect understands platform services:
// Blueprint includes platform service requirements
platformServices: [
{ type: 'logging', provider: 'loki' }, // Always recommended
{ type: 'email', provider: 'resend' }, // When emails needed
{ type: 'stats', provider: 'posthog' }, // For analytics
{ type: 'auth', provider: 'clerk' }, // For user accounts
]
When the Blueprint includes a service, the build phase:
- Provisions credentials (if not already done)
- Injects into K8s secrets
- Adds integration code to the project
10. The Preview System
Preview = Staging Environment
The Preview pane is an iframe pointing to the staging deployment:
<iframe
src="https://staging.cool-project.threesix.ai"
sandbox="allow-scripts allow-same-origin allow-forms"
/>
Environment Switcher
The Studio includes an environment switcher to view either environment:
┌─────────────────────────────────────────┐
│ Preview │
│ ───────────────────────────────────── │
│ │
│ Environment: [Staging ▼] │
│ ├─ Staging │
│ └─ Production │
│ │
│ ┌─────────────────────────────────┐ │
│ │ [iframe content] │ │
│ │ │ │
│ └─────────────────────────────────┘ │
│ │
│ [↻ Refresh] [Open in New Tab] │
└─────────────────────────────────────────┘
Refresh Mechanism
When a build completes:
- SSE event:
{"type": "complete", "url": "https://staging.cool-project.threesix.ai"} - UI receives event
- Show notification: "Staging updated. [Refresh Preview]"
When publish completes:
- SSE event:
{"type": "published", "url": "https://cool-project.threesix.ai"} - UI receives event
- Show notification: "Published to production!"
11. Success Criteria
The Demo: "Aeries in 10 Minutes"
The flagship demo should be:
- Genesis (30 sec): User spawns "Social World" template
- Consultation (5 min): Chat defines agent simulation features
- Build (3-4 min): Watch SDLC execute, tests pass, deploy
- Live (immediate): Click into preview, see agents walking around
If this flow works smoothly, the platform is viable.
Metrics to Track
| Metric | Target | Why It Matters |
|---|---|---|
| Genesis to Live URL | < 90 sec | First impression |
| Chat turn latency | < 3 sec | Conversational feel |
| Build time (simple feature) | < 5 min | User patience |
| Build success rate | > 90% | Trust in system |
| Preview refresh after deploy | < 10 sec | Instant gratification |
Definition of Done: Phase by Phase
Phase 1 (Engine): slackpath-1 completes autonomously via CLI
Phase 2 (API): Same flow works via curl to new endpoints
Phase 3 (Architect): Conversation produces valid Blueprint JSON
Phase 4 (Studio): Three-pane UI renders and triggers builds
Phase 5 (Aeries): Social world built entirely through Studio
12. Risks and Mitigations
| Risk | Impact | Mitigation |
|---|---|---|
| Architect asks too many questions | User frustration | Limit to 2-3 questions per turn, suggest defaults |
| Build takes too long | User abandonment | Show granular progress, allow cancel |
| Build fails mid-way | Broken state | SDLC already handles partial state, surface clearly in UI |
| Preview shows stale content | Confusion | Force refresh on deploy complete, show version indicator |
| LLM costs unpredictable | Budget overrun | Show estimates before build, set per-project limits |
| Blueprint schema too rigid | Can't express features | Start simple, evolve schema based on real usage |
13. What We're NOT Building (Yet)
To stay focused:
- No collaborative editing (one user per project for now)
- No cost estimation UI (track internally, expose later)
- No rollback UI (use git history directly if needed)
- No custom domains (subdomains only:
*.threesix.ai) - No self-hosted service providers (platform manages all integrations)
These are all future enhancements, not blockers.