name: foundary description: "Foundary Studio: Conversational product development lifecycle. Bootstraps a React+API+DB project, specs two features via SDLC, implements with build agents, reviews, merges, and releases." version: 1 vars: project_name: "" feature_1_slug: "data-models" feature_1_title: "Core Data Models & Persistence" feature_2_slug: "task-management-ui" feature_2_title: "Task Management UI" steps: # ============================================================ # SECTION 1: INFRASTRUCTURE # Create project with React app, API service, and database # ============================================================ create-project: description: "Create project with bootstrap build" action: api method: POST endpoint: /project/create-and-build body: name: "{{ .vars.project_name }}" description: "Foundary Studio: Conversational product development" template: "default" prompt: "Set up the monorepo workspace. Ensure the root README describes a product studio for conversational product development." auto_commit: true auto_push: true outputs: - project_id: .data.project_id - domain: .data.domain - git_clone_http: .data.git.clone_http - bootstrap_task_id: .data.task_id wait-bootstrap: description: "Wait for bootstrap build to complete" depends_on: [create-project] action: wait_build build_id: "{{ .outputs.create-project.bootstrap_task_id }}" max_attempts: 720 poll_interval: 5 add-components: description: "Add React frontend, API service, and Postgres database" depends_on: [wait-bootstrap] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/components/batch" body: components: - type: app-react name: studio-ui - type: service name: studio-api - type: postgres name: studio-db wait-components: description: "Wait for component scaffolding pipeline" depends_on: [add-components] action: wait_pipeline project_id: "{{ .outputs.create-project.project_id }}" max_attempts: 720 on_error: continue verify-site: description: "Verify site is live (may 503 until first build pushes component images)" depends_on: [wait-components] action: wait_site domain: "{{ .outputs.create-project.domain }}" max_attempts: 60 on_error: continue verify-sdlc: description: "Verify SDLC state is initialized" depends_on: [verify-site] action: api method: GET endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/state" outputs: - sdlc_initialized: .data.initialized # ============================================================ # SECTION 2: ARCHITECT # Conversational product design via architect API. # Tries the full conversational flow (start → refine → generate). # Falls back to direct blueprint creation if agent isn't available. # ============================================================ architect-start: description: "Start architect conversation about product goals" depends_on: [verify-sdlc] on_error: continue action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/architect/start" body: prompt: "I want to build a task management studio. The product needs: 1) Core data models for Task, Project, Label, and Assignment entities with full CRUD stored in Postgres via studio-db, exposed as REST endpoints on studio-api. 2) A React frontend in studio-ui with a Kanban board (drag-and-drop columns: To Do, In Progress, Done), task creation/edit modals, and filtering by label and assignee. Propose the architecture and identify the two MVP features we should build." outputs: - conversation_id: .data.id architect-refine: description: "Refine architecture with component details" depends_on: [architect-start] on_error: continue action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/architect/continue/{{ .outputs.architect-start.conversation_id }}" body: message: "Good. Let's define exactly two features for the MVP: Feature 1 'data-models' covers the persistence layer (Task, Project, Label, Assignment entities, migrations, repository layer, service layer, handler tests). Feature 2 'task-management-ui' covers the React frontend (Kanban board, task CRUD modals, label/assignee filters). Feature 2 depends on Feature 1 being complete since it consumes the API. Please confirm this breakdown and note any architectural considerations." architect-generate-blueprint: description: "Generate structured blueprint from conversation" depends_on: [architect-refine] on_error: continue action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/architect/generate-blueprint/{{ .outputs.architect-start.conversation_id }}" body: name: "foundary-studio-mvp" outputs: - blueprint_id: .data.blueprint.id architect-create-blueprint-fallback: description: "Fallback: create blueprint directly if conversational flow unavailable" depends_on: [architect-generate-blueprint] on_error: continue action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/blueprints" body: name: "foundary-studio-mvp" description: "Task management studio MVP blueprint" spec: version: "1.0" architecture: type: "monorepo" components: - name: studio-ui type: app-react description: "React frontend with Kanban board" - name: studio-api type: service description: "REST API for task management" - name: studio-db type: postgres description: "PostgreSQL database for persistence" features: - slug: data-models title: "Core Data Models & Persistence" priority: high - slug: task-management-ui title: "Task Management UI" priority: high outputs: - fallback_blueprint_id: .data.id # ============================================================ # SECTION 3: FEATURE 1 — Core Data Models (draft → released) # Full 10-phase SDLC lifecycle # ============================================================ # --- Phase 1: Draft --- f1-create-feature: description: "Create data-models feature in draft phase" depends_on: [architect-create-blueprint-fallback] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features" body: slug: "{{ .vars.feature_1_slug }}" title: "{{ .vars.feature_1_title }}" outputs: - feature_phase: .data.phase f1-verify-draft: description: "Verify feature 1 is in draft phase" depends_on: [f1-create-feature] action: shell command: | PHASE="{{ .outputs.f1-create-feature.feature_phase }}" if [ "$PHASE" == "draft" ]; then echo "Feature 1 created in draft phase" exit 0 else echo "Expected draft, got $PHASE" exit 1 fi # --- Phase 2: Draft → Specified --- f1-write-spec: description: "Agent writes spec for data models" depends_on: [f1-verify-draft] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "/spec-feature {{ .vars.feature_1_slug }} --requirements 'Define Task, Project, Label, and Assignment entities with full CRUD. Postgres storage via studio-db. REST endpoints on studio-api. Include migrations, repository layer, service layer, and handler tests.'" auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id f1-wait-spec: depends_on: [f1-write-spec] action: wait_build build_id: "{{ .outputs.f1-write-spec.build_id }}" max_attempts: 720 poll_interval: 5 f1-approve-spec: description: "Approve spec artifact" depends_on: [f1-wait-spec] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/artifacts/spec/approve" body: comment: "Spec approved by foundary automation" f1-transition-to-specified: description: "Transition from draft to specified" depends_on: [f1-approve-spec] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/transition" body: phase: "specified" outputs: - new_phase: .data.phase # --- Phase 3: Specified → Planned --- f1-write-design: description: "Agent writes design for data models" depends_on: [f1-transition-to-specified] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "/design-feature {{ .vars.feature_1_slug }}" auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id f1-wait-design: depends_on: [f1-write-design] action: wait_build build_id: "{{ .outputs.f1-write-design.build_id }}" max_attempts: 720 poll_interval: 5 f1-approve-design: description: "Approve design artifact" depends_on: [f1-wait-design] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/artifacts/design/approve" body: comment: "Design approved by foundary automation" f1-write-tasks: description: "Agent breaks down into tasks" depends_on: [f1-approve-design] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "/breakdown-feature {{ .vars.feature_1_slug }}" auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id f1-wait-tasks: depends_on: [f1-write-tasks] action: wait_build build_id: "{{ .outputs.f1-write-tasks.build_id }}" max_attempts: 720 poll_interval: 5 f1-approve-tasks: description: "Approve tasks artifact" depends_on: [f1-wait-tasks] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/artifacts/tasks/approve" body: comment: "Tasks approved by foundary automation" f1-write-qa-plan: description: "Agent writes QA plan" depends_on: [f1-approve-tasks] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "/create-qa-plan {{ .vars.feature_1_slug }}" auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id f1-wait-qa-plan: depends_on: [f1-write-qa-plan] action: wait_build build_id: "{{ .outputs.f1-write-qa-plan.build_id }}" max_attempts: 720 poll_interval: 5 f1-approve-qa-plan: description: "Approve QA plan artifact" depends_on: [f1-wait-qa-plan] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/artifacts/qa_plan/approve" body: comment: "QA plan approved by foundary automation" f1-transition-to-planned: description: "Transition from specified to planned" depends_on: [f1-approve-qa-plan] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/transition" body: phase: "planned" outputs: - new_phase: .data.phase # --- Phase 4: Planned → Ready --- f1-create-branch: description: "Create feature branch for data-models" depends_on: [f1-transition-to-planned] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/branches" outputs: - branch_name: .data.name f1-transition-to-ready: description: "Transition from planned to ready" depends_on: [f1-create-branch] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/transition" body: phase: "ready" outputs: - new_phase: .data.phase # --- Phase 5: Ready → Implementation --- f1-implement: description: "Agent implements data models feature" depends_on: [f1-transition-to-ready] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "/implement-feature {{ .vars.feature_1_slug }}" auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id f1-wait-implement: depends_on: [f1-implement] action: wait_build build_id: "{{ .outputs.f1-implement.build_id }}" max_attempts: 720 poll_interval: 5 f1-wait-deploy-impl: description: "Wait for implementation to deploy" depends_on: [f1-wait-implement] action: wait_pipeline project_id: "{{ .outputs.create-project.project_id }}" max_attempts: 720 f1-transition-to-implementation: description: "Transition to implementation phase" depends_on: [f1-wait-deploy-impl] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/transition" body: phase: "implementation" outputs: - new_phase: .data.phase # --- Phase 6: Implementation → Review --- f1-write-review: description: "Agent writes code review" depends_on: [f1-transition-to-implementation] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "/review-feature {{ .vars.feature_1_slug }}" auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id f1-wait-review: depends_on: [f1-write-review] action: wait_build build_id: "{{ .outputs.f1-write-review.build_id }}" max_attempts: 720 poll_interval: 5 f1-pass-review: description: "Mark review as passed" depends_on: [f1-wait-review] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/artifacts/review/pass" f1-transition-to-review: description: "Transition to review phase" depends_on: [f1-pass-review] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/transition" body: phase: "review" outputs: - new_phase: .data.phase # --- Phase 7: Review → Audit --- f1-write-audit: description: "Agent writes security audit" depends_on: [f1-transition-to-review] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "/audit-feature {{ .vars.feature_1_slug }}" auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id f1-wait-audit: depends_on: [f1-write-audit] action: wait_build build_id: "{{ .outputs.f1-write-audit.build_id }}" max_attempts: 720 poll_interval: 5 f1-pass-audit: description: "Mark audit as passed" depends_on: [f1-wait-audit] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/artifacts/audit/pass" f1-transition-to-audit: description: "Transition to audit phase" depends_on: [f1-pass-audit] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/transition" body: phase: "audit" outputs: - new_phase: .data.phase # --- Phase 8: Audit → QA --- f1-run-qa: description: "Agent runs QA plan" depends_on: [f1-transition-to-audit] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "/run-qa {{ .vars.feature_1_slug }}" auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id f1-wait-qa: depends_on: [f1-run-qa] action: wait_build build_id: "{{ .outputs.f1-run-qa.build_id }}" max_attempts: 720 poll_interval: 5 f1-pass-qa: description: "Mark QA as passed" depends_on: [f1-wait-qa] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/artifacts/qa_results/pass" f1-transition-to-qa: description: "Transition to QA phase" depends_on: [f1-pass-qa] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/transition" body: phase: "qa" outputs: - new_phase: .data.phase # --- Phase 9: QA → Merge --- f1-transition-to-merge: description: "Transition to merge phase" depends_on: [f1-transition-to-qa] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/transition" body: phase: "merge" outputs: - new_phase: .data.phase f1-merge: description: "Merge data-models feature branch to main" depends_on: [f1-transition-to-merge] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/merge" body: strategy: "squash" outputs: - merge_commit: .data.commit_sha f1-wait-merge-deploy: description: "Wait for merged code to deploy" depends_on: [f1-merge] action: wait_pipeline project_id: "{{ .outputs.create-project.project_id }}" max_attempts: 720 # --- Phase 10: Merge → Released --- # Note: sdlc merge already transitions to released internally. # This step is a safety net; on_error: continue handles the case # where the feature is already at released. f1-transition-to-released: description: "Transition to released phase (may already be done by merge)" depends_on: [f1-wait-merge-deploy] on_error: continue action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/transition" body: phase: "released" f1-archive: description: "Archive data-models feature" depends_on: [f1-transition-to-released] on_error: continue action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_1_slug }}/archive" # ============================================================ # SECTION 4: FEATURE 2 — Task Management UI (draft → released) # Spec starts after Feature 1 spec (independent) # Design depends on Feature 1 reaching planned (schema defined) # Implementation depends on Feature 1 released (schema in main) # ============================================================ # --- Phase 1: Draft --- # Feature 2 creation can start after Feature 1 spec is approved (parallel speccing) f2-create-feature: description: "Create task-management-ui feature in draft phase" depends_on: [f1-approve-spec] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features" body: slug: "{{ .vars.feature_2_slug }}" title: "{{ .vars.feature_2_title }}" outputs: - feature_phase: .data.phase f2-verify-draft: description: "Verify feature 2 is in draft phase" depends_on: [f2-create-feature] action: shell command: | PHASE="{{ .outputs.f2-create-feature.feature_phase }}" if [ "$PHASE" == "draft" ]; then echo "Feature 2 created in draft phase" exit 0 else echo "Expected draft, got $PHASE" exit 1 fi # --- Phase 2: Draft → Specified --- f2-write-spec: description: "Agent writes spec for task management UI" depends_on: [f2-verify-draft] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "/spec-feature {{ .vars.feature_2_slug }} --requirements 'React UI in studio-ui for managing tasks. Kanban board view with drag-and-drop columns (To Do, In Progress, Done). Task creation/edit modal with title, description, label, assignee fields. Filter by label and assignee. Connects to studio-api REST endpoints for Task CRUD.'" auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id f2-wait-spec: depends_on: [f2-write-spec] action: wait_build build_id: "{{ .outputs.f2-write-spec.build_id }}" max_attempts: 720 poll_interval: 5 f2-approve-spec: description: "Approve spec artifact" depends_on: [f2-wait-spec] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/artifacts/spec/approve" body: comment: "Spec approved by foundary automation" f2-transition-to-specified: description: "Transition from draft to specified" depends_on: [f2-approve-spec] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/transition" body: phase: "specified" outputs: - new_phase: .data.phase # --- Phase 3: Specified → Planned --- # Design depends on Feature 1 reaching planned (schema must be defined first) f2-write-design: description: "Agent writes design for task management UI (after F1 schema planned)" depends_on: [f2-transition-to-specified, f1-transition-to-planned] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "/design-feature {{ .vars.feature_2_slug }}" auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id f2-wait-design: depends_on: [f2-write-design] action: wait_build build_id: "{{ .outputs.f2-write-design.build_id }}" max_attempts: 720 poll_interval: 5 f2-approve-design: description: "Approve design artifact" depends_on: [f2-wait-design] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/artifacts/design/approve" body: comment: "Design approved by foundary automation" f2-write-tasks: description: "Agent breaks down into tasks" depends_on: [f2-approve-design] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "/breakdown-feature {{ .vars.feature_2_slug }}" auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id f2-wait-tasks: depends_on: [f2-write-tasks] action: wait_build build_id: "{{ .outputs.f2-write-tasks.build_id }}" max_attempts: 720 poll_interval: 5 f2-approve-tasks: description: "Approve tasks artifact" depends_on: [f2-wait-tasks] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/artifacts/tasks/approve" body: comment: "Tasks approved by foundary automation" f2-write-qa-plan: description: "Agent writes QA plan" depends_on: [f2-approve-tasks] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "/create-qa-plan {{ .vars.feature_2_slug }}" auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id f2-wait-qa-plan: depends_on: [f2-write-qa-plan] action: wait_build build_id: "{{ .outputs.f2-write-qa-plan.build_id }}" max_attempts: 720 poll_interval: 5 f2-approve-qa-plan: description: "Approve QA plan artifact" depends_on: [f2-wait-qa-plan] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/artifacts/qa_plan/approve" body: comment: "QA plan approved by foundary automation" f2-transition-to-planned: description: "Transition from specified to planned" depends_on: [f2-approve-qa-plan] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/transition" body: phase: "planned" outputs: - new_phase: .data.phase # --- Phase 4: Planned → Ready --- f2-create-branch: description: "Create feature branch for task-management-ui" depends_on: [f2-transition-to-planned] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/branches" outputs: - branch_name: .data.name f2-transition-to-ready: description: "Transition from planned to ready" depends_on: [f2-create-branch] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/transition" body: phase: "ready" outputs: - new_phase: .data.phase # --- Phase 5: Ready → Implementation --- # Implementation depends on Feature 1 being released (schema in main) f2-implement: description: "Agent implements task management UI (after F1 released to main)" depends_on: [f2-transition-to-ready, f1-transition-to-released] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "/implement-feature {{ .vars.feature_2_slug }}" auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id f2-wait-implement: depends_on: [f2-implement] action: wait_build build_id: "{{ .outputs.f2-implement.build_id }}" max_attempts: 720 poll_interval: 5 f2-wait-deploy-impl: description: "Wait for implementation to deploy" depends_on: [f2-wait-implement] action: wait_pipeline project_id: "{{ .outputs.create-project.project_id }}" max_attempts: 720 f2-transition-to-implementation: description: "Transition to implementation phase" depends_on: [f2-wait-deploy-impl] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/transition" body: phase: "implementation" outputs: - new_phase: .data.phase # --- Phase 6: Implementation → Review --- f2-write-review: description: "Agent writes code review" depends_on: [f2-transition-to-implementation] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "/review-feature {{ .vars.feature_2_slug }}" auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id f2-wait-review: depends_on: [f2-write-review] action: wait_build build_id: "{{ .outputs.f2-write-review.build_id }}" max_attempts: 720 poll_interval: 5 f2-pass-review: description: "Mark review as passed" depends_on: [f2-wait-review] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/artifacts/review/pass" f2-transition-to-review: description: "Transition to review phase" depends_on: [f2-pass-review] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/transition" body: phase: "review" outputs: - new_phase: .data.phase # --- Phase 7: Review → Audit --- f2-write-audit: description: "Agent writes security audit" depends_on: [f2-transition-to-review] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "/audit-feature {{ .vars.feature_2_slug }}" auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id f2-wait-audit: depends_on: [f2-write-audit] action: wait_build build_id: "{{ .outputs.f2-write-audit.build_id }}" max_attempts: 720 poll_interval: 5 f2-pass-audit: description: "Mark audit as passed" depends_on: [f2-wait-audit] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/artifacts/audit/pass" f2-transition-to-audit: description: "Transition to audit phase" depends_on: [f2-pass-audit] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/transition" body: phase: "audit" outputs: - new_phase: .data.phase # --- Phase 8: Audit → QA --- f2-run-qa: description: "Agent runs QA plan" depends_on: [f2-transition-to-audit] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "/run-qa {{ .vars.feature_2_slug }}" auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id f2-wait-qa: depends_on: [f2-run-qa] action: wait_build build_id: "{{ .outputs.f2-run-qa.build_id }}" max_attempts: 720 poll_interval: 5 f2-pass-qa: description: "Mark QA as passed" depends_on: [f2-wait-qa] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/artifacts/qa_results/pass" f2-transition-to-qa: description: "Transition to QA phase" depends_on: [f2-pass-qa] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/transition" body: phase: "qa" outputs: - new_phase: .data.phase # --- Phase 9: QA → Merge --- f2-transition-to-merge: description: "Transition to merge phase" depends_on: [f2-transition-to-qa] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/transition" body: phase: "merge" outputs: - new_phase: .data.phase f2-merge: description: "Merge task-management-ui feature branch to main" depends_on: [f2-transition-to-merge] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/merge" body: strategy: "squash" outputs: - merge_commit: .data.commit_sha f2-wait-merge-deploy: description: "Wait for merged code to deploy" depends_on: [f2-merge] action: wait_pipeline project_id: "{{ .outputs.create-project.project_id }}" max_attempts: 720 # --- Phase 10: Merge → Released --- f2-transition-to-released: description: "Transition to released phase (may already be done by merge)" depends_on: [f2-wait-merge-deploy] on_error: continue action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/transition" body: phase: "released" f2-archive: description: "Archive task-management-ui feature" depends_on: [f2-transition-to-released] on_error: continue action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_2_slug }}/archive" # ============================================================ # SECTION 5: VERIFICATION # ============================================================ verify-site-live: description: "Verify frontend and API are live after both features" depends_on: [f2-archive] action: shell command: | DOMAIN="{{ .outputs.create-project.domain }}" # Check frontend UI_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://$DOMAIN") echo "Frontend status: $UI_STATUS" # Check API health API_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://$DOMAIN/api/studio-api/health") echo "API status: $API_STATUS" if [ "$UI_STATUS" -ge 200 ] && [ "$UI_STATUS" -lt 400 ] && [ "$API_STATUS" -ge 200 ] && [ "$API_STATUS" -lt 400 ]; then echo "Site is live: frontend and API responding" exit 0 else echo "Site check failed" exit 1 fi verify-sdlc-complete: description: "Verify both features completed the full SDLC lifecycle" depends_on: [verify-site-live] action: shell command: | echo "" echo "============================================================" echo "SUCCESS: Foundary Studio lifecycle complete" echo "============================================================" echo "Both features traversed all 10 SDLC phases:" echo " draft -> specified -> planned -> ready -> implementation ->" echo " review -> audit -> qa -> merge -> released" echo "" echo "Infrastructure: React + API + Postgres (batch provisioned)" echo "Feature 1: Core Data Models & Persistence" echo "Feature 2: Task Management UI (dependent on F1 schema)" echo "============================================================" exit 0 teardown: - action: api method: DELETE endpoint: "/project/{{ .outputs.create-project.project_id }}"