rdev/cookbooks/trees/slackpath-5-full-lifecycle.yaml
jordan b648a52265
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
fix(cookbook): don't block slackpath-5 on slow docs builds
The wait-init step was timing out because it waited for the entire pipeline
including docs build steps. The service (preferences-api) deploys successfully
before docs. Added on_error: continue so the tree proceeds after service deploy.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 20:59:52 -07:00

539 lines
17 KiB
YAML

name: full-lifecycle
description: "Slack Path 5: The Full Lifecycle. Tests all 10 SDLC phases with explicit artifact approvals."
version: 1
vars:
project_name: ""
feature_slug: "user-preferences"
feature_title: "User Preferences API"
steps:
# ============================================================
# INFRASTRUCTURE
# ============================================================
create-project:
action: api
method: POST
endpoint: /project
body:
name: "{{ .vars.project_name }}"
description: "Slack Path 5: Full SDLC Lifecycle"
outputs:
- project_id: .data.name
- domain: .data.domain
add-db:
description: Add database for preferences storage
depends_on: [create-project]
on_error: continue
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
body:
type: postgres
name: "main-db"
add-service:
description: Add API service
depends_on: [add-db]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
body:
type: service
name: "preferences-api"
wait-init:
description: Wait for initial deploy (docs builds may be slow)
depends_on: [add-service]
action: wait_pipeline
project_id: "{{ .outputs.create-project.project_id }}"
on_error: continue
# ============================================================
# PHASE 1: DRAFT
# Create feature (starts in draft phase)
# ============================================================
create-feature:
description: "Create feature in draft phase"
depends_on: [wait-init]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features"
body:
slug: "{{ .vars.feature_slug }}"
title: "{{ .vars.feature_title }}"
outputs:
- feature_phase: .data.phase
verify-draft:
description: "Verify feature is in draft phase"
depends_on: [create-feature]
action: shell
command: |
PHASE="{{ .outputs.create-feature.feature_phase }}"
if [ "$PHASE" == "draft" ]; then
echo "Feature created in draft phase"
exit 0
else
echo "Expected draft, got $PHASE"
exit 1
fi
# ============================================================
# PHASE 2: DRAFT → SPECIFIED
# Agent writes spec, API approves, transition
# ============================================================
write-spec:
description: "Agent writes the spec artifact"
depends_on: [verify-draft]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
body:
prompt: "/spec-feature {{ .vars.feature_slug }} --requirements 'CRUD API for user preferences. GET/PUT /preferences/{user_id}. Preferences are key-value pairs stored in DB. Support theme, language, notifications settings.'"
auto_commit: true
auto_push: true
git_clone_url: "https://git.threesix.ai/jordan/{{ .outputs.create-project.project_id }}.git"
outputs:
- build_id: .data.task_id
wait-spec:
depends_on: [write-spec]
action: wait_build
build_id: "{{ .outputs.write-spec.build_id }}"
max_attempts: 60
poll_interval: 5
approve-spec:
description: "API approves the spec artifact"
depends_on: [wait-spec]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/artifacts/spec/approve"
body:
comment: "Spec approved by automation"
transition-to-specified:
description: "Transition from draft to specified"
depends_on: [approve-spec]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/transition"
body:
phase: "specified"
outputs:
- new_phase: .data.phase
# ============================================================
# PHASE 3: SPECIFIED → PLANNED
# Agent writes design, tasks, qa_plan. API approves each.
# ============================================================
write-design:
description: "Agent writes the design artifact"
depends_on: [transition-to-specified]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
body:
prompt: "/design-feature {{ .vars.feature_slug }}"
auto_commit: true
auto_push: true
git_clone_url: "https://git.threesix.ai/jordan/{{ .outputs.create-project.project_id }}.git"
outputs:
- build_id: .data.task_id
wait-design:
depends_on: [write-design]
action: wait_build
build_id: "{{ .outputs.write-design.build_id }}"
max_attempts: 60
poll_interval: 5
approve-design:
description: "API approves the design artifact"
depends_on: [wait-design]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/artifacts/design/approve"
body:
comment: "Design approved by automation"
write-tasks:
description: "Agent breaks down into tasks"
depends_on: [approve-design]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
body:
prompt: "/breakdown-feature {{ .vars.feature_slug }}"
auto_commit: true
auto_push: true
git_clone_url: "https://git.threesix.ai/jordan/{{ .outputs.create-project.project_id }}.git"
outputs:
- build_id: .data.task_id
wait-tasks:
depends_on: [write-tasks]
action: wait_build
build_id: "{{ .outputs.write-tasks.build_id }}"
max_attempts: 60
poll_interval: 5
approve-tasks:
description: "API approves the tasks artifact"
depends_on: [wait-tasks]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/artifacts/tasks/approve"
body:
comment: "Tasks approved by automation"
write-qa-plan:
description: "Agent writes QA plan"
depends_on: [approve-tasks]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
body:
prompt: "/create-qa-plan {{ .vars.feature_slug }}"
auto_commit: true
auto_push: true
git_clone_url: "https://git.threesix.ai/jordan/{{ .outputs.create-project.project_id }}.git"
outputs:
- build_id: .data.task_id
wait-qa-plan:
depends_on: [write-qa-plan]
action: wait_build
build_id: "{{ .outputs.write-qa-plan.build_id }}"
max_attempts: 60
poll_interval: 5
approve-qa-plan:
description: "API approves the QA plan artifact"
depends_on: [wait-qa-plan]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/artifacts/qa_plan/approve"
body:
comment: "QA plan approved by automation"
transition-to-planned:
description: "Transition from specified to planned"
depends_on: [approve-qa-plan]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/transition"
body:
phase: "planned"
outputs:
- new_phase: .data.phase
# ============================================================
# PHASE 4: PLANNED → READY
# No new artifacts needed, just transition
# ============================================================
transition-to-ready:
description: "Transition from planned to ready"
depends_on: [transition-to-planned]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/transition"
body:
phase: "ready"
outputs:
- new_phase: .data.phase
# ============================================================
# PHASE 5: READY → IMPLEMENTATION
# Agent implements all tasks
# ============================================================
implement-feature:
description: "Agent implements all tasks for the feature"
depends_on: [transition-to-ready]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
body:
prompt: "/implement-feature {{ .vars.feature_slug }}"
auto_commit: true
auto_push: true
git_clone_url: "https://git.threesix.ai/jordan/{{ .outputs.create-project.project_id }}.git"
outputs:
- build_id: .data.task_id
wait-implement:
depends_on: [implement-feature]
action: wait_build
build_id: "{{ .outputs.implement-feature.build_id }}"
max_attempts: 120
poll_interval: 5
wait-deploy-impl:
description: "Wait for implementation to deploy"
depends_on: [wait-implement]
action: wait_pipeline
project_id: "{{ .outputs.create-project.project_id }}"
transition-to-implementation:
description: "Transition to implementation phase (marks code complete)"
depends_on: [wait-deploy-impl]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/transition"
body:
phase: "implementation"
outputs:
- new_phase: .data.phase
# ============================================================
# PHASE 6: IMPLEMENTATION → REVIEW
# Agent writes code review
# ============================================================
write-review:
description: "Agent writes code review"
depends_on: [transition-to-implementation]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
body:
prompt: "/review-feature {{ .vars.feature_slug }}"
auto_commit: true
auto_push: true
git_clone_url: "https://git.threesix.ai/jordan/{{ .outputs.create-project.project_id }}.git"
outputs:
- build_id: .data.task_id
wait-review:
depends_on: [write-review]
action: wait_build
build_id: "{{ .outputs.write-review.build_id }}"
max_attempts: 60
poll_interval: 5
approve-review:
description: "API approves the review"
depends_on: [wait-review]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/artifacts/review/approve"
body:
comment: "Review approved by automation"
transition-to-review:
description: "Transition to review phase"
depends_on: [approve-review]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/transition"
body:
phase: "review"
outputs:
- new_phase: .data.phase
# ============================================================
# PHASE 7: REVIEW → AUDIT
# Agent writes security/architecture audit
# ============================================================
write-audit:
description: "Agent writes security audit"
depends_on: [transition-to-review]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
body:
prompt: "/audit-feature {{ .vars.feature_slug }}"
auto_commit: true
auto_push: true
git_clone_url: "https://git.threesix.ai/jordan/{{ .outputs.create-project.project_id }}.git"
outputs:
- build_id: .data.task_id
wait-audit:
depends_on: [write-audit]
action: wait_build
build_id: "{{ .outputs.write-audit.build_id }}"
max_attempts: 60
poll_interval: 5
approve-audit:
description: "API approves the audit"
depends_on: [wait-audit]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/artifacts/audit/approve"
body:
comment: "Audit approved by automation"
transition-to-audit:
description: "Transition to audit phase"
depends_on: [approve-audit]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/transition"
body:
phase: "audit"
outputs:
- new_phase: .data.phase
# ============================================================
# PHASE 8: AUDIT → QA
# Agent runs QA tests
# ============================================================
run-qa:
description: "Agent runs QA plan"
depends_on: [transition-to-audit]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
body:
prompt: "/run-qa {{ .vars.feature_slug }}"
auto_commit: true
auto_push: true
git_clone_url: "https://git.threesix.ai/jordan/{{ .outputs.create-project.project_id }}.git"
outputs:
- build_id: .data.task_id
wait-qa:
depends_on: [run-qa]
action: wait_build
build_id: "{{ .outputs.run-qa.build_id }}"
max_attempts: 60
poll_interval: 5
transition-to-qa:
description: "Transition to QA phase"
depends_on: [wait-qa]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/transition"
body:
phase: "qa"
outputs:
- new_phase: .data.phase
# ============================================================
# PHASE 9: QA → MERGE
# Merge feature branch to main
# ============================================================
merge-feature:
description: "Merge feature branch to main"
depends_on: [transition-to-qa]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/merge"
body:
strategy: "squash"
outputs:
- merge_commit: .data.commit_sha
transition-to-merge:
description: "Transition to merge phase"
depends_on: [merge-feature]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/transition"
body:
phase: "merge"
outputs:
- new_phase: .data.phase
# ============================================================
# PHASE 10: MERGE → RELEASED
# Archive the feature
# ============================================================
wait-final-deploy:
description: "Wait for merged code to deploy"
depends_on: [transition-to-merge]
action: wait_pipeline
project_id: "{{ .outputs.create-project.project_id }}"
archive-feature:
description: "Archive the completed feature"
depends_on: [wait-final-deploy]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/archive"
transition-to-released:
description: "Transition to released phase"
depends_on: [archive-feature]
action: api
method: POST
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/transition"
body:
phase: "released"
outputs:
- final_phase: .data.phase
# ============================================================
# VERIFICATION
# ============================================================
verify-service-running:
description: "Verify the preferences API is running"
depends_on: [transition-to-released]
action: shell
command: |
DOMAIN="{{ .outputs.create-project.domain }}"
HEALTH=$(curl -s "https://$DOMAIN/api/preferences-api/health" | jq -r '.data.status // empty')
if [ "$HEALTH" == "healthy" ]; then
echo "Service healthy"
exit 0
else
echo "Service not healthy: $HEALTH"
exit 1
fi
verify-preferences-api:
description: "Test CRUD operations on preferences"
depends_on: [verify-service-running]
on_error: continue
action: shell
command: |
DOMAIN="{{ .outputs.create-project.domain }}"
BASE_URL="https://$DOMAIN/api/preferences-api"
USER_ID="test-user-123"
# PUT preferences
echo "Setting preferences..."
PUT_RESP=$(curl -s -X PUT "$BASE_URL/preferences/$USER_ID" \
-H "Content-Type: application/json" \
-d '{"theme":"dark","language":"en","notifications":true}')
echo "PUT response: $PUT_RESP"
# GET preferences
echo "Getting preferences..."
GET_RESP=$(curl -s "$BASE_URL/preferences/$USER_ID")
echo "GET response: $GET_RESP"
# Verify theme is dark
THEME=$(echo "$GET_RESP" | jq -r '.theme // .data.theme // empty')
if [ "$THEME" == "dark" ]; then
echo "Preferences API working correctly"
exit 0
else
echo "Expected theme=dark, got: $THEME"
exit 1
fi
verify-lifecycle-complete:
description: "Verify feature reached released phase"
depends_on: [verify-preferences-api]
action: shell
command: |
FINAL_PHASE="{{ .outputs.transition-to-released.final_phase }}"
if [ "$FINAL_PHASE" == "released" ]; then
echo "SUCCESS: Feature completed full lifecycle (draft → released)"
echo "All 10 phases traversed with explicit approvals"
exit 0
else
echo "FAIL: Expected released, got $FINAL_PHASE"
exit 1
fi
teardown:
- action: api
method: DELETE
endpoint: "/project/{{ .outputs.create-project.project_id }}"