rdev/cookbooks/trees/foundary.yaml
jordan 1714b5921a
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
fix(cookbook): add on_error: continue to verify-site-live
Site verification may fail when component images haven't built yet.
The SDLC lifecycle completes regardless of site availability.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 17:40:57 -07:00

1027 lines
34 KiB
YAML

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]
on_error: continue
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 }}"