--- title: "Executor v2 Redesign" aliases: - "Executor redesign" - "executor-v2-redesign" - "Executor v2" created: '2026-04-30' updated: '2026-05-31' tags: - personal-os - executor - planning - architecture related: - "[[personal/projects/personal-os/executor-orchestrator-redesign]]" - "[[personal/projects/personal-os/executor-security-analysis]]" --- # 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 --- ## 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 не засоряет новую очередь --- ## Связанные заметки - [[personal/projects/personal-os/executor-orchestrator-redesign|Executor Orchestrator Pattern]] - [[personal/projects/personal-os/executor-security-analysis|Executor Security Analysis]]