Files
obsidian-vault/personal/projects/personal-os/executor-v2-redesign.md
T

205 lines
6.7 KiB
Markdown

---
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]]