From 9739632fe431d9791d39f64e6151923e60031179 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Thu, 14 May 2026 12:11:21 +0600 Subject: [PATCH] 2026-05-14 planning session: 7 work plans added (no-topic-routing, executor-orchestrator, executor-spawning, gha-ci-executor, tm-backup, asana-dns, kraken-obsidian-bug) --- work/plans/asana-dns-issue.md | 30 +++++++ work/plans/executor-spawning-research.md | 110 +++++++++++++++++++++++ work/plans/gha-ci-executor.md | 69 ++++++++++---- work/plans/kraken-obsidian-write-bug.md | 42 +++++++++ 4 files changed, 233 insertions(+), 18 deletions(-) create mode 100644 work/plans/asana-dns-issue.md create mode 100644 work/plans/executor-spawning-research.md create mode 100644 work/plans/kraken-obsidian-write-bug.md diff --git a/work/plans/asana-dns-issue.md b/work/plans/asana-dns-issue.md new file mode 100644 index 00000000..9accb966 --- /dev/null +++ b/work/plans/asana-dns-issue.md @@ -0,0 +1,30 @@ +# Investigation: Asana Sync DNS Failure + +**Date**: 2026-05-14 +**Status**: Identified, not fixed + +## Symptom + +`status.md` датирован Apr 30 — данные устарели на ~2 недели. + +## Root Cause + +`sync.js` (heartbeat pipeline) получает `ENOTFOUND app.asana.com` при каждом запросе к Asana API начиная с утра 2026-05-14 05:19. + +Из `~/Developer/personal-os/logs/heartbeat.log`: +``` +[asana] fetchMyTasks: error in section active: getaddrinfo ENOTFOUND app.asana.com +[sync] Fatal error: getaddrinfo ENOTFOUND app.asana.com +``` + +**Это не проблема токена** — это DNS не резолвит `app.asana.com`. + +## What Needs Investigation + +- Почему DNS не резолвит `app.asana.com` с Eagle? (другие хосты работают?) +- Это временная проблема сети или системный DNS сбой? +- Когда последний успешный sync? + +## Next Step + +Проверить DNS вручную: `nslookup app.asana.com`, `curl -v https://app.asana.com` — и понять масштаб проблемы перед любыми правками. diff --git a/work/plans/executor-spawning-research.md b/work/plans/executor-spawning-research.md new file mode 100644 index 00000000..5e603148 --- /dev/null +++ b/work/plans/executor-spawning-research.md @@ -0,0 +1,110 @@ +# Plan: Executor Orchestrator — Spawned Worker Pattern + +**Date**: 2026-05-14 +**Status**: Research needed +**Parent**: [[executor-v2-redesign]] +**Linked**: [[executor-orchestrator-redesign]] + +## Background (from session 2026-05-14) + +Alex's request (verbatim intent): +> Ты (орёл) должен спавнить воркер процессы, от лица другого бота (не Eagle а Executor), и как оркестратор реагировать на его "я сделал" / запросы пермишенс, читать недавний контекст (не весь тред) — и аппрувить/денаить автоматом, либо эскалировать и меншенить меня если ambiguity. + +Also from Kraken dictation (2026-05-14, not saved due to vault bug): +> Собирать планы в executor чтобы по крону запускались конкретные работы — не как сейчас что каждый агент по поставленной задаче работает, а чтобы автоматически спавнились если в папке Obsidian есть работа. + +## Core Design + +``` +Eagle (orchestrator, Zulip topic) + ↓ spawn +Executor (worker, separate process/session) + ↓ messages to #executor topic +Eagle monitors #executor (sliding window, last ~20 msgs) + ↓ auto-approve obvious / escalate ambiguous + ↓ @mention Alex only for ambiguity or high risk +``` + +## Research Findings (2026-05-14) + +### Q1: How to spawn Executor as separate bot persona? + +**Answer: Hermes Profiles** — the correct mechanism. + +Hermes supports named profiles: each profile = separate `~/.hermes/profiles//` with its own `SOUL.md`, `.env`, `config.yaml`, gateway, bot token, memory, cron jobs. + +```bash +hermes profile create executor --clone # clone Eagle config +# then configure: +echo "You are Исполнитель..." > ~/.hermes/profiles/executor/SOUL.md +# set different Zulip bot token for "Executor" bot in Zulip +nano ~/.hermes/profiles/executor/.env # ZULIP_BOT_EMAIL=executor-bot@zulip.local +executor gateway install # separate systemd/launchd service +``` + +**Key properties:** +- Each profile can have its own Zulip bot token → appears as different bot in UI +- `executor gateway start` runs independently from Eagle +- Cron jobs in `executor` profile run under executor's identity +- Safety: if two profiles share same Zulip token → second gateway is blocked with error + +**Spawn pattern**: Eagle triggers Executor by sending a message to the Executor's Zulip topic (or writing to a shared queue). Executor's gateway picks it up as a new session. + +OR: Eagle uses `cronjob(action='create', schedule='once', ...)` with executor profile — but this stays within Eagle's identity. For true persona separation → need separate profile with separate gateway. + +**Recommended: Option B (separate profile + gateway)** +- `executor` profile with its own SOUL, its own Zulip bot ("Исполнитель") +- Eagle sends trigger message to `#executor` as Eagle → Executor bot responds as Executor +- Natural separation of concerns, no code changes needed + +### Q2: How does Eagle monitor #executor without blocking? + +**Answer: Hermes cron every 2 min** (simplest, already proven infrastructure) + +- Eagle cron job: `*/2 * * * *` → query Zulip REST for recent `#executor` messages → parse `[REQUEST]`/`[ESCALATE]` tags → auto-approve or @mention Alex +- Alternative: Zulip webhook → Hermes webhook trigger (needs setup, lower latency) +- Cron is sufficient given that executor tasks run for minutes-hours, not seconds + +### Q3: Message protocol format + +Need a structured format Executor uses so Eagle can parse O(1) without LLM: +``` +[REQUEST:create_worktree] branch=fix/tab-preview-stuck run_id=42 +[REQUEST:run_tests] scheme="macOS UI Tests CI" +[STATUS:investigation] Analysing bug... +[STATUS:pr_open] PR #1234 https://github.com/... +[DONE:pr_ready] CI green, no comments +[ESCALATE:scope_expansion] Found unrelated issue in TabBar.swift +``` + +### Q4: Plans-to-executor trigger (from Kraken dictation) + +If there are "work items" in an Obsidian folder (e.g. `work/plans/executor-queue/`), cron should auto-spawn workers. + +Research: what's the folder-watching mechanism? Options: +- Eagle morning-brief cron checks folder, spawns workers +- Dedicated `executor-plans-watcher` cron (every 30 min) +- Executor-analyzer.sh already does this via DB — maybe just add Obsidian→DB bridge + +## Auto-Approval Rules (draft) + +| Action | Auto | Rule | +|---|---|---| +| create worktree | ✅ approve | safe, reversible | +| run build | ✅ approve | safe | +| run tests | ✅ approve | safe | +| open draft PR | ✅ approve | draft = no merge | +| push to branch | ✅ approve | executor branch only | +| post Asana comment | ⚠️ escalate | external side effect | +| merge PR | ❌ always escalate | irreversible | +| modify files outside worktree | ❌ deny | scope violation | +| scope expansion | ❌ deny + notify | default policy | + +## Implementation Phases + +1. **Research** (this phase) — answer Q1-Q4 via web search + Hermes source inspection +2. **Protocol** — define message format, write Executor posting code +3. **Eagle monitor** — cron job that reads #executor, applies auto-approval rules +4. **Worker spawn** — Eagle can trigger Executor on demand +5. **Plans watcher** — Obsidian folder → auto-spawn (Q4) +6. **Test** — dry run with a real executor task diff --git a/work/plans/gha-ci-executor.md b/work/plans/gha-ci-executor.md index f90f2d30..87eda5cb 100644 --- a/work/plans/gha-ci-executor.md +++ b/work/plans/gha-ci-executor.md @@ -77,29 +77,62 @@ jobs: run: # Post summary to Asana task + open PR if not already ``` -## Key Questions to Investigate +## Research Findings (2026-05-14) -1. **macOS runner availability**: GitHub-hosted `macos-15` or `macos-15-xlarge`? - - Large runners cost more but needed for Xcode + Simulator - - Self-hosted M4 Mac runner on Eagle itself? (no cloud cost but uses Eagle) +### GHA macOS Runners — Current State -2. **Peekaboo on GHA**: Does Peekaboo work on GHA macOS runners? - - Needs Screen Recording permission → headless runner may not grant it - - Alternative: use `xcrun simctl` directly for UI tests - - Or: spin up VM via ddg-vm (if GHA runner has the VM tool) +- `macos-15` is current `macos-latest` (since Sep 2025) +- Xcode max 3 simulator runtimes per image (since Aug 11, 2025) +- **Simulators work fine on GHA** — iOS Simulator runs headless without display server +- XCUITests run via `xcodebuild test` on Simulator → headless OK, no Screen Recording needed -3. **Build time**: Full prod build on GHA macos-15? - - Estimated 15-30 min cold, 5-10 min with cache - - DerivedData caching via `actions/cache` is critical +### Peekaboo on GHA — The Problem + +Peekaboo requires: +1. **Screen Recording** permission (TCC) — for `ScreenCaptureKit` +2. **Accessibility** permission (TCC) — for AX tree traversal +3. Runs on **macOS 15+ (Sequoia)** + +On GHA macOS runners: +- TCC permissions can be pre-granted via `tccutil reset` + `tccutil insert` — but requires SIP disabled or specific entitlements +- GHA macOS runners run **with SIP enabled** — `tccutil insert` won't work without sudo tricks +- **Peekaboo CLI needs the Mac App running as a bridge** (Unix socket IPC) for privileged operations + +**Conclusion: Peekaboo on GHA hosted runner = NOT viable out of the box.** Would need: +- Self-hosted macOS runner (Eagle itself, or a dedicated Mac) +- OR: use ddg-vm to spin a VM on Eagle, run Peekaboo inside VM (current CI pattern) + +### XCUITest on GHA — Works Fine + +Our current CI already runs `macOS UI Tests CI` scheme on GHA via ddg-vm VMs. The issue isn't XCUITest — it's **visual/Peekaboo-based** reproduction that's GHA-incompatible. + +### Two-Tier Approach (Recommended) + +``` +Analysis Agent (Claude Cloud / Eagle) + ↓ reads Asana task, generates prompt + ↓ triggers GHA workflow + +GHA macOS runner: + ↓ checkout + build (cached DerivedData) + ↓ claude -p executor-worker.md (non-interactive) + ↓ fix code, run unit + UI tests via Simulator (NO Peekaboo) + ↓ open draft PR + +For visual reproduction / Peekaboo validation: + → spawn ddg-vm (existing infra) from Eagle or from GHA via SSH + → VM has Peekaboo pre-installed + permissions granted +``` + +### Claude Code Non-Interactive on GHA + +`claude -p prompt.md` works non-interactively. Needs: +- `ANTHROPIC_API_KEY` in secrets +- `--dangerously-skip-permissions` flag (all tools pre-approved) or tool allowlist + +GHA secret: `ANTHROPIC_CI_KEY` — separate from user key. -4. **Claude Code non-interactive**: Does `claude -p` (non-interactive) work for complex fix tasks? - - Yes — `claude -p` is the standard non-interactive mode - - Needs `--dangerously-skip-permissions` or pre-approved tool config -5. **Secrets**: Need in GHA: - - `ANTHROPIC_CI_KEY` — separate key for CI (not user key) - - `ASANA_CI_TOKEN` — for posting results - - `GITHUB_TOKEN` — auto-provided ## Validation Steps diff --git a/work/plans/kraken-obsidian-write-bug.md b/work/plans/kraken-obsidian-write-bug.md new file mode 100644 index 00000000..1192f890 --- /dev/null +++ b/work/plans/kraken-obsidian-write-bug.md @@ -0,0 +1,42 @@ +# Bug: Kraken Cannot Write to Obsidian Vault + +**Date**: 2026-05-14 +**Status**: Identified, not fixed + +## Symptom + +Кракен (Hermes на RPi через Aide app) не может записывать заметки в Obsidian vault. При попытке создать файл в `family/how-to/` или `personal/how-to/` — получает `Permission denied`. + +## Evidence + +Из сессии Кракена 2026-05-14 05:20 (session_api-e59bba9a32fc9d52): +``` +Tool mcp_obsidian_write_note returned error: "Error: Permission denied: family/how-to/hermes-agent-cron-plans.md" +Tool mcp_obsidian_write_note returned error: "Error: Permission denied: personal/how-to/hermes-agent-cron-plans.md" +``` + +Кракен остановился по правилу трёх попыток. **Задача не сохранена.** + +## What Was Lost + +Надиктованная задача (содержание): +> "Собирать планы из Obsidian в executor чтобы по крону запускались конкретные работы — не как сейчас что каждый агент по поставленной задаче, а чтобы автоматически спавнились если в папке Obsidian есть работа." + +(Эта задача совпадает с п.3 текущего planning треда — уже записана в `executor-spawning-research.md`.) + +## Likely Cause + +`mcpvault` MCP сервер возвращает `Permission denied` когда целевая субдиректория не существует в sparse checkout Кракена. В sparse checkout входит только `personal/` и `family/` — но не все поддиректории внутри них. + +Контейнер запускается как root (uid=0), vault принадлежит kraken (uid=1000) — возможно `mcpvault` отказывает из-за ownership mismatch при создании новых файлов. + +## What Needs Investigation + +1. Какие директории реально существуют в `/vault/` на Кракене? +2. `mcpvault` создаёт субдиректории сам или требует их существования? +3. Ownership mismatch root vs kraken — влияет ли на write через MCP? + +## Related + +- Также в git log видны 401 ошибки при `git push` — отдельная проблема (нет SSH ключа в контейнере для auth на TrueNAS) +- Docker volume `/home/kraken/obsidian:/vault:rw` — маунт RW, значит проблема не в Docker