diff --git a/docs/creator-mode/IMPLEMENTATION_BACKLOG.md b/docs/creator-mode/IMPLEMENTATION_BACKLOG.md new file mode 100644 index 00000000..4e45eb75 --- /dev/null +++ b/docs/creator-mode/IMPLEMENTATION_BACKLOG.md @@ -0,0 +1,168 @@ +# Creator Mode Implementation Backlog + +## Scope +This backlog translates `docs/creator-mode/SPEC.md` into implementation-ready epics and stories targeted at: +- `cartridge-gg/internal` (Go control plane and orchestration) +- Arcade frontend (`client/`) for Creator UI + +All stories include acceptance criteria and dependencies. + +## Milestone M0: Foundations (2 weeks) + +### Epic M0-E1: Data + API Skeleton (`internal`) +1. Story M0-E1-S1: Create core DB schema migrations +- Files: mirrored in `docs/creator-mode/scaffolding/internal/migrations/0001_creator_mode.sql` +- Acceptance: + - Tables for projects, plans, runs, events, artifacts, deployments, quotas, usage exist. + - FK constraints and indexes exist for key lookup paths. + +2. Story M0-E1-S2: Implement Creator API route group +- Endpoints: + - `POST /v1/creator/projects` + - `GET /v1/creator/projects/{id}` + - `GET /v1/creator/projects/{id}/runs/{runId}` +- Acceptance: + - OpenAPI generated docs include all request/response models. + - AuthZ middleware enforces workspace scope. + +3. Story M0-E1-S3: Implement run event SSE endpoint +- Endpoint: `GET /v1/creator/projects/{id}/runs/{runId}/events` +- Acceptance: + - Supports `Last-Event-ID` replay semantics. + - Events emitted in monotonic `sequence` order. + +### Epic M0-E2: GitHub provisioning (`internal`) +1. Story M0-E2-S1: GitHub App installation and token exchange +- Acceptance: + - Installation ID linked to workspace. + - API can mint short-lived installation token. + +2. Story M0-E2-S2: Repo bootstrap flow +- Acceptance: + - Repo created per project. + - Starter template copied with README and CI. + - Project status transitions to `active` on success. + +## Milestone M1: Interactive Planning (2-3 weeks) + +### Epic M1-E1: Planning sessions + versions (`internal`) +1. Story M1-E1-S1: Create planning session lifecycle endpoints +- `POST /plan/sessions`, `POST /messages`, `POST /approve` +- Acceptance: + - Session statuses persist correctly. + - Version history immutable. + +2. Story M1-E1-S2: Plan completeness validator +- Acceptance: + - Required schema fields validated. + - Completeness score returned in API. + +### Epic M1-E2: Creator planning UI (`client`) +1. Story M1-E2-S1: Add `/creator` route and project selector +- Acceptance: + - Route appears in app navigation. + - Project state sourced from Creator API. + +2. Story M1-E2-S2: Planning chat + editable plan tree +- Acceptance: + - User can answer clarifying prompts. + - Plan graph edits persist to new plan version. + - Approve button only enabled when complete. + +## Milestone M2: Run Execution + Sandboxes (3 weeks) + +### Epic M2-E1: Harness adapter runtime (`internal`) +1. Story M2-E1-S1: Implement adapter interface and registry +- Adapters: codex, claude, gemini +- Acceptance: + - Common `HarnessAdapter` contract implemented. + - Provider errors normalized to standard taxonomy. + +2. Story M2-E1-S2: Usage metering integration +- Acceptance: + - Tokens/runtime tracked by run and workspace. + - Usage ledger written per completed step. + +### Epic M2-E2: K8s sandbox controller (`internal`) +1. Story M2-E2-S1: Job launcher + monitor +- Acceptance: + - One Kubernetes Job per run with resource caps. + - Lease row created/updated with pod status. + +2. Story M2-E2-S2: Checkpoint and resume primitives +- Acceptance: + - Step checkpoints stored durably. + - Resume on pod restart from last checkpoint. + +3. Story M2-E2-S3: Quota enforcement +- Acceptance: + - Run blocked when workspace caps exceeded. + - Budget exceeded during run triggers terminal state with reason. + +### Epic M2-E3: Execution UI (`client`) +1. Story M2-E3-S1: Run timeline + step graph +- Acceptance: + - Live status updates from SSE. + - Failed step shows actionable summary. + +2. Story M2-E3-S2: Logs and artifact browser +- Acceptance: + - Logs stream in near real-time. + - Artifacts downloadable with metadata. + +## Milestone M3: Dojo Pipeline + Deploy (2 weeks) + +### Epic M3-E1: Build/test/deploy workflow (`internal`) +1. Story M3-E1-S1: Build + test execution stage +- Acceptance: + - Cairo and TS checks run and persist outputs. + - Deploy stage gated by passing checks. + +2. Story M3-E1-S2: Devnet + Sepolia deployment stage +- Acceptance: + - Deploy tx hashes and world/contract addresses persisted. + - Deployment summary artifact generated. + +### Epic M3-E2: Deployment UI (`client`) +1. Story M3-E2-S1: Deployments panel +- Acceptance: + - Shows per-environment status and tx metadata. + - Displays reproducibility metadata (git SHA, tool versions). + +## Milestone M4: Hardening + Launch (2 weeks) + +### Epic M4-E1: Observability +1. Story M4-E1-S1: Metrics + tracing +- Acceptance: + - Dashboards for run success, queue time, cost/usage. + - Alerting on provider outage and queue backlog. + +### Epic M4-E2: Security + abuse controls +1. Story M4-E2-S1: Secret isolation + redaction audit +- Acceptance: + - No secret values in logs/events. + +2. Story M4-E2-S2: Self-serve guardrails +- Acceptance: + - Per-workspace rate limits and anti-abuse limits configured. + +## Cross-Cutting Test Matrix +1. Unit: validator, adapter normalization, scheduler, quota evaluator. +2. Integration: planning to approved plan, run with mocked harness, repo provisioning. +3. E2E: create -> plan -> run -> deploy success. +4. Chaos: pod preemption, provider timeout, SSE reconnect/replay. + +## Delivery Ownership (Proposed) +- Internal platform/backend team: M0/M1 internal, M2, M3 backend, M4 backend. +- Frontend team: M1 UI, M2 UI, M3 UI. +- DevOps/SRE: cluster capacity, job templates, observability stack. + +## Critical Path +1. M0 schema + API + GitHub provisioning +2. M1 planning and approval flow +3. M2 run orchestration + sandbox stability +4. M3 deploy automation + +## Launch Readiness Gate +- Reference game can be generated and deployed to Sepolia via each harness adapter. +- Quota controls verified under load profile for 100 active creators/month. diff --git a/docs/creator-mode/PRD.md b/docs/creator-mode/PRD.md new file mode 100644 index 00000000..2683aff5 --- /dev/null +++ b/docs/creator-mode/PRD.md @@ -0,0 +1,202 @@ +# Creator Mode PRD + +## 1. Document Control +- Product: Creator Mode for Onchain Games (Dojo + Cartridge) +- Target release: MVP over 5 phases +- Last updated: 2026-02-24 +- Primary audience: internal/partner game teams and open self-serve developers + +## 2. Problem Statement +Game teams building on Dojo/Cartridge currently stitch together planning, code generation, repo setup, CI, and Starknet deployment manually across multiple tools. This creates high setup friction, inconsistent quality, and long cycle times from idea to a deployed, skill-based onchain game. + +We need a "creator" mode that: +- Interactively clarifies requirements into a decision-complete plan. +- Orchestrates agent execution (Codex, Claude Code, Gemini) to implement end-to-end. +- Persists all code and artifacts to GitHub. +- Shows live plan/progress while work executes. +- Automates devnet + Sepolia build/test/deploy flows. +- Remains cost-efficient for an MVP scale of up to 100 active creators/month. + +## 3. Goals +1. Reduce idea-to-first-deployed-game time by >60% versus manual baseline. +2. Provide structured planning that resolves ambiguities before execution. +3. Provide portable harness support (Codex/Claude/Gemini) behind one orchestration layer. +4. Ensure deterministic persistence (repo-per-project, auditable commits, run logs, artifacts). +5. Keep infra cost low with Kubernetes job-based ephemeral sandboxes and strict quotas. + +## 4. Non-Goals (MVP) +- Mainnet deployment automation. +- Fully custom plugin marketplace for arbitrary third-party tools. +- Real-time multiplayer simulation hosting. +- Multi-region active-active orchestration. + +## 5. Personas +1. Studio Technical Lead +- Wants rapid prototyping and reliable delivery to Sepolia. +- Needs auditable plans/runs, PRs, and deploy artifacts. + +2. Solo Onchain Developer +- Wants guided planning and low-ops automation. +- Needs clear errors and actionable remediation. + +3. Internal Ecosystem Team +- Wants standardized project outputs and lower support burden. +- Needs policy controls, cost guardrails, and observability. + +## 6. Jobs To Be Done +- "Given a game concept, help me reach a complete implementation plan without missing critical decisions." +- "Given an approved plan, generate and iterate Cairo/Dojo code, tests, and deployment artifacts in GitHub." +- "Show me exactly where execution stands and what failed, in language I can act on." + +## 7. User Journey +1. Project setup +- User creates Creator project. +- System provisions one GitHub repo from template and links workspace. + +2. Interactive planning +- Planner agent asks targeted clarification questions. +- User answers and edits a structured plan tree. +- Plan enters "Approved" state. + +3. Execution +- User chooses harness (Codex/Claude/Gemini) and starts run. +- Orchestrator spawns sandbox and executes step graph. +- UI streams live progress, logs, artifacts. + +4. Validation + deployment +- Build/tests run automatically. +- Deploy to devnet + Sepolia (if selected). +- Outputs include contract/world addresses and tx hashes. + +5. Handoff +- Repo contains code, CI config, docs, and deployment summary. +- Run report is archived for auditability. + +## 8. Functional Requirements + +### 8.1 Project + Repo Lifecycle +- Create Creator project with metadata and owner. +- Provision GitHub repo per game project via GitHub App. +- Seed with Dojo/Cartridge starter template and CI workflows. +- Support branch/PR strategy for agent-generated changes. + +### 8.2 Planning System +- Start a planning session per project. +- Planner must ask clarifying questions until required spec fields are complete. +- Represent plan as editable tree/graph with statuses and dependencies. +- Require explicit user approval before execution. +- Maintain immutable plan versions and diffs. + +### 8.3 Multi-Agent Harness +- Single harness abstraction with adapters for: + - Codex + - Claude Code + - Gemini +- Normalize token usage, step output, and error semantics. +- Allow harness selection per run. + +### 8.4 Run Orchestration +- Execute approved plan as step graph with retries and checkpoints. +- Stream run events/logs to UI in near real-time. +- Support cancel/pause/resume (resume from last durable checkpoint). +- Persist artifacts (patches, test outputs, manifests, deploy records). + +### 8.5 Sandbox Execution +- Spawn Kubernetes Job per run (one sandbox for full run). +- Enforce resource limits, timeouts, and cleanup TTL. +- Use ephemeral workspace storage plus durable artifact uploads. + +### 8.6 Dojo/Starknet Delivery +- Build/test Cairo + TS where applicable. +- Automate deployment to devnet and Sepolia. +- Capture world/contract addresses and tx hashes. +- Emit deployment summary and rollback guidance. + +### 8.7 Progress UX +- Display current plan, active step, completed steps, blocked steps. +- Provide structured step logs and summarized errors. +- Show cost/runtime counters at run and workspace level. + +### 8.8 Security + Credentials +- BYOK provider credentials scoped per workspace. +- Secret-at-rest encryption and runtime injection only. +- No plaintext secrets in logs/artifacts. + +## 9. Non-Functional Requirements +- Availability: control plane 99.5% for MVP. +- Durability: plan/run/audit records persisted transactionally. +- Latency: + - event stream update target p95 < 2s from producer to UI + - run creation p95 < 5s before queued/running state +- Security: strict RBAC on project/run operations. +- Cost: quotas and worker pool controls to fit MVP budget envelope. + +## 10. Success Metrics + +### Product Metrics +- Time from project creation to first successful Sepolia deployment. +- Planning completion rate (sessions reaching approved plan). +- Run success rate and mean retries per run. +- Weekly active creators. + +### Quality Metrics +- % runs with actionable error summaries. +- % deployments requiring manual intervention. +- Test pass rate on generated projects. + +### Cost Metrics +- Median run cost by harness. +- Monthly infra cost per active creator. +- % runs terminated by quota/timeout (must remain controlled). + +## 11. Constraints +- Existing backend foundation is `cartridge-gg/internal` (Go). +- Must support both internal/partner teams and open self-serve. +- Must minimize infra/ops overhead for MVP. + +## 12. Risks and Mitigations +1. Scope overload from multi-persona MVP +- Mitigation: strict phased rollout + minimum UX surface in phase 1. + +2. Runaway compute/token cost +- Mitigation: workspace quotas, concurrency caps, hard runtime ceilings. + +3. Unclear plan quality leads to bad execution +- Mitigation: required plan schema completeness checks before approval. + +4. Provider instability across harnesses +- Mitigation: adapter isolation + fallback/retry policy + clear provider health telemetry. + +5. Sandbox failures (preemption/timeout) +- Mitigation: durable checkpoints and idempotent step execution. + +## 13. Rollout Plan +1. Phase 0 (Foundations) +- Project/repo provisioning, schema, eventing, basic run primitives. + +2. Phase 1 (Planning) +- Interactive clarifications, plan tree editor, approval gates. + +3. Phase 2 (Execution) +- Multi-harness adapter, sandbox runner, live progress stream. + +4. Phase 3 (Dojo pipeline) +- Automated build/test + devnet/Sepolia deploy outputs. + +5. Phase 4 (Hardening) +- Quotas, observability, reliability, security hardening. + +## 14. MVP Acceptance Criteria +- User can create project and get a linked GitHub repo. +- User can complete an interactive planning session to an approved plan. +- User can execute approved plan with selected harness. +- UI shows live step progress and logs during execution. +- Code and artifacts are persisted to GitHub and storage. +- Automated devnet + Sepolia deployment succeeds for at least one reference template game. +- Quotas prevent unbounded cost in test load. + +## 15. Out-of-Scope Backlog (Post-MVP) +- Mainnet deployment automation with policy approvals. +- Advanced collaborative planning board and multiplayer editing. +- Custom tool/plugin marketplace and third-party extension SDK. +- Enterprise SSO/SCIM and per-org compliance exports. diff --git a/docs/creator-mode/SPEC.md b/docs/creator-mode/SPEC.md new file mode 100644 index 00000000..67fa768e --- /dev/null +++ b/docs/creator-mode/SPEC.md @@ -0,0 +1,389 @@ +# Creator Mode Technical SPEC + +## 1. Document Control +- System: Creator Mode Orchestration + UI +- Last updated: 2026-02-24 +- Language/runtime assumptions: + - Backend control plane in Go (within `cartridge-gg/internal`) + - Frontend integration in existing React app + - Execution sandboxes on Kubernetes + +## 2. Architecture Overview + +### 2.1 Components +1. Creator API (Go) +- Project, planning, run, deployment, quota APIs. +- AuthZ and workspace RBAC enforcement. + +2. Planner Service (Go + harness adapter) +- Manages interactive clarification loop. +- Produces structured plan graph and completeness scoring. + +3. Run Orchestrator (Go) +- Converts approved plan version into executable DAG. +- Manages queueing, scheduling, state transitions, retries. + +4. Sandbox Controller (Go) +- Creates/monitors Kubernetes Jobs. +- Streams logs/events and enforces runtime/resource limits. + +5. Harness Adapter Layer +- Provider-neutral interface with adapters: + - CodexAdapter + - ClaudeAdapter + - GeminiAdapter + +6. Artifact + State Stores +- PostgreSQL for system-of-record state. +- Object storage for logs/artifacts/checkpoints. +- GitHub repo per project for source persistence. + +7. Creator UI (React) +- Planning chat + editable plan tree. +- Run timeline, live logs, artifacts, deployment panel. + +### 2.2 High-Level Data Flow +1. User creates project -> GitHub repo provisioned. +2. User starts planning session -> planner asks clarifications -> plan versions stored. +3. User approves plan -> run created with selected harness. +4. Orchestrator acquires quota -> launches K8s Job. +5. Sandbox executes steps, emits events, pushes commits/artifacts. +6. Build/test/deploy outputs persisted and shown in UI. + +## 3. Domain Model + +### 3.1 Core Entities +- `creator_projects` + - `id`, `workspace_id`, `name`, `github_repo`, `default_branch`, `status`, `created_at` + +- `plan_sessions` + - `id`, `project_id`, `status` (`draft`, `awaiting_user`, `ready_for_approval`, `approved`, `archived`), `created_by`, `created_at` + +- `plan_versions` + - `id`, `session_id`, `version`, `plan_graph_json`, `completeness_score`, `assumptions_json`, `created_at` + +- `runs` + - `id`, `project_id`, `plan_version_id`, `harness`, `status` (`queued`, `starting`, `running`, `paused`, `failed`, `succeeded`, `canceled`), `started_at`, `finished_at`, `cost_estimate` + +- `run_steps` + - `id`, `run_id`, `step_key`, `depends_on`, `status`, `attempt`, `started_at`, `finished_at`, `summary`, `error_code` + +- `run_events` + - `id`, `run_id`, `sequence`, `event_type`, `payload_json`, `created_at` + +- `artifacts` + - `id`, `run_id`, `step_id`, `type`, `uri`, `checksum`, `metadata_json`, `created_at` + +- `deployments` + - `id`, `run_id`, `environment` (`devnet`, `sepolia`), `status`, `world_address`, `tx_hashes_json`, `manifest_uri`, `created_at` + +- `sandbox_leases` + - `id`, `run_id`, `k8s_job_name`, `pod_name`, `node_type`, `cpu_limit`, `mem_limit_mb`, `deadline_ts`, `status` + +- `workspace_quotas` + - `workspace_id`, `max_concurrent_runs`, `max_run_minutes`, `max_monthly_tokens`, `max_monthly_runtime_minutes` + +- `usage_ledger` + - `id`, `workspace_id`, `run_id`, `provider`, `tokens_in`, `tokens_out`, `runtime_seconds`, `estimated_cost_usd` + +## 4. API Contracts + +## 4.1 Projects +### `POST /v1/creator/projects` +Request: +```json +{ + "workspace_id": "ws_123", + "name": "dojo-roguelike", + "github_owner": "team-or-user", + "template": "dojo-cartridge-skill-game" +} +``` +Response: +```json +{ + "project_id": "proj_abc", + "status": "active", + "github_repo": "https://github.com/team-or-user/dojo-roguelike" +} +``` + +## 4.2 Planning +### `POST /v1/creator/projects/{id}/plan/sessions` +Creates planning session and initial draft plan. + +### `POST /v1/creator/projects/{id}/plan/sessions/{sid}/messages` +Request: +```json +{ + "role": "user", + "content": "Game should include quests and leaderboard with referral rewards" +} +``` +Response includes: +- next clarifying question OR +- updated `plan_version` with `ready_for_approval=true` + +### `POST /v1/creator/projects/{id}/plan/sessions/{sid}/approve` +Locks selected plan version for execution. + +## 4.3 Runs +### `POST /v1/creator/projects/{id}/runs` +Request: +```json +{ + "plan_version_id": "pv_17", + "harness": "codex", + "target_envs": ["devnet", "sepolia"] +} +``` +Response: +```json +{ + "run_id": "run_987", + "status": "queued" +} +``` + +### `GET /v1/creator/projects/{id}/runs/{runId}` +Returns run metadata, step graph, resource usage, and deployment summary. + +### `GET /v1/creator/projects/{id}/runs/{runId}/events` +- SSE stream. +- Supports `Last-Event-ID` replay. + +### `POST /v1/creator/projects/{id}/runs/{runId}/cancel` +Graceful stop; kill pod; mark run canceled. + +## 4.4 Deployments +### `POST /v1/creator/projects/{id}/deployments` +Creates deployment task from run artifact set. + +## 5. Harness Adapter Interface + +```go +type HarnessAdapter interface { + Name() string + ValidateCredentials(ctx context.Context, creds WorkspaceCredentials) error + StartStep(ctx context.Context, req StepRequest) (StepHandle, error) + PollStep(ctx context.Context, handle StepHandle) (StepProgress, error) + CancelStep(ctx context.Context, handle StepHandle) error + Usage(ctx context.Context, handle StepHandle) (UsageMetrics, error) +} +``` + +Normalization requirements: +- Map provider-native statuses to standard step statuses. +- Normalize usage fields (input/output tokens, billed units). +- Normalize error categories (`rate_limit`, `invalid_auth`, `tool_failure`, `provider_unavailable`, `unknown`). + +## 6. Planning Engine Design + +### 6.1 Required Plan Completeness Schema +A plan cannot be approved unless these are complete: +- Core game loop and win/loss conditions. +- Onchain model/system definitions. +- Required modules (quests, leaderboard, social, economy, etc.). +- Permission/admin model. +- Test strategy. +- Deployment targets and acceptance criteria. +- Known assumptions and unresolved risks. + +### 6.2 Clarification Loop +1. Planner inspects current plan graph and completeness score. +2. Generates highest-impact missing-question prompt. +3. User answer updates graph and assumptions. +4. Repeat until completeness threshold is met. + +## 7. Run Orchestrator State Machine +Run state transitions: +- `queued -> starting -> running -> succeeded` +- `running -> failed` +- `queued|starting|running -> canceled` +- `running -> paused -> running` + +Step state transitions: +- `pending -> running -> succeeded` +- `running -> failed -> retrying -> running` +- `running -> canceled` + +Rules: +- Max retries per step configurable (default: 2). +- Retry only idempotent steps or after safe checkpoint. + +## 8. Sandbox Spawning and Lifecycle + +## 8.1 Execution Unit +- One Kubernetes Job per run. +- Single pod by default; optional sidecar for log shipper. + +## 8.2 Pod Spec Requirements +- Image: pinned version with Dojo/Scarb/Katana/Node/pnpm/tooling. +- Resource caps (initial defaults): + - `cpu: 2` + - `memory: 4Gi` + - `ephemeral-storage: 20Gi` +- `activeDeadlineSeconds`: default 7200. +- `ttlSecondsAfterFinished`: default 600. + +## 8.3 Storage Strategy +- Ephemeral volume for workspace. +- Durable uploads for: + - step logs (chunked) + - patch bundles + - test/build outputs + - deployment manifests + +## 8.4 Cost Controls +- Workspace quotas checked before enqueue and before each major phase. +- Concurrency cap per workspace. +- Hard stop on runtime/token budget breach. +- Prefer spot/preemptible nodes for worker pool. + +## 8.5 Failure Recovery +- Checkpoint after each successful major step. +- On pod loss/preemption: recreate job and resume from checkpoint. +- Commit deduplication via idempotency key (`run_id + step_key + attempt`). + +## 9. GitHub Persistence + +## 9.1 Auth Model +- GitHub App installation scoped per workspace/org. +- App token minted per operation. + +## 9.2 Repo Strategy +- One repository per Creator project. +- Branch naming: `creator/run-{run_id}`. +- Commit style: + - atomic per step where possible. + - include run metadata trailer in commit message. + +## 9.3 Merge Strategy +- MVP default: open PR and optional auto-merge if checks pass and policy allows. +- Protected branch compatibility required. + +## 10. Dojo/Cartridge Pipeline + +### 10.1 Build/Test Steps +1. Generate/update code from plan. +2. Run formatting/lint checks. +3. Run Cairo tests and TS tests where applicable. +4. Build artifacts and manifests. + +### 10.2 Deploy Steps +- Devnet deploy (Katana or configured devnet endpoint). +- Sepolia deploy via configured RPC. +- Persist: + - world address + - contract addresses + - tx hashes + - deployment manifest URI + +### 10.3 Acceptance Gates +- No deploy if tests/build fail. +- Deploy summary must include reproducibility metadata (git SHA, image tag, tool versions). + +## 11. Frontend Integration + +### 11.1 New Route/Feature Surface +- Add `creator` feature module and route in client app. +- Views: + - Project setup + - Planning chat + plan tree editor + - Run timeline + logs + - Artifacts + deployment panel + +### 11.2 Realtime UX +- SSE consumer with reconnect and replay using `Last-Event-ID`. +- Event ordering by monotonic `sequence`. +- UI source-of-truth reconciliation via periodic run snapshot fetch. + +### 11.3 ViewModel Pattern +- Follow existing `useViewModel` conventions. +- Keep data orchestration in hooks, views dumb. + +## 12. Security Model +- BYOK credentials encrypted at rest (KMS-backed). +- Decrypt only inside execution boundary for active step. +- Secrets never written to logs/events/artifacts. +- RBAC: + - `creator:read` + - `creator:plan:write` + - `creator:run:execute` + - `creator:deploy` + +## 13. Observability +- Metrics: + - run duration, step duration, queue time + - success/failure rates by harness and phase + - token/runtime/cost usage by workspace +- Tracing: + - request -> run -> step -> sandbox correlation IDs +- Logs: + - structured JSON with PII/secret redaction + +## 14. Testing Strategy + +### 14.1 Unit Tests +- Plan completeness validator. +- Harness adapter status/error normalization. +- Quota evaluator and run scheduler logic. + +### 14.2 Integration Tests +- End-to-end planning session to approved plan. +- Run orchestration with mocked harnesses. +- GitHub repo provisioning + branch/PR flow. +- K8s job lifecycle and event streaming. + +### 14.3 E2E Tests +- User creates project -> approves plan -> executes run -> sees live progress. +- Successful devnet + Sepolia deployment from template game. +- Cancellation and recovery from sandbox failure. + +### 14.4 Performance and Cost Tests +- Queue behavior under 100 active creator profile. +- Token/runtime budget enforcement under stress. + +## 15. Phase-by-Phase Implementation Plan + +### Phase 0: Foundations +- DB migrations for core entities. +- Creator API skeleton and authz wiring. +- GitHub App integration and repo bootstrap. +- Event table + SSE endpoint. + +### Phase 1: Planning +- Planner session endpoints. +- Clarification loop + plan graph persistence. +- Plan approval gating. +- UI planning chat + editable plan tree. + +### Phase 2: Execution +- Run creation/cancel APIs. +- Harness adapter interface + Codex/Claude/Gemini adapters. +- K8s Job launcher and monitor. +- Run timeline/logs UI. + +### Phase 3: Delivery +- Dojo generation/build/test pipeline. +- Devnet/Sepolia deployment tasks. +- Deployment artifact panel. + +### Phase 4: Hardening +- Quotas and budget policies. +- Retry/resume from checkpoint on failures. +- Observability dashboards + alerting. +- Security review and abuse controls for self-serve. + +## 16. Open Decisions (Explicit Defaults Chosen) +1. Real-time transport: SSE (default) instead of WebSockets for MVP. +2. Sandbox model: one sandbox per full run. +3. Repo model: one GitHub repo per project. +4. Credential model: BYOK. +5. Deploy automation: devnet + Sepolia only. + +## 17. MVP Exit Criteria +- All PRD acceptance criteria satisfied. +- At least one reference Dojo game generated and deployed end-to-end via each harness adapter in staging. +- Quota enforcement blocks runaway costs in load test. +- Incident runbook exists for sandbox/job failures and provider outages. diff --git a/docs/creator-mode/architecture/README.md b/docs/creator-mode/architecture/README.md new file mode 100644 index 00000000..faa88381 --- /dev/null +++ b/docs/creator-mode/architecture/README.md @@ -0,0 +1,10 @@ +# Creator Mode Architecture Diagrams + +This folder contains sequence and data-model diagrams for the Creator Mode MVP. + +## Files +- `sequence-planning-and-run.mmd`: End-to-end planning and execution lifecycle. +- `sequence-sandbox-recovery.mmd`: Recovery flow for preemption/failure. +- `erd.mmd`: Core relational data model. + +Render with any Mermaid-compatible viewer. diff --git a/docs/creator-mode/architecture/erd.mmd b/docs/creator-mode/architecture/erd.mmd new file mode 100644 index 00000000..a940ff9f --- /dev/null +++ b/docs/creator-mode/architecture/erd.mmd @@ -0,0 +1,124 @@ +erDiagram + creator_projects ||--o{ plan_sessions : has + plan_sessions ||--o{ plan_versions : versions + creator_projects ||--o{ runs : executes + plan_versions ||--o{ runs : source + runs ||--o{ run_steps : contains + runs ||--o{ run_events : emits + runs ||--o{ artifacts : produces + runs ||--o{ deployments : deploys + runs ||--|| sandbox_leases : leased_by + creator_projects }o--|| workspace_quotas : constrained_by + runs ||--o{ usage_ledger : records + + creator_projects { + text id PK + text workspace_id + text name + text github_owner + text github_repo + text default_branch + text status + timestamptz created_at + } + + plan_sessions { + text id PK + text project_id FK + text status + text created_by + timestamptz created_at + } + + plan_versions { + text id PK + text session_id FK + int version + jsonb plan_graph_json + jsonb assumptions_json + numeric completeness_score + timestamptz created_at + } + + runs { + text id PK + text project_id FK + text plan_version_id FK + text harness + text status + text[] target_envs + timestamptz started_at + timestamptz finished_at + timestamptz created_at + } + + run_steps { + text id PK + text run_id FK + text step_key + jsonb depends_on + text status + int attempt + text summary + text error_code + } + + run_events { + text id PK + text run_id FK + bigint sequence + text event_type + jsonb payload_json + timestamptz created_at + } + + artifacts { + text id PK + text run_id FK + text step_id FK + text type + text uri + text checksum + jsonb metadata_json + } + + deployments { + text id PK + text run_id FK + text environment + text status + text world_address + jsonb tx_hashes_json + text manifest_uri + } + + sandbox_leases { + text id PK + text run_id FK + text k8s_job_name + text pod_name + int cpu_limit_millicores + int mem_limit_mb + timestamptz deadline_ts + text status + } + + workspace_quotas { + text workspace_id PK + int max_concurrent_runs + int max_run_minutes + bigint max_monthly_tokens + bigint max_monthly_runtime_minutes + } + + usage_ledger { + text id PK + text workspace_id + text run_id FK + text provider + bigint tokens_in + bigint tokens_out + bigint runtime_seconds + numeric estimated_cost_usd + timestamptz created_at + } diff --git a/docs/creator-mode/architecture/sequence-planning-and-run.mmd b/docs/creator-mode/architecture/sequence-planning-and-run.mmd new file mode 100644 index 00000000..66a3325e --- /dev/null +++ b/docs/creator-mode/architecture/sequence-planning-and-run.mmd @@ -0,0 +1,52 @@ +sequenceDiagram + participant U as User + participant UI as Creator UI + participant API as Creator API (Go) + participant P as Planner Service + participant O as Run Orchestrator + participant K as K8s Sandbox Controller + participant H as Harness Adapter + participant GH as GitHub + participant DB as Postgres + + U->>UI: Create project + UI->>API: POST /v1/creator/projects + API->>GH: Provision repo from template + API->>DB: Insert creator_projects + API-->>UI: project_id + repo URL + + U->>UI: Start planning session + UI->>API: POST /plan/sessions + API->>P: create session + P->>DB: insert plan_session + plan_version + API-->>UI: session_id + + loop Clarification loop + U->>UI: answer clarification + UI->>API: POST /messages + API->>P: process message + P->>DB: persist next plan_version + API-->>UI: next question or ready + end + + U->>UI: Approve plan + UI->>API: POST /approve + API->>DB: mark session approved + + U->>UI: Execute run (select harness) + UI->>API: POST /runs + API->>O: enqueue run + O->>DB: insert run + steps + O->>K: launch job + K->>DB: create sandbox_lease + + O->>H: execute step + H-->>O: progress + usage + O->>GH: commit changes + open PR + O->>DB: persist events, steps, usage + API-->>UI: SSE events stream + + O->>O: build/test/deploy devnet+sepolia + O->>DB: deployment records + artifacts + O-->>API: run succeeded + API-->>UI: final state + outputs diff --git a/docs/creator-mode/architecture/sequence-sandbox-recovery.mmd b/docs/creator-mode/architecture/sequence-sandbox-recovery.mmd new file mode 100644 index 00000000..2aa62c55 --- /dev/null +++ b/docs/creator-mode/architecture/sequence-sandbox-recovery.mmd @@ -0,0 +1,21 @@ +sequenceDiagram + participant O as Run Orchestrator + participant K as K8s Controller + participant DB as Postgres + participant OBJ as Object Storage + + O->>K: Launch run job + K->>DB: sandbox_lease(status=running) + O->>DB: run_step(status=running) + + Note over K: Node preemption/pod eviction + K-->>O: pod terminated unexpectedly + + O->>OBJ: fetch latest checkpoint + O->>DB: mark failed attempt, increment retry + O->>K: relaunch job with resume context + K->>DB: sandbox_lease(status=restarted) + + O->>DB: run_step(status=running, attempt+1) + O->>OBJ: persist new checkpoint + O->>DB: run_step(status=succeeded) diff --git a/docs/creator-mode/scaffolding/internal/go/models/types.go b/docs/creator-mode/scaffolding/internal/go/models/types.go new file mode 100644 index 00000000..8f346328 --- /dev/null +++ b/docs/creator-mode/scaffolding/internal/go/models/types.go @@ -0,0 +1,99 @@ +package models + +import "time" + +type RunStatus string + +type PlanSessionStatus string + +type StepStatus string + +type DeploymentEnv string + +const ( + RunQueued RunStatus = "queued" + RunStarting RunStatus = "starting" + RunRunning RunStatus = "running" + RunPaused RunStatus = "paused" + RunFailed RunStatus = "failed" + RunSuccess RunStatus = "succeeded" + RunCanceled RunStatus = "canceled" +) + +const ( + PlanDraft PlanSessionStatus = "draft" + PlanAwaiting PlanSessionStatus = "awaiting_user" + PlanReady PlanSessionStatus = "ready_for_approval" + PlanApproved PlanSessionStatus = "approved" + PlanArchived PlanSessionStatus = "archived" +) + +const ( + StepPending StepStatus = "pending" + StepRunning StepStatus = "running" + StepSuccess StepStatus = "succeeded" + StepFailed StepStatus = "failed" + StepRetrying StepStatus = "retrying" + StepCanceled StepStatus = "canceled" +) + +const ( + EnvDevnet DeploymentEnv = "devnet" + EnvSepolia DeploymentEnv = "sepolia" +) + +type CreatorProject struct { + ID string + WorkspaceID string + Name string + GithubOwner string + GithubRepo string + DefaultBranch string + Status string + CreatedAt time.Time + UpdatedAt time.Time +} + +type PlanVersion struct { + ID string + SessionID string + Version int + PlanGraphJSON []byte + AssumptionsJSON []byte + CompletenessScore float64 + CreatedAt time.Time +} + +type Run struct { + ID string + ProjectID string + PlanVersionID string + Harness string + Status RunStatus + TargetEnvs []string + StartedAt *time.Time + FinishedAt *time.Time + CreatedAt time.Time +} + +type RunStep struct { + ID string + RunID string + StepKey string + DependsOn []byte + Status StepStatus + Attempt int + Summary string + ErrorCode string + StartedAt *time.Time + FinishedAt *time.Time +} + +type RunEvent struct { + ID string + RunID string + Sequence int64 + EventType string + PayloadJSON []byte + CreatedAt time.Time +} diff --git a/docs/creator-mode/scaffolding/internal/go/services/interfaces.go b/docs/creator-mode/scaffolding/internal/go/services/interfaces.go new file mode 100644 index 00000000..c9b1c815 --- /dev/null +++ b/docs/creator-mode/scaffolding/internal/go/services/interfaces.go @@ -0,0 +1,100 @@ +package services + +import ( + "context" + "time" +) + +type CreateProjectRequest struct { + WorkspaceID string + Name string + GithubOwner string + Template string +} + +type CreateProjectResponse struct { + ProjectID string + Status string + GithubRepo string +} + +type PlanMessageRequest struct { + ProjectID string + SessionID string + Content string +} + +type PlanMessageResponse struct { + SessionStatus string + LatestPlanVersionID string + NextQuestion *string +} + +type CreateRunRequest struct { + ProjectID string + PlanVersionID string + Harness string + TargetEnvs []string + RequestedBy string +} + +type UsageMetrics struct { + TokensIn int64 + TokensOut int64 + RuntimeSecond int64 + EstimatedUSD float64 +} + +type StepRequest struct { + RunID string + StepKey string + Instruction string + WorkingDirURI string + Timeout time.Duration +} + +type StepHandle struct { + Provider string + OpaqueID string +} + +type StepProgress struct { + Status string + Summary string + LogChunk string + Done bool +} + +type WorkspaceCredentials struct { + WorkspaceID string + Provider string + SecretRef string +} + +type HarnessAdapter interface { + Name() string + ValidateCredentials(ctx context.Context, creds WorkspaceCredentials) error + StartStep(ctx context.Context, req StepRequest) (StepHandle, error) + PollStep(ctx context.Context, handle StepHandle) (StepProgress, error) + CancelStep(ctx context.Context, handle StepHandle) error + Usage(ctx context.Context, handle StepHandle) (UsageMetrics, error) +} + +type PlannerService interface { + CreateSession(ctx context.Context, projectID, actorID string) (sessionID string, err error) + ProcessMessage(ctx context.Context, req PlanMessageRequest) (PlanMessageResponse, error) + ApprovePlan(ctx context.Context, projectID, sessionID, planVersionID, actorID string) error +} + +type RunService interface { + CreateRun(ctx context.Context, req CreateRunRequest) (runID string, err error) + CancelRun(ctx context.Context, projectID, runID, actorID string) error + PauseRun(ctx context.Context, projectID, runID, actorID string) error + ResumeRun(ctx context.Context, projectID, runID, actorID string) error +} + +type SandboxController interface { + LaunchRunSandbox(ctx context.Context, runID string) (leaseID string, err error) + TerminateRunSandbox(ctx context.Context, runID string) error + ResumeRunSandbox(ctx context.Context, runID string) (leaseID string, err error) +} diff --git a/docs/creator-mode/scaffolding/internal/go/services/k8s_job_template.yaml b/docs/creator-mode/scaffolding/internal/go/services/k8s_job_template.yaml new file mode 100644 index 00000000..6c5ed80a --- /dev/null +++ b/docs/creator-mode/scaffolding/internal/go/services/k8s_job_template.yaml @@ -0,0 +1,45 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: creator-run-{{ .RunID }} + labels: + app: creator-mode + creator.run_id: "{{ .RunID }}" +spec: + backoffLimit: 0 + ttlSecondsAfterFinished: 600 + activeDeadlineSeconds: 7200 + template: + metadata: + labels: + app: creator-mode + creator.run_id: "{{ .RunID }}" + spec: + restartPolicy: Never + containers: + - name: runner + image: ghcr.io/cartridge-gg/creator-runner:0.1.0 + imagePullPolicy: IfNotPresent + env: + - name: RUN_ID + value: "{{ .RunID }}" + - name: PROJECT_ID + value: "{{ .ProjectID }}" + - name: HARNESS + value: "{{ .Harness }}" + resources: + requests: + cpu: "500m" + memory: "1Gi" + ephemeral-storage: "5Gi" + limits: + cpu: "2" + memory: "4Gi" + ephemeral-storage: "20Gi" + volumeMounts: + - name: workspace + mountPath: /workspace + volumes: + - name: workspace + emptyDir: + sizeLimit: 20Gi diff --git a/docs/creator-mode/scaffolding/internal/migrations/0001_creator_mode.sql b/docs/creator-mode/scaffolding/internal/migrations/0001_creator_mode.sql new file mode 100644 index 00000000..a5461109 --- /dev/null +++ b/docs/creator-mode/scaffolding/internal/migrations/0001_creator_mode.sql @@ -0,0 +1,136 @@ +-- Creator mode baseline schema + +CREATE TABLE IF NOT EXISTS creator_projects ( + id TEXT PRIMARY KEY, + workspace_id TEXT NOT NULL, + name TEXT NOT NULL, + github_owner TEXT NOT NULL, + github_repo TEXT, + default_branch TEXT NOT NULL DEFAULT 'main', + status TEXT NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS plan_sessions ( + id TEXT PRIMARY KEY, + project_id TEXT NOT NULL REFERENCES creator_projects(id) ON DELETE CASCADE, + status TEXT NOT NULL, + created_by TEXT NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS plan_versions ( + id TEXT PRIMARY KEY, + session_id TEXT NOT NULL REFERENCES plan_sessions(id) ON DELETE CASCADE, + version INTEGER NOT NULL, + plan_graph_json JSONB NOT NULL, + assumptions_json JSONB NOT NULL DEFAULT '{}'::jsonb, + completeness_score NUMERIC(5,2) NOT NULL DEFAULT 0, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + UNIQUE(session_id, version) +); + +CREATE TABLE IF NOT EXISTS runs ( + id TEXT PRIMARY KEY, + project_id TEXT NOT NULL REFERENCES creator_projects(id) ON DELETE CASCADE, + plan_version_id TEXT NOT NULL REFERENCES plan_versions(id), + harness TEXT NOT NULL, + status TEXT NOT NULL, + target_envs TEXT[] NOT NULL DEFAULT '{}', + started_at TIMESTAMPTZ, + finished_at TIMESTAMPTZ, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS run_steps ( + id TEXT PRIMARY KEY, + run_id TEXT NOT NULL REFERENCES runs(id) ON DELETE CASCADE, + step_key TEXT NOT NULL, + depends_on JSONB NOT NULL DEFAULT '[]'::jsonb, + status TEXT NOT NULL, + attempt INTEGER NOT NULL DEFAULT 0, + summary TEXT, + error_code TEXT, + started_at TIMESTAMPTZ, + finished_at TIMESTAMPTZ, + UNIQUE(run_id, step_key, attempt) +); + +CREATE TABLE IF NOT EXISTS run_events ( + id TEXT PRIMARY KEY, + run_id TEXT NOT NULL REFERENCES runs(id) ON DELETE CASCADE, + sequence BIGINT NOT NULL, + event_type TEXT NOT NULL, + payload_json JSONB NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + UNIQUE(run_id, sequence) +); + +CREATE TABLE IF NOT EXISTS artifacts ( + id TEXT PRIMARY KEY, + run_id TEXT NOT NULL REFERENCES runs(id) ON DELETE CASCADE, + step_id TEXT REFERENCES run_steps(id) ON DELETE SET NULL, + type TEXT NOT NULL, + uri TEXT NOT NULL, + checksum TEXT, + metadata_json JSONB NOT NULL DEFAULT '{}'::jsonb, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS deployments ( + id TEXT PRIMARY KEY, + run_id TEXT NOT NULL REFERENCES runs(id) ON DELETE CASCADE, + environment TEXT NOT NULL, + status TEXT NOT NULL, + world_address TEXT, + tx_hashes_json JSONB NOT NULL DEFAULT '[]'::jsonb, + manifest_uri TEXT, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS sandbox_leases ( + id TEXT PRIMARY KEY, + run_id TEXT NOT NULL UNIQUE REFERENCES runs(id) ON DELETE CASCADE, + k8s_job_name TEXT NOT NULL, + pod_name TEXT, + node_type TEXT, + cpu_limit_millicores INTEGER NOT NULL, + mem_limit_mb INTEGER NOT NULL, + deadline_ts TIMESTAMPTZ NOT NULL, + status TEXT NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS workspace_quotas ( + workspace_id TEXT PRIMARY KEY, + max_concurrent_runs INTEGER NOT NULL, + max_run_minutes INTEGER NOT NULL, + max_monthly_tokens BIGINT NOT NULL, + max_monthly_runtime_minutes BIGINT NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS usage_ledger ( + id TEXT PRIMARY KEY, + workspace_id TEXT NOT NULL, + run_id TEXT NOT NULL REFERENCES runs(id) ON DELETE CASCADE, + provider TEXT NOT NULL, + tokens_in BIGINT NOT NULL DEFAULT 0, + tokens_out BIGINT NOT NULL DEFAULT 0, + runtime_seconds BIGINT NOT NULL DEFAULT 0, + estimated_cost_usd NUMERIC(12,4) NOT NULL DEFAULT 0, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE INDEX IF NOT EXISTS idx_creator_projects_workspace ON creator_projects(workspace_id); +CREATE INDEX IF NOT EXISTS idx_plan_sessions_project ON plan_sessions(project_id); +CREATE INDEX IF NOT EXISTS idx_plan_versions_session ON plan_versions(session_id, version DESC); +CREATE INDEX IF NOT EXISTS idx_runs_project_created ON runs(project_id, created_at DESC); +CREATE INDEX IF NOT EXISTS idx_run_steps_run ON run_steps(run_id, step_key); +CREATE INDEX IF NOT EXISTS idx_run_events_run_seq ON run_events(run_id, sequence); +CREATE INDEX IF NOT EXISTS idx_artifacts_run ON artifacts(run_id, created_at DESC); +CREATE INDEX IF NOT EXISTS idx_deployments_run ON deployments(run_id, created_at DESC); +CREATE INDEX IF NOT EXISTS idx_usage_workspace_created ON usage_ledger(workspace_id, created_at DESC); diff --git a/docs/creator-mode/scaffolding/internal/openapi/creator.v1.yaml b/docs/creator-mode/scaffolding/internal/openapi/creator.v1.yaml new file mode 100644 index 00000000..991a8bb7 --- /dev/null +++ b/docs/creator-mode/scaffolding/internal/openapi/creator.v1.yaml @@ -0,0 +1,305 @@ +openapi: 3.1.0 +info: + title: Creator Mode API + version: 0.1.0 +servers: + - url: https://api.cartridge.gg +paths: + /v1/creator/projects: + post: + operationId: createCreatorProject + tags: [creator] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateProjectRequest' + responses: + '201': + description: Created + content: + application/json: + schema: + $ref: '#/components/schemas/ProjectResponse' + /v1/creator/projects/{projectId}/plan/sessions: + post: + operationId: createPlanSession + tags: [planning] + parameters: + - $ref: '#/components/parameters/ProjectId' + responses: + '201': + description: Created + content: + application/json: + schema: + $ref: '#/components/schemas/PlanSessionResponse' + /v1/creator/projects/{projectId}/plan/sessions/{sessionId}/messages: + post: + operationId: sendPlanMessage + tags: [planning] + parameters: + - $ref: '#/components/parameters/ProjectId' + - $ref: '#/components/parameters/SessionId' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PlanMessageRequest' + responses: + '200': + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/PlanMessageResponse' + /v1/creator/projects/{projectId}/plan/sessions/{sessionId}/approve: + post: + operationId: approvePlanSession + tags: [planning] + parameters: + - $ref: '#/components/parameters/ProjectId' + - $ref: '#/components/parameters/SessionId' + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [plan_version_id] + properties: + plan_version_id: + type: string + responses: + '200': + description: Approved + /v1/creator/projects/{projectId}/runs: + post: + operationId: createRun + tags: [runs] + parameters: + - $ref: '#/components/parameters/ProjectId' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateRunRequest' + responses: + '201': + description: Created + content: + application/json: + schema: + $ref: '#/components/schemas/RunResponse' + /v1/creator/projects/{projectId}/runs/{runId}: + get: + operationId: getRun + tags: [runs] + parameters: + - $ref: '#/components/parameters/ProjectId' + - $ref: '#/components/parameters/RunId' + responses: + '200': + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/RunResponse' + /v1/creator/projects/{projectId}/runs/{runId}/events: + get: + operationId: streamRunEvents + tags: [runs] + parameters: + - $ref: '#/components/parameters/ProjectId' + - $ref: '#/components/parameters/RunId' + responses: + '200': + description: Server-sent event stream + content: + text/event-stream: + schema: + type: string + /v1/creator/projects/{projectId}/runs/{runId}/cancel: + post: + operationId: cancelRun + tags: [runs] + parameters: + - $ref: '#/components/parameters/ProjectId' + - $ref: '#/components/parameters/RunId' + responses: + '202': + description: Accepted + /v1/creator/projects/{projectId}/deployments: + post: + operationId: createDeployment + tags: [deployments] + parameters: + - $ref: '#/components/parameters/ProjectId' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateDeploymentRequest' + responses: + '201': + description: Created + content: + application/json: + schema: + $ref: '#/components/schemas/DeploymentResponse' +components: + parameters: + ProjectId: + name: projectId + in: path + required: true + schema: + type: string + SessionId: + name: sessionId + in: path + required: true + schema: + type: string + RunId: + name: runId + in: path + required: true + schema: + type: string + schemas: + CreateProjectRequest: + type: object + required: [workspace_id, name, github_owner, template] + properties: + workspace_id: + type: string + name: + type: string + github_owner: + type: string + template: + type: string + ProjectResponse: + type: object + required: [project_id, status, github_repo] + properties: + project_id: + type: string + status: + type: string + enum: [active, provisioning, failed] + github_repo: + type: string + format: uri + PlanSessionResponse: + type: object + required: [session_id, status, latest_plan_version_id] + properties: + session_id: + type: string + status: + type: string + latest_plan_version_id: + type: string + PlanMessageRequest: + type: object + required: [role, content] + properties: + role: + type: string + enum: [user] + content: + type: string + PlanMessageResponse: + type: object + required: [session_status, latest_plan_version_id] + properties: + session_status: + type: string + latest_plan_version_id: + type: string + next_question: + type: string + nullable: true + CreateRunRequest: + type: object + required: [plan_version_id, harness] + properties: + plan_version_id: + type: string + harness: + type: string + enum: [codex, claude, gemini] + target_envs: + type: array + items: + type: string + enum: [devnet, sepolia] + RunStep: + type: object + required: [step_key, status, attempt] + properties: + step_key: + type: string + status: + type: string + attempt: + type: integer + minimum: 0 + summary: + type: string + RunResponse: + type: object + required: [run_id, project_id, status, harness, steps] + properties: + run_id: + type: string + project_id: + type: string + status: + type: string + harness: + type: string + started_at: + type: string + format: date-time + nullable: true + finished_at: + type: string + format: date-time + nullable: true + steps: + type: array + items: + $ref: '#/components/schemas/RunStep' + CreateDeploymentRequest: + type: object + required: [run_id, environment] + properties: + run_id: + type: string + environment: + type: string + enum: [devnet, sepolia] + DeploymentResponse: + type: object + required: [deployment_id, status, environment] + properties: + deployment_id: + type: string + status: + type: string + environment: + type: string + world_address: + type: string + nullable: true + tx_hashes: + type: array + items: + type: string