6.1 KiB
6.1 KiB
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:
- Fetch active runs from DB
- For each: fetch GitHub PR status, CI checks, unresolved comments
- Validate labels on draft PRs, trigger CI if missing
- Maintain 2 concurrent workers (track PIDs)
- Spawn worker with state-appropriate prompt
- If no actionable tasks remain → exit
executor-analyzer.sh
Filters and analyzes incoming executor_queue tasks. One task per run. Each iteration:
- Pick one unanalyzed task (status=null/pending)
- Run
claude -pwith analysis prompt - Set status: for_review / awaiting_go / skip
- Exit (cron restarts for next task)
DB Schema
executor_queue (incoming tasks)
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)
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
- Phase 1: DB migration — new schema, migrate existing runs, user_context → notes
- Phase 2: executor-runner.sh — lockfile, GitHub/CI fetch, label validation, worker spawn
- Phase 3: Worker prompts — 5 new prompt files
- Phase 4: executor-analyzer.sh + analyzer prompt
- Phase 5: Cron replacement — replace executor-autonomous, archive old prompts
- 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
Timeouts
executor-runner.sh (worker processes)
- No-output watchdog: 30 min → kill + mark stuck
- Hard timeout per worker: 3 hours
- Loop sleep: 60s (while workers alive)
- Exit condition: no live workers AND no queued tasks
executor-analyzer.sh (claude -p analysis)
- No-output watchdog: 5 min → kill
- Hard timeout per task: 15 min
- Exit condition: no unanalyzed tasks remain
Corrections (2026-04-30)
- Analyzer: не одна задача за запуск — внутренний цикл пока задачи есть
- Runner: sleep 60s пока workers живые; выход когда workers=0 и queued=0
- Cron — только watchdog если скрипт упал или завершился
- Recording/UI acceptance criteria → в pr-review промпт, не отдельная фаза
Phase 7: Re-analyze skipped tasks
- Проверить структуру
skipзадач после завершения всего (что реально в полях) - Сбросить статус:
skip→null(или новыйpending) для всех macOS задач которые прошли бы новые фильтры - Запустить executor-analyzer.sh на них
- Убедиться что 924 skip не засоряет новую очередь