155 lines
4.8 KiB
Markdown
155 lines
4.8 KiB
Markdown
# Executor v2 Redesign
|
|
|
|
**Date**: 2026-04-30
|
|
**Status**: Planning
|
|
**Context**: Replacing LLM-based orchestrator with deterministic bash scripts + focused worker prompts
|
|
|
|
---
|
|
|
|
## Architecture
|
|
|
|
### Two daemons + cron watchdog
|
|
|
|
```
|
|
cron */5 → executor-runner.sh (lockfile: ~/.hermes/run/executor-runner.pid)
|
|
cron */5 → executor-analyzer.sh (lockfile: ~/.hermes/run/executor-analyzer.pid)
|
|
```
|
|
|
|
**Behavior**: Each script runs until no unprocessed tasks remain, then exits. No sleep loops. Cron restarts if crashed or finished. One instance at a time via lockfile + kill -0 check.
|
|
|
|
### executor-runner.sh
|
|
Processes tasks in `queued / in_progress / pr` states.
|
|
Each iteration:
|
|
1. Fetch active runs from DB
|
|
2. For each: fetch GitHub PR status, CI checks, unresolved comments
|
|
3. Validate labels on draft PRs, trigger CI if missing
|
|
4. Maintain 2 concurrent workers (track PIDs)
|
|
5. Spawn worker with state-appropriate prompt
|
|
6. If no actionable tasks remain → exit
|
|
|
|
### executor-analyzer.sh
|
|
Filters and analyzes incoming executor_queue tasks. One task per run.
|
|
Each iteration:
|
|
1. Pick one unanalyzed task (status=null/pending)
|
|
2. Run `claude -p` with analysis prompt
|
|
3. Set status: for_review / awaiting_go / skip
|
|
4. Exit (cron restarts for next task)
|
|
|
|
---
|
|
|
|
## DB Schema
|
|
|
|
### executor_queue (incoming tasks)
|
|
```sql
|
|
id serial PK
|
|
task_gid text UNIQUE NOT NULL
|
|
added_at timestamptz
|
|
updated_at timestamptz
|
|
source text
|
|
description text
|
|
notes text
|
|
status text -- for_review / awaiting_go / approved / skip / done
|
|
priority int
|
|
complexity text
|
|
feasibility text
|
|
analysis_summary text
|
|
executor_run_id int FK → executor_runs
|
|
```
|
|
|
|
### executor_runs (concrete run)
|
|
```sql
|
|
id serial PK
|
|
task_gid text FK → tasks
|
|
worktree_path text
|
|
branch_name text
|
|
pr_url text
|
|
pr_number int
|
|
thread_id text
|
|
started_at timestamptz
|
|
updated_at timestamptz
|
|
completed_at timestamptz
|
|
state text -- queued / in_progress / pr / complete / abandoned
|
|
ci_attempts int default 0
|
|
worker_session_id text
|
|
worker_last_update timestamptz
|
|
worker_pid int
|
|
worker_stuck_count int default 0
|
|
```
|
|
|
|
### Work logs
|
|
```
|
|
~/Developer/personal-os/executor/logs/{task_gid}/
|
|
investigation_YYYY-MM-DD-HH-MM-SS.md
|
|
pr_review_YYYY-MM-DD-HH-MM-SS.md
|
|
fix_ci_YYYY-MM-DD-HH-MM-SS.md
|
|
fix_comments_YYYY-MM-DD-HH-MM-SS.md
|
|
```
|
|
|
|
---
|
|
|
|
## State Machine
|
|
|
|
```
|
|
[queue] for_review → awaiting_go → approved
|
|
↓
|
|
[run] queued → in_progress → pr → complete
|
|
↑ ↓
|
|
(Alex comments abandoned
|
|
+ draft PR)
|
|
```
|
|
|
|
### pr sub-logic (script, not worker):
|
|
- CI running → skip this tick
|
|
- CI failed → spawn fix_ci worker
|
|
- Unresolved comments (non-ACKNOWLEDGED) → spawn fix_comments worker
|
|
- Last comment = `[ACKNOWLEDGED: ...]` → treated as resolved
|
|
- Claude review green + no unresolved + CI green → complete, notify Alex (@mention)
|
|
- Alex comments on complete+draft PR → back to pr
|
|
|
|
---
|
|
|
|
## Worker Prompts
|
|
|
|
| File | Trigger | End state |
|
|
|---|---|---|
|
|
| executor-worker-queued.md | state=queued | pr |
|
|
| executor-worker-inprogress.md | state=in_progress (resume) | pr |
|
|
| executor-worker-fix-ci.md | pr + CI failures | pr (CI running) |
|
|
| executor-worker-fix-comments.md | pr + unresolved comments | pr |
|
|
| executor-worker-pr-review.md | pr + CI green + no comments | complete |
|
|
|
|
PR review prompt requirements:
|
|
- Based on pull-request.mdc + pixels.instructions.md + .cursor rules
|
|
- macOS UI Tests GHA must be green (mandatory)
|
|
- Posts review comments directly to PR via gh CLI
|
|
|
|
---
|
|
|
|
## Analyzer Filters (skip if any match)
|
|
|
|
- Not macOS task
|
|
- Description contains "Timeline" AND "Project Advisor:" → project template
|
|
- Contains Figma link
|
|
- Task closed / not unassigned or not assigned to Alex
|
|
- Source = user_feedback_raw
|
|
|
|
Qualifying sources: O-L Backlog (Desktop Browsers), user_reports, watched, hack_days, my_tasks_inbox, my_tasks_backlog
|
|
|
|
---
|
|
|
|
## Migration Plan
|
|
|
|
1. **Phase 1: DB migration** — new schema, migrate existing runs, user_context → notes
|
|
2. **Phase 2: executor-runner.sh** — lockfile, GitHub/CI fetch, label validation, worker spawn
|
|
3. **Phase 3: Worker prompts** — 5 new prompt files
|
|
4. **Phase 4: executor-analyzer.sh + analyzer prompt**
|
|
5. **Phase 5: Cron replacement** — replace executor-autonomous, archive old prompts
|
|
6. **Phase 6: Recording pass tasks** — notes migration, PR review enforces UI tests
|
|
|
|
---
|
|
|
|
## Current State (before migration)
|
|
- executor_queue: 924 skip, 16 in_progress, 10 awaiting_go
|
|
- executor_runs: 2 ci_running (blocking), 7 queued (recording pass), 6 awaiting_review, 2 complete
|
|
- Blocker: runs 10+11 (ci_running) block concurrency → fix in Phase 1
|