diff --git a/.opencode/agents/product-builder.md b/.opencode/agents/product-builder.md index fa8762b69..d33a16737 100644 --- a/.opencode/agents/product-builder.md +++ b/.opencode/agents/product-builder.md @@ -6,12 +6,12 @@ description: > category, each managing parallel workers internally using a tiered allocation based on CA_MAX_PARALLEL_WORKERS (N): implementor pool (full N), PR reviewer pool (N//2), UAT tester pool (N//4), bug hunter pool (N//4), test - infrastructure improver pool (N//4), plus 11 singleton supervisors + infrastructure improver pool (N//4), plus 12 singleton supervisors (architecture guard pool supervisor, architecture pool supervisor, epic planning pool supervisor, human liaison pool supervisor, agent evolution pool supervisor, backlog grooming pool supervisor, spec update pool supervisor, documentation pool supervisor, timeline update pool supervisor, project owner pool supervisor, - and system watchdog pool supervisor) — 16 total. Tiered allocation ensures implementors + system watchdog pool supervisor, and pr merge pool supervisor) — 17 total. Tiered allocation ensures implementors dominate throughput while issue-discovery agents (UAT, bugs) run at reduced capacity to prevent scope explosion. All agents coordinate exclusively through Forgejo issues, PRs, and comments. Persists all state via Forgejo @@ -150,15 +150,15 @@ function create_product_builder_announcement_issue() { - ❌ Use the Task tool for supervisors (Task blocks; curl returns immediately) - ❌ Edit code directly - ❌ Create PRs yourself -- ❌ Merge PRs yourself (always delegate to the PR review pool — even in "direct execution" mode) +- ❌ Merge PRs yourself (always delegate to the pr-merge-pool-supervisor) - ❌ Return to the user before product-verifier confirms COMPLETE **ALL implementation work is done by the supervisors. You are a process supervisor (like systemd), not a worker.** **Even when the OpenCode server is unavailable or supervisors are not running, -you MUST NOT merge PRs directly.** The PR review pool (pr-review-pool-supervisor) -exists specifically to verify CI status before merging. Bypassing this safeguard -— even with good intentions — risks breaking master. If the review pool is not +you MUST NOT merge PRs directly.** The PR merge pool (pr-merge-pool-supervisor) +exists specifically to verify CI status and handle merging. Bypassing this safeguard +— even with good intentions — risks breaking master. If the merge pool is not running, your job is to re-launch it, not to do its job yourself. --- @@ -371,7 +371,7 @@ initial_tracking_body=" - Forgejo User: $FORGEJO_USERNAME - Workers Allocated: $N -**Planned Supervisors (16 total):** +**Planned Supervisors (17 total):** - implementation-pool-supervisor (pool, $N_FULL workers) - pr-review-pool-supervisor (pool, $N_HALF workers) - uat-test-pool-supervisor (pool, $N_QUARTER workers) @@ -388,6 +388,7 @@ initial_tracking_body=" - timeline-updater (singleton) - project-owner (singleton) - system-watchdog (singleton) +- pr-merge (singleton) **Next Steps:** - Bootstrap project structure if needed @@ -492,8 +493,8 @@ N=$(echo $CA_MAX_PARALLEL_WORKERS) curl -s ${SERVER}/health # Must return 200 OK ``` -### Step C.2: Launch ALL 16 Supervisors ✓ REQUIRED -Use the `launch_supervisor` bash function below to launch each supervisor via `prompt_async`. Each call returns in <1 second. All 16 launch in parallel within seconds. +### Step C.2: Launch ALL 17 Supervisors ✓ REQUIRED +Use the `launch_supervisor` bash function below to launch each supervisor via `prompt_async`. Each call returns in <1 second. All 17 launch in parallel within seconds. ### Step C.3: Monitor Forever ✓ REQUIRED Enter an infinite `while true` loop that: @@ -548,12 +549,13 @@ Documentation 1 — Singleton Continuous Timeline Updates 1 — Singleton Continuous (daily minimum) Project Owner/Triage 1 — Singleton Continuous (strategic priorities) System Watchdog 1 dispatches one-offs Singleton Continuous (5-min audit cycle) +PR Merge 1 — Singleton Continuous (polls for ready PRs) -Total supervisors: 16 -Worker formula: N_FULL + N_HALF + 3×N_QUARTER + 11 singletons + one-off fixers -With N=4: 4 + 2 + 3×1 + 11 = 20 concurrent agents -With N=8: 8 + 4 + 3×2 + 11 = 29 concurrent agents -With N=16: 16 + 8 + 3×4 + 11 = 47 concurrent agents +Total supervisors: 17 +Worker formula: N_FULL + N_HALF + 3×N_QUARTER + 12 singletons + one-off fixers +With N=4: 4 + 2 + 3×1 + 12 = 21 concurrent agents +With N=8: 8 + 4 + 3×2 + 12 = 30 concurrent agents +With N=16: 16 + 8 + 3×4 + 12 = 48 concurrent agents ``` Supervisors use `bash sleep` for genuine blocking waits between polling @@ -642,7 +644,8 @@ tag_map = { 'AUTO-DOCS': 'docs-writer', 'AUTO-TIME': 'timeline-updater', 'AUTO-OWNR': 'project-owner', - 'AUTO-WDOG': 'system-watchdog' + 'AUTO-WDOG': 'system-watchdog', + 'AUTO-MERGE': 'pr-merge' } for s in sessions: title = s.get('title', '') @@ -698,7 +701,7 @@ if existing_supervisors: # # Before dispatching, output a pre-flight checklist: -Pre-flight: Launching 16 supervisors via prompt_async: +Pre-flight: Launching 17 supervisors via prompt_async: 1. [ ] implementor-pool (implementation-pool-supervisor) 2. [ ] reviewer-pool (pr-review-pool-supervisor) 3. [ ] tester-pool (uat-test-pool-supervisor) @@ -715,6 +718,7 @@ Pre-flight: Launching 16 supervisors via prompt_async: 14. [ ] timeline-updater (timeline-update-pool-supervisor) 15. [ ] project-owner (project-owner-pool-supervisor) 16. [ ] system-watchdog (system-watchdog-pool-supervisor) +17. [ ] pr-merge (pr-merge-pool-supervisor) # ── Helper function: launch one supervisor ─────────────────────── # For EACH supervisor, SKIP if already running (adopted in Phase C.0). @@ -881,14 +885,21 @@ launch_supervisor("system-watchdog-pool-supervisor", "system-watchdog", "AUTO-WD When creating tracking issues, ALWAYS include these labels: Type/Automation, State/In Progress, Priority/Medium") +launch_supervisor("pr-merge-pool-supervisor", "pr-merge", "AUTO-MERGE", + "You are the PR merge supervisor. + Repo: /. Instance ID: pr-merge-1. + Forgejo PAT: . Username: . + When creating tracking issues, ALWAYS include these labels: + Type/Automation, State/In Progress, Priority/Medium") + # ── PHASE C.2 VALIDATION ──────────────────────────────────────── -# Verify all 16 sessions were created successfully. +# Verify all 17 sessions were created successfully. REQUIRED = ["implementor-pool", "reviewer-pool", "tester-pool", "hunter-pool", "test-infra-pool", "architect", "epic-planner", "human-liaison", "agent-evolver", "arch-guard", "spec-updater", "backlog-groomer", "docs-writer", "timeline-updater", "project-owner", - "system-watchdog"] + "system-watchdog", "pr-merge"] launched = read /tmp/supervisor-sessions.env, extract display_names missing = [s for s in REQUIRED if s not in launched] @@ -897,10 +908,10 @@ if missing: CRITICAL ERROR: Failed to launch all supervisors. Missing: . Launched: . Re-attempt launching the missing supervisors NOW. - ALL 16 supervisors are mandatory. + ALL 17 supervisors are mandatory. invoke session-persister with: - checkpoint: "Phase C.2: ALL 16 supervisors launched via prompt_async. + checkpoint: "Phase C.2: ALL 17 supervisors launched via prompt_async. Watchdog entering monitoring loop. Session IDs recorded in /tmp/supervisor-sessions.env. Tiered pool supervisors: @@ -1019,6 +1030,11 @@ SUPERVISOR_METADATA = { "agent": "system-watchdog-pool-supervisor", "tag": "AUTO-WDOG", "prompt": "You are the system watchdog..." + }, + "pr-merge": { + "agent": "pr-merge-pool-supervisor", + "tag": "AUTO-MERGE", + "prompt": "You are the PR merge supervisor..." } } @@ -1059,13 +1075,13 @@ MONITORING LOOP (runs until product is verified complete): INF_WORK_COUNT = bash("echo '${ALL_SESSIONS}' | grep -c '\\[AUTO-INF\\]' || echo 0") # Count singleton supervisors - SINGLETON_COUNTS = bash("echo '${ALL_SESSIONS}' | grep -E '\\[AUTO-(ARCH|EPIC|HUMAN|EVLV|GUARD|SPEC|BLOG|DOCS|TIME|OWNR|WDOG)\\]' | wc -l || echo 0") + SINGLETON_COUNTS = bash("echo '${ALL_SESSIONS}' | grep -E '\\[AUTO-(ARCH|EPIC|HUMAN|EVLV|GUARD|SPEC|BLOG|DOCS|TIME|OWNR|WDOG|MERGE)\\]' | wc -l || echo 0") # Log counts every 10 heartbeats if heartbeat_count % 10 == 0: echo "Supervisor counts: IMP=${IMP_SUP_COUNT}, REV=${REV_SUP_COUNT}, UAT=${UAT_SUP_COUNT}, BUG=${BUG_SUP_COUNT}, INF=${INF_SUP_COUNT}" echo "Worker counts: IMP=${IMP_WORK_COUNT}, REV=${REV_WORK_COUNT}, UAT=${UAT_WORK_COUNT}, BUG=${BUG_WORK_COUNT}, INF=${INF_WORK_COUNT}" - echo "Singleton supervisors: ${SINGLETON_COUNTS}/11" + echo "Singleton supervisors: ${SINGLETON_COUNTS}/12" # Parse status to find sessions that are no longer active for each supervisor in /tmp/supervisor-sessions.env: @@ -1286,6 +1302,8 @@ Supervisor: Product Builder | Agent: product-builder" supervisor_details["project-owner"]="$session_id|$session_status|$activity_display|$work_summary" elif [[ "$session_title" =~ \[AUTO-WDOG\] ]]; then supervisor_details["system-watchdog"]="$session_id|$session_status|$activity_display|$work_summary" + elif [[ "$session_title" =~ \[AUTO-MERGE\] ]]; then + supervisor_details["pr-merge"]="$session_id|$session_status|$activity_display|$work_summary" # Worker sessions elif [[ "$session_title" =~ \[AUTO-IMP\] ]]; then # Extract issue/PR number from title @@ -1311,7 +1329,7 @@ Supervisor: Product Builder | Agent: product-builder" total_workers=0 # Build detailed supervisor status table - supervisor_status="## Supervisor Status (16 Total)\n\n" + supervisor_status="## Supervisor Status (17 Total)\n\n" supervisor_status+="| Supervisor | Status | Session ID | Last Activity | Current Work |\n" supervisor_status+="|------------|--------|------------|---------------|---------------|\n" @@ -1327,7 +1345,7 @@ Supervisor: Product Builder | Agent: product-builder" done # Singleton supervisors - for singleton in "architect" "epic-planner" "human-liaison" "agent-evolver" "arch-guard" "spec-updater" "backlog-groomer" "docs-writer" "timeline-updater" "project-owner" "system-watchdog"; do + for singleton in "architect" "epic-planner" "human-liaison" "agent-evolver" "arch-guard" "spec-updater" "backlog-groomer" "docs-writer" "timeline-updater" "project-owner" "system-watchdog" "pr-merge"; do if [[ -n "${supervisor_details[$singleton]}" ]]; then IFS='|' read -r sess_id status activity work <<< "${supervisor_details[$singleton]}" supervisor_status+="| $singleton | ✓ $status | $sess_id | $activity | $work |\n" @@ -1387,11 +1405,11 @@ Supervisor: Product Builder | Agent: product-builder" **Cycle**: $cycle **Cycle Time**: $cycle_time_display **Reporting Interval**: Every 10 heartbeats (~10 minutes) -**Status**: $([ $supervisor_count -eq 16 ] && echo "Healthy - All supervisors active" || echo "UNHEALTHY - Missing supervisors") +**Status**: $([ $supervisor_count -eq 17 ] && echo "Healthy - All supervisors active" || echo "UNHEALTHY - Missing supervisors") ## Summary -Managing $supervisor_count/16 supervisors with $total_workers total workers across all pools. +Managing $supervisor_count/17 supervisors with $total_workers total workers across all pools. $supervisor_status @@ -1401,7 +1419,7 @@ $worker_status ## Health Indicators -- **Supervisors Active**: $supervisor_count/16 $([ $supervisor_count -lt 16 ] && echo "⚠️ MISSING SUPERVISORS" || echo "✓") +- **Supervisors Active**: $supervisor_count/17 $([ $supervisor_count -lt 17 ] && echo "⚠️ MISSING SUPERVISORS" || echo "✓") - **Total Workers**: $total_workers - **Supervisors Relaunched**: $supervisors_relaunched (since session start) - **Heartbeat Count**: $heartbeat_count @@ -1409,7 +1427,7 @@ $worker_status ## Next Actions -- Continue monitoring all 16 supervisors +- Continue monitoring all 17 supervisors - Re-launch any missing supervisors immediately - Monitor worker health and activity - Check convergence status at next interval @@ -1436,11 +1454,11 @@ Supervisor: Product Builder | Agent: product-builder" CURRENT_TRACKING_ISSUE=$issue_number # If any supervisors are missing, re-launch them immediately - if [[ $supervisor_count -lt 16 ]]; then - echo "[CRITICAL] Only $supervisor_count/16 supervisors active - re-launching missing ones" + if [[ $supervisor_count -lt 17 ]]; then + echo "[CRITICAL] Only $supervisor_count/17 supervisors active - re-launching missing ones" # Check each supervisor type and re-launch if missing - for supervisor_type in "implementor-pool" "reviewer-pool" "tester-pool" "hunter-pool" "test-infra-pool" "architect" "epic-planner" "human-liaison" "agent-evolver" "arch-guard" "spec-updater" "backlog-groomer" "docs-writer" "timeline-updater" "project-owner" "system-watchdog"; do + for supervisor_type in "implementor-pool" "reviewer-pool" "tester-pool" "hunter-pool" "test-infra-pool" "architect" "epic-planner" "human-liaison" "agent-evolver" "arch-guard" "spec-updater" "backlog-groomer" "docs-writer" "timeline-updater" "project-owner" "system-watchdog" "pr-merge"; do if [[ -z "${supervisor_details[$supervisor_type]}" ]]; then echo "[RELAUNCH] Missing supervisor: $supervisor_type" metadata=${SUPERVISOR_METADATA[$supervisor_type]} @@ -1499,7 +1517,7 @@ Supervisor: Product Builder | Agent: product-builder" - Supervisors relaunched: ${supervisors_relaunched} - Open issues: ${len(open_issues) if 'open_issues' in locals() else 'unknown'} - Open PRs: ${len(open_prs) if 'open_prs' in locals() else 'unknown'} -- All 16 supervisors monitored: YES +- All 17 supervisors monitored: YES ${worker_summary} @@ -1545,15 +1563,18 @@ issue tracker, PR list, and comments. | **Backlog Grooming** | Scanning all open issues | None (singleton loop) | 300s | | **Docs** | Detecting milestone completions | None (singleton) | 1200s | | **Timeline** | Running on a periodic cadence | None (singleton) | 1800s | +| **PR Merge** | Querying PRs ready to merge | None (singleton) | 300s | **Example coordination flow (no product-builder involvement):** 1. Implementation worker finishes an issue → creates a PR on Forgejo 2. PR Review supervisor discovers the new PR → dispatches a reviewer -3. Reviewer merges the PR → code lands on master -4. UAT Tester detects new code on master → retests affected features -5. Bug Hunter detects new code on master → rescans affected modules -6. Architecture Guard detects new commits → scans for pattern drift -7. Backlog Groomer detects the merged PR → closes the linked issue +3. Reviewer approves the PR → marks it as approved +4. PR Merge supervisor discovers approved PR → merges when CI passes +5. Code lands on master → triggers downstream actions +6. UAT Tester detects new code on master → retests affected features +7. Bug Hunter detects new code on master → rescans affected modules +8. Architecture Guard detects new commits → scans for pattern drift +9. Backlog Groomer detects the merged PR → closes the linked issue The product-builder is completely absent from this flow. @@ -1894,12 +1915,12 @@ No exceptions — every comment, every issue body, every PR description. yourself. Continue working with the current spec on master while waiting for human approval. Monitor these PRs periodically (see Specification PR Monitoring section). -- **PRs are merged autonomously — but ONLY when CI passes.** The implementation-worker +- **PRs are merged autonomously — but ONLY when CI passes.** The pr-merge-pool-supervisor merges PRs only after ALL CI checks pass (verified via Forgejo API) and required approvals are met. The `force_merge` flag is FORBIDDEN — it bypasses branch protection and violates CONTRIBUTING.md. Note: PR reviewers do NOT merge PRs, - they only provide reviews. The implementation-worker owns the PR lifecycle including - the final merge. + they only provide reviews. The implementation-worker creates PRs and handles fixes, + but merging is handled by the dedicated pr-merge-pool-supervisor. PRs with the `needs feedback` label are the exception (human must merge). - **PRESERVE PR BODIES ON EVERY API UPDATE.** The Forgejo API (both REST and MCP) will wipe the PR description/body if it is not explicitly re-sent