--- namespace: work tags: [system, architecture] last_updated: 2026-04-28 confidence: 1.0 --- # Personal OS — Architecture ## Why It Exists See: `personal-os-purpose.md` ## Agents ### Стратег (Strategist) — data pipeline, no conversation - `~/scripts/run-pipeline.sh` → sync.js + generate-status.js every 30 min (workdays via Hermes cron) - Writes `~/context/status.md` and `~/Developer/personal-os/asana_context.md` - Writes daily AW activity summaries to `activity_daily` table with quadrant classification - No Discord output — pure data layer ### Орёл / Eagle (Tactician + reactive layer) — Hermes v0.11.x Discord bot - Reads `~/context/status.md`, daily/weekly briefs, vault via obsidian MCP - Discord channels: `#daily-brief` `#inbox` `#focus` `#executor` `#projects` `#journal` `#retrospector` - Cron jobs: generate-daily-brief (07:00 MTWRF), morning-brief (08:30 MTWRF), eod-summary (18:00 MTWRF), inbox-check (30 min 09–19 MTWRF), weekly-plan (Mon 08:00), weekly-review (Fri 17:00), retrospector (Fri 17:30), executor-autonomous (every 30 min 09–18 MTWRF), commit-vault (23:00 daily) - Logs corrections to `corrections_log` table (SQL INSERT, silently on pushback) - **Never accesses Asana API directly** — only reads pre-rendered markdown and DB ### Ретроспектор (Retrospector) — Friday pattern analysis - Runs as separate Hermes cron at 17:30 Friday → `#retrospector` - Sources: corrections_log table, status.md subtask counts, obsidian git log, activity_daily quadrants, stories visibility metric - Prompt: `~/Developer/personal-os/agent/prompts/retrospector.md` ### Исполнитель (Executor) — two modes **Manual mode**: triggered by "fix bug [GID]" in #executor - Single STOP gate after analysis; then autonomous: fix → build → test → draft PR → CI loop - Prompt: `~/Developer/personal-os/agent/prompts/executor-bug-fix.md` **Autonomous mode**: hourly cron (09–18 workdays) → #executor - Maintains a queue from: My Hack Days, Watched, O-L Backlog, stale My Tasks - Analyzes tasks → posts "[Auto] Ready to start" with complexity/feasibility - Waits for "go {gid}" to start; no reply = moves to next analysis - Max 1 active fix at a time; handles CI/review on open draft PRs - Stops touching a PR once Alex moves it out of draft or pushes commits - No Asana comments; no touching other people's PRs - Queue state in `executor_queue` table; live plan: `~/Developer/personal-os/briefs/executor-queue.md` - Prompt: `~/Developer/personal-os/agent/prompts/executor-autonomous.md` **Shared**: - Worktree at `~/DuckDuckGo/apple-browsers.git/.claude/worktrees/executor-{gid}-{slug}/` - Always `git fetch origin main` + branch from `origin/main` - State machine in `executor_runs` table - For UI tests: spins VM via ddg-vm MCP (virfield), cleans up on PR close/merge **Eagle commands in #executor**: | Command | Effect | |---------|--------| | `fix bug {gid}` | Spawn manual executor (separate agent) | | `go {gid}` | Approve autonomous task → starts next tick | | `skip {gid}` | Skip task in queue | | `stop` | Pause current autonomous task | | `next` | Pause current, analyze next | | `resume {gid}` | Re-queue paused task | | `queue` | Show current executor-queue.md | ## Data Flow ``` Asana API → sync.js (30 min, Hermes cron, silent) → PostgreSQL: tasks, stories, task_edges, sync_state, task_annotations ActivityWatch (local daemon) → generate-status.js (reads AW HTTP API) → activity_daily (upserts daily project/quadrant summaries) generate-status.js → ~/context/status.md ← Eagle reads this → ~/Developer/personal-os/asana_context.md ← inbox-check reads this Eagle corrections in Discord → corrections_log table (INSERT on pushback, no announcement) → Retrospector reads weekly Executor runs → executor_runs table (state machine) → ~/DuckDuckGo/apple-browsers.git/.claude/worktrees/ → GitHub draft PRs (--draft, --assignee @me, no reviewers) ``` ## Key File Locations | File / Path | Purpose | |-------------|---------| | `~/context/status.md` | Live Asana + AW snapshot. Written by generate-status.js. Eagle reads this. | | `~/Developer/personal-os/asana_context.md` | Raw Asana context for inbox-check | | `~/Developer/personal-os/agent/prompts/` | All agent prompts (Hermes cron + on-demand) | | `~/.hermes/SOUL.md` | Eagle's identity, rules, vault write permissions | | `~/Developer/personal-os/config.json` | Asana workspace/user GIDs, section GIDs | | `~/Developer/personal-os/aw-projects.json` | ActivityWatch project classification rules | | `~/.hermes/config.yaml` | Hermes config: model, MCP servers, cron settings | | `~/obsidian/` | Vault — git repo, NAS remote, obsidian-mcp for search | | `~/Developer/personal-os/logs/` | heartbeat.log, wiki-ingest-YYYY-MM-DD.md | | `~/Developer/personal-os/briefs/` | daily/, weekly/, inbox/ — agent-written brief files | | `~/DuckDuckGo/apple-browsers.git/` | Browser repo (bare), worktrees as sibling dirs | | `~/DuckDuckGo/apple-browsers.git/.claude/worktrees/` | Executor worktrees | ## Database Tables | Table | Written by | Read by | |-------|-----------|---------| | tasks | sync.js | generate-status.js, executor, status queries | | stories | sync.js | generate-status.js, executor, retrospector | | task_edges | sync.js | subtask traversal | | sync_state | sync.js | generate-status.js header | | task_annotations | manual / Eagle | generate-status.js irrelevant filter | | activity_daily | generate-status.js | retrospector quadrant drift | | corrections_log | Eagle on pushback | retrospector pattern analysis | | executor_runs | executor (manual + autonomous) | generate-status.js active runs, executor state machine | | executor_queue | executor-autonomous | generate-status.js queue display, autonomous tick state | ## MCP Servers **Hermes agents:** | Name | Command | Used for | |------|---------|---------| | obsidian | `/opt/homebrew/bin/obsidian-mcp ~/obsidian` | Vault search, read, write | **Claude Code / `claude -p` sessions:** | Name | Command | Used for | |------|---------|---------| | ddg-vm | `npx tsx ~/Developer/virfield/server/mcp-server.ts` | VM lifecycle for UI tests | | obsidian | `/opt/homebrew/bin/obsidian-mcp ~/obsidian` | Vault access | ## launchd Agents | Label | Schedule | Purpose | |-------|----------|---------| | personal.os.heartbeat | :05 every hour | Runs run-pipeline.sh directly (no Claude auth needed); also triggers missed Hermes jobs after wake | | personal.os.wiki-ingest | 22:00 daily | `claude -p` wiki synthesis (needs filesystem access) | ## Vault Structure ``` ~/obsidian/ ├── wiki/ ← LLM-generated + hand-written (confidence: 1.0 = never overwrite) │ ├── personal-os-architecture.md (this file) │ ├── personal-os-purpose.md │ ├── personal-os-agent-rules.md │ ├── personal-os-self-modification.md │ ├── personal-os-sync-pipeline.md │ ├── personal-os-schema.md (auto-generated) │ ├── ddg-asana-workflow.md │ └── vault-filling-guide.md ├── raw/ ← symlinks to external source files (schema.sql, etc.) ├── work/ │ └── wiki/ │ └── apple-browsers/ ← .cursor/rules copies (.md) + vm-ui-testing.md └── personal/ family/ ```