162 lines
7.2 KiB
Markdown
162 lines
7.2 KiB
Markdown
---
|
||
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/
|
||
```
|