<!-- SPDX-License-Identifier: MIT -->
<!-- SPDX-FileCopyrightText: 2025-2026 Marcus Quinn -->

# Execution Plans

Complex, multi-session work requiring research, design decisions, and detailed tracking.

Based on [OpenAI's PLANS.md](https://cookbook.openai.com/articles/codex_exec_plans) and [plan.md](https://github.com/Digital-Tvilling/plan.md), with TOON-enhanced parsing.

<!--TOON:meta{version,format,updated}:
1.0,plans-md+toon,2026-03-31T00:00:00Z
-->

## Format

Each plan includes:

- **Status**: Planning / In Progress (Phase X/Y) / Blocked / Completed
- **Time Estimate**: `~2w (ai:1w test:0.5w read:0.5w)`
- **Timestamps**: `logged:`, `started:`, `completed:`
- **Progress**: Timestamped checkboxes with estimates and actuals
- **Decision Log**: Key decisions with rationale
- **Surprises & Discoveries**: Unexpected findings
- **Outcomes & Retrospective**: Results and lessons (when complete)

## Active Plans

### [2026-04-10] Qlty Maintainability Recovery Phase 2 (C→A)

**Status:** In Progress (Phase 1/4)
**Estimate:** ~28h across 18 tasks (6 existing + 12 new)
**TODOs:** t1860, t1910, t1911, t1912, t1913, t1914, t1915, t1941, t1942, t1943, t1944, t1945, t1946, t1947, t1948, t1949, t1950, t1951, t1952
**Logged:** 2026-04-10
**Trigger:** Qlty maintainability badge at C rating. 112 smell findings across 49 files. Phase 1 (t1858-t1863, April 2026) addressed 5 files but smells persist in 49 files. Systematic sweep needed to reach and maintain A.

#### Purpose

Eliminate all Qlty code smell findings to restore the maintainability badge to A and prevent regression. Four phases:

1. **Quick wins** (t1950, t1948) — fix function-level smells (many returns, duplication) in small files. ~1.25h.
2. **Core refactors** (t1941-t1947, t1949, t1951) — reduce total complexity in standalone scripts and utilities. ~21h.
3. **Plugin decomposition** (t1860, t1914) — decompose the opencode-aidevops plugin directory. ~12.5h. Blocked by phase 2 for oauth-pool.mjs.
4. **Regression prevention** (t1910, t1911, t1912, t1913, t1915) — CI gates, scanner extensions, ratchets. ~8.5h.

The higgsfield cluster (t1952, 1017 combined complexity) is the single largest contributor (~25% of all findings). t1862 was marked completed but smells persist — this is the follow-up.

#### Development Environment

| Item | Value |
|------|-------|
| Language/runtime | Python 3.11+, Node.js (ESM), TypeScript, Shell |
| Tests | `qlty smells --all --no-snippets` (zero findings target), shellcheck, existing test suites |
| Constraints | All refactors must preserve existing functionality. No API changes. Decomposition only — no feature changes. |

#### Progress

**Phase 1 — Quick wins:**
- [ ] (2026-04-10) t1950: Fix many-returns in git_safety_guard.py + extract-urls.py ~45m
- [ ] (2026-04-10) t1948: Deduplicate linkedin/local-browser automation ~30m

**Phase 2 — Core refactors (ordered by complexity, highest first):**
- [ ] (2026-04-10) t1952: Higgsfield stack (1017 combined) ~5h
- [ ] (2026-04-10) t1943: Email stack (502 combined) ~4h
- [ ] (2026-04-10) t1946: cross-document-linking + extraction_pipeline + voice-bridge (335 combined) ~3h
- [ ] (2026-04-10) t1947: tabby-profile-sync + add-related-docs + generate-manifest + pageindex-generator (327 combined) ~3h
- [ ] (2026-04-10) t1945: playwright-contrast + browser-qa (217 combined) ~2.5h
- [ ] (2026-04-10) t1944: session-miner extract + compress (225 combined) ~2h
- [ ] (2026-04-10) t1942: agent-discovery + opencode-agent-discovery (329 combined + dedup) ~2.5h
- [ ] (2026-04-10) t1941: chromium-debug-use (211) ~2h
- [ ] (2026-04-10) t1949: .opencode/ toon.ts + api-gateway.ts + ai-research.ts (145 combined) ~1.5h
- [ ] (2026-04-10) t1951: simplex-bot commands.ts + index.ts (119 combined) ~1.5h

**Phase 3 — Plugin decomposition:**
- [ ] t1860: oauth-pool.mjs (117) ~5.5h
- [ ] t1914: Full opencode-aidevops plugin directory (~1300 combined) ~7h (blocked-by:t1860)

**Phase 4 — Regression prevention:**
- [ ] t1910: Extend complexity scanner to .py/.mjs/.js/.ts ~2h
- [ ] t1911: Qlty smells CI gate ~1.5h
- [ ] t1912: Post-merge re-queue (blocked-by:t1910) ~2.5h
- [ ] t1913: Automate ratchet-down thresholds ~2h
- [ ] t1915: Qlty verification in simplification briefs ~40m

#### Decision Log

| Date | Decision | Rationale |
|------|----------|-----------|
| 2026-04-10 | All code is authored and maintained by us — no qltyignore exclusions | User confirmed all files are our creation. Apply simplification to everything rather than excluding. |
| 2026-04-10 | Order by complexity (highest first) | Highest-complexity files contribute most to the grade. Fixing them first gives the fastest badge improvement. |
| 2026-04-10 | Quick wins first (returns, dedup) | These are tier:simple tasks that can be dispatched immediately and completed in <1h each. |
| 2026-04-10 | Higgsfield follow-up (t1952) despite t1862 completed | t1862 reduced complexity but qlty smells still reports 1017 combined. The previous refactor was insufficient. |

---

### [2026-04-07] Pulse Triage Restoration and Linux Scheduler Fixes

**Status:** In Progress (Phase 1/2)
**Estimate:** ~3.5h across 2 tasks
**TODOs:** t1916, t1917
**Logged:** 2026-04-07
**Trigger:** User noticed pulse stopped posting triage analysis comments on external `needs-maintainer-review` issues. Investigation revealed t1894's cryptographic approval gate was applied too broadly (blocking triage, not just dispatch). Separately, GH#17695 identified real Linux scheduler gaps.

#### Purpose

Two related fixes:
1. **Pulse triage restoration** (t1916) -- remove the approval gate from triage dispatch so the pulse posts analysis comments on external issues before approval. The comment helps the maintainer decide whether to approve.
2. **Linux scheduler completion** (t1917) -- fix dual-execution bug and complete systemd migration on Linux. macOS (launchd) is unaffected.

#### Development Environment

| Item | Value |
|------|-------|
| Language/runtime | Shell (bash 3.2) |
| Tests | shellcheck, manual triage verification |
| Constraints | macOS launchd path must remain unchanged. Approval gate must stay on implementation dispatch. |

#### Progress

- [ ] (2026-04-07) t1916: Remove approval gate from triage dispatch ~25m
- [ ] (2026-04-07) t1917: Linux scheduler dual-execution fix ~3h

#### Decision Log

| Date | Decision | Rationale |
|------|----------|-----------|
| 2026-04-07 | Triage exempt from approval gate | Triage is read + comment, not code execution. The comment is what helps the maintainer decide whether to approve. Blocking it defeats the purpose. |
| 2026-04-07 | Accept GH#17695 despite being Linux-only | Valid cross-platform work. macOS uses launchd correctly. Linux scheduler path had real bugs. |
| 2026-04-07 | t1916 implemented first | Quick fix, enables triage on GH#17695 immediately. t1917 can be dispatched to workers. |

---

### [2026-04-03] mngr-Inspired Quality and Architecture Improvements

**Status:** Planning
**Estimate:** ~18.5h across 4 tasks
**TODOs:** t1876, t1877, t1878, t1879
**Logged:** 2026-04-03
**Trigger:** Analysis of [imbue-ai/mngr](https://github.com/imbue-ai/mngr/) (MIT-licensed agent process manager) identified 4 adoptable patterns for aidevops. Three are quality/pipeline improvements; one is strategic research for the SaaS agent hosting roadmap.

#### Purpose

Adopt proven patterns from mngr's architecture to improve aidevops in two dimensions:
1. **Quality pipeline** (t1876, t1877, t1878) -- better signal mining, structured reviews, and regression prevention. These enrich existing systems (session miner, audit agents, linters) rather than creating new ones.
2. **Strategic research** (t1879) -- evaluate mngr's tmux/provider/idle-detection architecture as a design reference for aidevops SaaS agent hosting, where users need AI agents running in secure containers.

#### Development Environment

| Item | Value |
|------|-------|
| Language/runtime | Shell (bash 3.2), Python 3.11+ (session miner), Markdown |
| Tests | shellcheck, markdownlint-cli2, ratchet self-test |
| Constraints | No new tools/commands -- enrich existing pipelines. Conservative false-positive tolerance (user directive). |

#### Progress

- [ ] (2026-04-03) t1876: Add `instruction_to_save` detection to session miner ~4h
- [ ] (2026-04-03) t1877: Structured code review categories reference doc ~2.5h
- [ ] (2026-04-03) t1878: Ratchet pattern for quality regression prevention ~4h
- [ ] (2026-04-03) t1879: Research mngr architecture for SaaS agent hosting ~8h

#### Decision Log

| Date | Decision | Rationale |
|------|----------|-----------|
| 2026-04-03 | Enrich session miner instead of creating `/verify-conversation` command | We already have session-miner-pulse.sh (743 lines) and autoagent signal-mining.md. Adding a signal source is cheaper than a new command and uses the established pipeline. |
| 2026-04-03 | Drop worktree ownership lock file idea | User warned about false positives disrupting productivity. Current prompt-level enforcement works. Revisit only if session miner shows evidence of actual ownership collisions. |
| 2026-04-03 | Ratchets advisory by default, --strict for CI | Productivity > strictness. Developers shouldn't be blocked by ratchets during interactive work, but CI should enforce them. |
| 2026-04-03 | t1879 is research-only, no code | SaaS hosting is strategic but premature to implement. Design doc informs future tasks when that work begins. |
| 2026-04-03 | Credit mngr in CREDITS.md | Attribution for design inspiration and patterns adopted. |

#### Surprises & Discoveries

- mngr and aidevops are complementary, not competing: mngr manages agent *processes*; aidevops manages agent *intelligence and workflow*. mngr could be a provider backend for aidevops headless dispatch.
- mngr's convention-based state (no database, prefix naming) is resilient but slower for multi-tenant SaaS. A thin metadata layer on top would be needed.
- mngr's conversation review categories include `instruction_to_save` -- detecting persistent user guidance -- which has no equivalent in our pipeline. This is the highest-novelty finding.
- Their ratchet pattern (`test_ratchets.py`) is simple but effective: ~50 lines of code prevent quality regression across an entire codebase.

### [2026-03-31] Chromium Debug Use Live Chromium Session Skill

**Status:** In Progress (Phase 1/4 after foundation)
**Estimate:** ~6h (ai:4h test:45m read:1h15m)
**TODOs:** t1706, t1707, t1708, t1709, t1710
**PRs:** #14956 (foundation)
**Logged:** 2026-03-31
**Trigger:** User wants an aidevops-owned `chromium-debug-use` agent/skill for inspecting what is already open in a Chromium-based browser, teaching the user how to enable the required debugging path for that browser, and using the live session as a fast discovery step before formal automation planning.

#### Purpose

PR #14956 already landed the initial `chromium-debug-use` browser guide and baseline discovery links. The remaining gap is turning that foundation into a fuller worker-ready capability with explicit browser enablement guidance, a loadable skill/helper surface, deeper automation-planning handoff rules, and bounded future-scope documentation.

V1 should optimize for the fastest path to answer: “help me understand or interact with what I already have open right now.” It should not replace Playwright, dev-browser, Stagehand, or Playwriter. Instead, it should provide a low-friction attach path, explicit consent model, and a clean handoff into the heavier tools when the task shifts from investigation to repeatable automation.

#### Development Environment

| Item | Value |
|------|-------|
| Language/runtime | Markdown, Bash 3.2 wrapper(s), Node.js 22+ for direct CDP/WebSocket access |
| Install | Prefer zero npm install for v1 helper path; reuse repo conventions for shell helpers and tool docs |
| Tests | `markdownlint-cli2` for new docs, `shellcheck` for any new shell helper, and a documented manual smoke check against a supported Chromium browser |
| Do NOT | Replace the existing browser stack, require a browser extension for v1, or promise blanket Electron support before adapter constraints are documented |

#### Linkage (The Pin)

| Concept | Files | Lines | Synonyms |
|---------|-------|-------|----------|
| Existing-browser routing gap | `.agents/tools/browser/browser-automation.md` | 17-35, 69-79 | current browser, live session, browser selection |
| Existing-browser automation baseline | `.agents/tools/browser/playwriter.md` | 23-35 | Playwriter, attached browser, extension attach |
| Inspection/debugging companion | `.agents/tools/browser/chrome-devtools.md` | 21-25, 39-54 | DevTools MCP, debugging, network inspection |
| Managed persistent browser alternative | `.agents/tools/browser/dev-browser.md` | 21-35, 161-170 | dev-browser, persistent profile, stateful automation |
| Top-level browser routing entry | `.agents/build-plus.md` | 124-126 | browser automation, tool routing |

#### Progress

- [x] (2026-03-31 15:28Z) Foundation: initial `chromium-debug-use` browser guide and baseline discovery links landed via PR #14956 (`t1706`) ~1h
- [ ] (2026-03-31 16:00Z) Phase 1: add the loadable skill entry point, helper wrapper, and richer attach operations for live Chromium sessions (`t1707`) ~2h
- [ ] (2026-03-31 16:00Z) Phase 2: add per-browser enablement, consent, and safety guidance for Chrome-family browsers (`t1708`) ~1h
- [ ] (2026-03-31 16:00Z) Phase 3: deepen browser tool routing and “inspect before automating” workflow guidance (`t1709`) ~1.5h
- [ ] (2026-03-31 16:00Z) Phase 4: document the Electron/macOS extension envelope and recommended follow-up boundaries (`t1710`) ~1h

#### Decision Log

| Date | Decision | Rationale |
|------|----------|-----------|
| 2026-03-31 | Name the aidevops-owned capability `chromium-debug-use` | User explicitly wants that identity, and it distinguishes the tool from broader “browser-use” style automation claims. |
| 2026-03-31 | Treat PR #14956 as shipped foundation and re-scope follow-ups around it | A pulse worker merged the initial guide before the planning commit landed, so the remaining tasks should build on that work instead of duplicating it. |
| 2026-03-31 | Keep v1 Chromium-only | Chromium browsers expose the same CDP family and satisfy the immediate “current browser window/webapp” use case with lower complexity than cross-engine support. |
| 2026-03-31 | Require explicit user approval before attaching to a live session | This is a more privileged attach path than isolated automation and should always be framed as opt-in local inspection. |
| 2026-03-31 | Position the tool as investigation-first, not automation-stack replacement | Playwright, Stagehand, dev-browser, Playwriter, and DevTools MCP already cover repeatable automation, self-healing, or deep analysis better once the session has been understood. |
| 2026-03-31 | Treat Electron and macOS automation as extension paths, not promised v1 scope | Electron support varies by app launch model and exposed debugging endpoint; macOS automation is valuable mainly for focus/discovery/handoff rather than DOM control. |

#### Surprises & Discoveries

- The upstream `chrome-cdp-skill` model proves there is a small-footprint Node 22+ path with no npm install and a daemonized attach model, so the main aidevops work is packaging, consent, routing, and verification rather than raw protocol feasibility.
- A pulse worker merged the initial browser guide from issue creation alone before the TODO/plan commit landed, which means follow-up planning must account for live GitHub state instead of assuming a clean queue.

### [2026-03-27] Context Token Optimization — Reduce Session Baseline

**Status:** In Progress (Phase 1/3)
**Estimate:** ~11h
**TODOs:** t1678, t1679, t1680, t1681, t1682

**Problem:** Session baseline grew from ~9.5k tokens (Mar 1) to ~39k tokens (Mar 27) before the first user message. User reported "hi" used to cost <20k, now costs 40k+. This is a compounding cost — every message pays for the base context.

**Root causes identified:**
1. **build.txt** grew 2.5x: 5,649 → 13,973 tokens (Mar 1-27). Each incident/learning added inline rules.
2. **.agents/AGENTS.md** grew 2x: 3,888 → 7,789 tokens. Domain index, self-improvement, agent routing sections expanded.
3. **12 repo-local .opencode/tool/*.ts files** injected ~3-4k tokens of tool schemas — 11 were pure shell script wrappers.
4. **7 plugin tools** (tools.mjs) add ~3.2k tokens — some may be consolidatable.
5. **Errored MCP servers** (auggie, cloudflare, playwright) may inject dead schemas.

**Phase 1 — Quick wins (done):**
- [x] Disabled 11 .opencode/tool/ shell wrappers (t1678 partial). Saved ~3-4k tokens. Verified: 122k → 39k mid-session, fresh session 38,885 tokens.
- [x] Discovered `system-cleanup` tool was actually broken (wrong arg format) — bash direct is better.

**Phase 2 — Progressive loading (t1679, t1680):**
- Move rarely-used build.txt sections to on-demand subagent docs (~3,800 tokens)
- Move AGENTS.md large sections to on-demand references (~3,500 tokens)
- Target: ~14k token reduction from prompt files

**Phase 3 — Plugin and MCP cleanup (t1681, t1682):**
- Consolidate plugin tools (7 → fewer)
- Fix or remove errored MCP server registrations

**Decision log:**
- 2026-03-27: Keep `ai-research.ts` as only repo-local tool — it has real logic (OAuth, API calls, rate limiting, domain mapping). All others are bash-replaceable.
- 2026-03-27: Use `.disabled` extension for reversibility during testing. Delete after verification.
- 2026-03-27: build.txt and AGENTS.md are "protected" — changes require interactive session with user decisions, not auto-dispatch.

**Surprises:**
- The 122k → 39k drop was mostly conversation accumulation, not tool schemas. Actual tool schema savings were ~3-4k tokens — still meaningful but not the 83k implied by the raw numbers.
- The `system-cleanup` tool had a stale enum that didn't match the script's actual interface. Tool wrappers can mask the real CLI, making them worse than direct bash.

### [2026-03-14] Restore OpenAI Codex and Enforce Model ID Conventions

**Status:** Completed
**Estimate:** ~2.5h
**TODO:** t1483 ✅
**PR:** #4660
**Issue:** GH#4656 CLOSED
**Logged:** 2026-03-14
**Trigger:** User review of PR#4641 and PR#4647 — both made incorrect model ID changes based on false assumptions.

#### Purpose

Fix two classes of model ID mismanagement by pulse workers, and make the default model list work for all users regardless of which providers they have configured:

1. **Codex removal (PR#4641):** A worker observed `ProviderModelNotFoundError` for `openai/gpt-5.3-codex` and assumed the model doesn't exist. It does — it's available via OpenAI OAuth subscription. The real issue is auth/provider config (the helper only checks `OPENAI_API_KEY`, not OAuth tokens). The fix replaced Codex with `gpt-4o`, losing coding specialisation and provider diversity.

2. **Haiku snapshot pinning (PR#4647/GH#3337):** A worker tried to pin `claude-haiku-4-5` to `claude-haiku-4-5-20251001` (a dated snapshot from Oct 2025). The codebase convention is to use unversioned latest aliases. PR closed.

3. **Multi-user compatibility:** The default model list must work for users who don't have OpenAI OAuth configured. The current backoff system handles this reactively (fail → backoff → skip on retry), wasting a dispatch attempt. A proactive auth-availability pre-check in `choose_model()` is needed — skip providers with no auth silently, no error, no backoff noise.

#### Phases

- [ ] **Phase 1 — Revert and add auth pre-check** (~1h): Revert PR#4641's model change in `headless-runtime-helper.sh` (lines 18, 817). Restore `openai/gpt-5.3-codex` in `DEFAULT_HEADLESS_MODELS`. Add `provider_auth_available()` function that checks whether a provider has auth configured (env var, OAuth token, or gateway). Wire it into `choose_model()` loop alongside `provider_backoff_active()` — if no auth, skip silently. Update tests for both auth-present and no-auth scenarios.

- [ ] **Phase 2 — Fix OpenAI auth and provider config** (~45m): Update `compute_auth_signature()` (line 161) to handle OAuth token auth, not just `OPENAI_API_KEY`. Add OpenAI provider entry to `model-routing-table.json`. Evaluate whether `opencode/*` gateway model IDs should be supported as an alternative path for users routing through OpenCode Zen.

- [ ] **Phase 3 — Audit and enforce conventions** (~45m): Scan all model ID references across scripts and configs for dated snapshots. Ensure all active routing uses unversioned latest aliases. Add a note to model-routing.md documenting the convention: latest aliases for routing, dated snapshots only in normalization/parsing paths.

#### Related

- PR#4641 (merged, needs revert): replaced Codex with gpt-4o
- GH#4628 (closed, needs reopen or supersede): original issue
- PR#4647 (closed): tried to pin haiku to dated snapshot
- GH#3337 (closed): quality-debt issue that prompted PR#4647

### [2026-03-12] Agent Runtime Sync After Merge/Release

**Status:** Completed
**Estimate:** ~3h (ai:1.75h test:45m read:30m)
**TODO:** t1453 ✅
**PR:** #4256
**Issue:** GH#4205 CLOSED
**Logged:** 2026-03-12
**Trigger:** Issue [GH#4205](https://github.com/marcusquinn/aidevops/issues/4205) plus observed post-release drift where new SEO subagent and slash-command docs were present in repo but missing in `~/.aidevops/agents/` until manual `rsync`.

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,completed}:
p046,Agent Runtime Sync After Merge/Release,completed,3,3,,deployment|automation|release|runtime-drift,3h,1.75h,45m,30m,2026-03-12T00:00Z,2026-03-21T00:00Z
-->

#### Purpose

Eliminate deployment drift between repo state (`.agents/`) and runtime state (`~/.aidevops/agents/`) after merge/release workflows. Newly merged docs/agents/commands should become available without requiring operators to remember manual sync commands.

This is a framework reliability issue, not only a one-off docs problem. If runtime sync is best-effort, every release can silently ship incomplete behavior from the user's perspective.

#### Constraints

- Preserve user-managed directories in runtime deploy (`custom/`, `draft/`, `loop-state/`, plugin namespaces).
- Avoid destructive cleanup unless explicitly in clean mode.
- Keep behavior deterministic in both interactive and headless flows.
- Do not require manual operator action for standard merge/release paths.

#### Phases

- [ ] **Phase 1 — Reproduce and instrument drift check** (~45m): Add a deterministic check command/script that compares `.agents/` against `~/.aidevops/agents/` for tracked files relevant to runtime behavior (especially `seo/`, `scripts/commands/`, and top-level agent docs). Emit clear PASS/DRIFT output.

- [ ] **Phase 2 — Wire automatic sync into post-merge/release paths** (~1.5h): Integrate `deploy_aidevops_agents` (or equivalent safe sync wrapper) into the existing merge/release lifecycle where drift can occur. Ensure sync runs from canonical repo path and logs success/failure with actionable diagnostics.

- [ ] **Phase 3 — Harden and verify** (~45m): Add regression checks and a fallback remediation command surfaced in release output when sync cannot run automatically. Verify newly added files appear in runtime immediately after merge/release.

#### Acceptance Criteria

- Standard merge/release flow updates `~/.aidevops/agents/` without manual `rsync`.
- Drift detection command reports PASS when runtime is current and DRIFT with precise file list when stale.
- New subagent files and slash commands become available in runtime right after release completion.
- Existing preserved runtime directories (`custom/`, `draft/`, plugin namespaces, `loop-state/`) are untouched.
- Docs reference the new behavior and fallback remediation command.

#### Decision Log

| Date | Decision | Rationale |
|------|----------|-----------|
| 2026-03-12 | Track as framework deployment issue | Drift affects user-visible capabilities after release and should not depend on operator memory. |
| 2026-03-12 | Prefer deterministic sync + check over heuristics | File-level diff is testable and avoids ambiguous "maybe deployed" states. |
| 2026-03-12 | Preserve user/private runtime dirs | Deploy automation must not overwrite user custom agents or runtime state. |

### [2026-03-11] gh Mutation `/bin/zsh` `posix_spawn` Failure

**Status:** Completed
**Estimate:** ~3h (ai:2h test:45m read:15m)
**TODO:** t1434 ✅
**PR:** #4127
**Issue:** GH#4122 CLOSED
**Logged:** 2026-03-11
**Trigger:** Provider-aware headless runtime release session hit `gh` write-path failures during merge and issue lifecycle steps.

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,completed}:
p045,gh Mutation /bin/zsh posix_spawn Failure,completed,3,3,,github|release|orchestration|bugfix,3h,2h,45m,15m,2026-03-11T00:00Z,2026-03-21T00:00Z
-->

#### Purpose

Fix intermittent failures in mutating GitHub CLI commands on this machine/runtime. During PR #4116 merge/release, read-only commands such as `gh pr view` and `gh issue view` worked, but mutating paths such as `gh pr merge`, `gh api --method PUT .../merge`, and other write operations failed with `ENOENT: no such file or directory, posix_spawn '/bin/zsh'`.

This is a framework-level reliability issue because full-loop, release, and supervisor workflows assume `gh` mutations work once auth is valid. Falling back to local git unblocked the release, but it bypasses part of the intended PR/issue lifecycle and is not acceptable as the normal automation path.

#### Known Observations

- The failure reproduces only on `gh` mutation commands; read-only `gh` commands continued to work in the same shell session.
- `/bin/zsh` exists on disk, so this is not a simple missing-binary problem.
- The failure occurred after a long interactive/release session with multiple worktrees and AI-run subprocesses.
- Local git fallback succeeded, which suggests repo state and credentials were otherwise healthy.

#### Phases

- [ ] **Phase 1 — Reproduce and isolate** (~45m): Capture the smallest command matrix that distinguishes working read-only commands from failing mutation commands. Test from main repo, worktree, clean shell env, and minimal env (`env -i ...`). Record whether failure is tied to `gh`, shell selection, pager/editor config, or inherited env vars.

- [ ] **Phase 2 — Root cause and fix** (~1.5h): Trace why `gh` attempts to spawn `/bin/zsh` for mutation paths. Check `SHELL`, git editor/pager env vars, `gh` config, and any aidevops wrappers that may inject shell-specific behavior. Implement the narrowest reliable fix in aidevops or local runtime setup.

- [ ] **Phase 3 — Harden and verify** (~45m): Add a deterministic preflight/health check for `gh` mutation capability, document the failure mode, and ensure full-loop/release paths either recover cleanly or emit a precise blocked state instead of failing late.

#### Acceptance Criteria

- `gh pr merge` works reliably in the same contexts where `gh pr view` already works.
- `gh api` mutation commands no longer fail with `/bin/zsh` `posix_spawn` in normal aidevops sessions.
- Full-loop can complete PR merge/comment/close steps without requiring local git fallback.
- A targeted verification command exists for future regressions.

#### Decision Log

| Date | Decision | Rationale |
|------|----------|-----------|
| 2026-03-11 | Track as framework bug, not machine-only note | The failure breaks release/merge automation and should be diagnosable by future sessions rather than rediscovered ad hoc. |
| 2026-03-11 | Capture reproduction before changing defaults | `gh` reads worked while writes failed, so changing shell config blindly risks masking the real cause. |
| 2026-03-11 | Keep local-git merge as emergency fallback only | It unblocks releases, but the normal path must preserve PR/issue automation and review-bot workflow integrity. |

### [2026-03-09] Grith-Inspired Security Enhancements

**Status:** Completed
**Estimate:** ~18h (ai:14h test:2.5h read:1.5h)
**TODO:** t1428 ✅ (parent), t1428.1-t1428.5 ✅ (subtasks)
**PRs:** #4030, #4031, #4035, #4036, #4042
**Issue:** GH#4025 CLOSED
**Logged:** 2026-03-09
**Inspiration:** [grith.ai](https://grith.ai) — zero-trust AI agent security proxy. Blog analysis of 9 posts covering: 7-agent security audit, MCP tool poisoning, skill supply chain attacks, Clinejection, DNS exfiltration (CVE-2025-55284), IDEsaster 24 CVEs, OpenClaw bans, vibe coding OSS impact.

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,completed}:
p044,Grith-Inspired Security Enhancements,completed,5,5,,security|prompt-injection|mcp|network|observability,18h,14h,2.5h,1.5h,2026-03-09T00:00Z,2026-03-21T00:00Z
-->

#### Purpose

Gap analysis of aidevops security stack against Grith.ai's zero-trust AI agent security model. After deep audit of our existing capabilities (prompt-guard-helper.sh, network-tier-helper.sh, worker-sandbox-helper.sh, content-classifier-helper.sh, audit-log-helper.sh, verify-operation-helper.sh, security-helper.sh, opsec.md CI/CD section, skill-scanner, privacy-filter-helper.sh, tirith, sandbox-exec-helper.sh), 5 genuine gaps were identified. These enhance both the framework's own security posture and provide patterns/guidance for apps built with aidevops.

**What we already have (no gap):** prompt injection detection (70+ patterns + LLM classifier), MCP tool poisoning awareness (mcporter.md security section), network egress controls (5-tier domain classification, 222 domains), tamper-evident audit trail (hash-chained JSONL), high-stakes operation verification (cross-provider), cost tracking, worker credential isolation (fake HOME), execution sandboxing, skill supply chain scanning (Cisco + VirusTotal), CI/CD AI agent security guidance (Clinejection case study, 10-point checklist), privacy filter, terminal security (Tirith), AI config scanning (Ferret), dependency scanning (Socket.dev + OSV).

**What's missing:** The 5 gaps below represent capabilities Grith implements at the syscall level that we can implement at the prompt/script layer — without kernel instrumentation.

#### Phases

- [ ] **Phase 1 — DNS exfiltration detection** (t1428.1, ~2h): Add patterns to `prompt-injection-patterns.yaml` and `sandbox-exec-helper.sh` that detect DNS exfiltration command shapes (`dig $(...).`, `nslookup $(...).`, `host $(...).`, base64-encoded data piped to DNS tools). Directly addresses CVE-2025-55284 demonstrated against Claude Code. Low effort, high value.

- [ ] **Phase 2 — MCP tool description runtime scanning** (t1428.2, ~3h): Create `mcp-audit` command that uses `mcporter list --json` to fetch all configured MCP server tool descriptions, runs `prompt-guard-helper.sh scan` on each description text, and flags any containing injection patterns. Run automatically on `aidevops init` and after `mcporter config add`. Catches the most underappreciated MCP attack vector — tool descriptions that instruct the model to read sensitive files.

- [ ] **Phase 3 — Session-scoped composite security scoring** (t1428.3, ~5h): Add a session security context that accumulates signals across operations. When `prompt-guard-helper.sh` detects a sensitive file access, it writes to a session state file. When `network-tier-helper.sh` evaluates an outbound request, it checks the session state — if sensitive data was accessed, the composite score gets elevated. Implements lightweight taint tracking without syscall interception. Extends `prompt-guard-helper.sh` to produce numeric composite scores from existing severity weights.

- [ ] **Phase 4 — Quarantine digest with learn feedback** (t1428.4, ~5h): Create `quarantine-helper.sh` providing a unified quarantine queue that `prompt-guard-helper.sh`, `network-tier-helper.sh`, and `sandbox-exec-helper.sh` all write to. Items in the ambiguous score range are batched for periodic review via `/security-review` command. "Learn" action feeds back into `network-tiers-custom.conf` or `prompt-guard-custom.txt`, creating a self-improving feedback loop.

- [ ] **Phase 5 — Unified post-session security summary** (t1428.5, ~3h): Enhance `session-review-helper.sh` with a `--security` mode that aggregates: cost from `observability-helper.sh`, security events from `audit-log-helper.sh` (filtered to current session), flagged domains from `network-tier-helper.sh`, quarantine items pending review, prompt-guard detections. Single summary view after each session. All data sources already exist — this is presentation/aggregation.

#### Future consideration

**Interactive session security posture dashboard** — deferred to a future aidevops interface project. The information (accessible sensitive paths, network egress posture, gopass entries) is security-sensitive and should not be published to public GitHub issues. Will be part of a local-only aidevops UI. For now, `security-posture-helper.sh` (t1412.6) provides CLI-based posture checks.

#### Decision Log

| Date | Decision | Rationale |
|------|----------|-----------|
| 2026-03-09 | Defer interactive dashboard to future aidevops UI | Security posture data (accessible keys, credentials, network state) should not be published to public GitHub issues. Needs a local-only interface. |
| 2026-03-09 | Implement at prompt/script layer, not syscall level | Grith's core value is OS-level interception. We can achieve 80% of the security benefit at the prompt/script layer using existing infrastructure (prompt-guard, network-tier, sandbox-exec). Syscall interception would require a separate tool. |
| 2026-03-09 | DNS exfil detection as Phase 1 | Lowest effort, highest immediate value. Directly addresses a demonstrated CVE. Pattern-based detection catches known attack shapes from CVE-2025-55284. |
| 2026-03-09 | MCP description scanning before composite scoring | MCP tool descriptions entering model context is a pre-execution attack vector. Catching it before the model processes the description is more effective than scoring the resulting operations after the fact. |

### [2026-03-07] Convos Encrypted Messaging Agent

**Status:** Completed
**Estimate:** ~2h (ai:1.5h read:30m)
**TODO:** t1414 ✅ (parent), t1414.1-t1414.2 ✅ (subtasks)
**PRs:** #3140, #3143, #3187
**Issue:** GH#3126 CLOSED
**Logged:** 2026-03-07
**Upstream skill:** `https://convos.org/skill.md`

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_read,logged,completed}:
p042,Convos Encrypted Messaging Agent,completed,2,2,,agent|communications|xmtp|convos,2h,1.5h,30m,2026-03-07T00:00Z,2026-03-21T00:00Z
-->

#### Purpose

Add a Convos subagent to the communications domain. [Convos](https://convos.org) is an encrypted messaging app built on XMTP that provides a CLI (`@xmtp/convos-cli`) for agent participation in conversations. The upstream project publishes a well-structured skill file at `https://convos.org/skill.md` covering the full agent lifecycle: CLI installation, joining/creating conversations, real-time participation via `convos agent serve` (ndjson stdin/stdout protocol), bridge script templates, group management, and behavioural principles.

**Relationship to existing agents:** We already have `xmtp.md` covering the protocol/SDK layer. Convos is a distinct product built on XMTP — a consumer-facing encrypted chat app with its own CLI and agent mode. The two agents are complementary: `xmtp.md` for building on the protocol, `convos.md` for participating in Convos conversations.

#### Phases

- [ ] **Phase 1 — Create agent file** (t1414.1, ~1h): Ingest upstream skill content into `.agents/services/communications/convos.md`. Add aidevops frontmatter (mode, tools, description), `AI-CONTEXT` markers, Quick Reference section, and Related section linking to `xmtp.md`, `simplex.md`, `matterbridge.md`. Adapt bridge script section to reference aidevops dispatch patterns instead of OpenClaw-specific calls.
- [ ] **Phase 2 — Index and cross-reference** (t1414.2, ~30m): Add `convos` to `subagent-index.toon` communications entry. Add to AGENTS.md domain index communications list. Update `xmtp.md` Production Apps table (Convos URL changed from `converse.xyz` to `convos.org`).
- [ ] **Phase 3 — Register for upstream tracking** (t1414.3, ~15m): Add entry to `skill-sources.json` with `format_detected: "url"` and `upstream_url: "https://convos.org/skill.md"`. Depends on t1415 for the update checker to handle URL-based sources.

#### Upstream Tracking

The skill is published at `https://convos.org/skill.md` — a raw URL, not a GitHub repo. The existing `skill-update-helper.sh` only supports GitHub commit comparison. Task t1415 adds URL-based content-hash checking to close this gap. Once t1415 is complete, Convos (and any future URL-sourced skills) will be tracked automatically.

#### Decision Log

| Date | Decision | Rationale |
|------|----------|-----------|
| 2026-03-07 | Separate file from xmtp.md | Convos is a distinct product with its own CLI; xmtp.md covers the protocol layer. Keeping them separate follows the pattern of other comms agents (e.g., Matrix protocol vs Matrix bot). |
| 2026-03-07 | Ingest upstream skill rather than link-only | The skill content is substantial and well-structured. Ingesting ensures availability even if the upstream URL changes, and allows aidevops-specific adaptations. |
| 2026-03-07 | URL-based tracking needed | No GitHub repo found hosting the skill. The upstream URL is `convos.org/skill.md`. Created t1415 to add content-hash comparison to the skill update pipeline. |

### [2026-03-07] URL-Based Skill Update Checking for Non-GitHub Sources

**Status:** Completed
**Estimate:** ~3h (ai:2.5h test:30m)
**TODO:** t1415 ✅ (parent), t1415.1-t1415.3 ✅ (subtasks)
**PRs:** #3139, #3141, #3886
**Issue:** GH#3131 CLOSED
**Logged:** 2026-03-07
**Depends on:** None
**Enables:** t1414.3 (Convos upstream tracking)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,logged,completed}:
p043,URL-Based Skill Update Checking,completed,3,3,,enhancement|skills|infrastructure,3h,2.5h,30m,2026-03-07T00:00Z,2026-03-21T00:00Z
-->

#### Purpose

The skill update pipeline (`skill-update-helper.sh` + `add-skill-helper.sh`) currently only supports GitHub-hosted skills — it compares commit SHAs via the GitHub API. Skills published at raw URLs (e.g., `https://convos.org/skill.md`, or any project that hosts a `skill.md` on their own domain) are invisible to update detection.

As more projects adopt the skill.md convention and publish at their own domains, this gap will grow. The fix is straightforward: content-hash comparison for URL-sourced skills.

**Problem:** `skill-update-helper.sh` skips non-GitHub sources entirely (line ~980: `if [[ "$upstream_url" != *"github.com"* ]]; then ... continue`). `add-skill-helper.sh` only accepts GitHub repos or ClawdHub slugs — no raw URL import path.

#### Phases

- [ ] **Phase 1 — URL import** (t1415.1, ~1.5h): Enhance `add-skill-helper.sh` to detect raw `.md` URLs (not GitHub, not ClawdHub). Fetch with curl, compute SHA-256 of response body, register in `skill-sources.json` with `format_detected: "url"` and new `upstream_hash` field. Security scan still runs on fetched content.
- [ ] **Phase 2 — URL update checking** (t1415.2, ~1h): Enhance `skill-update-helper.sh` to handle `format_detected: "url"` entries. Fetch the URL, compute SHA-256, compare against stored `upstream_hash`. If different, flag as update available. Wire into `--auto-update` and `pr` commands — re-fetch and re-import on update.
- [ ] **Phase 3 — HTTP caching** (t1415.3, ~30m): Store `ETag` and `Last-Modified` response headers in `skill-sources.json`. Use conditional requests (`If-None-Match`, `If-Modified-Since`) to avoid re-downloading unchanged content. Reduces bandwidth and avoids unnecessary hash computation on periodic checks.

#### Schema Changes

New fields in `skill-sources.json` skill entries:

```json
{
  "format_detected": "url",
  "upstream_url": "https://convos.org/skill.md",
  "upstream_hash": "sha256:abc123...",
  "upstream_etag": "\"67890\"",
  "upstream_last_modified": "Sat, 07 Mar 2026 12:00:00 GMT"
}
```

Existing GitHub-sourced skills continue using `upstream_commit` — no breaking changes.

#### Decision Log

| Date | Decision | Rationale |
|------|----------|-----------|
| 2026-03-07 | Content hash (SHA-256) over timestamp | Timestamps can change without content changing (CDN re-deploy). Hash comparison is definitive. ETag/Last-Modified are optimisations layered on top. |
| 2026-03-07 | Separate format_detected value ("url") | Clean separation from "skill-md", "clawdhub", etc. The update checker dispatches on this field, so a distinct value avoids polluting existing code paths. |

### [2026-03-06] Recursive Task Decomposition for Dispatch — Classify/Decompose Pipeline

**Status:** Completed
**Estimate:** ~10h (ai:7h test:2h read:1h)
**TODO:** t1408 ✅ (parent), t1408.1-t1408.5 ✅ (subtasks)
**PRs:** #2989, #2997, #2999, #3000, #3091
**Issue:** GH#2983 CLOSED
**Logged:** 2026-03-06
**Brief:** [todo/tasks/t1408-brief.md](tasks/t1408-brief.md)
**Inspired by:** [TinyAGI/fractals](https://github.com/TinyAGI/fractals) (recursive agentic task orchestrator, 146 stars, MIT)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,completed}:
p041,Recursive Task Decomposition for Dispatch,completed,3,3,,plan|feature|orchestration|decomposition,10h,7h,2h,1h,2026-03-06T00:00Z,2026-03-21T00:00Z
-->

#### Purpose

Add an LLM-powered pre-dispatch step that classifies tasks as atomic (execute directly) or composite (split into subtasks), then recursively decomposes composites into 2-5 independent subtasks with dependency edges and lineage context. Catches "task too big for one worker" failures that currently require human judgment.

**Three problems solved:**

1. **Over-scoped tasks cause worker failures.** A task like "build auth with login, registration, password reset, and OAuth" dispatched to one worker produces either a massive unfocused PR or fails partway. Currently, decomposition requires human judgment at task creation time.

2. **Workers drift off-scope without context.** Workers don't know what their siblings are doing, so they duplicate work or implement functionality that belongs to another subtask. Lineage context (ancestor chain + sibling descriptions) keeps workers focused.

3. **No batch ordering for parallel dispatch.** When multiple subtasks are ready, the pulse dispatches them ad-hoc. Explicit batch strategies (depth-first, breadth-first) enable smarter parallel execution that respects dependencies and rate limits.

**Catalyst:** [TinyAGI/fractals](https://github.com/TinyAGI/fractals) — a ~500-line TypeScript recursive task orchestrator that demonstrates the classify -> decompose -> lineage -> batch pattern works reliably. Their prompts are well-tuned with the right biases: "when in doubt, choose atomic" and "break into MINIMUM number of subtasks." We adopt the pattern, not the code.

#### Architecture

```text
Current dispatch flow:
  Task description → dispatch worker → worker executes → PR

New flow with decomposition:
  Task description
    │
    ▼
  classify(task, lineage)
    ├── atomic → dispatch worker directly (unchanged)
    │
    └── composite → decompose(task, lineage)
                      │
                      ▼
                    [2-5 subtasks with dependency edges]
                      │
                      ├── Interactive: show tree, ask confirmation
                      │   └── create child TODOs + briefs → dispatch leaves
                      │
                      └── Pulse: auto-proceed (depth limit: 3)
                          └── create child TODOs + briefs → dispatch leaves

Lineage context (passed to each worker):
  0. Build a CRM with contacts, deals, and email
    1. Implement contact management module
    2. Implement deal pipeline module  <-- (this task)
    3. Implement email integration module

  "You are one of several agents working in parallel on sibling tasks.
   Do not duplicate work that sibling tasks would handle."

Batch strategies:
  depth-first (default):        breadth-first:
    1.1 ─┐                       1.1, 2.1, 3.1 ─ batch 1
    1.2 ─┤ batch 1 (concurrent)  1.2, 2.2, 3.2 ─ batch 2
    1.3 ─┘                       1.3, 2.3, 3.3 ─ batch 3
    2.1 ─┐
    2.2 ─┤ batch 2 (concurrent)
    2.3 ─┘
```

#### Key Design Decisions

| Decision | Rationale |
|----------|-----------|
| Haiku-tier for classify/decompose | Judgment calls, not complex reasoning. ~$0.001/call. Opus would be overkill. |
| "When in doubt, atomic" bias | Over-decomposition creates more overhead (tasks, PRs, merge conflicts) than under-decomposition |
| Depth limit of 3 | Deeper decomposition suggests the original task was poorly scoped. Fractals allows 5 but notes depth as open question. |
| Reuse existing infrastructure | Child tasks use `claim-task-id.sh`, `blocked-by:`, standard briefs. No new state management. |
| Skip already-decomposed tasks | If TODO.md task already has subtasks, don't re-decompose. Prevents pulse from re-splitting manually decomposed tasks. |
| Shell script, not TypeScript | Consistent with aidevops infrastructure. Fractals is TypeScript but the pattern is language-agnostic. |

#### What Fractals Does That We Don't Need

| Fractals feature | Why we skip it |
|---|---|
| Web UI tree visualization | `/dashboard` + TODO.md serve the same purpose CLI-natively |
| Worktree-per-task isolation | Already have this via worktree workflow |
| Session management | Already have cross-session memory + TODO.md persistence |
| `--dangerously-skip-permissions` | Never — we have pre-edit checks and quality gates |

#### What We Have That Fractals Doesn't

| aidevops capability | Fractals gap |
|---|---|
| PR-based merge flow with review gates | No merge/backpropagation |
| `blocked-by:` dependency tracking | No dependency ordering |
| Cross-session memory + TODO.md | Session dies with process |
| Pre-edit checks, linters, review bot gate | Workers run unguarded |
| Cross-repo orchestration | Single-repo only |
| Model routing (haiku→opus by complexity) | Uses gpt-5.4 for everything |
| Full audit trail (task→issue→branch→PR→merge) | No traceability |

#### Subtask Breakdown

| ID | Task | Est | Model | Dependencies |
|----|------|-----|-------|-------------|
| t1408.1 | Classify/decompose helper script + prompts + lineage formatter | ~3h | sonnet | none |
| t1408.2 | Wire into dispatch pipeline (interactive + pulse + mission) | ~3h | sonnet | t1408.1 |
| t1408.3 | Lineage context in worker dispatch prompts | ~1.5h | sonnet | t1408.1 |
| t1408.4 | Batch execution strategies | ~1.5h | sonnet | t1408.2 |
| t1408.5 | Testing and verification | ~1h | sonnet | t1408.1-t1408.4 |

t1408.1 runs first (no dependencies). t1408.2 and t1408.3 can start after t1408.1 (parallel). t1408.4 depends on t1408.2. t1408.5 is the final verification step.

#### Progress

- [ ] (2026-03-06) Phase 1: Core implementation ~3h
  - [ ] t1408.1 Classify/decompose helper script, prompts, lineage formatter
- [ ] Phase 2: Integration ~4.5h
  - [ ] t1408.2 Dispatch pipeline integration (interactive + pulse + mission)
  - [ ] t1408.3 Lineage context in worker prompts (parallel with t1408.2)
  - [ ] t1408.4 Batch execution strategies
- [ ] Phase 3: Verification ~1h
  - [ ] t1408.5 Testing against real tasks, regression check

#### Decision Log

| Date | Decision | Rationale |
|------|----------|-----------|
| 2026-03-06 | Adopt classify/decompose pattern from Fractals | Highest-ROI idea — catches over-scoped tasks before dispatch at ~$0.001/call |
| 2026-03-06 | Shell script implementation, not TypeScript | Consistent with aidevops infrastructure; pattern is language-agnostic |
| 2026-03-06 | Lineage context as prompt engineering, not code | Adding ancestor/sibling descriptions to worker prompts is a guidance change, not a tool change |
| 2026-03-06 | Depth-first as default batch strategy | Fractals found this works well; completing one branch before starting next reduces coordination overhead |

#### Surprises & Discoveries

- Fractals' entire orchestration is ~500 lines of TypeScript — the pattern is simpler than expected
- Their classify/decompose prompts have well-tuned heuristics that prevent over-decomposition
- The lineage context formatter is trivially simple (indented text with a marker) but highly effective at keeping workers focused
- aidevops already has all the infrastructure Fractals is missing (merge flow, dependencies, persistence, quality gates) — we just need the decomposition step

---

### [2026-03-05] LLM Evaluation Suite — Benchmarking, Evaluators, Datasets, and Prompt Version Tracking

**Status:** Completed
**Estimate:** ~10h (ai:7h test:1.25h read:1h doc:0.75h)
**TODO:** t1393 ✅, t1394 ✅, t1395 ✅, t1396 ✅
**PRs:** #2914, #2916, #2917, #3079
**Issues:** GH#2914 CLOSED, GH#2916 CLOSED, GH#2917 CLOSED
**Logged:** 2026-03-05
**Briefs:** [t1393](tasks/t1393-brief.md), [t1394](tasks/t1394-brief.md), [t1395](tasks/t1395-brief.md), [t1396](tasks/t1396-brief.md)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,completed}:
p040,LLM Evaluation Suite,completed,4,4,,plan|feature|evaluation|model-comparison|observability,10h,7h,1.25h,1h,2026-03-05T00:00Z,2026-03-21T00:00Z
-->

#### Purpose

Build a lightweight LLM evaluation toolkit into aidevops — live model benchmarking, output quality scoring, reusable test datasets, and prompt version tracking. Inspired by [LangWatch](https://github.com/langwatch/langwatch) but implemented as CLI tools that fit our existing infrastructure (shell scripts, JSONL, pattern tracker) rather than requiring a 6-container Docker stack.

**Four problems solved:**

1. **No live model comparison.** `compare-models-helper.sh` compares models by static specs (pricing, context windows). There's no way to run the same prompt through N models and compare actual outputs. Choosing a model for a specific use case requires manual copy-paste between provider playgrounds.

2. **No output quality evaluation.** Code review bots check code, but nothing checks LLM-generated content for hallucination, relevance, or safety. No CI/CD quality gates exist for prompt changes.

3. **No reusable test datasets.** Every evaluation is ad-hoc. You can't re-run the same test cases after a prompt change to detect regressions, or build a golden set of edge cases from production.

4. **No prompt-to-trace linkage.** Prompts are in git (versioned) but traces don't record which version produced them. There's no way to answer "did my last prompt edit make things better or worse?"

**Catalyst:** Evaluating [LangWatch](https://github.com/langwatch/langwatch) (BSL 1.1, 3k stars) for aidevops integration. Their core value — batch evaluation with comparison charts, pluggable evaluators, dataset management, prompt versioning — can be replicated at 80% fidelity with CLI tools at ~$0.001/evaluation using haiku-tier calls.

#### Task Breakdown

| Task | Description | Estimate | Dependencies |
|------|-------------|----------|--------------|
| t1395 | Dataset convention (JSONL format, `dataset-helper.sh`) | ~2h | none |
| t1394 | Evaluator presets for `ai-judgment-helper.sh` | ~3h | none (enhances t1393 `--judge`) |
| t1393 | `compare-models-helper.sh bench` — live model benchmarking | ~4h | t1395 (required), t1394 (optional enhancement via `--judge`) |
| t1396 | Prompt version tracking in observability traces | ~1h | none (enhances observability for t1393/t1394 outputs) |

Recommended order: t1395 (required input format) -> t1394 (optional evaluator presets) -> t1393 (bench) -> t1396 (observability enhancement).

#### Terminology (adopted from LangWatch)

| Term | Meaning in aidevops |
|------|---------------------|
| **Experiment** | A deliberate batch comparison — `compare-models-helper.sh bench` |
| **Monitor** | Passive trace collection — `observability-helper.sh` |
| **Guardrail** | Sync evaluator that blocks responses — `prompt-guard-helper.sh` |
| **Evaluator** | Scoring function — `ai-judgment-helper.sh evaluate --type X` |
| **Dataset** | Collection of test cases — JSONL files in `datasets/` |
| **Score** | Evaluator result — `{score: 0-1, passed: bool, details: string}` |

#### Architecture

```text
Dataset (JSONL)
  |
  v
compare-models-helper.sh bench    ai-judgment-helper.sh evaluate
  |  sends prompt to N models       |  scores output on quality dims
  |  records: latency, tokens, cost  |  records: score, passed, details
  |                                  |
  +------ --judge delegates -------->+
  |                                  |
  v                                  v
bench-results.jsonl              eval-results (pattern tracker)
  |                                  |
  +--- prompt_version field ---------+  (from observability-helper.sh)
  |
  v
Historical trending / regression detection
```

#### LangWatch agent (separate)

A LangWatch subagent doc (`services/monitoring/langwatch.md`) was also created in this session for users who want the full platform. It covers self-hosting setup, Docker Compose, localdev integration, and the decision factors for when LangWatch is worth the infrastructure overhead vs the CLI tools above.

#### Progress

(To be updated during implementation)

#### Decision Log

| Date | Decision | Rationale |
|------|----------|-----------|
| 2026-03-05 | CLI tools over LangWatch self-hosting | 80% of LangWatch's eval value at ~$0.001/eval using haiku, without a 6-container Docker stack |
| 2026-03-05 | JSONL for all storage | Consistent with observability-helper.sh, streamable, grep-friendly |
| 2026-03-05 | Git short hash for prompt versioning | Prompts already in git — no new versioning system needed |
| 2026-03-05 | Independent tasks, recommended order | No hard blockers, but t1395 (format) -> t1394 (evaluators) -> t1393 (bench) -> t1396 (observability) is natural |

#### Surprises & Discoveries

- LangWatch's core eval value (batch comparison, pluggable evaluators, dataset management, prompt versioning) can be replicated at 80% fidelity with CLI tools
- The existing `compare-models-helper.sh discover` command already detects available providers — bench can reuse this for model availability
- `ai-judgment-helper.sh` already makes haiku-tier judgment calls — extending it with named evaluator presets is a natural fit

---

### [2026-03-05] Fix Runaway Memory Consumption — Process Guards, ShellCheck Limits, Session Awareness

**Status:** Completed
**Estimate:** ~6h (ai:4h test:1.5h read:30m)
**TODO:** t1398 ✅ (parent), t1398.1-t1398.5 ✅ (subtasks)
**Logged:** 2026-03-05
**Issue:** [GH#2854](https://github.com/marcusquinn/aidevops/issues/2854) CLOSED
**Replaces:** PR #2792 (declined)

#### Purpose

Root-cause fix for the March 3 kernel panic and ongoing memory pressure. Analysis identified three sources of excessive RAM consumption, all caused by aidevops itself:

1. **ShellCheck exponential expansion** (highest impact) — `shellcheck --external-sources` with recursive `--source-path` follows source directives across 100+ scripts. Single invocation observed at 5.7 GB RSS, 88% CPU, 35+ minutes runtime. Most likely cause of the kernel panic (46 swap files, 100% compressor saturation, watchdog timeout at 94s).

2. **Zombie pulse processes** — opencode enters idle state after completing but never exits. Stale detection depends on launchd re-invoking pulse-wrapper.sh. If launchd stops firing (sleep, plist unloaded), zombies persist indefinitely. Observed: 28+ hour zombie.

3. **Session accumulation** — 10+ interactive opencode sessions across terminal tabs, each 100-440 MB plus language servers. Total ~2.5 GB with no framework warning.

#### Phases

**Phase 1: Process guards (t1398.1, t1398.2)** ~2.5h
- Add `cleanup_runaway_processes()` to pulse-wrapper.sh — kill child processes exceeding RSS limit (2 GB) or runtime limit (10 min for shellcheck)
- Harden ShellCheck: remove `--external-sources` or restrict `--source-path`, add per-file timeout

**Phase 2: Self-watchdog and session awareness (t1398.3, t1398.4)** ~2h
- Pulse self-watchdog: process-level idle timeout (not just external stale detection)
- Session count check: warn when >5 concurrent interactive sessions open

**Phase 3: Memory pressure monitor rewrite (t1398.5)** ~1.5h
- Monitor the right signals: process count, individual RSS, process runtime
- Incorporate valid concepts from PR #2792 (launchd integration, notifications) with correct thresholds
- `kern.memorystatus_level` as secondary signal only, with much higher thresholds (macOS runs fine with compression + swap)

#### Decision Log

- **2026-03-05:** Declined PR #2792 — monitored wrong signals (kern.memorystatus_level at 40%/20% thresholds too aggressive), had unresolved security issues (command injection via arithmetic eval, XML injection in plist, AppleScript injection), CI failures, external contributor unresponsive to review feedback. Core concept (memory monitoring) valid but implementation needs rewrite.
- **2026-03-05:** Root cause is aidevops processes, not external memory pressure — the framework should fix its own resource consumption before adding a generic OS monitor.

---

### [2026-03-02] Prompt Injection Scanner — Tool-Agnostic Defense for aidevops and Agentic Apps

**Status:** Completed
**Estimate:** ~7.5h (ai:5.5h test:1h read:1h)
**TODO:** t1375 ✅ (parent), t1375.1-t1375.5 ✅ (subtasks)
**Logged:** 2026-03-02
**Brief:** [todo/tasks/t1375-brief.md](tasks/t1375-brief.md)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,completed}:
p039,Prompt Injection Scanner,completed,3,3,,plan|feature|security|prompt-injection,7.5h,5.5h,1h,1h,2026-03-02T00:00Z,2026-03-21T00:00Z
-->

#### Purpose

Extend aidevops prompt injection defense from chat-only (t1327.8) to all untrusted content ingestion points, and create developer guidance for building injection-resistant agentic apps.

**Three problems solved:**

1. **Zero defense on content ingestion.** aidevops agents routinely fetch web content (webfetch), read untrusted repos (PRs, dependencies), and call external MCP tools. Any of these can contain hidden instructions that manipulate agent behavior. The existing `prompt-guard-helper.sh` only covers inbound chat messages in the SimpleX/Matrix bot framework.

2. **Pattern coverage gaps.** Our existing scanner has ~40 patterns focused on chat-style attacks. Lasso Security's [claude-hooks](https://github.com/lasso-security/claude-hooks) (MIT, 119 stars) adds ~29 net-new patterns covering: homoglyph attacks (Cyrillic/Greek lookalikes), zero-width Unicode manipulation, fake JSON/XML system roles, HTML/code comment injection, priority manipulation, fake delimiters, split personality/evil twin, acrostic/steganographic instructions, and fake previous conversation claims.

3. **No developer guidance.** Dev agents building agentic apps have no knowledge of prompt injection defense. They'll build apps that process untrusted inputs (user uploads, web scraping, API responses) without any scanning or sanitization.

**Catalyst:** [lasso-security/claude-hooks](https://github.com/lasso-security/claude-hooks) — Lasso Security's prompt injection defender for Claude Code. Their research paper ["The Hidden Backdoor in Claude Coding Assistant"](https://www.lasso.security/blog/the-hidden-backdoor-in-claude-coding-assistant) demonstrates indirect prompt injection is a real, exploited attack vector against coding agents. Their `patterns.yaml` (MIT) is the most comprehensive open-source pattern database for this threat.

**What this is NOT:** A Claude Code-specific integration. Lasso's hooks use Claude Code's `PostToolUse` hook system — we use OpenCode primarily. This task creates a tool-agnostic scanner callable from any context (shell script), and an agent doc that teaches integration patterns for any AI tool or agentic app.

#### Architecture

```text
Existing state (t1327.8):
  Chat message → prompt-guard-helper.sh check → allow/warn/block
  (Only used by SimpleX/Matrix bot framework, ~40 inline patterns)

Target state:
  ┌─────────────────────────────────────────────────────────────────┐
  │ Untrusted content sources          Pattern sources              │
  │                                                                 │
  │  webfetch results ──┐              ┌── patterns.yaml (primary)  │
  │  MCP tool outputs ──┤              │   (Lasso-compatible YAML)  │
  │  PR content ────────┤──→ scanner ──┤                            │
  │  repo file reads ───┤              ├── inline patterns (fallback│
  │  chat messages ─────┘              │   when YAML unavailable)   │
  │                                    └── custom patterns (env var)│
  │                                                                 │
  │  New subcommand: scan-stdin (pipeline use)                      │
  │  Policy: warn (content) or block (chat)                         │
  └─────────────────────────────────────────────────────────────────┘

Pattern gap analysis (Lasso patterns NOT in our prompt-guard-helper.sh):

  Category                              Net-new patterns
  ─────────────────────────────────────────────────────
  Homoglyph attacks (Cyrillic/Greek)    2
  Zero-width Unicode (specific ranges)  2
  Fake JSON system roles                3
  HTML comment injection                2
  Code comment injection                2
  Priority manipulation                 4
  Fake delimiter markers                4
  Split personality / evil twin         3
  Acrostic/steganographic               1
  Fake previous conversation claims     3
  System prompt extraction variants     2
  URL encoded payload detection         1
  ─────────────────────────────────────────────────────
  Total net-new                         ~29

Agent doc teaches:
  1. aidevops agents: when to scan (webfetch, MCP, untrusted repos)
  2. App developers: how to integrate scanning in their own apps
  3. Claude Code users: how to install Lasso's hooks directly
  4. Pattern extension: how to add custom patterns
  5. Layered defense: patterns are layer 1, not the only layer
```

#### Subtask Breakdown

| ID | Task | Est | Model | Dependencies |
|----|------|-----|-------|-------------|
| t1375.1 | YAML pattern loading + merge Lasso patterns + scan-stdin | ~2h | sonnet | none |
| t1375.2 | Agent doc (`tools/security/prompt-injection-defender.md`) | ~2h | sonnet | none |
| t1375.3 | Wire into build-plus.md, build.txt, opsec.md | ~1.5h | sonnet | t1375.2 |
| t1375.4 | Cross-references (subagent-index, AGENTS.md, security-audit) | ~30m | sonnet | t1375.2 |
| t1375.5 | Testing and verification | ~1h | sonnet | t1375.1 |

t1375.1 and t1375.2 can run in parallel. t1375.3 and t1375.4 depend on the agent doc. t1375.5 depends on the pattern changes.

#### Progress

- [ ] (2026-03-02) Phase 1: Core implementation ~4h
  - [ ] t1375.1 YAML pattern loading, Lasso pattern merge, scan-stdin subcommand
  - [ ] t1375.2 Agent doc for aidevops + agentic app developers
- [ ] (2026-03-02) Phase 2: Integration ~2h
  - [ ] t1375.3 Wire into build-plus.md, build.txt, opsec.md
  - [ ] t1375.4 Cross-references and index updates
- [ ] (2026-03-02) Phase 3: Verification ~1h
  - [ ] t1375.5 Test suite, new pattern verification, ShellCheck

#### Decision Log

| Date | Decision | Rationale |
|------|----------|-----------|
| 2026-03-02 | Extend prompt-guard-helper.sh, don't build new scanner | Already has pattern engine, policy system, logging, test suite (993 lines). Adding YAML loading + patterns is cheaper than starting fresh |
| 2026-03-02 | Lasso-compatible YAML format for patterns | Same schema means we can periodically pull upstream pattern updates without format conversion |
| 2026-03-02 | Warn, don't block for content scanning | Chat inputs can be blocked (user rephrases). Webfetch/MCP outputs can't — agent needs to see content but be warned |
| 2026-03-02 | Tool-agnostic shell script, not Claude Code hooks | We use OpenCode primarily. Shell script works with any AI tool. Lasso's hooks are Claude Code-specific |
| 2026-03-02 | Reference Lasso, don't fork | They maintain their repo (MIT), we maintain ours. Pattern format compatibility enables sharing |
| 2026-03-02 | Pattern-based is layer 1, not the only layer | Regex catches known patterns but misses novel attacks. Agent doc must teach layered defense |

#### Surprises & Discoveries

- We already have `prompt-guard-helper.sh` (993 lines, t1327.8) with a solid pattern matching engine — this was built for SimpleX/Matrix chat but the architecture is general-purpose
- Lasso's `patterns.yaml` has ~29 patterns we don't have, particularly in homoglyph/Unicode and context manipulation categories
- Our existing `shannon.md` (entropy detection) is complementary — Shannon detects high-entropy strings (secrets), prompt-guard detects semantic injection patterns
- Lasso's Python hook reads from stdin JSON (Claude Code's hook protocol) — our shell script reads from arguments/files/stdin text. Different interfaces, same patterns.

---

### [2026-03-01] Vector Search Agent — zvec and Per-Tenant RAG for SaaS

**Status:** Completed
**Estimate:** ~7h (ai:5h test:1h read:1h)
**TODO:** t1370 ✅ (parent), t1370.1-t1370.5 ✅ (subtasks)
**Logged:** 2026-03-01
**Brief:** [todo/tasks/t1370-brief.md](tasks/t1370-brief.md)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,completed}:
p037,Vector Search Agent,completed,2,2,,plan|feature|database|vector-search|rag,7h,5h,1h,1h,2026-03-01T00:00Z,2026-03-21T00:00Z
-->

#### Purpose

Add a unified vector search decision guide and implementation reference for SaaS app development. The framework currently has database agents (Postgres/Drizzle, PGlite, multi-org isolation) and a Cloudflare Vectorize reference, but no single place to compare vector search options or design per-tenant RAG pipelines.

The catalyst is **zvec** (alibaba/zvec, 8.4k stars, Apache-2.0) — an in-process C++ vector database built on Alibaba's Proxima engine. It fills a specific gap as a **server-side embedded vector DB** that doesn't require Postgres or a hosted service, with native Node.js and Python bindings.

**Why zvec matters for multi-tenant SaaS:**

- **Collection-per-tenant isolation**: Each org gets its own collection (or DB file) — physical isolation without running N server instances. Creating/destroying a collection is a single function call.
- **In-process, zero network hop**: Vector search runs in the same process as your app server. No vector DB service to manage, no network latency on queries.
- **Dense + sparse + hybrid**: Native multi-vector queries (dense semantic + sparse lexical) in a single call, with built-in rerankers (RRF, weighted, cross-encoder).
- **Built-in embedding pipeline**: Ships with embedding functions (local Sentence Transformers, OpenAI, Jina v5, Qwen, BM25, SPLADE) — no separate embedding service needed.
- **Performance ceiling**: Sub-millisecond search on billions of vectors. INT8 quantization for reduced memory.

**What this is NOT**: A replacement for our internal memory system (stays on SQLite FTS5) or code search (stays on osgrep). This is for SaaS app development where users/orgs upload their own documents for RAG.

#### Architecture

```text
Vector Search Option Landscape:

  ┌─────────────────────────────────────────────────────────────────────────┐
  │                    Deployment Model Spectrum                           │
  │                                                                       │
  │  Embedded/In-Process          Server-Side              Hosted/Cloud   │
  │  ├── zvec (C++ native)        ├── pgvector (Postgres)  ├── Pinecone   │
  │  ├── PGlite+pgvector (WASM)   ├── Qdrant (Rust)        ├── Weaviate  │
  │  └── SQLite+vss (limited)     └── Milvus (distributed) └── Vectorize │
  │                                                                       │
  └─────────────────────────────────────────────────────────────────────────┘

Per-Tenant RAG Pipeline (using zvec as example):

  User uploads file (PDF/DOCX/TXT/HTML)
    │
    ▼
  [Chunking] ─── Split by type (Docling for PDF, custom for text)
    │              Chunk size: 512-1024 tokens, 128-token overlap
    │
    ▼
  [Embedding] ─── zvec built-in: DefaultLocalDense (384d, free)
    │              or OpenAI text-embedding-4 (1536d, API cost)
    │              or Jina v5 (1024d, Matryoshka to 256d)
    │
    ▼
  [Store] ─── zvec collection per tenant: /data/vectors/{org_id}/
    │          Schema: id, content_chunk, embedding(dense), sparse_embedding
    │          Metadata: source_file, chunk_index, uploaded_at
    │          Index: HNSW (default) or IVF (memory-constrained)
    │
    ▼
  [Query] ─── User asks question
    │          1. Embed query (same model as storage)
    │          2. Search tenant's collection (topk=20)
    │          3. Rerank (cross-encoder or RRF if hybrid)
    │          4. Return top-5 chunks with metadata
    │
    ▼
  [LLM Context] ─── Assemble prompt: system + retrieved chunks + user query
                     Token budget: reserve for response, fill with chunks

Tenant Isolation Comparison:

  ┌──────────────────────┬───────────────┬──────────────┬──────────────────┐
  │ Approach             │ Isolation     │ Ops Cost     │ Best For         │
  ├──────────────────────┼───────────────┼──────────────┼──────────────────┤
  │ zvec collection/org  │ Physical      │ Low          │ <10k tenants     │
  │ Vectorize namespace  │ Logical       │ Low          │ <50k tenants     │
  │ pgvector + RLS       │ Logical (DB)  │ Medium       │ Already on PG    │
  │ Metadata filter      │ Logical       │ Low          │ Simple cases     │
  │ Separate DB/index    │ Physical      │ High         │ Regulated/ent.   │
  └──────────────────────┴───────────────┴──────────────┴──────────────────┘
```

#### zvec Feature Summary

| Feature | Details |
|---------|---------|
| **Language** | C++ core, Python 3.10-3.12, Node.js bindings |
| **License** | Apache 2.0 |
| **Platforms** | Linux (x86_64, ARM64), macOS (ARM64) |
| **Index types** | HNSW (best recall/speed), IVF (memory-efficient), Flat (exact) |
| **Vector types** | Dense (FP32, FP16, INT8), Sparse |
| **Metrics** | Euclidean, Cosine, Dot-product, Inner-product |
| **Quantization** | INT8 (reduced memory, minimal recall loss) |
| **Embeddings** | Local (all-MiniLM-L6-v2, 384d), OpenAI, Jina v5, Qwen, BM25, SPLADE |
| **Rerankers** | RRF (rank fusion), Weighted, Cross-encoder (ms-marco-MiniLM-L6-v2), Qwen |
| **Hybrid search** | Multi-vector queries (dense+sparse) in single call |
| **Schema** | Collections with typed fields, DDL (add/alter/drop columns) |
| **Operations** | Insert, Update, Upsert, Delete, DeleteByFilter, Fetch, Query, GroupByQuery |
| **Scale** | Sub-millisecond on billions of vectors (Cohere 10M benchmark) |
| **Persistence** | Filesystem-based (directory per collection) |

#### Subtask Breakdown

| ID | Task | Est | Model | Dependencies |
|----|------|-----|-------|-------------|
| t1370.1 | Decision guide (`tools/database/vector-search.md`) | ~2h | sonnet | none |
| t1370.2 | zvec reference section (within or alongside vector-search.md) | ~2h | sonnet | none |
| t1370.3 | Per-tenant RAG architecture section | ~1.5h | sonnet | t1370.1 |
| t1370.4 | Cross-references and index updates | ~30m | sonnet | t1370.1, t1370.2 |
| t1370.5 | Installation verification and basic ops test | ~1h | sonnet | t1370.2 |

t1370.1 and t1370.2 can run in parallel. t1370.3 depends on the decision guide structure. t1370.4 depends on docs being written. t1370.5 depends on the zvec reference.

#### Progress

- [ ] (2026-03-01) Phase 1: Core docs ~4h
  - [ ] t1370.1 Decision guide with comparison matrix
  - [ ] t1370.2 zvec feature reference
  - [ ] t1370.3 Per-tenant RAG architecture
- [ ] (2026-03-01) Phase 2: Integration and verification ~1.5h
  - [ ] t1370.4 Cross-references and indexes
  - [ ] t1370.5 Installation and basic ops test

#### Decision Log

| Date | Decision | Rationale |
|------|----------|-----------|
| 2026-03-01 | Unified decision guide, not separate per-tool docs | Developers need to compare at decision time; 5 separate docs = 5 files to read for one decision |
| 2026-03-01 | zvec gets deepest coverage | Newest option, least known, richest feature set (embeddings, rerankers, hybrid) — others well-documented elsewhere |
| 2026-03-01 | Collection-per-tenant as recommended pattern | Physical isolation without N server instances; zvec makes this cheap (single function call) |
| 2026-03-01 | No helper script | zvec is a library (pip/npm), not a CLI tool — helper scripts are for tools with CLI interfaces |
| 2026-03-01 | Agent doc only, not MCP integration | zvec is for app development, not for aidevops internal use — no MCP server needed |

#### Surprises & Discoveries

- zvec ships with built-in embedding functions (local + API) and rerankers — most vector DBs require you to bring your own embedding pipeline
- Jina v5 embeddings support Matryoshka dimensions (1024 down to 32) — can reduce storage 4-32x with controlled recall trade-off
- zvec's BM25 embedding function runs locally with no API key — useful for sparse/lexical matching in hybrid search without external dependencies
- Node.js bindings exist (`@zvec/zvec`) but examples directory only has C++ — Node.js API may be less mature than Python

---

### [2026-03-01] UI/UX Inspiration Skill and Brand Identity System

**Status:** Completed
**Estimate:** ~10h (ai:8h test:1h read:1h)
**TODO:** t1371 ✅ (catalogue), t1372 ✅ (skill + interview), t1373 ✅ (brand identity), t1374 ✅ (wiring)
**Logged:** 2026-03-01
**Briefs:** [t1371](tasks/t1371-brief.md), [t1372](tasks/t1372-brief.md), [t1373](tasks/t1373-brief.md), [t1374](tasks/t1374-brief.md)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,completed}:
p038,UI/UX Inspiration Skill and Brand Identity System,completed,3,3,,plan|feature|design|content,11.75h,8h,2h,1.75h,2026-03-01T00:00Z,2026-03-21T00:00Z
-->

#### Purpose

Add a comprehensive UI/UX design intelligence system to aidevops that bridges the gap between design agents and content agents. Currently, design decisions (colours, typography, layout) and content decisions (copywriting voice, imagery style) are made independently — a project can have beautiful UI with copy that reads like a different brand.

**Three problems solved:**

1. **No design reference data.** LLMs default to generic "blue SaaS" designs. The catalogue provides 67 UI styles, 96 colour palettes, 57 font pairings, and 100 industry-specific reasoning rules as structured TOON data agents read directly.

2. **No design-content bridge.** A designer picks "Glassmorphism + Trust Blue" but the copywriter doesn't know that means "confident, technical, concise." The brand identity template defines both visual and verbal identity in one file that all agents read.

3. **No style interview.** Projects start design work without understanding the user's aesthetic preferences. The interview workflow presents example sites, asks the user to share sites they like, extracts patterns, and synthesises a brand identity before any implementation begins.

**Seed data source:** [nextlevelbuilder/ui-ux-pro-max-skill](https://github.com/nextlevelbuilder/ui-ux-pro-max-skill) (MIT, 36k stars). CSV data converted to TOON. No Python runtime, no premium API dependency, no external service.

#### Architecture

```text
New files:
  .agents/tools/design/
    ui-ux-catalogue.toon      ← t1371: Structured design knowledge (TOON)
    ui-ux-inspiration.md      ← t1372: Skill entry point + interview + URL study
    brand-identity.md         ← t1373: Bridge agent + per-project template

Per-project (created by interview workflow, in project's own repo):
  context/
    brand-identity.toon        ← Filled-in brand identity for this project
    inspiration/               ← Extracted design patterns from studied URLs
      stripe.toon              ← Example: patterns extracted from stripe.com
      linear.toon              ← Example: patterns extracted from linear.app

Relationship map:
  brand-identity.toon (per-project)
      ├── read by: tools/design/ui-ux-inspiration.md  (design decisions)
      ├── read by: content/guidelines.md               (copywriting voice)
      ├── read by: content/platform-personas.md         (channel adaptation)
      ├── read by: content/production/image.md          (imagery style)
      ├── read by: content/production/characters.md     (character design)
      └── read by: workflows/ui-verification.md         (quality gates)

Catalogue TOON sections (shared framework — .agents/tools/design/):
  styles[67]              ← UI styles with CSS keywords, accessibility, anti-patterns
  palettes[96]            ← Industry-mapped colour palettes with hex values
  typography[57]          ← Font pairings with Google Fonts imports
  industry_patterns[100]  ← Product type → style/colour/typography mapping
  buttons_and_forms[]     ← Button variants + form elements + states per UI style
  inspiration_template[]  ← Entry format template ONLY (no actual entries)

Inspiration entries (per-project — context/inspiration/):
  Extracted patterns from studied URLs stay in project repos (typically private).
  Avoids leaking competitive intelligence into the public aidevops repo.

Brand identity dimensions:
  visual_style | voice_and_tone | copywriting_patterns | imagery
  iconography | buttons_and_forms | media_and_motion | brand_positioning
```

#### Interview Workflow

```text
New/Rebranding Project:

  1. Present curated examples (15+ URLs across 4+ style categories)
     ├── Minimal: stripe.com, linear.app, notion.so
     ├── Bold: vercel.com, figma.com, arc.net
     ├── Premium: apple.com, tesla.com, bang-olufsen.com
     └── Playful: duolingo.com, notion.so/templates, mailchimp.com

  2. Ask user to share sites/apps they already like
     └── Accept: URLs, bookmarks export, or "I like sites like X"

  3. For each URL, extract via Playwright:
     ├── Visual: colours, typography, layout, border-radius, spacing scale
     ├── Interactive: button styles, form fields, hover states, transitions
     ├── Content: copy tone, CTA language, headline style, vocabulary
     ├── Media: photography vs illustration, icon library, image treatment
     └── Motion: animation approach, transition timing, loading patterns

  4. Synthesise findings into draft brand-identity.toon
     └── Present to user for approval/adjustment

  5. Save to project repo:
     ├── context/brand-identity.toon  ← Brand identity (all agents read)
     └── context/inspiration/*.toon   ← Extracted patterns (private to project)
```

#### Subtask Breakdown

| ID | Task | Est | Model | Dependencies |
|----|------|-----|-------|-------------|
| t1371 | UI/UX catalogue TOON (seed from upstream CSVs) | ~4h | sonnet | none |
| t1372 | Skill entry point + interview + URL study workflow | ~3h | sonnet | t1371, t1373 |
| t1373 | Brand identity bridge agent + template | ~3.5h | sonnet | t1371 |
| t1374 | Wire into agent index + update cross-references | ~1.25h | sonnet | t1371, t1372, t1373 |

t1371 runs first (no dependencies). t1373 can start after t1371 (needs catalogue for style references). t1372 needs both t1371 and t1373 (references both). t1374 is the final wiring step.

#### Progress

- [ ] (2026-03-01) Phase 1: Foundation ~4h
  - [ ] t1371 UI/UX catalogue TOON file
- [ ] (2026-03-01) Phase 2: Agents ~6.5h
  - [ ] t1373 Brand identity bridge agent (can start after t1371)
  - [ ] t1372 Skill entry point + interview workflow (after t1371 + t1373)
- [ ] (2026-03-01) Phase 3: Integration ~1.25h
  - [ ] t1374 Wire into indexes and cross-references

#### Decision Log

| Date | Decision | Rationale |
|------|----------|-----------|
| 2026-03-01 | TOON over markdown for catalogue | Structured tabular data (67 styles x 20+ fields) is better in TOON. More token-efficient for LLM consumption. |
| 2026-03-01 | No Python search engine | Upstream uses BM25 over CSVs. LLM reads TOON directly and reasons better than keyword matching. Zero dependencies. |
| 2026-03-01 | No premium API dependency | Upstream premium (uupm.cc) wraps same data as hosted MCP API. We use MIT-licensed local data only. |
| 2026-03-01 | Brand identity as bridge, not replacement | guidelines.md stays for structural rules. brand-identity.toon adds voice/visual identity on top. Per-project, not global. |
| 2026-03-01 | Interview before implementation | User explicitly requested. Prevents starting design work without understanding aesthetic preferences. |
| 2026-03-01 | Buttons and forms as first-class dimension | User explicitly requested. Most-touched interactive elements. Both visual (design) and verbal (CTA copy, error messages). |
| 2026-03-01 | Copywriting patterns in brand identity | User noted brand character comes from copy style, imagery, iconography, media — not just visual design. |
| 2026-03-01 | `.agents/tools/design/` location | Existing directory with design-inspiration.md. Natural home for design skill files. |
| 2026-03-01 | Inspiration entries in project repos, not shared catalogue | Studied URLs reveal competitive intelligence (what sites you're analysing). Curated example URLs (stripe.com, etc.) are fine in the public repo — they're well-known references. Extracted patterns go to per-project `context/inspiration/` in private repos. |

#### Surprises & Discoveries

- Upstream repo (36k stars) is essentially a CSV database with a Python BM25 search wrapper. The data is the value, not the tooling.
- The premium product adds API access (rate-limited), not additional data. All CSV data is MIT-licensed and in the public repo.
- Our existing `workflows/ui-verification.md` already has comprehensive design quality gates (typography, spacing, accessibility, interaction) — the new skill complements rather than duplicates.
- `content/guidelines.md` is hardcoded to one client (Trinity Joinery). The brand identity system parameterises this — each project gets its own voice.

---

### [2026-03-01] PaddleOCR Integration — Screenshot and Scene Text OCR

**Status:** Completed
**Estimate:** ~8h (ai:6h test:1h read:1h)
**TODO:** t1369 ✅ (parent), t1369.1-t1369.5 ✅ (subtasks)
**Logged:** 2026-03-01
**Brief:** [todo/tasks/t1369-brief.md](tasks/t1369-brief.md)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,completed}:
p036,PaddleOCR Integration,completed,2,2,,plan|feature|ocr|document,5h,3.5h,1h,30m,2026-03-01T00:00Z,2026-03-21T00:00Z
-->

#### Purpose

Add scene text / screenshot OCR capability to aidevops. Current stack (MinerU + Docling + ExtractThinker + LibPDF) handles document parsing and structured extraction well, but cannot read text from screenshots, photos, UI captures, signs, or other non-document images.

PaddleOCR (71k stars, Apache-2.0, PaddlePaddle/PaddleOCR) fills this gap:

- **PP-OCRv5**: text detection + recognition from any image, 100+ languages, lightweight
- **PaddleOCR-VL** (0.9B): vision-language model for document understanding, runs locally
- **Native MCP server**: ships with PaddleOCR 3.1.0+, integrates directly with Claude Desktop and our agent framework
- **Scene text strength**: designed for varied lighting, angles, fonts — not just clean documents

**What this is NOT**: a replacement for MinerU or Docling. Those tools excel at document-to-markdown and structured extraction respectively. PaddleOCR is the specialist for raw OCR from arbitrary images.

#### Architecture

```text
Current Document Pipeline:
  PDF/DOCX → Docling (parsing) → ExtractThinker (LLM extraction) → Structured JSON
  PDF      → MinerU (layout-aware) → Markdown/JSON for LLM
  PDF      → LibPDF (manipulation) → Text with positions

NEW — Scene Text Pipeline:
  Screenshot/Photo/Image → PaddleOCR (PP-OCRv5) → Raw text + bounding boxes
  Screenshot/Photo/Image → PaddleOCR-VL (0.9B)  → Structured understanding

  Integration points:
  ├── paddleocr-helper.sh ocr <image>     → CLI text extraction
  ├── PaddleOCR MCP Server (stdio/HTTP)   → Agent framework integration
  └── Python API                          → Pipeline composition with Docling/ExtractThinker

Tool Selection (overview.md):
  ┌─────────────────────┬──────────────┬─────────────────────────────────┐
  │ Input               │ Tool         │ Output                          │
  ├─────────────────────┼──────────────┼─────────────────────────────────┤
  │ Screenshot/photo    │ PaddleOCR    │ Raw text + bounding boxes       │
  │ Complex PDF layout  │ MinerU       │ Markdown/JSON (layout-aware)    │
  │ Invoice/receipt     │ Docling+ET   │ Structured JSON (schema-mapped) │
  │ PDF form/signing    │ LibPDF       │ Modified PDF                    │
  │ Simple text PDF     │ Pandoc       │ Markdown                        │
  └─────────────────────┴──────────────┴─────────────────────────────────┘
```

#### Subtask Breakdown

| ID | Task | Est | Model | Dependencies |
|----|------|-----|-------|-------------|
| t1369.1 | PaddleOCR subagent doc (`tools/ocr/paddleocr.md`) | ~2h | sonnet | none |
| t1369.2 | OCR overview + tool selection guide (`tools/ocr/overview.md`) | ~30m | sonnet | none |
| t1369.3 | `paddleocr-helper.sh` (install, ocr, serve, status) | ~1.5h | sonnet | none |
| t1369.4 | Update cross-references and indexes | ~30m | sonnet | t1369.1, t1369.2 |
| t1369.5 | Installation verification + screenshot OCR test | ~30m | sonnet | t1369.3 |

t1369.1-t1369.3 can run in parallel. t1369.4 depends on docs being written. t1369.5 depends on the helper script.

#### Progress

- [ ] (2026-03-01) Phase 1: Core docs and helper script ~4h
  - [ ] t1369.1 PaddleOCR subagent doc
  - [ ] t1369.2 OCR overview doc
  - [ ] t1369.3 paddleocr-helper.sh
- [ ] (2026-03-01) Phase 2: Integration and verification ~1h
  - [ ] t1369.4 Cross-references and indexes
  - [ ] t1369.5 Installation and OCR test

#### Decision Log

| Date | Decision | Rationale |
|------|----------|-----------|
| 2026-03-01 | Add PaddleOCR, don't replace MinerU/Docling | Different tools for different jobs — scene text vs document parsing |
| 2026-03-01 | PaddleOCR over Tesseract | Better accuracy on scene text, active development, MCP server, 100+ languages |
| 2026-03-01 | PaddleOCR over EasyOCR | 3x stars, more active, better benchmarks, native MCP server |
| 2026-03-01 | Create new `tools/ocr/` directory | OCR is a distinct domain from PDF manipulation or document extraction |
| 2026-03-01 | Default to PP-OCRv5, document VL as optional | PP-OCRv5 is lightweight and sufficient for most OCR; VL needs more resources |

#### Surprises & Discoveries

(To be filled during implementation)

---

### [2026-02-28] Multi-Model Orchestration Improvements — Parallel Verification + Bundle Presets

**Status:** Completed
**Estimate:** ~10h (ai:7h test:2h read:1h)
**TODO:** t1364 ✅ (parent), t1364.1-t1364.3 ✅ (verification), t1364.4-t1364.6 ✅ (bundles)
**Logged:** 2026-02-28
**Brief:** [todo/tasks/t1364-brief.md](tasks/t1364-brief.md)
**Research:** [#2558](https://github.com/marcusquinn/aidevops/issues/2558) — Perplexity Computer + Microsoft Amplifier comparison

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,completed}:
p035,Multi-Model Orchestration Improvements,completed,2,2,,plan|feature|orchestration|models,20h,14h,4h,2h,2026-02-28T00:00Z,2026-03-21T00:00Z
-->

#### Purpose

Two near-term improvements from the multi-model orchestration research review (#2558):

1. **Parallel model verification** catches single-model hallucinations before destructive operations cause irreversible damage. Different providers have different failure modes, so correlated errors are rare. Targeted verification only — not full council-style parallel invocation on every task. Cost: minimal (only triggered on flagged operations).

2. **Bundle-based project presets** right-size tooling per project type. Currently every project gets identical treatment — ShellCheck runs on content sites (waste), haiku is used for complex web-app architecture (under-provisioned). Bundles pre-configure model tier defaults, quality gates, and agent routing per project type.

Inspired by Perplexity Computer (model council for reliability) and Microsoft Amplifier (modular architecture with swappable policies).

#### Architecture

```text
Workstream 1: Parallel Model Verification
  t1364.1 Taxonomy → t1364.2 Agent + Script → t1364.3 Pipeline Integration

  Operation detected → Check taxonomy → Match? → Invoke cross-provider verifier
                                          │              │
                                          No             ├── Verified → Proceed
                                          │              ├── Concerns → Warn/Block
                                          ▼              └── Disagree → Escalate to opus
                                        Proceed

Workstream 2: Bundle-Based Project Presets
  t1364.4 Schema + Defaults → t1364.5 Detection + Resolution → t1364.6 Pipeline Integration

  Repo path → Check repos.json → Explicit bundle? → Use it
                                       │
                                       No → Auto-detect from markers
                                              │
                                              ├── package.json → web-app
                                              ├── Dockerfile → infrastructure
                                              ├── *.sh → cli-tool
                                              ├── wp-config.php → content-site
                                              └── Cargo.toml/go.mod → library
                                              │
                                              ▼
                                        Compose bundles → Apply to dispatch/quality/routing
```

#### Progress

- [ ] (2026-02-28) Phase 1: Verification workstream ~9h
  - [ ] t1364.1 Define taxonomy and trigger rules ~2h
  - [ ] t1364.2 Create verification agent and helper script ~4h
  - [ ] t1364.3 Wire into pipeline ~3h
- [ ] (2026-02-28) Phase 2: Bundle workstream ~10h
  - [ ] t1364.4 Design schema and default bundles ~3h
  - [ ] t1364.5 Create detection and resolution logic ~4h
  - [ ] t1364.6 Wire into dispatch, quality, routing ~3h

#### Context from Discussion

- **Source**: Issue #2558 — research review comparing aidevops against Perplexity Computer and Microsoft Amplifier
- **Scope decision**: Only near-term items (1 and 4) from the 5 proposed improvements. Mid-term items (confidence-weighted selection, modular supervisor decomposition) deferred.
- **Verification approach**: Targeted, not universal. Full council-style parallel invocation on every task would be expensive and slow. Only high-stakes operations warrant the cost of a second model call.
- **Bundle composition**: Multiple bundles can combine (e.g., web-app + infrastructure). Union for quality gates, most-restrictive for model defaults.
- **Cross-provider preference**: Anthropic primary → Google verifier (and vice versa) because different providers have different failure modes. Same-provider different-model is acceptable but less effective.

#### Decision Log

(To be populated during implementation)

#### Surprises & Discoveries

(To be populated during implementation)

### [2026-02-27] Mission System — Autonomous Long-Running Project Orchestration

**Status:** Completed
**Estimate:** ~28h (ai:20h test:5h read:3h)
**TODO:** t1357 ✅ (core), t1358 ✅-t1362 ✅ (dependent features)
**Logged:** 2026-02-27
**Brief:** [todo/tasks/t1357-brief.md](tasks/t1357-brief.md)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,completed}:
p034,Mission System,completed,3,3,,plan|feature|orchestration|mission,52h,38h,10h,4h,2026-02-27T00:00Z,2026-03-21T00:00Z
-->

#### Purpose

Close the gap between "I have an idea" and "autonomous execution." Current aidevops handles task-level work (`/full-loop`) and supervisor dispatch (`/pulse`), but nothing takes a high-level goal and drives it to completion over days. Missions extend beyond code into research, procurement, infrastructure setup, and 3rd-party communication — making aidevops a true autonomous project agent.

Inspired by Factory.ai Missions (multi-day autonomous coding, Feb 2026) but significantly broader in scope. Factory solves "multi-day coding tasks." This solves "autonomous project lifecycle from idea to delivery."

#### Architecture

```text
/mission "Build a CRM with contacts, deals, and email"
    │
    ▼
Phase 1: SCOPING (interactive interview, opus-tier)
    ├── Goal, mode (POC/Full), budget, constraints, preferences
    ├── Existing repo / new repo / homeless (no repo yet)
    └── Budget analysis: "For $X you get Y; for $A you get B"
    │
    ▼
Phase 2: DECOMPOSITION (opus-tier)
    ├── Research phase (if needed)
    ├── 3-7 milestones (sequential)
    ├── 2-5 features per milestone (parallelisable)
    ├── Resource requirements (accounts, services, credentials)
    └── Creates mission.md + TODO entries + GitHub issues
    │
    ▼
Phase 3: EXECUTION (autonomous, pulse-integrated)
    ├── For each milestone (sequential):
    │   ├── Dispatch features as workers
    │   ├── Self-organise: create agents/scripts as needed
    │   ├── Track budget (time, money, tokens)
    │   └── On complete → milestone validation
    │       ├── Pass → advance
    │       └── Fail → create fix tasks, re-validate
    │
    ▼
Phase 4: COMPLETION
    ├── Final validation, budget reconciliation
    ├── Offer improvements back to aidevops
    └── Summary report
```

#### Mission Homes

- `~/.aidevops/missions/{id}/` — homeless missions (POC drafting, no repo yet)
- `todo/missions/{id}/` — missions attached to a project repo
- Migration: homeless → repo-attached when `aidevops init` + `git init` runs

#### POC vs Full Mode

| Aspect | POC Mode | Full Mode |
|---|---|---|
| Branching | Main (dedicated repo) or single branch (existing) | Worktrees + PRs per feature |
| Briefs | Inline in mission.md | Full brief per feature |
| Code review | Skip | Standard PR review + quality gates |
| Testing | Basic smoke tests | Full test suite + lint + type-check |
| Commits | Informal, batch OK | Conventional commits per feature |
| Browser QA | On demand | Every milestone validation |

#### Progress

- [ ] (2026-02-27) Phase 1: Foundation — template, command, orchestrator agent ~12h
  - [ ] t1357.1 Mission state file template ~2h
  - [ ] t1357.2 `/mission` command ~6h
  - [ ] t1357.3 Mission orchestrator agent ~4h
- [ ] Phase 2: Execution modes — POC mode, pulse integration ~6h
  - [ ] t1357.4 POC mode in `/full-loop` ~2h
  - [ ] t1357.5 Pulse integration ~4h
- [ ] Phase 3: Validation & budget — milestone validation, budget engine ~8h
  - [ ] t1357.6 Milestone validation worker ~4h
  - [ ] t1357.7 Budget analysis engine ~4h
- [ ] Dependent features ~24h
  - [ ] t1358 Payment agent ~8h
  - [ ] t1359 Browser QA in validation ~4h
  - [ ] t1360 Email agent for missions ~4h
  - [ ] t1361 Skill learning ~4h
  - [ ] t1362 Progress dashboard ~4h

#### Context from Discussion

**Key design decisions:**
- Mission state in git (markdown), not a database — consistent with "GitHub + TODO.md are the database" principle
- Orchestrator as pulse extension, not separate daemon — avoids new process management
- POC mode is a flag, not a separate system — same pipeline, fewer gates
- Milestones sequential, features within milestones parallelisable — Factory found this works better than broad parallelism
- One orchestrator layer, not recursive — Factory notes recursive depth as open question; one layer suffices for our scale
- Budget analysis before execution — mission agent should tell you what you'll get for your budget before starting
- Mission-specific agents are draft-tier — temporary tools, promoted if generally useful

**Factory.ai Missions analysis (Feb 2026):**
- Median mission: ~2 hours. 65% run >1 hour. 37% run >4 hours. 14% run >24 hours.
- Missions use ~2x token weight per message vs normal sessions (19K vs 11K)
- Multi-model: orchestrator (opus), workers (sonnet), validators (varies), research (cheapest)
- Key insight: "serial execution with targeted parallelization has worked better than broad parallelism"
- Open questions they identified: parallelization balance, correctness over long horizons, worker scope, recursive management depth

**What aidevops already has (strong overlap):**
- Worker dispatch, task decomposition, fresh context per worker, multi-model routing, git as source of truth, validation (preflight/postflight), failure recovery, skill/memory, browser QA, task briefs, worker efficiency, autonomous operation

**What's genuinely new:**
- Mission-level orchestration (goal → milestones → features → validation → completion)
- Milestone validation (pause after milestone N, validate integration, then proceed)
- Mission state persistence (durable entity grouping tasks into a coherent goal)
- Automatic re-planning (validation failure → create fix tasks)
- POC/shortcut mode
- Budget feasibility analysis and outcome-level recommendations
- Self-organising mission folders
- Autonomous procurement (payment agent)
- 3rd-party communication (email agent)

#### Decision Log

(To be populated during implementation)

#### Surprises & Discoveries

(To be populated during implementation)

### [2026-02-27] Conversational Memory and Entity Relationship System

**Status:** Completed
**Estimate:** ~27h (ai:20h test:4h read:3h)
**TODO:** t1363 ✅
**Logged:** 2026-02-27
**Brief:** [todo/tasks/t1363-brief.md](tasks/t1363-brief.md)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,completed}:
p035,Conversational Memory Entity Relationship System,completed,3,3,,plan|feature|memory|entity|communications,27h,20h,4h,3h,2026-02-27T00:00Z,2026-03-21T00:00Z
-->

#### Purpose

Give aidevops multi-channel agents (Matrix, SimpleX, email, CLI) the ability to maintain relationship continuity with individuals across all channels — and self-evolve capabilities based on observed interaction patterns. Currently, memory is project-scoped ("CORS fixed with nginx") with no concept of entities ("Marcus prefers concise responses and repeatedly asks about deployment status"). Each channel interaction starts from zero relationship context.

The differentiator: entity interaction patterns → capability gap detection → automatic TODO creation → system upgrade → better service. No chatbot platform does this. Everyone does conversation memory. Nobody does "the system upgrades itself based on what users actually need."

#### Core Principles

1. **Immutability**: Raw interactions (Layer 0) are append-only, never edited. All higher layers (summaries, profiles, inferences) are derived and reference back to source records. History is precious.
2. **Model-agnosticism**: The memory layer IS the continuity, not the model's context window. Whether Opus or a local Qwen model handles today's conversation, the entity relationship provides equivalent context.
3. **Intelligence over determinism**: Replace hardcoded thresholds (sessionIdleTimeout=300, pruneAge=90d, exact-string dedup) with AI judgment calls (haiku-tier, ~$0.001 each).
4. **Privacy-first**: Channel-level privacy filtering. Private SimpleX DM content never surfaces in public Matrix rooms without explicit consent.

#### Architecture

```text
Layer 0: RAW INTERACTION LOG (immutable, append-only)
├── Every message across all channels
├── Source of truth — all other layers derived from this
└── Retention: indefinite (user can request privacy deletion)

Layer 1: PER-CONVERSATION CONTEXT (tactical)
├── Active threads per entity+channel
├── Summaries with source range references
├── Tone/style profile, pending actions
└── AI-judged idle detection (not fixed timeout)

Layer 2: ENTITY RELATIONSHIP MODEL (strategic)
├── Identity: cross-channel linking (Matrix + SimpleX + email = same person)
├── Inferred needs, expectations, preferences (versioned, with evidence)
├── Capability gaps → automatic TODO creation
└── Satisfaction signals

Self-Evolution Loop:
  Interactions → Pattern detection → Gap identification → TODO → Upgrade → Better service
```

#### Progress

- [ ] (2026-02-27) Phase 1: Foundation — schema, entity management, conversation lifecycle ~13h
  - [ ] t1363.1 Schema + entity-helper.sh ~6h
  - [ ] t1363.2 conversation-helper.sh ~4h
  - [ ] t1363.3 Memory system integration ~3h
- [ ] Phase 2: Intelligence — self-evolution, threshold replacement ~6h
  - [ ] t1363.4 Self-evolution loop ~4h
  - [ ] t1363.6 Intelligent threshold replacement ~2h
- [ ] Phase 3: Channel integration + docs ~6h
  - [ ] t1363.5 Matrix bot integration ~3h
  - [ ] t1363.7 Architecture doc + tests ~3h

#### Context from Discussion

**Key design decisions:**
- Same SQLite database (memory.db), new tables — enables cross-queries between entity and project memories without cross-DB joins
- Three layers, not two — Layer 0 (immutable raw log) is the critical addition over the OpenClaw approach. Summaries and profiles are derived, not primary.
- Versioned entity profiles using existing `supersedes_id` pattern from Supermemory-inspired memory system — profiles are never updated in place
- Identity resolution requires confirmation — never auto-link entities across channels. Suggest, don't assume.
- AI judgment for thresholds — haiku-tier calls (~$0.001) handle outliers that no fixed threshold can. Per Intelligence Over Determinism principle.
- Flat-file conversation dumps (OpenClaw approach) rejected — structured summaries with source references at ~2k tokens recover 80% of continuity at 10% of the cost, and raw data always available in Layer 0

**What aidevops already has (strong overlap):**
- SQLite FTS5 memory with relational versioning (updates/extends/derives)
- Dual timestamps (created_at vs event_date)
- Memory namespaces (per-runner isolation)
- Semantic search via embeddings (opt-in)
- Matrix bot with per-room sessions and compaction
- SimpleX bot framework with WebSocket API
- Mail system with transport adapters (local/SimpleX/Matrix)
- Auto-capture with privacy filters
- Memory graduation (local → shared docs)

**What's genuinely new:**
- Entity concept (person/agent/service with cross-channel identity)
- Per-conversation context that survives compaction and session resets
- Entity relationship model (inferred needs, expectations, capability gaps)
- Self-evolution loop (gap detection → TODO creation with evidence)
- Privacy-aware cross-channel context loading
- AI-judged thresholds replacing hardcoded values
- Immutable interaction log as source of truth

**Deterministic → intelligent upgrades identified:**
- `sessionIdleTimeout: 300` → AI judges "has this conversation naturally paused?"
- `DEFAULT_MAX_AGE_DAYS=90` → AI judges "is this memory still relevant to active entity relationships?"
- Exact-string dedup → semantic similarity via existing embeddings
- Fixed compaction at token limit → AI judges "what's worth preserving for this entity?"
- Fixed `maxPromptLength: 4000` → dynamic based on entity's observed preference for detail level

#### Decision Log

(To be populated during implementation)

#### Surprises & Discoveries

(To be populated during implementation)

### [2026-02-27] Fix Worker PR Lookup Race Condition

**Status:** Completed
**Estimate:** ~1.5h (ai:45m test:30m read:15m)
**TODO:** t1343
**Logged:** 2026-02-27
**Completed:** 2026-02-27
**PR:** #2423
**Brief:** [todo/tasks/t1343-brief.md](tasks/t1343-brief.md)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started}:
p033,Fix Worker PR Lookup Race Condition,completed,1,1,,bugfix|supervisor|lifecycle|race-condition,1.5h,45m,30m,15m,2026-02-27T00:00Z,2026-02-27T00:00Z
-->

#### Purpose

Fix a race condition where a worker's issue lifecycle transition overwrites a supervisor's correct closure. Observed on issue #2250: supervisor correctly closed with merged PR #2268 at 19:29, but a worker added `needs-review` at 19:55/19:59 because its own PR lookup returned empty.

#### Context

The archived `issue-sync.sh` (lines 409-447) had deterministic logic for this: look up PR in DB, check if merged via `gh pr view`, close or flag. When this was migrated to AI-guided reasoning (t1335-t1337), the edge case of cross-session PR ownership was lost. The AI worker doesn't know to:

1. Check if the issue is already closed before modifying it
2. Search GitHub for PRs when its own DB has no record
3. Defer to the supervisor's prior resolution

#### Execution (single phase)

- [x] Add "check issue state before modifying" rule to `pulse.md` and worker guidance
- [x] Add PR lookup fallback (`gh pr list --search`) to `planning-detail.md`
- [x] Document the #2250 scenario as a concrete example

#### Decision Log

| Date       | Decision                                                | Rationale                                                                                                                                                                |
| ---------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 2026-02-27 | Guidance-only fix, no new scripts                       | Per "Intelligence Over Scripts" principle — the archived bash logic was replaced by AI reasoning, so the fix must improve the AI guidance                                |
| 2026-02-27 | Three-layer fix (state check + PR fallback + skip rule) | Each layer catches a different failure mode: state check prevents modifying closed issues, PR fallback finds cross-session PRs, skip rule prevents redundant transitions |

#### Outcomes & Retrospective

**What was delivered:**
- Added mandatory OPEN state check before issue label modifications in pulse guidance
- Added `gh pr list --search` fallback for cross-session PR lookup
- Documented the #2250 race condition scenario as a concrete example

**Time Summary:**
- Estimated: 1.5h
- Actual: ~1h
- PR: #2423 merged 2026-02-27

---

### [2026-02-27] Add Local Dev / `.local` Domains to Build+ Domain Expertise Check

**Status:** Completed
**Estimate:** ~15m
**TODO:** t1344
**Logged:** 2026-02-27
**Completed:** 2026-02-27
**PR:** #2453

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started}:
p034,Add Local Dev to Build+ Domain Expertise Check,completed,1,1,,bugfix|agent|build-plus|local-hosting,15m,10m,5m,0m,2026-02-27T00:00Z,2026-02-27T00:00Z
-->

#### Purpose

Build+'s step 2b Domain Expertise Check table routes agents to specialist subagents before implementing. It's missing an entry for local development infrastructure. Without it, agents encountering `.local` domain, port, Traefik, HTTPS, or LocalWP issues default to guessing instead of reading `services/hosting/local-hosting.md`.

#### Context

Observed in a webapp session: agent suggested Caddy for a `.local` HTTPS proxy when the actual stack is dnsmasq + Traefik + mkcert managed by `localdev-helper.sh`. The `local-hosting.md` subagent documents the full architecture but Build+ had no trigger to read it.

#### Execution (single phase)

- [x] Add row to `build-plus.md` Domain Expertise Check table: `Local dev / .local domains / ports / proxy / HTTPS / LocalWP → services/hosting/local-hosting.md`

#### Outcomes & Retrospective

**What was delivered:**
- Added `Local dev / .local domains / ports / proxy / HTTPS / LocalWP → services/hosting/local-hosting.md` row to Build+ Domain Expertise Check table

**Time Summary:**
- Estimated: 15m
- Actual: ~15m
- PR: #2453 merged 2026-02-27

---

### [2026-02-27] Add Cross-Repo Improvement Guidance to AGENTS.md

**Status:** Completed
**Estimate:** ~30m
**TODO:** t1345
**Logged:** 2026-02-27
**Completed:** 2026-02-27
**PR:** #2443

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started}:
p035,Add Cross-Repo Improvement Guidance to AGENTS.md,completed,1,1,,docs|agent|framework|workflow,30m,20m,5m,5m,2026-02-27T00:00Z,2026-02-27T00:00Z
-->

#### Purpose

When agents working on other repos (e.g. a webapp repo) discover aidevops framework improvements, they currently edit the installed copy at `~/.aidevops/agents/` which is overwritten on next `aidevops update`. There's no guidance telling agents to make changes on the source repo or capture them as todos there, with PLANS.md entries recommended for clarity of objectives when the improvement is non-trivial.

#### Context

Observed in a webapp session: a `build-plus.md` improvement was made to `~/.aidevops/agents/build-plus.md` (the installed copy). This edit will be lost on next `aidevops update` because `setup.sh` copies from `~/Git/aidevops/.agents/` to `~/.aidevops/agents/`. The agent had no guidance that improvements must go to the source repo.

#### Execution (single phase)

- [x] Add section to root `AGENTS.md` (developer guide) explaining: framework improvements must be made in `~/Git/aidevops/` or captured as todos/plans in that repo's TODO.md. Recommend PLANS.md entries for non-trivial improvements to ensure clarity of objectives
- [x] Add matching guidance to `.agents/AGENTS.md` (user guide) so agents working on other repos know to create todos (and PLANS.md entries for non-trivial changes) in the aidevops repo rather than editing the installed copy

#### Outcomes & Retrospective

**What was delivered:**
- Added "Framework Improvements" section to root `AGENTS.md` and `.agents/AGENTS.md` directing agents to make changes in the source repo, not the installed copy
- Prevents future loss of improvements on `aidevops update`

**Time Summary:**
- Estimated: 30m
- Actual: ~20m
- PR: #2443 merged 2026-02-27

---

### [2026-02-25] Local AI Model Support

**Status:** Completed
**Estimate:** ~13.5h (ai:10h test:2h read:1.5h)
**TODO:** t1338
**Logged:** 2026-02-25
**Completed:** 2026-02-26
**Brief:** [todo/tasks/t1338-brief.md](tasks/t1338-brief.md)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started}:
p032,Local AI Model Support,completed,4,4,,feature|local-models|infrastructure|model-routing,13.5h,10h,2h,1.5h,2026-02-25T00:00Z,2026-02-26T00:00Z
-->

#### Purpose

Add local AI model inference to aidevops via llama.cpp + HuggingFace, completing the cost spectrum from free (local) through budget (haiku) to premium (opus). Users get guided hardware-aware setup, access to any HuggingFace GGUF model, usage tracking, and disk cleanup recommendations.

#### Context

**Why llama.cpp (not Ollama, LM Studio, or Jan.ai):**

| Criterion          | llama.cpp                              | Ollama                                            | LM Studio             | Jan.ai                |
| ------------------ | -------------------------------------- | ------------------------------------------------- | --------------------- | --------------------- |
| License            | MIT                                    | MIT                                               | Closed frontend       | AGPL                  |
| Speed              | Fastest (baseline)                     | 20-70% slower                                     | Same (uses llama.cpp) | Same (uses llama.cpp) |
| Security           | No daemon, localhost only              | 175k+ exposed instances (Jan 2026), multiple CVEs | Desktop-safe          | Desktop-safe          |
| Binary size        | 23-40 MB                               | ~200 MB                                           | ~500 MB+              | ~300 MB+              |
| HuggingFace access | Direct GGUF download                   | Walled library                                    | HF browser built-in   | HF download           |
| Control            | Full (quantization, context, sampling) | Abstracted                                        | GUI-mediated          | GUI-mediated          |

**Key decision: download-on-first-use, not bundled.** llama.cpp releases weekly (b8152 current, daily commits). Bundling means stale binaries. Platform-specific (macOS ARM 29 MB, Linux x64 23 MB, Linux Vulkan 40 MB). Optional feature — not every user wants local models.

**Binary sizes by platform (b8152):**

| Platform        | Size   |
| --------------- | ------ |
| macOS ARM64     | 29 MB  |
| macOS x64       | 82 MB  |
| Linux x64 (CPU) | 23 MB  |
| Linux Vulkan    | 40 MB  |
| Linux ROCm      | 130 MB |

#### Execution Phases

**Phase 1: Foundation (t1338.1, t1338.3) ~3h**

- [x] Extend `model-routing.md` with `local` tier — routing rules, cost table, decision flowchart, provider discovery
- [x] Create `huggingface.md` subagent — model discovery, GGUF format, quantization guide, hardware-tier recommendations

These two are independent and can run in parallel. model-routing extension is the architectural anchor; HuggingFace guide is reference material needed by the helper script.

**Phase 2: Documentation (t1338.2) ~2h**

- [x] Create `local-models.md` subagent — llama.cpp setup guide, platform matrix, server management, hardware detection

Depends on Phase 1 (references model-routing integration points).

**Phase 3: Implementation (t1338.4) ~6h**

- [x] Create `local-model-helper.sh` — 11 subcommands covering full lifecycle

The main implementation. Depends on Phase 2 for design decisions. Largest single task — consider splitting into 2 PRs (install/serve/stop/status in first, search/pull/recommend/usage/cleanup/update in second).

**Phase 4: Polish (t1338.5, t1338.6) ~2.5h**

- [x] Usage logging SQLite schema + disk management logic
- [x] Update AGENTS.md domain index + subagent-index.toon

#### Decision Log

| Date       | Decision                                         | Rationale                                                             |
| ---------- | ------------------------------------------------ | --------------------------------------------------------------------- |
| 2026-02-25 | llama.cpp as primary runtime                     | MIT license, fastest, most secure, every other tool wraps it anyway   |
| 2026-02-25 | Download-on-first-use, not bundled               | Weekly releases, platform-specific, optional feature                  |
| 2026-02-25 | Single model-routing.md (extend, not new file)   | Local is just another tier in the same routing decision               |
| 2026-02-25 | HuggingFace as model source (not Ollama library) | Largest open repo, no walled garden, GGUF is standard                 |
| 2026-02-25 | SQLite for usage logging                         | Consistent with existing framework pattern                            |
| 2026-02-25 | 30-day cleanup threshold                         | Models are 2-50+ GB; generous but prevents unbounded disk growth      |
| 2026-02-25 | No Ollama fallback in v1                         | Users with Ollama can point at its API manually; add if demand exists |

#### Risks

| Risk                                                     | Mitigation                                                            |
| -------------------------------------------------------- | --------------------------------------------------------------------- |
| llama.cpp binary API changes between releases            | Pin to known-good release in helper script, test on update            |
| HuggingFace API rate limits for search                   | Cache search results, fallback to `huggingface-cli`                   |
| Model recommendations become stale as new models release | Recommend by capability tier, not specific model names where possible |
| Large model downloads fail mid-transfer                  | `huggingface-cli` handles resume; document manual resume              |
| GPU detection unreliable across platforms                | Graceful fallback to CPU-only with clear messaging                    |

#### Outcomes & Retrospective

**What was delivered:**
- `tools/local-models/local-models.md` — llama.cpp setup guide, platform matrix, server management
- `tools/local-models/huggingface.md` — GGUF model discovery, quantization guide, hardware-tier recommendations
- `scripts/local-model-helper.sh` — 11 subcommands: install, serve, stop, status, models, search, pull, recommend, usage, cleanup, update
- Extended `model-routing.md` with `local` tier ($0 cost, no fallback)
- SQLite usage logging + 30-day disk cleanup nudges
- AGENTS.md domain index + subagent-index.toon updated

**Time Summary:**
- Estimated: 13.5h
- Actual: ~13h (6 subtasks, all merged 2026-02-26)
- PRs: #2385, #2390, #2335, #2395, #2340, #2394

---

### [2026-02-22] Manifest-Driven Brief Generation

**Status:** Completed
**Estimate:** ~8h (ai:6h test:2h)
**TODO:** t1312, t1313
**Logged:** 2026-02-22
**Completed:** 2026-02-23
**Reference:** https://github.com/doodledood/manifest-dev (MIT, 40 stars)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started}:
p031,Manifest-Driven Brief Generation,completed,2,2,,feature|workflow|brief|quality,8h,6h,2h,0m,2026-02-22T00:00Z,2026-02-23T00:00Z
-->

#### Purpose

Analysis of doodledood/manifest-dev revealed two high-value ideas worth adapting to aidevops:

1. **Interactive brief generation** — a structured interview that surfaces "latent criteria" (requirements users don't know they have until probed) before creating a task brief
2. **Executable verification blocks** — machine-runnable `verify:` blocks attached to each acceptance criterion, creating an automated completion gate

Both address the same root problem: task briefs vary wildly in quality, and auto-dispatched workers have no human to catch gaps mid-implementation. Front-loading discovery (interview) and back-loading verification (executable checks) creates a tighter loop.

#### Context

**What manifest-dev does well (steal):**

| Concept                    | Their Implementation                                                                    | Our Adaptation                                                           |
| -------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| Structured interview       | 30KB `/define` SKILL.md with domain grounding, pre-mortem, backcasting, outside view    | Lighter `/define` slash command (~2KB) with probing angles per task type |
| Concrete options           | AskUserQuestion tool: 2-4 options, one recommended                                      | Agent instruction: present numbered options with recommendation          |
| Per-criterion verification | YAML `verify:` blocks (bash, codebase, subagent, research, manual)                      | Same schema, minus `research` method (not needed for our domain)         |
| Task-type guidance         | 8 task files (CODING.md, FEATURE.md, BUG.md, etc.) with quality gates, risks, scenarios | Compact probing angle files in `reference/define-probes/`                |
| Verify-fix loop            | /do -> /verify -> fix -> /verify until all pass                                         | verify-brief.sh as completion gate in task-complete-helper.sh            |
| Escalation protocol        | /escalate with 3+ attempts required                                                     | Adapt as structured escalation guidance (not a separate command)         |

**What manifest-dev over-engineers (don't steal):**

| Concept                                | Why Skip                                                                        |
| -------------------------------------- | ------------------------------------------------------------------------------- |
| Separate manifest file + discovery log | Our brief IS the output — no intermediate state needed                          |
| manifest-verifier agent                | Over-engineered for brief validation — the interview itself is the quality gate |
| Global Invariants as separate concept  | Our brief's AC section covers this                                              |
| Amendment protocol (INV-G1.1)          | Too formal for our ephemeral briefs                                             |
| 10 specialized review agents           | We have existing linters + code-standards.md + qlty                             |
| Workflow enforcement hooks (Python)    | We use pre-edit-check.sh + pre-commit hooks                                     |

**LLM first principles (from their LLM_CODING_CAPABILITIES.md, 20KB research doc):**

Key findings that validate this approach:

- LLMs achieve 92% on single-function tasks but drop to 23% on complex multi-file tasks
- "Clear acceptance criteria play to their strength" (goal-oriented RL training)
- Context drift in long sessions causes "context rot" — external state (the brief) compensates
- LLMs can't express genuine uncertainty — verification catches what self-assessment misses
- After ~5 self-debugging iterations, diminishing returns — verify-fix loop should cap retries
- Effective context is 25-50% of claimed context window — keep briefs concise

#### Execution Phases

**Phase 1: Interactive Brief Generation (t1312) ~4h**

- Create `.agents/scripts/commands/define.md` slash command
- Create `.agents/reference/define-probes/` with task-type probing angles:
  - `coding.md` — base probes for all code changes
  - `feature.md` — feature-specific probes
  - `bugfix.md` — bug-specific probes
  - `refactor.md` — refactor-specific probes
  - `shell.md` — shell script-specific probes
- Interview workflow: classify -> domain ground -> probe -> pre-mortem -> generate brief
- Each question: 2-4 concrete options, one recommended
- Output: complete brief at `todo/tasks/{task_id}-brief.md`

**Phase 2: Executable Verification Blocks (t1313) ~4h**

- Extend `templates/brief-template.md` with `verify:` block syntax
- Create `scripts/verify-brief.sh` — extracts and runs verification blocks
- Four methods: bash (exit code), codebase (rg pattern), subagent (review prompt), manual (skip)
- Integrate with `task-complete-helper.sh` as completion gate
- Update at least one existing brief with verify blocks as example

#### Decision Log

| Date       | Decision                                          | Rationale                                                                                                                                                                   |
| ---------- | ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 2026-02-22 | Adapt ideas, don't adopt the plugin               | manifest-dev is a Claude Code plugin (Python hooks, Claude-specific skills). We're tool-agnostic. Extract the ideas, implement in our architecture.                         |
| 2026-02-22 | Lighter interview than manifest-dev's 30KB prompt | Their `/define` is comprehensive but heavy (~30KB loaded per invocation). Our probing angles are compact reference files (~500 bytes each), loaded on-demand per task type. |
| 2026-02-22 | Skip `research` verification method               | manifest-dev includes web research verification for API compatibility checks. Our briefs are about code changes — bash + codebase + subagent covers our needs.              |
| 2026-02-22 | Verification blocks are optional                  | Existing briefs without `verify:` blocks still work. Gradual adoption — new briefs from `/define` include them, old briefs can be retrofitted.                              |
| 2026-02-22 | Subagent verification uses task's model tier      | manifest-dev defaults to opus for verification. We use the task's assigned model tier or default to sonnet (cost-aware).                                                    |

#### Risks

| Risk                                   | Likelihood | Impact | Mitigation                                                                                                                        |
| -------------------------------------- | ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------- |
| Interview adds friction to quick tasks | Medium     | Low    | `/define` is optional — users can still create briefs manually for simple tasks                                                   |
| Probing angles become stale            | Low        | Low    | Angles are generic domain knowledge, not project-specific. Update when new failure patterns emerge.                               |
| verify-brief.sh false positives        | Medium     | Medium | Each method has clear pass/fail semantics. Subagent method is the most subjective — use specific prompts, not vague "review this" |
| Workers ignore verification failures   | Low        | High   | Integration with task-complete-helper.sh makes it a hard gate, not advisory                                                       |

#### Outcomes & Retrospective

**What was delivered:**
- `/define` slash command (`scripts/commands/define.md`) — structured interview with task-type probing angles
- `reference/define-probes/` — compact probing angle files (coding, feature, bugfix, refactor, shell)
- Extended `templates/brief-template.md` with `verify:` block syntax
- `scripts/verify-brief.sh` — extracts and runs bash/codebase/subagent/manual verification blocks
- Integrated with `task-complete-helper.sh` as completion gate

**Time Summary:**
- Estimated: 8h
- Actual: ~6h
- PRs: #2183 (t1312), #2187 (t1313) merged 2026-02-23

---

### [2026-02-22] Harness Engineering: oh-my-pi Learnings

**Status:** Completed
**Estimate:** ~20h (ai:14h test:4h research:2h)
**TODO:** t1302, t1303, t1304, t1305, t1306, t1307, t1308, t1309, t1310
**Logged:** 2026-02-22
**Completed:** 2026-02-25
**Reference:** https://blog.can.ac/2026/02/12/the-harness-problem/ | https://github.com/can1357/oh-my-pi (cloned to <LOCAL_OH_MY_PI_PATH>; store path in user-local config or env var)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started}:
p030,Harness Engineering: oh-my-pi Learnings,completed,5,5,,feature|harness|edit-tool|observability|orchestration|opencode,20h,14h,4h,2h,2026-02-22T00:00Z,2026-02-25T00:00Z
-->

#### Purpose

Can Boluk's "The Harness Problem" blog post and oh-my-pi codebase (1,300+ commits, fork of Pi) demonstrate that the harness -- the tool layer between model output and workspace changes -- is the highest-leverage place to innovate. His benchmark showed a single edit tool change (hashline) improved 15 models, with Grok Code Fast 1 going from 6.7% to 68.3% success rate. Zero training compute.

Deep analysis of oh-my-pi revealed 10+ patterns applicable to aidevops, ranging from edit tool improvements to real-time streaming policy enforcement (TTSR), observability, and multi-agent orchestration. This plan captures all actionable learnings as concrete implementation tasks.

#### Context

**Key findings from oh-my-pi analysis:**

| Pattern                                       | Impact                                                    | Feasibility                                                   |
| --------------------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------- |
| TTSR (real-time stream rules)                 | High -- policy enforcement during generation              | Blocked in OpenCode (no stream hooks); needs upstream PR      |
| Soft TTSR (system prompt + message transform) | Medium -- preventative enforcement                        | Available now via unused OpenCode plugin hooks                |
| Hashline edit format                          | High -- 5-14% success improvement, 20-61% token reduction | Custom tooling only (can't replace Claude Code's str_replace) |
| Intent tracing                                | Medium -- tool-level chain-of-thought for observability   | Implementable in OpenCode plugin                              |
| SQLite observability                          | High -- cost/performance tracking, budget enforcement     | No equivalent exists in aidevops                              |
| Steering messages                             | Medium -- user interruption mid-execution                 | OpenCode architecture question                                |
| Swarm DAG execution                           | Medium -- dependency-resolved multi-agent orchestration   | Enhances existing supervisor dispatch                         |
| Blob/artifact storage                         | Low-medium -- session compactness                         | Platform-dependent                                            |

**OpenCode plugin hooks we're NOT using yet:**

- `experimental.chat.system.transform` -- transform system prompt before LLM call
- `experimental.chat.messages.transform` -- transform message history before LLM call
- `experimental.text.complete` -- modify completed text parts after generation
- `chat.message` -- intercept new user messages
- `chat.params` -- modify LLM parameters
- `event` -- receive bus events

**OpenCode plugin hooks that DON'T exist (needed for full TTSR):**

- `stream.delta` -- observe individual streaming tokens
- `stream.aborted` -- handle abort with retry/inject capability

#### Execution Phases

**Phase 1: Soft TTSR + Rule Engine (t1302, t1303)** ~4h

Implement preventative rule enforcement using existing OpenCode plugin hooks. Define rules in `.agents/rules/` with regex triggers. Inject rules into system prompt via `experimental.chat.system.transform`. Scan previous outputs for violations via `experimental.chat.messages.transform` and inject corrections. Post-hoc detection via `experimental.text.complete`.

**Phase 2: OpenCode Upstream -- Stream Hooks (t1304, t1305)** ~6h

Open issue on opencode-ai/opencode proposing `stream.delta` and `stream.aborted` plugin hooks. Reference oh-my-pi benchmark data as evidence. Create proof-of-concept PR demonstrating the implementation in OpenCode's `processor.ts`.

**Phase 3: Observability (t1306, t1307)** ~4h

Implement SQLite-based LLM request tracking: model, provider, tokens, costs, duration, TTFT, stop reason. Incremental session parsing. CLI dashboard (`aidevops stats`). Wire into budget enforcement (t1100).

**Phase 4: Intent Tracing + Edit Tool Research (t1308, t1309)** ~4h

Add intent field to tool call logging in OpenCode plugin. Document hashline autocorrect heuristics as reference for future custom edit tooling. Benchmark str_replace failure rates in our actual workloads.

**Phase 5: Swarm DAG Patterns (t1310)** ~2h

Evaluate oh-my-pi's YAML-defined swarm orchestration with `reports_to`/`waits_for` dependency resolution. Compare with our TODO.md `blocked-by:` system. Propose enhancements to supervisor dispatch.

#### Decision Log

- 2026-02-22: Full TTSR blocked by OpenCode plugin API -- no `stream.delta` hook exists. Pursuing soft TTSR (preventative) + upstream contribution for real TTSR.
- 2026-02-22: Hashline edit format is valuable but only applicable where we own the full tool chain (headless dispatch, objective runner). Can't replace Claude Code's str_replace.
- 2026-02-22: oh-my-pi cloned to <LOCAL_OH_MY_PI_PATH> for ongoing reference. Track upstream changes. Store the path in user-local config or env var.

### [2026-02-21] Cloudflare Code Mode MCP Integration

**Status:** Completed
**Estimate:** ~4h (ai:3h test:1h)
**TODO:** t1289, t1290, t1291, t1292, t1293
**Logged:** 2026-02-21

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p027,Cloudflare Code Mode MCP Integration,completed,4,4,,feature|mcp|cloudflare|agent,4h,3h,1h,0m,2026-02-21T00:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Cloudflare released a Code Mode MCP server (`mcp.cloudflare.com/mcp`) that provides full API coverage (2,500+ endpoints) via just 2 tools (`search()` + `execute()`) in ~1,000 tokens. Our current Cloudflare integration uses a static imported skill (`dmmulroy/cloudflare-skill`) with 310 files / 773KB of reference docs that drift from the live API and cost thousands of tokens per product loaded.

Code Mode is strictly better for **operations** (DNS, WAF, DDoS, R2, Workers management) — more accurate, more efficient, more secure, zero maintenance. The imported skill remains better for **development guidance** (patterns, gotchas, decision trees, SDK usage). This plan integrates Code Mode for operations and trims the static docs it supersedes.

#### Context

**Current state:**

```text
cloudflare.md (254 lines)
  - Manual API token setup, curl/bash scripts for DNS ops
  - No MCP integration

cloudflare-platform.md (241 lines)
  - Decision trees for 59 products
  - Points to cloudflare-platform/references/

cloudflare-platform/references/ (310 files, 773KB)
  - Per-product: README.md, api.md, configuration.md, patterns.md, gotchas.md
  - 96 files (api.md + configuration.md) = 250KB of API reference
  - Static snapshots from dmmulroy/cloudflare-skill, can drift from live API
  - Imported via skill-sources.json, daily auto-update via t1081
```

**Target state:**

```text
cloudflare.md
  - Intent-based routing: operations -> Code Mode MCP, development -> skill docs
  - API token setup retained for CI/CD (non-OAuth use cases)

cloudflare-platform.md
  - Clarified role: development patterns & architecture guidance (not API reference)
  - Reference file structure table updated (no more api.md/configuration.md)

cloudflare-platform/references/ (~214 files, ~523KB)
  - 96 api.md + configuration.md files REMOVED (superseded by Code Mode)
  - README.md, patterns.md, gotchas.md RETAINED (development guidance)

tools/api/cloudflare-mcp.md (NEW)
  - Subagent doc for Code Mode MCP usage
  - search() patterns, execute() patterns, auth setup, security model

MCP config:
  cloudflare-api: { url: "https://mcp.cloudflare.com/mcp" }
```

**Key metrics:**

| Metric                           | Before               | After                        | Improvement            |
| -------------------------------- | -------------------- | ---------------------------- | ---------------------- |
| API reference tokens per product | ~2,000-5,000         | ~1,000 (fixed)               | 60-80% reduction       |
| API coverage                     | 59 products (static) | 2,500+ endpoints (live)      | 42x more endpoints     |
| Reference file count             | 310                  | ~214                         | 31% fewer files        |
| Reference disk size              | 773KB                | ~523KB                       | 32% smaller            |
| Maintenance burden               | Daily skill sync     | Zero (Cloudflare-maintained) | Eliminated for API ops |
| API accuracy                     | Snapshot (can drift) | Live OpenAPI spec            | Always current         |

#### Execution Phases

**Phase 1: MCP server config + subagent doc (t1290, ~1h)**

- Add `cloudflare-api` entry to `mcp-integrations.md` under new "API Management" section
- Create `configs/mcp-templates/cloudflare-api.json` with Claude Code config snippet
- Create `tools/api/cloudflare-mcp.md` subagent doc covering:
  - `search()` usage patterns (filter by product, path, tags; inspect schemas)
  - `execute()` usage patterns (single calls, chained operations, pagination)
  - Auth: OAuth 2.1 flow (interactive) vs API token (CI/CD)
  - Security model: sandboxed V8 isolate, no filesystem, no env var leakage
  - When to use Code Mode vs skill docs (routing guidance)
- Update `subagent-index.toon` with new entry
- Verification: MCP config is valid JSON, subagent doc loads correctly

**Phase 2: Update routing and role clarification (t1291, ~30m, blocked-by t1290)**

- Update `cloudflare.md` Quick Reference to include Code Mode MCP
- Add intent-based routing section: operations -> MCP, development -> skill docs
- Update `cloudflare-platform.md` description and header to clarify "development patterns & architecture guidance"
- Update reference file structure table (remove api.md/configuration.md rows)
- Verification: both files have consistent cross-references

**Phase 3: Trim superseded reference docs (t1292, ~1.5h, blocked-by t1291)**

- Remove 48 `api.md` files from `cloudflare-platform/references/*/`
- Remove 48 `configuration.md` files from `cloudflare-platform/references/*/`
- Verify no broken cross-references in remaining README.md/patterns.md/gotchas.md files
- Update `skill-sources.json` notes field to reflect trimmed state
- Verification: `find references/ -name 'api.md' -o -name 'configuration.md'` returns 0 results

**Phase 4: End-to-end testing (t1293, ~1h, blocked-by t1292)**

- Connect to Code Mode MCP server via OAuth
- Test `search()`: discover DNS endpoints, WAF endpoints, R2 endpoints
- Test `execute()`: list zones, query DNS records, inspect WAF rules
- Test routing: verify operations question triggers MCP, development question triggers skill docs
- Test fallback: verify API token auth works for CI/CD (non-OAuth)
- Verification: all 5 test scenarios pass

#### Decision Log

| Date       | Decision                                                          | Rationale                                                                                                                                                                                                                                                                    |
| ---------- | ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 2026-02-21 | Add Code Mode MCP alongside existing skill (not replace)          | They solve different problems: Code Mode for operations (live API), skill for development guidance (patterns, gotchas, SDK usage). Together they cover the full spectrum at lower total context cost.                                                                        |
| 2026-02-21 | Remove api.md + configuration.md but keep README/patterns/gotchas | api.md and configuration.md contain API endpoint details and wrangler.toml config that Code Mode's live OpenAPI spec supersedes. README (overview/decision support), patterns (best practices), and gotchas (pitfalls) contain development wisdom that no API spec provides. |
| 2026-02-21 | OAuth 2.1 as primary auth, API token as CI/CD fallback            | OAuth provides scoped per-session permissions (more secure). API tokens needed for headless/CI environments where OAuth flow isn't possible.                                                                                                                                 |
| 2026-02-21 | Subtasks chained sequentially (blocked-by)                        | Each phase builds on the previous. Config must exist before routing can reference it. Routing must be updated before docs are trimmed. Testing validates the complete stack.                                                                                                 |

#### Risks

| Risk                                                            | Likelihood | Impact | Mitigation                                                                                                                   |
| --------------------------------------------------------------- | ---------- | ------ | ---------------------------------------------------------------------------------------------------------------------------- |
| Code Mode MCP server downtime                                   | Low        | Medium | API token fallback in cloudflare.md; skill docs still available for manual reference                                         |
| OAuth flow not supported in headless dispatch                   | Medium     | Low    | API token auth documented as CI/CD alternative; workers use token-based auth                                                 |
| Removing api.md/configuration.md breaks skill auto-update       | Low        | Low    | Update skill-sources.json notes; daily auto-update (t1081) will re-import from upstream but our trimmed state is intentional |
| Code Mode search() returns too many results for complex queries | Low        | Low    | Subagent doc includes query refinement patterns (filter by path, tags, method)                                               |

#### Relationship to Other Tasks

- **t1288** (OpenAPI MCP Server / openapisearch.com): General-purpose OpenAPI discovery for any API. t1289 is Cloudflare-specific with authenticated execution. Complementary, no dependency.
- **t1294** (MCPorter): MCP toolkit for discovery/testing. Could be used to test the Cloudflare Code Mode MCP during Phase 4. No hard dependency.

---

### [2026-02-21] OpenAPI Search MCP Integration

**Status:** Completed
**Estimate:** ~2h (ai:1.5h test:30m)
**TODO:** t1288, t1288.1, t1288.2, t1288.3, t1288.4, t1288.5, t1288.6
**Logged:** 2026-02-21

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p026,OpenAPI Search MCP Integration,completed,6,6,,feature|mcp|agent|context,2h,1.5h,30m,0m,2026-02-21T00:00Z,,2026-03-21T00:00Z
-->

#### Purpose

[janwilmake/openapi-mcp-server](https://github.com/janwilmake/openapi-mcp-server) (875 stars, MIT, TypeScript) is a hosted MCP that lets LLMs search and explore 2500+ OpenAPI specifications through [openapisearch.com](https://openapisearch.com/). It uses a 3-step process:

1. **Search** — find the right API identifier from the directory
2. **Overview** — get a simple-language summary of the API's capabilities
3. **Detail** — drill into specific endpoints with request/response schemas in plain language

This is valuable when agents need to discover or understand third-party APIs without manually reading raw OpenAPI specs. Use cases:

- Agent needs to integrate with an unfamiliar API — search, understand, and generate code
- Exploring what APIs exist for a given domain (payments, email, CRM, etc.)
- Getting endpoint details (auth, params, response shape) without leaving the conversation

**Key advantage**: Remote MCP at `https://openapi-mcp.openapisearch.com/mcp` — zero install, no API key, no local dependencies. Runs on Cloudflare Workers. Self-hosting via `wrangler dev` available as fallback.

#### Integration Decision

**Use as remote MCP** (not CLI agent). Rationale:

- Zero dependencies — no npm install, no local server, no API key
- Already a production Cloudflare Worker with public MCP endpoint
- Follows the same remote-MCP pattern we'd use for any hosted service
- Self-hosting adds complexity with no clear benefit (the data is public anyway)

**Subagent pattern**: Disabled globally, enabled on-demand per `add-new-mcp-to-aidevops.md` checklist. Same pattern as FluentCRM, Unstract, iOS Simulator MCPs.

**Agent enablement**:

| Agent     | Enabled | Rationale                                                    |
| --------- | ------- | ------------------------------------------------------------ |
| Build+    | Yes     | Primary development agent — API integration is core workflow |
| AI-DevOps | Yes     | Infrastructure and integration work                          |
| Research  | Yes     | API discovery and evaluation                                 |
| Others    | No      | Not relevant to their domains                                |

#### Execution Phases

**Phase 1: Subagent documentation (t1288.1, ~30m)**

- Create `.agents/tools/context/openapi-search.md` following context7.md pattern
- Frontmatter: `openapi-search_*: true` in tools section
- AI-CONTEXT-START block with: purpose, MCP URL, tool names, common API IDs
- Tool descriptions: `searchAPIs`, `getAPIOverview`, `getOperationDetails`
- Usage examples and verification prompt
- All AI assistant configurations (remote URL — same for all)

**Phase 2: Config templates (t1288.2, ~20m, blocked-by Phase 1)**

- Create `configs/openapi-search-config.json.txt` — comprehensive template
- Create `configs/mcp-templates/openapi-search.json` — per-assistant snippets
- Remote URL config only — no env vars, no API keys, no local binary

**Phase 3: OpenCode agent generation (t1288.3, ~15m, blocked-by Phase 2)**

- Add `openapi-search` MCP to `generate-opencode-agents.sh`
- Global config: `"enabled": false`
- Enable `openapi-search_*: true` for Build+, AI-DevOps, Research agents

**Phase 4: CLI config function (t1288.4, ~15m, blocked-by Phase 2)**

- Add `configure_openapi_search_mcp()` to `ai-cli-config.sh`
- Configure for all detected AI assistants
- No prerequisites check needed (remote URL)

**Phase 5: Index and docs updates (t1288.5, ~15m, blocked-by Phase 1)**

- Add to `mcp-integrations.md` under Development Tools / Context section
- Register in `subagent-index.toon`
- Update AGENTS.md domain index if needed

**Phase 6: Verification (t1288.6, ~15m, blocked-by Phases 3-5)**

- Run `generate-opencode-agents.sh`, verify MCP in config
- Test verification prompt: "Search for the Stripe API and show me the create payment intent endpoint"
- Run `linters-local.sh` and markdownlint
- Verify subagent loads correctly via agent invocation

#### Decision Log

- d001: Remote MCP over self-hosted — zero deps, public data, production Cloudflare Worker. Self-host only if latency or availability becomes an issue. 2026-02-21
- d002: Place at `tools/context/openapi-search.md` — this is a context/discovery tool (finding and understanding APIs), same category as context7, augment-context-engine, osgrep. 2026-02-21
- d003: Enable for Build+, AI-DevOps, Research only — API discovery is a development/research task. Domain agents (SEO, WordPress, etc.) can invoke via subagent reference if needed. 2026-02-21

#### Risks

- **Remote service availability**: Hosted on Cloudflare Workers — generally reliable, but no SLA. Mitigation: self-hosting via `wrangler dev` documented as fallback.
- **API coverage gaps**: Directory may not have every API. Mitigation: document how to contribute specs to openapisearch.com, and note that agents can fall back to reading raw specs.
- **MCP protocol changes**: The server uses standard MCP over HTTP. Mitigation: pin to known-working URL, document version.

### [2026-02-21] MCPorter MCP Toolkit Agent

**Status:** Completed
**Estimate:** ~4h (ai:3h test:1h)
**TODO:** t1294, t1294.1, t1294.2, t1294.3, t1294.4, t1294.5
**Logged:** 2026-02-21

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p025,MCPorter MCP Toolkit Agent,completed,5,5,,feature|mcp|agent,4h,3h,1h,0m,2026-02-21T00:00Z,,2026-03-21T00:00Z
-->

#### Purpose

[steipete/mcporter](https://github.com/steipete/mcporter) (2K stars, MIT, v0.7.3) is a TypeScript runtime, CLI, and code-generation toolkit for MCP. It auto-discovers MCP servers from all major AI editors (Cursor, Claude, Codex, Windsurf, VS Code), calls tools from CLI or TypeScript, generates standalone CLIs from MCP servers, and emits typed TypeScript clients.

Adding MCPorter as an aidevops agent provides:

1. **Unified MCP CLI** — replaces ad-hoc `npx` calls with a single tool for discovery, calling, and testing
2. **Cross-editor discovery** — `mcporter list` shows all MCPs from all editors in one view
3. **Automation** — TypeScript API (`callOnce()`, `createRuntime()`) for composing MCP calls in scripts/agents
4. **CLI generation** — `mcporter generate-cli` turns any MCP server into a standalone CLI
5. **Typed clients** — `mcporter emit-ts` generates `.d.ts` interfaces for MCP servers
6. **Testing** — quick CLI-based MCP validation without restarting editors

MCPorter complements (does not replace) existing infrastructure:

- `mcp-index-helper.sh` — token-aware on-demand loading (MCPorter doesn't solve token cost)
- `setup-mcp-integrations.sh` — initial setup automation (MCPorter is for runtime use)
- `validate-mcp-integrations.sh` — validation (MCPorter's `list` can augment this)

#### Key Capabilities to Document

| Capability     | Command                             | aidevops Use Case                   |
| -------------- | ----------------------------------- | ----------------------------------- |
| Discovery      | `mcporter list`                     | See all MCPs across all editors     |
| Tool calling   | `mcporter call server.tool args`    | Test MCP tools from CLI             |
| CLI generation | `mcporter generate-cli`             | Create standalone CLIs from MCPs    |
| Typed clients  | `mcporter emit-ts`                  | TypeScript wrappers for MCP servers |
| OAuth auth     | `mcporter auth <server>`            | Handle OAuth for hosted MCPs        |
| Daemon         | `mcporter daemon start/stop/status` | Keep stateful servers warm          |
| Ad-hoc         | `mcporter list --http-url <url>`    | Test MCPs without config changes    |
| Config mgmt    | `mcporter config list/add/remove`   | Manage MCP configs                  |

#### Execution Phases

**Phase 1: Subagent documentation (t1294.1, ~1.5h)**

- Create `.agents/tools/mcp-toolkit/mcporter.md` following `add-new-mcp-to-aidevops.md` template
- Include AI-CONTEXT-START block with quick reference, install, key commands
- Document all major capabilities with examples
- Cover per-assistant configuration (Claude Code, Cursor, OpenCode, etc.)
- Include verification prompt and troubleshooting

**Phase 2: Config templates (t1294.2, ~30m, blocked-by Phase 1)**

- Create `configs/mcp-templates/mcporter.json` with per-assistant snippets
- Not an MCP server itself — it's a CLI tool, so config is about making it available
- Document `config/mcporter.json` for projects that want MCPorter's own config

**Phase 3: Integration updates (t1294.3, ~30m, blocked-by Phase 1)**

- Update `mcp-integrations.md` — add MCPorter under Development Tools
- Update `mcp-discovery.md` — reference MCPorter as alternative discovery method
- Cross-reference with existing MCP infrastructure

**Phase 4: Index registration (t1294.4, ~15m, blocked-by Phase 3)**

- Add to `subagent-index.toon`
- Update AGENTS.md domain index (Agent/MCP dev row)

**Phase 5: Verification (t1294.5, ~30m, blocked-by Phase 4)**

- Test `npx mcporter list` discovers existing MCPs
- Test `mcporter call context7.resolve-library-id libraryName=react`
- Verify subagent doc loads correctly via agent invocation
- Run linters (`linters-local.sh`, markdownlint)

#### Decision Log

- d001: Place at `tools/mcp-toolkit/mcporter.md` (new category) rather than `tools/context/` — MCPorter is a toolkit for MCP management, not a context/search tool. New category allows future MCP toolkit additions. 2026-02-21
- d002: MCPorter is NOT an MCP server itself — it's a CLI/library that calls MCP servers. Config templates document how to use it alongside existing MCPs, not how to register it as an MCP. 2026-02-21
- d003: Enable for Build+ and AI-DevOps agents only — MCP toolkit operations are developer/infrastructure tasks, not domain-specific. Other agents can invoke via subagent reference. 2026-02-21

#### Risks

- **Pre-1.0 API instability**: v0.7.3 means breaking changes possible. Mitigation: document version pinning, link to changelog.
- **Node/pnpm dependency**: aidevops prefers Bun. Mitigation: MCPorter has Bun support (`dist-bun/`), document both options.
- **Overlap with existing tools**: Could confuse users about when to use MCPorter vs existing scripts. Mitigation: clear "when to use what" section in subagent doc.

### [2026-02-21] Context Optimisation: Slim Always-Loaded Harness

**Status:** Completed
**Estimate:** ~9h (ai:7h test:1.5h read:30m)
**TODO:** t1281, t1282, t1283
**Logged:** 2026-02-21

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p024,Context Optimisation: Slim Always-Loaded Harness,completed,3,3,,refactor|context|token-efficiency|progressive-disclosure,9h,7h,1.5h,30m,2026-02-21T00:00Z,,2026-03-21T00:00Z
-->

#### Purpose

The always-loaded context chain (build.txt + AGENTS.md files + build-plus.md) consumes ~18,300 tokens before the first user message. Combined with Claude Code's own system prompt (~8-10K), sessions start at ~28K tokens just to say "hi". Analysis shows ~70% of .agents/AGENTS.md content is procedural detail only relevant in specific scenarios, and ~1,500 tokens are duplicated across files.

This plan reduces the always-loaded footprint by ~49% (18,300 → ~9,300 tokens) through three sequential passes: deduplication, tiering, and language tightening. All knowledge is preserved — detail moves to on-demand reference files, not deleted.

#### Principles (MUST be followed by all passes)

1. **Nothing deleted** — knowledge was earned through real failures and discoveries. Every rule exists for a reason. Content moves to on-demand files, never to /dev/null.
2. **Progressive disclosure** — load the minimum needed to route correctly, then pull detail when the session encounters that domain. The subagent-index.toon is the detailed index; AGENTS.md needs only enough to route.
3. **Deterministic workflows, intelligent exceptions** — the harness should be crisp and procedural. Intelligence is for scenarios that fall outside pre-determined instructions, not for re-deriving the instructions themselves.
4. **Agent awareness without agent loading** — sessions must know what capabilities exist (the index) without loading the full instructions of every capability. A 1-line pointer per domain is sufficient for routing.
5. **Smaller models benefit most** — concise, directive language reduces confusion from unnecessary optionality. Write for the least capable model that might read the file.
6. **Inheritance chain is sacred** — build.txt → repo AGENTS.md → .agents/AGENTS.md → agent.md. Each file inherits everything above it. Dedup means keeping content at the highest (earliest-loaded) appropriate level.

#### Architecture: File Roles After Optimisation

```
ALWAYS LOADED (every session):
  build.txt (~2,800 tokens)
    - Universal behavioural rules (mission, tone, critical thinking)
    - Completion discipline (KIRA)
    - Tool usage, file discovery, code search
    - Security rules
    - Git workflow essentials (pre-edit check)
    - Quality standards
    - Working directories
    - Context compaction survival
    - Model reinforcements

  repo AGENTS.md (~1,000 tokens)
    - Contributing guide for aidevops framework development
    - Pointer to .agents/AGENTS.md for operational rules

  .agents/AGENTS.md (~3,000 tokens)
    - Identity & mission (3 lines)
    - Mandatory rules (pointers to build.txt + unique additions)
    - Planning & tasks (core format, task ID, auto-dispatch basics)
    - Git workflow (branch types, PR format, worktree basics)
    - Compressed domain index (1 line per domain)
    - Capabilities index (1 line per capability)
    - Security pointer + unique content

  build-plus.md (~2,500 tokens)
    - Intent detection (deliberation vs execution)
    - Build workflow (aidevops-specific steps only)
    - Domain expertise check (full — high value)
    - Planning file access & auto-commit
    - Quality gates & git safety pointers

ON-DEMAND (loaded when session touches the domain):
  reference/planning-detail.md (~1,700 tokens)
    - Auto-dispatch, blocker statuses, auto-subtasking
    - Stale-claim recovery, task completion rules
    - Atomic counter, interactive claim guard

  reference/orchestration.md (~1,500 tokens)
    - Supervisor CLI, pulse scheduler
    - Model routing detail, budget-aware routing
    - Pattern tracking, session memory monitoring

  reference/services.md (~1,200 tokens)
    - Memory system, inter-agent mailbox
    - MCP discovery, skills system
    - Auto-update, repo-sync

  reference/session.md (~500 tokens)
    - Session completion, context compaction
    - Browser automation, localhost standards
    - Bot reviewer feedback
```

#### Execution Phases

**Phase 1: Deduplicate (t1281, ~3h)**

- Establish build.txt as single source of truth for universal rules
- Remove duplicated content from downstream files, replace with pointers
- Preserve any unique content that exists only in downstream files
- Target: ~1,500 token reduction
- Verification: `wc -c` each file, trace inheritance chain

**Phase 2: Tier AGENTS.md (t1282, ~4h, blocked-by t1281)**

- Split .agents/AGENTS.md into slim core + 4 reference files
- Compress progressive disclosure table to 1-line-per-domain format
- Create reference/planning-detail.md, orchestration.md, services.md, session.md
- Target: ~6,000 token reduction from always-loaded
- Verification: every original section heading traceable to exactly one file

**Phase 3: Tighten language (t1283, ~2h, blocked-by t1282)**

- Compress explanatory paragraphs to directive statements
- Move "why" explanations to comments or reference files
- Trim generic coding advice from build-plus.md (models know how to code)
- Target: ~1,500 token reduction
- Verification: sonnet-tier model can follow every rule unambiguously

#### Decision Log

- d001: DSPy evaluated and rejected — solves structured pipeline optimisation (input→output with training data), not behavioural instruction compression for interactive agents. Would increase tokens via few-shot examples. 2026-02-21
- d002: Chose 3-pass sequential approach over single rewrite — each pass is independently verifiable and reversible. If pass 1 causes issues, passes 2-3 can be deferred. 2026-02-21
- d003: reference/ directory chosen over splitting into multiple AGENTS-\*.md files — cleaner separation, avoids Claude Code auto-loading multiple AGENTS.md files from the same directory. 2026-02-21
- d004: Opus tier required for all three passes — the model must understand the full context of why each rule exists to safely reorganise without losing intent. Sonnet might optimise too literally, removing content that appears redundant but serves a distinct purpose in its specific loading context. 2026-02-21

#### Risks

- **Over-trimming**: A model focused on token reduction may remove content that appears redundant but serves a purpose in a specific context (e.g., the same rule repeated in build.txt and AGENTS.md may seem redundant, but AGENTS.md is the only file loaded by some tools). Mitigation: opus tier, explicit "nothing deleted" constraint, verification step traces inheritance chain.
- **Reference files not discovered**: If the slim AGENTS.md pointers are too terse, sessions may not know when to load reference files. Mitigation: each pointer includes a trigger condition ("when working on planning tasks, read reference/planning-detail.md").
- **Worker regression**: Headless workers load the same AGENTS.md chain. If the slim version loses critical worker-specific rules (e.g., "Workers must NEVER edit TODO.md"), workers may misbehave. Mitigation: worker-specific rules stay in the always-loaded core, not in reference files.

### [2026-02-18] Dual-CLI Architecture: OpenCode Primary + Claude Code Fallback

**Status:** Completed
**Estimate:** ~20h (ai:14h test:4h read:2h)
**TODO:** t1160, t1161, t1162, t1163, t1164, t1165
**Logged:** 2026-02-18

**Problem:** The supervisor dispatch stack is built exclusively around OpenCode CLI. Claude Code CLI (`claude`) has matured into a viable headless dispatch tool with OAuth subscription billing, built-in cost caps (`--max-budget-usd`), native model fallback (`--fallback-model`), inline agent definitions (`--agents JSON`), and system prompt injection (`--append-system-prompt`). Anthropic is pushing OAuth-based usage for Claude Code CLI, which means workers dispatched via `claude -p` can run on a Max subscription (effectively free within plan limits) rather than paying per-token via API keys through OpenCode.

The framework already has 12+ duplicated `if [[ "$ai_cli" == "opencode" ]]` branches across supervisor modules, plus 3 scripts hardcoded to OpenCode-only and 1 hardcoded to Claude-only. The config parity gap is large: OpenCode gets 494 subagent stubs, 82 slash commands, full MCP config, per-agent model routing. Claude Code gets 1 AGENTS.md pointer, safety hooks, and 1 MCP.

**Current state:**

```text
OpenCode (primary, fully configured):
  ~/.config/opencode/opencode.json     # 494 agents, MCPs, tools, model routing
  ~/.config/opencode/agent/*.md        # 494 subagent stubs
  ~/.config/opencode/command/*.md      # 82 slash commands
  ~/.config/opencode/AGENTS.md         # Session greeting + pre-edit rules

Claude Code (minimal):
  ~/.claude/settings.json              # Safety hooks ONLY
  ~/.claude/commands/AGENTS.md         # 1 reference pointer
  ~/.claude/skills/                    # SKILL.md symlinks
  1 MCP registered (auggie-mcp)
```

**Target state:**

```text
OpenCode (primary — unchanged):
  [all existing config preserved, no regressions]

Claude Code (first-class fallback):
  ~/.claude/settings.json              # Safety hooks + tool permissions
  ~/.claude/commands/*.md              # Slash commands (parity with OpenCode)
  ~/.claude/skills/                    # SKILL.md symlinks (already done)
  MCPs registered via claude mcp add   # Parity with OpenCode MCP config
  OAuth dispatch for Anthropic models  # Subscription billing, not per-token

Supervisor dispatch:
  resolve_ai_cli() → opencode (primary) | claude (fallback/OAuth)
  build_cli_cmd()  → semantic args → CLI-specific command array
  SUPERVISOR_CLI   → env var override for explicit CLI selection
  SUPERVISOR_PREFER_OAUTH → prefer claude for Anthropic when OAuth available

Container pool (Phase 5):
  OrbStack/Docker containers with individual OAuth tokens
  Round-robin dispatch across container pool
  Per-container rate limit tracking and health checks
  Remote container support via SSH/Tailscale
```

**CLI flag mapping (reference):**

| Concept          | OpenCode                              | Claude Code                              |
| ---------------- | ------------------------------------- | ---------------------------------------- |
| Run one-shot     | `opencode run "prompt"`               | `claude -p "prompt"`                     |
| Model selection  | `-m provider/model`                   | `--model alias` (strips provider prefix) |
| Output format    | `--format json`                       | `--output-format json`                   |
| Session title    | `--title "name"`                      | N/A (no equivalent)                      |
| Autonomous mode  | `OPENCODE_PERMISSION='{"*":"allow"}'` | `--permission-mode bypassPermissions`    |
| Agent selection  | `--agent name`                        | `--agent name`                           |
| Inline agents    | N/A                                   | `--agents '{"name": {...}}'`             |
| System prompt    | Per-agent in config                   | `--append-system-prompt "text"`          |
| MCP injection    | Config in opencode.json               | `--mcp-config file --strict-mcp-config`  |
| Cost cap         | N/A (our budget-tracker)              | `--max-budget-usd N`                     |
| Fallback model   | N/A (our fallback-chain)              | `--fallback-model alias`                 |
| Continue session | `-s SESSION_ID`                       | `--resume ID`                            |
| Prompt position  | Positional (last arg)                 | Named (`-p "prompt"`)                    |

**Accepted limitations (no Claude Code equivalent):**

| Feature                             | Impact                                     | Mitigation                         |
| ----------------------------------- | ------------------------------------------ | ---------------------------------- |
| Warm server mode (`opencode serve`) | Workers cold-boot (~2-3s each)             | Acceptable for task-level dispatch |
| Tab-switchable agents               | Workers get one task, don't need switching | N/A                                |
| Session titles                      | Cosmetic — we track by PID/task-ID         | N/A                                |
| OpenCode SDK/HTTP API               | Supervisor is bash-based, doesn't use SDK  | N/A                                |
| On-demand MCP loading               | `--strict-mcp-config` per invocation       | Different mechanism, same outcome  |

**OAuth and containerization details:**

- `claude setup-token` generates a long-lived OAuth token for headless/CI use
- `CLAUDE_CODE_OAUTH_TOKEN` env var injects the token into any Claude CLI instance
- Each container gets its own token from a separate subscription account
- This enables N parallel workers across N subscriptions, each with their own rate limits
- OrbStack (our container runtime, v2.0.5) supports local containers + remote VMs
- Container image needs: claude CLI, git, node/bun, aidevops agents (volume mount)
- Repo access via bind mount from host or git clone inside container

#### Phases

**Phase 0: No-Regression Refactor (t1160.1-t1160.7) ~5.5h**

Pure refactoring of the dispatch stack. No behavior change. All existing OpenCode dispatch continues to work identically.

- [x] Audit complete: 12+ CLI branches identified across 6 supervisor modules
- [ ] t1160.1 Create `build_cli_cmd()` abstraction — single function replaces all duplicated branches
- [ ] t1160.2 Add `SUPERVISOR_CLI` env var — explicit override, default auto-detect
- [ ] t1160.3 Claude CLI branching in runner-helper.sh (currently OpenCode-only)
- [ ] t1160.4 Claude CLI branching in contest-helper.sh (currently OpenCode-only)
- [ ] t1160.5 Fix email-signature-parser-helper.sh (currently Claude-only, should use resolve_ai_cli)
- [ ] t1160.6 Add `claude` to orphan process detection in pulse.sh Phase 5
- [ ] t1160.7 Integration test: `SUPERVISOR_CLI=claude` full dispatch cycle

**Verification gate:** Run existing supervisor test suite + manual pulse with both `SUPERVISOR_CLI=opencode` and `SUPERVISOR_CLI=claude`. Both must produce identical outcomes for the same task.

**Phase 1: Claude Code Config Parity in setup.sh (t1161) ~4h**

Make `aidevops setup` and `aidevops update` deploy equivalent configuration to Claude Code.

- [ ] t1161.1 `generate-claude-commands.sh` — slash commands to `~/.claude/commands/`
- [ ] t1161.2 Automated MCP registration via `claude mcp add-json`
- [ ] t1161.3 Enhanced `~/.claude/settings.json` with tool permissions (merge, don't overwrite hooks)
- [ ] t1161.4 Wire `update_claude_config()` into setup.sh (conditional on `claude` binary)

**Key design decisions:**

- Slash commands generated from same source as OpenCode commands, with minor format adaptation (OpenCode `agent: Build+` frontmatter ignored by Claude Code)
- MCP registration uses existing `configs/mcp-templates/` `claude_code_command` entries
- `settings.json` merge strategy: read existing, deep-merge new permissions, preserve hooks
- Entire phase conditional on `command -v claude` — no-op if Claude Code not installed

**Verification gate:** Fresh `aidevops setup` on a machine with both CLIs produces working configs for both. Claude Code interactive session has slash commands and MCPs available.

**Phase 2: Worker MCP Isolation for Claude CLI (t1162) ~2h**

When dispatching workers via `claude -p`, provide equivalent MCP isolation to OpenCode's `generate_worker_mcp_config()`.

- [ ] t1162 Create `generate_worker_mcp_config_claude()` — builds temporary JSON for `--mcp-config`
- [ ] Use `--strict-mcp-config` to prevent workers from using user's global MCP config
- [ ] Cleanup: remove temp config files after worker exits

**Verification gate:** Worker dispatched via Claude CLI gets exactly the MCPs specified, not the user's full set.

**Phase 3: OAuth-Aware Dispatch (t1163) ~2h**

The value proposition: workers on Max subscription = no per-token cost for Anthropic models.

- [ ] t1163 Detect OAuth: `claude -p "OK" --output-format text` succeeds without `ANTHROPIC_API_KEY`
- [ ] `SUPERVISOR_PREFER_OAUTH` env var (default: true)
- [ ] When true + dispatching Anthropic models + OAuth available → use `claude` CLI
- [ ] When dispatching non-Anthropic models (OpenRouter, Groq, etc.) → always use `opencode`
- [ ] Budget tracker: record Claude CLI dispatches as `subscription` billing type
- [ ] Leverage `--max-budget-usd` for per-worker cost caps
- [ ] Leverage `--fallback-model` for native fallback
- [ ] Auth failure detection: if Claude CLI returns auth error, fall back to OpenCode + API key

**Verification gate:** Mixed batch with Anthropic + non-Anthropic tasks routes correctly. Anthropic tasks go via Claude CLI (OAuth), non-Anthropic via OpenCode. Auth failure triggers automatic fallback.

**Phase 4: End-to-End Verification (t1164) ~2h**

Comprehensive testing of the complete dual-CLI architecture before proceeding to containerization.

- [ ] t1164 Full regression suite:
  - Pure OpenCode batch (existing behavior, must be identical)
  - Pure Claude CLI batch (all Anthropic models)
  - Mixed batch (Anthropic via Claude, non-Anthropic via OpenCode)
  - OAuth failure scenario (Claude CLI auth expires mid-batch → fallback to OpenCode)
  - Config parity check (both CLIs have equivalent slash commands, MCPs)
  - Cost tracking verification (subscription vs token billing recorded correctly)

**Verification gate:** All scenarios pass. No regressions to existing workflows. Cost tracking accurate.

**Phase 5: Containerized Multi-Subscription Scaling (t1165) ~6h**

Scale beyond a single subscription's rate limits by running Claude Code CLI instances in containers, each with its own OAuth token.

- [ ] t1165.1 Container image design:
  - Base: Node.js LTS (Claude CLI requires Node)
  - Install: `claude` CLI, `git`, `gh`, core unix tools
  - Volume mounts: repo checkout (read-write), `~/.aidevops/agents/` (read-only)
  - Token injection: `CLAUDE_CODE_OAUTH_TOKEN` env var from `claude setup-token`
  - Permissions: `--permission-mode bypassPermissions` (trusted container)
  - No MCP servers inside container (injected via `--mcp-config` per dispatch)

- [ ] t1165.2 Container pool manager:
  - `container-pool-helper.sh [create|destroy|list|dispatch|health|scale]`
  - Pool config: `~/.config/aidevops/container-pool.json` (image, count, tokens, hosts)
  - Dispatch strategy: round-robin across healthy containers, skip rate-limited ones
  - Health checks: periodic `claude -p "OK"` inside each container
  - Rate limit tracking: per-container request count + 429 detection
  - Auto-scaling: spawn new containers when all existing ones are rate-limited

- [ ] t1165.3 Remote container support:
  - OrbStack remote VMs or SSH to any Docker host
  - Tailscale for secure networking between hosts
  - Credential forwarding: OAuth tokens via encrypted env vars, never in image
  - Log collection: `docker logs` piped to supervisor log directory
  - Worktree sync: git push from host, git pull inside container (or bind mount for local)

- [ ] t1165.4 Integration test: multi-container batch

**Verification gate:** Batch of 6+ tasks dispatched across 3+ containers. Each container uses its own OAuth token. Rate-limited containers are skipped. Logs aggregated correctly. Workers produce valid PRs.

#### Decision Log

| Date       | Decision                                                       | Rationale                                                                                                                                                                                             |
| ---------- | -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 2026-02-18 | OpenCode stays primary, Claude Code is fallback                | OpenCode supports multi-provider routing (OpenRouter, Groq, DeepSeek). Claude CLI is Anthropic-only. Keep the broader capability as primary.                                                          |
| 2026-02-18 | Phase 0 is pure refactor with no behavior change               | The 12+ duplicated CLI branches are a maintenance burden and bug risk. Centralizing into `build_cli_cmd()` is valuable regardless of Claude CLI support.                                              |
| 2026-02-18 | `SUPERVISOR_CLI` env var for explicit override                 | Auto-detection is the default, but operators need a way to force a specific CLI for testing or when both are installed but one is preferred.                                                          |
| 2026-02-18 | Config parity is conditional on `command -v claude`            | Users without Claude Code installed should not see errors or slowdowns. The entire Claude Code config path is a no-op if the binary is absent.                                                        |
| 2026-02-18 | `--strict-mcp-config` for worker MCP isolation                 | Prevents workers from accidentally using the user's full MCP set. Each worker gets exactly the MCPs it needs, nothing more.                                                                           |
| 2026-02-18 | OAuth detection via test invocation, not token file inspection | Claude Code stores OAuth in the macOS keychain (not a file we can inspect). The only reliable test is whether `claude -p` succeeds without `ANTHROPIC_API_KEY`. Cache the result for the pulse cycle. |
| 2026-02-18 | Containerization as Phase 5 (after everything else is tested)  | Containers add complexity (networking, volume mounts, token management). Only pursue after the single-host dual-CLI path is proven stable.                                                            |
| 2026-02-18 | `CLAUDE_CODE_OAUTH_TOKEN` env var for container auth           | `claude setup-token` generates long-lived tokens specifically for headless/CI use. Each container gets a unique token from a separate subscription account.                                           |
| 2026-02-18 | OrbStack as container runtime                                  | Already installed (v2.0.5), supports both local containers and remote VMs, lighter than Docker Desktop on macOS.                                                                                      |
| 2026-02-18 | All tasks model:opus                                           | Sensitive infrastructure work touching the dispatch core. Wrong decisions here break all autonomous orchestration. Opus-tier reasoning is warranted.                                                  |

#### Risks

| Risk                                                         | Likelihood | Impact | Mitigation                                                                              |
| ------------------------------------------------------------ | ---------- | ------ | --------------------------------------------------------------------------------------- |
| Claude CLI behavior differs from OpenCode in subtle ways     | Medium     | High   | Phase 0.7 integration test catches differences before production use                    |
| OAuth token expires mid-batch                                | Medium     | Medium | Auth failure detection + automatic fallback to OpenCode + API key                       |
| Claude Code updates break our generated config               | Low        | Medium | `update_claude_config()` is idempotent, re-runs on every `aidevops update`              |
| Claude Code rewrites "OpenCode" in AGENTS.md at load time    | Confirmed  | Low    | Cosmetic only — doesn't affect functionality. Documented as known behavior.             |
| Container networking issues (DNS, port conflicts)            | Medium     | Medium | OrbStack handles networking; fallback to host-only dispatch                             |
| Multiple subscriptions = multiple billing accounts to manage | Low        | Low    | Container pool config tracks which token belongs to which account                       |
| Rate limit changes by Anthropic                              | Low        | High   | Per-container rate tracking adapts automatically; pool manager skips limited containers |

#### Surprises & Discoveries

- Claude Code CLI already supports inline agent definitions via `--agents JSON --agent name` — this is more flexible than OpenCode's file-based agent config for worker dispatch.
- `--output-format json` returns `total_cost_usd` and full `modelUsage` breakdown per invocation — better cost tracking than OpenCode provides natively.
- Claude Code rewrites "OpenCode" references to "Claude Code" when loading AGENTS.md files. This is a Claude Code behavior, not something in our codebase. The deployed file at `~/.aidevops/agents/AGENTS.md` correctly says "OpenCode". Confirmed by comparing on-disk content vs system prompt content.
- The t1022 revert (PR #1329) left a residual "Claude Code" reference in `.agents/aidevops/architecture.md:44` that should be corrected.
- `claude setup-token` is the key to containerized auth — generates long-lived tokens specifically for headless/CI environments, injected via `CLAUDE_CODE_OAUTH_TOKEN` env var.

---

### [2026-02-18] Supervisor Intelligence Upgrade

**Status:** Completed
**Estimate:** ~12h (ai:8h test:3h read:1h)
**TODO:** t1085
**Logged:** 2026-02-18

**Problem:** The supervisor is a 2164-line mechanical bash pulse loop (Phases 0-12) that runs every 2 minutes via cron. It picks up tasks, dispatches workers, checks PRs, and reconciles state — but it has zero intelligence. Every decision is a hardcoded conditional. It cannot:

- Look at open GitHub issues and figure out how to get them solved
- Verify that recently closed issues/PRs have proper evidence
- Ensure closed issues have linked PRs with real deliverables
- Comment on issues to acknowledge, request information, or provide status
- Reason about project priorities, blockers, or optimal dispatch order
- Learn from patterns of failure or success across tasks

The user's vision: transform the supervisor into an opus-tier AI engineering manager that runs 24/7 and maximises project outcomes through intelligent reasoning, not just mechanical state transitions.

**Current architecture:**

```text
Cron (*/2) → supervisor-helper.sh pulse
  → Phase 0:    Auto-pickup #auto-dispatch tasks from TODO.md
  → Phase 0.5:  Task ID deduplication
  → Phase 1:    Check running workers for completion
  → Phase 1b:   Re-prompt stale retrying tasks
  → Phase 2:    Dispatch queued tasks (mechanical: next in queue)
  → Phase 2.5:  Contest mode check
  → Phase 3:    Post-PR lifecycle (merge, deploy states)
  → Phase 3b:   Post-merge verification
  → Phase 3b2:  Reconcile stale blocked/verify_failed tasks
  → Phase 3c:   Reconcile terminal DB states with GH issues
  → Phase 3.5:  Auto-retry merge-conflict tasks
  → Phase 3.6:  Escalate rebase-blocked PRs to opus worker
  → Phase 4:    Worker health checks (dead, hung, orphaned)
  → Phase 4b-e: DB orphans, stale diagnostics, stuck deploys, process sweep
  → Phase 5:    Summary
  → Phase 6:    Orphaned PR scanner
  → Phase 7:    TODO.md reconciliation
  → Phase 7b:   Bidirectional DB<->TODO.md reconciliation
  → Phase 8:    Issue-sync reconciliation
  → Phase 8b-c: Status label sweep, pinned health issues
  → Phase 9:    Memory audit pulse
  → Phase 10:   CodeRabbit daily pulse
  → Phase 10b:  Auto-create TODO tasks from quality findings
  → Phase 10c:  Audit regression detection
  → Phase 11:   Memory monitoring + respawn
  → Phase 12:   MODELS.md leaderboard regeneration
```

**AI integration points today:** Only `evaluate.sh` uses AI (to assess worker output quality). Dispatch is purely mechanical. No phase reasons about what to do next.

**Existing infrastructure to leverage (not reinvent):**

- `memory-helper.sh` — cross-session learning, pattern storage, recall
- `pattern-tracker-helper.sh` — success/failure rates by model tier, task type
- `mail-helper.sh` — async inter-agent communication, status reports
- `model-registry-helper.sh` / `fallback-chain-helper.sh` — model selection + fallback
- `self-improve-helper.sh` — analyze → refine → test → pr pipeline for framework improvements

**Target architecture:**

```text
Cron (*/2) → supervisor-helper.sh pulse
  → Phases 0-12: (unchanged — mechanical state machine, fast, reliable)
  → Phase 13: Skill update PR pipeline (t1082.2, opt-in, daily)
  → Phase 14: AI Supervisor Reasoning (NEW)
      → Pre-flight: has_actionable_work() — skip if nothing to reason about
      → Concurrency: lock file prevents overlapping sessions
      → Feedback: check mailbox for responses to previous actions
      → Context: project snapshot + memory recall + pattern data
      → Reasoning: opus-tier AI analyzes 7 areas (solvability, verification,
        linkage, communication, priority, efficiency, self-improvement)
      → Actions: execute validated actions, store decisions in memory,
        record outcomes in pattern tracker, send results via mailbox
      → Self-improvement: identify efficiency gaps, create tasks to fix them,
        recommend model tier changes based on pattern data
```

**Design principles:**

1. **Additive, not replacement** — the mechanical phases stay. They're fast, reliable, and handle 95% of operations. The AI phase adds reasoning on top.
2. **Bounded cost** — opus sessions are expensive. Cap at 1 session per 30min, with token budget limits. Use sonnet for routine checks, opus only for complex reasoning.
3. **Auditable** — every AI decision is logged with reasoning. The AI cannot silently change state.
4. **Idempotent** — if the AI phase crashes or times out, the next pulse continues normally. No state corruption.
5. **Progressive rollout** — start with read-only analysis (Phase 13a), then add write actions (Phase 13b) after validation.
6. **Use existing infrastructure** — mailbox for inter-agent comms, memory for cross-session learning, pattern tracker for model selection. Don't reinvent what already works.
7. **Self-improving** — the supervisor should identify efficiency gaps (token waste, model mismatches, repeated failures, missing automation) and create tasks to fix them.

#### Phases

**Phase 1: AI Supervisor Context Builder (t1085.1) ~2h** [DONE - PR #1607]

Create `supervisor/ai-context.sh` module that assembles a comprehensive project snapshot for the AI:

- Open GitHub issues (title, labels, age, comments, linked PRs)
- Recent PRs (last 48h: state, reviews, CI status, merge status)
- TODO.md state (open tasks, blocked tasks, stale tasks)
- Supervisor DB state (running workers, recent completions, failure patterns)
- Recent memory entries (last 24h) — via `memory-helper.sh recall --recent`
- Pattern tracker data (success/failure rates by model tier) — via `pattern-tracker-helper.sh stats`
- Queue health metrics

Output: a structured markdown document (< 50K tokens) that gives the AI full situational awareness.

**Integration note (updated 2026-02-18):** Context builder should use existing `memory-helper.sh recall` and `pattern-tracker-helper.sh` rather than raw SQL where possible. This ensures the AI sees the same data format that workers and interactive sessions use, and benefits from any future improvements to those tools.

**Phase 2: AI Supervisor Reasoning Engine (t1085.2) ~3h** [DONE - PR #1609, efficiency guards PR #1611]

Create `supervisor/ai-reason.sh` module that:

1. Builds context via Phase 1
2. Spawns an AI session (opus tier) with a carefully crafted system prompt
3. The AI reasons about 7 key areas:
   - **Solvability**: Which open issues can be broken into dispatchable tasks?
   - **Verification**: Have recently closed issues/PRs been properly verified?
   - **Linkage**: Do all closed issues have linked PRs with real deliverables?
   - **Communication**: Should any issues get a comment (acknowledgement, status, clarification request)?
   - **Priority**: What should be worked on next and why?
   - **Efficiency**: Are tokens being wasted? Are models correctly sized for tasks? Are there repeated failures that indicate a systemic issue?
   - **Self-improvement**: What automation gaps, missing tests, or process inefficiencies could be fixed to reduce future manual intervention?
4. AI outputs a structured action plan (JSON)
5. Module validates and executes approved actions

Efficiency guards added: `has_actionable_work()` pre-flight skips opus session when nothing needs attention. Lock file prevents overlapping sessions.

**Phase 3: Action Executor (t1085.3) ~3h**

Implement the action types the AI can request:

- `comment_on_issue(issue_number, body)` — post a comment on a GitHub issue
- `create_task(title, description, tags, estimate, model)` — add to TODO.md via claim-task-id.sh, with correct model tier
- `create_subtasks(parent_id, subtasks[])` — break down an issue into subtasks
- `flag_for_review(issue_number, reason)` — add label + comment requesting human review
- `adjust_priority(task_id, reason)` — reorder in TODO.md
- `close_verified(issue_number, evidence)` — close with proof (only if PR merged + verified)
- `request_info(issue_number, questions[])` — comment asking for clarification
- `create_improvement(title, description, category)` — NEW: create self-improvement tasks (categories: efficiency, automation, testing, documentation, model-routing)
- `escalate_model(task_id, from_tier, to_tier, reason)` — NEW: recommend model tier change for a task that's failing or underperforming at current tier

Each action is validated before execution (e.g., close_verified checks PR merge status).

**Integration with existing infrastructure (updated 2026-02-18):**

- **Memory**: After executing actions, store decisions via `memory-helper.sh store --auto` so future reasoning cycles have continuity. Key memories: "Commented on issue #X about Y", "Created task tNNN for Z", "Escalated task tNNN from sonnet to opus because W".
- **Pattern tracker**: Record action outcomes via `pattern-tracker-helper.sh record`. When a created task succeeds/fails, the pattern feeds back into future model tier recommendations.
- **Mailbox**: Action results are sent via `mail-helper.sh send` to the `ai-supervisor` agent inbox. The next reasoning cycle checks inbox for feedback on previous actions (did the comment get a response? did the created task succeed?). Workers dispatched by the AI supervisor send status reports back through the existing mailbox system.
- **Model routing**: `create_task` and `create_improvement` actions use `pattern-tracker-helper.sh recommend` to select the optimal model tier based on historical data, not just hardcoded defaults. `escalate_model` updates the TODO.md entry and records the escalation pattern for future learning.

**Phase 4: Subtask Auto-Dispatch Enhancement (t1085.4) ~1h**

Fix the current gap where subtasks of `#auto-dispatch` parents aren't independently dispatched:

- Phase 0 auto-pickup: when a parent has `#auto-dispatch`, also consider its subtasks
- Respect `blocked-by:` dependencies before dispatching subtasks
- Propagate model tier from parent to subtasks if not specified
- This immediately unblocks t1081.1-t1081.4 and t1082.1-t1082.4

**Phase 5: Pulse Integration + Scheduling (t1085.5) ~2h**

Wire Phase 14 into pulse.sh (Phase 13 is now skill update PRs from t1082.2):

- Add `SUPERVISOR_AI_INTERVAL` config (default: 15 pulses = ~30min)
- Track last AI run timestamp in DB
- Skip if within cooldown or `has_actionable_work()` returns false
- Run after all mechanical phases complete
- Log AI reasoning and actions to dedicated log file
- Add `supervisor-helper.sh ai-status` command for monitoring
- **Feedback loop**: Before reasoning, check mailbox for responses to previous actions (`mail-helper.sh check --agent ai-supervisor`). Include unread messages in the context so the AI knows what happened since last cycle.
- **Memory recall**: Include `memory-helper.sh recall "ai supervisor reasoning"` in context to give the AI continuity across cycles (what did it decide last time? what worked?)

**Phase 6: Issue Audit Capabilities (t1085.6) ~2h**

Specific AI-driven audits that run as part of Phase 13:

- **Closed issue audit**: For each issue closed in last 48h, verify: has linked PR, PR is merged, PR has substantive changes (not just TODO.md edits), task in TODO.md is marked complete with `pr:` evidence
- **Stale issue detection**: Issues open > 7 days with no activity, no assignee, no linked task
- **Orphan PR detection**: PRs with no linked issue or TODO task
- **Blocked task analysis**: Tasks blocked > 48h — can the blocker be resolved? Should the task be redesigned?

**Phase 7: Testing + Validation (t1085.7) ~2h**

- Dry-run mode: `supervisor-helper.sh ai-pulse --dry-run` shows what AI would do without executing
- Mock context for testing without live GitHub API calls
- Token budget tracking and cost reporting
- Integration test: run against current repo state, verify reasonable output
- Verify mailbox integration: actions produce messages, next cycle reads them
- Verify memory integration: decisions are stored, recalled in next cycle
- Verify pattern tracking: action outcomes feed back into model recommendations
- Verify self-improvement: AI identifies at least one real efficiency gap in test run

#### Decision Log

| Date       | Decision                                                     | Rationale                                                                                                                                                                                                                   |
| ---------- | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 2026-02-18 | Additive phase (13), not replacement of existing phases      | Mechanical phases are fast and reliable. AI adds reasoning, doesn't replace plumbing.                                                                                                                                       |
| 2026-02-18 | Opus tier for reasoning, sonnet for routine checks           | Complex reasoning (issue triage, priority assessment) needs opus. Simple checks (is PR merged?) don't.                                                                                                                      |
| 2026-02-18 | 30-minute default interval                                   | Balance between responsiveness and cost. 48 opus calls/day at ~$0.50 each = ~$24/day. Configurable.                                                                                                                         |
| 2026-02-18 | Structured JSON action output, not free-form                 | Enables validation before execution. AI proposes, executor validates and acts.                                                                                                                                              |
| 2026-02-18 | Read-only first (Phase 13a), write actions later (Phase 13b) | Build trust in AI reasoning before letting it modify state.                                                                                                                                                                 |
| 2026-02-18 | Subtask dispatch fix (t1085.4) as part of this plan          | Directly addresses the stalled t1081/t1082 subtasks and is a prerequisite for AI-created subtasks.                                                                                                                          |
| 2026-02-18 | Use mailbox + memory + patterns, don't reinvent              | ai-context.sh was building its own data gathering. Existing infrastructure (memory recall, pattern tracker, mailbox) already solves cross-session learning and inter-agent comms. Wire them together instead.               |
| 2026-02-18 | AI reasoning should store decisions in memory                | Without memory, each reasoning cycle is stateless — no continuity, no learning from past decisions. Memory gives the AI a "what did I do last time?" capability.                                                            |
| 2026-02-18 | Add self-improvement as a core reasoning area                | The supervisor should proactively identify efficiency gaps (token waste, model mismatches, missing automation, repeated failures) and create tasks to fix them. This is the path to maximum utility from minimal token use. |
| 2026-02-18 | Phase 14 (not 13) for AI reasoning                           | t1082.2 (PR #1610) claimed Phase 13 for skill update PRs. AI reasoning becomes Phase 14.                                                                                                                                    |
| 2026-02-18 | Add escalate_model action type                               | When a task fails at sonnet tier, the AI should be able to recommend escalation to opus (or de-escalation from opus to sonnet for simple tasks). Pattern tracker data drives these recommendations.                         |

#### Surprises & Discoveries

- t1082.2 runner claimed Phase 13 for skill update PRs before we wired AI reasoning. Renumbered to Phase 14 — no conflict.
- The `has_actionable_work()` pre-flight check (efficiency guard) is critical for cost control. Without it, every 30-minute pulse would spawn an opus session even when nothing needs attention.
- The `gh` CLI `--repo` flag needs `owner/repo` format, not filesystem paths. Fixed in efficiency guards PR.

---

### [2026-02-17] Daily Skill Auto-Update Pipeline

**Status:** Completed
**Estimate:** ~7h (ai:5h test:2h)
**TODO:** t1081, t1082
**Logged:** 2026-02-17

**Problem:** Imported skills (e.g., cloudflare-platform from dmmulroy/cloudflare-skill) are checked for upstream updates during interactive `setup.sh` runs but never auto-pulled. Users run stale skill docs until a maintainer manually re-imports. The Cloudflare skill is already 3 commits behind upstream.

**Design:**

Two-layer approach:

**Layer 1 (t1081): User-side daily refresh**

- `auto-update-helper.sh cmd_check()` already runs every 10 min via cron
- After the existing version check + `setup.sh --non-interactive`, add a daily skill check
- Gate: check `last_skill_check` timestamp in `auto-update-state.json`, skip if <24h
- Call `skill-update-helper.sh check --auto-update --quiet` to pull upstream changes
- Updates the deployed copy at `~/.aidevops/agents/` for that user's local sessions
- Repo version wins on next `aidevops update` (no conflict risk)

**Layer 2 (t1082): Maintainer PR pipeline**

- New `skill-update-helper.sh pr` subcommand
- For each skill with upstream changes: create worktree, re-import via `add-skill-helper.sh add <url> --force`, commit, open PR
- PR goes through normal pr-loop (CI, review, merge)
- Optional supervisor phase (configurable schedule, default daily)
- One PR per skill for independent review (configurable)

**Key decisions:**

- [2026-02-17] Daily frequency (not hourly) to respect GitHub API rate limits and avoid churn
- [2026-02-17] User auto-update is a "preview" -- repo version is authoritative
- [2026-02-17] One PR per skill (not batched) for independent review cycles
- [2026-02-17] Supervisor phase is opt-in, not default (maintainers enable explicitly)

**Implementation order:**

1. t1081.2 -- Ensure skill-update-helper.sh works headlessly
2. t1081.1 -- Wire daily check into auto-update-helper.sh
3. t1081.3 -- State file schema update
4. t1081.4 -- Documentation
5. t1082.1 -- PR subcommand
6. t1082.2 -- Supervisor phase
7. t1082.3 -- Multi-skill batching config
8. t1082.4 -- PR template

### [2026-02-14] Automated Matrix+Cloudron Setup

**Status:** Completed
**Estimate:** ~4h (ai:3h test:1h)
**TODO:** t1056
**Logged:** 2026-02-14

#### Purpose

The Matrix bot integration (t1000) has full session persistence and multi-channel support, but setup requires manual steps across three systems: Cloudron dashboard (install Synapse), Element web client (get access token), and CLI (configure bot). A user with a Cloudron VPS should be able to run a single command to provision the entire stack.

#### Context

**Current state:**

- `matrix-dispatch-helper.sh setup` — interactive wizard, requires homeserver URL and access token already obtained manually
- `cloudron-helper.sh` — can list servers, list apps, exec commands, check status, but **cannot install apps** via the API
- Cloudron REST API supports `POST /api/v1/apps/install` with appStoreId, subdomain, domain
- Synapse Admin API supports user registration, room creation, and invites
- Matrix Client API supports login (to get access token)
- All the pieces exist but aren't wired together

**Target state:**

```bash
# One command provisions everything
matrix-dispatch-helper.sh auto-setup production
# → Installs Synapse on Cloudron server "production"
# → Creates bot user @aibot:matrix.yourdomain.com
# → Gets access token via Matrix login API
# → Configures matrix-bot.json
# → Creates rooms (#dev, #seo, #ops, etc.) per runner mappings
# → Invites bot to all rooms
# → Maps rooms to runners
# → Ready to start: matrix-dispatch-helper.sh start --daemon
```

#### Design

**Phase 1: Cloudron install-app (t1056.1)**

Add to `cloudron-helper.sh`:

```bash
# Install an app from the Cloudron App Store
cloudron-helper.sh install-app <server> <appstore-id> <subdomain>
# e.g.: cloudron-helper.sh install-app production io.element.synapse matrix

# Wait for app to be ready (polls status)
cloudron-helper.sh wait-ready <server> <app-id>

# Get app info by subdomain
cloudron-helper.sh app-info <server> <subdomain>

# Uninstall an app
cloudron-helper.sh uninstall-app <server> <app-id>
```

API calls:

- `POST /api/v1/apps/install` — `{ "appStoreId": "io.element.synapse", "subdomain": "matrix", "domain": "yourdomain.com" }`
- `GET /api/v1/apps/:id` — poll until `installationState === "installed"` and `runState === "running"`
- `DELETE /api/v1/apps/:id/uninstall`

**Phase 2: Synapse Admin API helpers (t1056.2)**

Add to `matrix-dispatch-helper.sh`:

```bash
# These are internal functions, not user-facing commands

# Register bot user (uses Synapse Admin API, requires admin token)
synapse_create_user <homeserver> <admin_token> <username> <password>
# PUT /_synapse/admin/v2/users/@username:server

# Login as bot to get access token
matrix_login <homeserver> <username> <password>
# POST /_matrix/client/v3/login → returns access_token

# Create a room
matrix_create_room <homeserver> <access_token> <room_alias> <room_name>
# POST /_matrix/client/v3/createRoom

# Invite user to room
matrix_invite <homeserver> <access_token> <room_id> <user_id>
# POST /_matrix/client/v3/rooms/:roomId/invite
```

Synapse admin token: obtained from Cloudron app environment variables via `cloudron-helper.sh exec-app <server> <synapse-app-id> 'cat /app/data/homeserver.yaml'` or via the Cloudron API app secrets endpoint.

**Phase 3: auto-setup orchestration (t1056.3)**

```text
auto-setup <cloudron-server> [--runners "code-reviewer,seo-analyst,ops-monitor"]
    │
    ├─ 1. Read cloudron-config.json for server details
    ├─ 2. Check if Synapse already installed (cloudron-helper.sh apps | grep synapse)
    │     └─ If yes: skip install, get existing app details
    │     └─ If no: install-app io.element.synapse matrix → wait-ready
    ├─ 3. Get Synapse admin token from Cloudron app env
    ├─ 4. Create bot user via Synapse Admin API
    ├─ 5. Login as bot → get access token
    ├─ 6. Store access token via aidevops secret set MATRIX_BOT_TOKEN
    ├─ 7. Write matrix-bot.json config (non-interactive)
    ├─ 8. For each runner in --runners:
    │     ├─ Create room with alias #runner-name:server
    │     ├─ Invite bot to room
    │     └─ Map room to runner in config
    ├─ 9. Generate bot scripts (session-store.mjs + bot.mjs)
    └─ 10. Print summary and "start with: matrix-dispatch-helper.sh start --daemon"
```

**Phase 4: Documentation and tests (t1056.4)**

- Update matrix-bot.md: add "Automated Setup" section before manual Cloudron section
- Update cloudron.md: reference install-app command
- Add `--dry-run` flag to auto-setup that prints what it would do without executing
- Test: `matrix-dispatch-helper.sh auto-setup production --dry-run`

#### Decision Log

- **2026-02-14**: Chose to extend existing cloudron-helper.sh rather than create a new script — the install-app capability is generally useful beyond Matrix
- **2026-02-14**: Synapse admin token retrieval via Cloudron app env rather than requiring manual input — keeps the flow fully automated
- **2026-02-14**: Store bot credentials via `aidevops secret set` (gopass) rather than plaintext — follows framework security conventions

#### Dependencies

- Requires a configured Cloudron server in `configs/cloudron-config.json`
- Requires Cloudron API token with app install permissions
- Requires the Synapse app to be available in the Cloudron App Store (it is: `io.element.synapse`)
- t1000 (Matrix bot SQLite session store) — completed

### [2026-02-14] PageIndex-Ready Markdown Normalisation

**Status:** Completed
**Estimate:** ~3h (ai:2h test:1h)
**TODO:** t1046
**Logged:** 2026-02-14

#### Purpose

All document converters in the pipeline (pdftotext, pandoc, Reader-LM, RolmOCR, OCR providers, email MIME extraction) produce markdown with inconsistent or absent heading structure. PageIndex (VectifyAI) builds hierarchical tree indexes from heading levels (`#`, `##`, `###`) for reasoning-based RAG — flat or poorly-structured markdown produces useless trees.

This plan adds a shared post-conversion normalisation step that transforms any raw converter output into well-structured, PageIndex-optimised markdown. It benefits:

- **Document conversion** (t1042): PDF, DOCX, ODT, HTML all get consistent heading hierarchy
- **AI conversion providers** (t1043): Reader-LM and RolmOCR output gets normalised
- **Email pipeline** (t1044): Email bodies, which rarely have headings, get logical section structure
- **Future converters**: Any new `*→md` path automatically benefits

#### Context

**Current state:**

- `pdftotext` → flat text, no headings
- `pandoc` → preserves source headings (if any), doesn't normalise
- Reader-LM → prompt says "preserving structure" but no heading hierarchy enforcement
- RolmOCR → same as Reader-LM
- OCR providers (tesseract, easyocr, glm-ocr) → raw text, no structure
- Email MIME → body text with no semantic sections

**Target state:**

Every `*→md` conversion produces markdown with:

1. Single `#` root heading (document title)
2. Sequential heading nesting (no skipped levels)
3. Logical sections detected and marked (for flat text sources)
4. YAML frontmatter with standard fields
5. Optional `.pageindex.json` sidecar with hierarchical tree

#### Design

**Normalisation pipeline** (runs after any converter):

```text
Raw markdown (from any converter)
    |
[1. Frontmatter enforcement]
    |  - Add/merge YAML frontmatter
    |  - title, source_file, converter, content_hash, tokens_estimate
    |
[2. Heading hierarchy]
    |  - Detect existing headings, fix skipped levels
    |  - For flat text: infer sections from structural cues
    |    - Capitalised lines followed by blank lines → headings
    |    - Short lines (<60 chars) followed by longer paragraphs → headings
    |    - Known patterns: "Dear...", "--" (signature), ">" (quotes)
    |  - Ensure single # root
    |
[3. Table cleanup]
    |  - Fix pipe alignment in markdown tables
    |  - Detect tab-separated data and convert to tables
    |
[4. Email-specific sections] (when source is email)
    |  - Quoted replies (>) → ### Quoted Reply
    |  - Signature block (after --) → ### Signature
    |  - Forwarded headers → ### Forwarded Message
    |
[5. PageIndex tree] (optional, when --pageindex flag)
    |  - Generate .pageindex.json from heading hierarchy
    |  - Node summaries: first sentence of each section (or LLM if available)
    |  - Page references from source PDF metadata
    |
Output: normalised markdown + optional .pageindex.json
```

**Implementation approach:**

- Add `normalise` subcommand to `document-creation-helper.sh` (keeps pipeline unified)
- Python script for the heavy lifting (heading inference, frontmatter YAML, tree generation)
- Shell wrapper for CLI interface and integration with existing convert flow
- Auto-runs after `*→md` conversions by default, `--no-normalise` to skip

#### Subtasks

- [ ] t1046.1 `normalise` subcommand — heading hierarchy, section detection, table cleanup (~1h)
- [ ] t1046.2 Frontmatter enforcement — standard YAML fields on all output (~30m)
- [ ] t1046.3 Convert pipeline integration — auto-normalise after `*→md` (~30m, blocked-by:t1046.1,t1046.2)
- [ ] t1046.4 Email pipeline integration — email-specific section detection (~30m, blocked-by:t1046.1,t1044.1)
- [ ] t1046.5 PageIndex tree generation — `.pageindex.json` sidecar (~30m, blocked-by:t1046.1)

#### Decision Log

| Date       | Decision                                                       | Rationale                                                                                |
| ---------- | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| 2026-02-14 | Post-conversion step, not per-converter                        | Applies uniformly to all converters; avoids duplicating logic in each converter function |
| 2026-02-14 | Subcommand in document-creation-helper.sh, not separate script | Keeps document pipeline unified; reuses existing Python venv                             |
| 2026-02-14 | Auto-enabled by default with --no-normalise opt-out            | Normalised output is always better; users who need raw output can skip                   |

#### Surprises & Discoveries

_(none yet)_

### [2026-02-13] Continual Improvement Audit Loop

**Status:** Completed
**Estimate:** ~6h (ai:4h test:2h)
**TODO:** t1032

#### Purpose

Close the loop between daily code audits and automated fixes so that all quality badges trend toward maximum scores every day:

| Badge                 | Current    | Target     | Source                              |
| --------------------- | ---------- | ---------- | ----------------------------------- |
| Code Quality Analysis | failing    | passing    | GitHub Actions CI (SonarCloud scan) |
| Quality Gate          | passed     | passed     | SonarCloud                          |
| CodeFactor            | A          | A          | CodeFactor                          |
| Maintainability       | D          | A          | Codacy                              |
| Code Quality          | A          | A          | Qlty                                |
| CodeRabbit            | AI Reviews | AI Reviews | CodeRabbit (issue #753)             |

The **Maintainability D** is the primary gap. The CI failure is a SonarCloud PR analysis error (not a code quality issue).

#### Context

**What exists today (working):**

1. **Phase 10** — `coderabbit-pulse-helper.sh` triggers a daily full codebase review on GitHub issue #753 via `@coderabbitai` comment. Self-throttles with 24h cooldown.
2. **Phase 10b** — `coderabbit-task-creator-helper.sh create` scans CodeRabbit findings from the collector SQLite DB, filters false positives, reclassifies severity, deduplicates, allocates task IDs via `claim-task-id.sh`, appends to TODO.md with `#auto-dispatch`, commits and pushes.
3. **Phase 0** — supervisor auto-pickup dispatches `#auto-dispatch` tasks to workers.
4. Workers create PRs that fix findings, PRs go through CI, get merged.

**What's missing (the gaps):**

1. **Only CodeRabbit is wired in.** Codacy, SonarCloud, and CodeFactor have API configs, documentation, and even a config template (`code-audit-config.json.txt`), but `code-audit-helper.sh` is a 6-line placeholder stub. No collector exists for these services.
2. **No unified findings schema.** CodeRabbit findings live in `reviews.db`, pulse findings in JSON files. There's no common table that all sources write to.
3. **No trend tracking.** We can't answer "are we improving?" — there's no historical record of finding counts over time.
4. **No regression detection.** If a merge introduces 10 new Codacy issues, nothing notices until the next manual check.
5. **No audit visibility.** The pinned queue health issue (t1013) shows task status but nothing about code quality scores or audit findings.
6. **Maintainability D is unaddressed.** Codacy's maintainability grade is the worst badge. Without collecting Codacy findings and creating fix tasks, it stays D.

**The closed loop (target state):**

```text
Daily pulse
  → Phase 10: Trigger reviews (CodeRabbit, Codacy, SonarCloud, CodeFactor)
  → Phase 10a: Collect findings from all services into unified SQLite
  → Phase 10b: Filter FPs, classify, dedup, create TODO tasks (#auto-dispatch)
  → Phase 0: Auto-dispatch fix tasks to workers
  → Workers: Create PRs that fix findings
  → CI: Verify fixes pass all quality gates
  → Merge: Scores improve
  → Next daily pulse: Trend tracking confirms improvement, surfaces regressions
  → Queue health issue: Shows audit health section with scores and trends
```

#### Design

**Unified audit findings schema** (new table in `~/.aidevops/.agent-workspace/work/code-audit/audit.db`):

```sql
CREATE TABLE audit_findings (
    id              INTEGER PRIMARY KEY AUTOINCREMENT,
    source          TEXT NOT NULL,  -- 'coderabbit', 'codacy', 'sonarcloud', 'codefactor'
    source_id       TEXT NOT NULL,  -- Service-specific finding ID
    repo            TEXT NOT NULL,
    path            TEXT,
    line            INTEGER,
    severity        TEXT NOT NULL,  -- critical/high/medium/low/info (normalised)
    original_severity TEXT,         -- As reported by the service
    category        TEXT,           -- bug/vulnerability/smell/duplication/style/security
    rule_id         TEXT,           -- Service-specific rule (e.g. 'S1192', 'SC2086')
    description     TEXT NOT NULL,
    is_false_positive INTEGER DEFAULT 0,
    fp_reason       TEXT,
    is_duplicate    INTEGER DEFAULT 0,
    duplicate_of    INTEGER,
    task_id         TEXT,
    task_created    INTEGER DEFAULT 0,
    collected_at    TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ','now')),
    UNIQUE(source, source_id)
);

CREATE TABLE audit_snapshots (
    id              INTEGER PRIMARY KEY AUTOINCREMENT,
    date            TEXT NOT NULL,
    source          TEXT NOT NULL,
    total_findings  INTEGER NOT NULL,
    critical        INTEGER DEFAULT 0,
    high            INTEGER DEFAULT 0,
    medium          INTEGER DEFAULT 0,
    low             INTEGER DEFAULT 0,
    info            INTEGER DEFAULT 0,
    false_positives INTEGER DEFAULT 0,
    tasks_created   INTEGER DEFAULT 0,
    delta_vs_prev   INTEGER,  -- positive = regression, negative = improvement
    UNIQUE(date, source)
);
```

**Severity mapping across services:**

| Our Scale | CodeRabbit       | Codacy   | SonarCloud | CodeFactor |
| --------- | ---------------- | -------- | ---------- | ---------- |
| critical  | Critical (emoji) | Critical | BLOCKER    | —          |
| high      | Major (emoji)    | Error    | CRITICAL   | Major      |
| medium    | Minor (emoji)    | Warning  | MAJOR      | Minor      |
| low       | Suggestion       | Info     | MINOR      | Style      |
| info      | —                | —        | INFO       | —          |

**Service API endpoints:**

- **Codacy**: `GET /analysis/organizations/{org}/repositories/{repo}/issues` (paginated, filter by severity)
- **SonarCloud**: `GET /issues/search?componentKeys={key}&resolved=false` + `GET /hotspots/search`
- **CodeFactor**: `GET /repos/{owner}/{repo}/issues` (via CodeFactor API)
- **CodeRabbit**: Already collected via existing `coderabbit-collector-helper.sh`

#### Phases

**Phase 1: Unified orchestrator + schema (t1032.1) ~1h**

- Replace `code-audit-helper.sh` stub with real implementation
- Create `audit.db` with unified schema
- Implement `collect` command that iterates configured services
- Implement `report` command that queries unified DB
- Implement `trend` command (Phase 4 populates data)

**Phase 2: Service collectors (t1032.2, t1032.3) ~1.5h**

- Codacy collector: API polling, severity mapping, pagination, store in audit_findings
- SonarCloud collector: issues + hotspots, severity mapping, store in audit_findings
- CodeFactor: defer (already A-grade, lowest priority)
- Each collector is a function in code-audit-helper.sh, not a separate script

**Phase 3: Generalise task creator (t1032.4) ~1h**

- Refactor `coderabbit-task-creator-helper.sh` to read from unified `audit_findings` table
- Keep all existing FP filtering, severity reclassification, dedup logic
- Add source-aware task descriptions (e.g. "Fix Codacy maintainability issue: ...")
- Rename to `audit-task-creator-helper.sh`, symlink old name

**Phase 4: Wire into supervisor pulse (t1032.5) ~30m**

- Phase 10: Keep CodeRabbit pulse trigger (it's async — comment on #753)
- Phase 10a (new): Run `code-audit-helper.sh collect` for Codacy + SonarCloud
- Phase 10b: Call `audit-task-creator-helper.sh create` instead of CodeRabbit-only version
- Keep 24h cooldown on collection, task creation runs every pulse if new findings exist

**Phase 5: Trend tracking + regression detection (t1032.6) ~45m**

- After each collection run, snapshot finding counts into `audit_snapshots`
- `code-audit-helper.sh trend` shows week-over-week and month-over-month
- Regression detection: if findings increased >20% vs previous snapshot, log warning
- Pattern tracker integration: record quality trends as patterns

**Phase 6: Dashboard integration (t1032.7) ~30m**

- Add "Audit Health" section to pinned queue health issue
- Show: last audit time, finding counts by source/severity, trend arrows, open fix task count
- Link to issue #753 for CodeRabbit review history

**Phase 7: End-to-end verification (t1032.8) ~30m**

- Manual trigger of full cycle
- Verify all services polled, findings stored, tasks created, dispatched, PRs created
- Verify trend tracking records the run
- Document any remaining gaps

#### Decision Log

| Date       | Decision                                                              | Rationale                                                                                                                                 |
| ---------- | --------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| 2026-02-13 | Unified SQLite DB, not per-service DBs                                | Single query point for dedup, trend, and dashboard. CodeRabbit collector keeps its own DB for backward compat but also writes to unified. |
| 2026-02-13 | Collectors as functions in code-audit-helper.sh, not separate scripts | Reduces file proliferation. Each collector is ~100-150 lines. The orchestrator calls them.                                                |
| 2026-02-13 | Defer CodeFactor collector                                            | Already A-grade. Focus on Codacy (D maintainability) and SonarCloud (CI failure) first.                                                   |
| 2026-02-13 | Keep CodeRabbit pulse on issue #753                                   | Async model works well. CodeRabbit reviews via GitHub comments, collector picks up results. No change needed.                             |
| 2026-02-13 | Rename task-creator to audit-task-creator                             | Reflects multi-source scope. Symlink preserves backward compat for any scripts referencing old name.                                      |

#### Surprises & Discoveries

- The SonarCloud CI failure is not a code quality issue — it's `Something went wrong while trying to get the pullrequest with key '1361'` (a SonarCloud API error on PR analysis). This is a transient/config issue, not a findings problem.
- The Maintainability D badge is the highest-impact target. Codacy maintainability issues are typically: long functions, high complexity, code duplication — exactly what the existing refactoring tasks (t1026, t1027, t1031) address. Wiring Codacy findings into the auto-dispatch pipeline would have caught these earlier.

---

### [2026-02-12] Automated Git Stash Audit and Cleanup

**Status:** Completed
**Estimate:** ~45m (ai:30m test:15m)
**TODO:** t1005

#### Purpose

Automate the detection and cleanup of obsolete git stashes that accumulate from `git pull --rebase --autostash` cycles, supervisor operations, and aborted edits. Must never drop stashes containing user work that isn't already in HEAD.

#### Context

**Problem:** Over time, stashes accumulate silently (9 found in this session). Most are autostashes from rebase cycles containing single-line TODO.md changes that have long since been superseded. Manually auditing each stash is tedious — you have to `git stash show` each one, cross-reference with HEAD, and decide. This is exactly the kind of routine maintenance that should be automated.

**Safety constraint:** Users may have intentionally stashed work-in-progress. The tool must distinguish between:

- **Autostashes** (from `--autostash`) — safe to drop if content is in HEAD
- **Superseded changes** — files modified more recently in git history
- **User-created stashes** — named stashes or stashes with non-planning files that aren't in HEAD

#### Design

**Classification algorithm** for each stash:

1. **SAFE** (auto-drop):
   - Message contains "autostash" AND all changed files' diffs are empty against HEAD (content already in HEAD)
   - All files in the stash are unchanged vs HEAD (zero diff)
   - Stash only contains 0-byte file changes (empty permission/mode changes from worktree operations)

2. **OBSOLETE** (auto-drop with `--force`, otherwise report):
   - Message contains "autostash" but some diffs remain vs HEAD (partial supersede)
   - All files in the stash have been modified more recently in `git log` (newer commits exist)
   - Stash is older than 7 days AND only touches TODO.md/VERIFY.md (planning churn)

3. **REVIEW** (never auto-drop):
   - Named stash (user-created with `-m`)
   - Contains files not in HEAD (new files the user created)
   - Contains diffs against HEAD in non-planning files (potential user work)
   - Stash is less than 24h old (might be actively used)

**Commands:**

```text
stash-audit-helper.sh status          # Classify all stashes, show report
stash-audit-helper.sh clean           # Drop SAFE stashes only
stash-audit-helper.sh clean --force   # Drop SAFE + OBSOLETE stashes
stash-audit-helper.sh clean --dry-run # Show what would be dropped
```

**Integration points:**

- Supervisor pulse Phase 6 (cleanup) — call `stash-audit-helper.sh clean` after worktree cleanup
- `session-review` workflow — show stash status as part of session end checklist
- `worktree-helper.sh clean` — audit stashes after removing merged worktrees

**Safety nets:**

- `git fsck --unreachable` can recover dropped stashes for ~30 days (document this)
- `--dry-run` is the default for any automated invocation (supervisor must pass `--auto` to actually drop)
- Log every drop to `~/.aidevops/logs/stash-audit.log` with stash content summary

#### Implementation

- [ ] Create `stash-audit-helper.sh` with classify/clean/status commands
- [ ] Add stash classification logic (SAFE/OBSOLETE/REVIEW)
- [ ] Integrate into supervisor pulse Phase 6 cleanup
- [ ] Add to session-review checklist
- [ ] Test: create known stash types, verify classification, verify no false drops

### [2026-02-12] Modularise Oversized Shell Scripts

**Status:** Completed
**Estimate:** ~8h (ai:6h test:2h)
**TODO:** t311

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p029,Modularise Oversized Shell Scripts,completed,5,5,,refactor|quality|architecture|shell,8h,6h,2h,30m,2026-02-12T02:30Z,,2026-03-21T00:00Z
-->

#### Purpose

Split oversized shell scripts into logical modules to improve maintainability, reduce ShellCheck noise, and prevent terminal rendering crashes in tools like OpenCode when linting produces thousands of warnings against a single file.

#### Context

**Problem:** `supervisor-helper.sh` has grown to 14,644 lines — a single shell script larger than many entire projects. Running ShellCheck against it produces thousands of warnings that flood terminal UIs (observed crashing OpenCode's renderer). Other scripts are also growing beyond comfortable single-file size.

**Scripts by size (500+ lines):**

| Script                        | Lines  | Priority | Notes                                    |
| ----------------------------- | ------ | -------- | ---------------------------------------- |
| supervisor-helper.sh          | 14,644 | Critical | Crashes linter UIs, impossible to review |
| memory-helper.sh              | 2,505  | High     | Growing, clear domain boundaries         |
| issue-sync-helper.sh          | 1,971  | Medium   | Moderate size, self-contained            |
| keyword-research-helper.sh    | 1,809  | Low      | Domain-specific, less churn              |
| generate-opencode-commands.sh | 1,625  | Low      | Codegen, rarely edited                   |
| quality-sweep-helper.sh       | 1,603  | Low      | Stable                                   |
| 15+ scripts at 1,100-1,500    | —      | Low      | Monitor, split if they grow              |

#### Approach: Source-Based Module Architecture

Shell doesn't have native modules, but `source` provides a clean equivalent. The pattern:

```text
scripts/
├── supervisor-helper.sh          # Entry point: arg parsing, dispatch
├── supervisor/
│   ├── _common.sh                # Shared constants, logging, DB helpers
│   ├── batch.sh                  # Batch management (create, status, cancel)
│   ├── dispatch.sh               # Worker dispatch, claiming, prompt building
│   ├── lifecycle.sh              # PR lifecycle, merge, deploy states
│   ├── pulse.sh                  # Pulse phases 0-11
│   ├── recovery.sh               # Auto-recovery, orphan cleanup, respawn
│   ├── release.sh                # Batch release, version management
│   └── todo-sync.sh              # TODO.md read/write, commit_and_push_todo
├── memory-helper.sh              # Entry point
├── memory/
│   ├── _common.sh
│   ├── store.sh
│   ├── recall.sh
│   └── maintenance.sh            # Prune, consolidate, graduate
```

**Key design decisions:**

1. **Entry point stays the same** — `supervisor-helper.sh` remains the CLI interface. No breaking changes to callers.
2. **Source at top** — entry point sources all modules at startup (not lazy-load). Simpler, avoids path resolution bugs.
3. **Shared state via globals** — modules share `SUPERVISOR_DB`, `SUPERVISOR_LOG`, etc. already defined as globals. No change needed.
4. **One function per concern** — each module owns a clear set of functions. No function spans modules.
5. **`_common.sh` convention** — underscore prefix = internal, sourced by siblings only.

#### Risks

- **Path resolution**: `source` paths must be relative to the entry point, not the module. Use `SCRIPT_DIR` pattern.
- **Function name collisions**: Currently no namespacing. Audit for collisions before splitting.
- **ShellCheck per-module**: Each module needs its own ShellCheck pass. May need `# shellcheck source=` directives.
- **Testing**: Existing tests (if any) call the entry point. Should still work since the interface doesn't change.
- **Deployment**: `setup.sh` copies scripts/ — needs to also copy subdirectories.

#### Phases

- [ ] **Phase 1: Audit & map** — catalogue every function in supervisor-helper.sh, group by domain, identify dependencies between groups. Produce a module assignment table. ~1h
- [ ] **Phase 2: Create module skeleton** — create `supervisor/` directory, `_common.sh` with shared helpers, empty module files with function stubs. Wire `source` into entry point. Verify script still works identically. ~1h
- [ ] **Phase 3: Extract modules** — move functions into modules one group at a time, running ShellCheck + syntax check after each move. Start with the most self-contained group (likely release or todo-sync). ~3h
- [ ] **Phase 4: Repeat for memory-helper.sh** — same pattern, smaller scope. ~1h
- [ ] **Phase 5: Update tooling** — update setup.sh to deploy subdirectories, update linters-local.sh to handle module structure, update any hardcoded paths. Verify end-to-end. ~1h

#### Decision Log

| Date       | Decision                                       | Rationale                                                                     |
| ---------- | ---------------------------------------------- | ----------------------------------------------------------------------------- |
| 2026-02-12 | Source-based modules, not separate executables | Preserves single CLI interface, avoids IPC complexity, globals work naturally |
| 2026-02-12 | Start with supervisor-helper.sh only           | Highest impact, others can wait                                               |
| 2026-02-12 | Eager source (not lazy)                        | Simpler, shell startup cost is negligible for CLI tools                       |

#### Surprises & Discoveries

(none yet)

---

### [2026-02-10] Email Testing Suite

**Status:** Completed
**Estimate:** ~2h (ai:1.5h test:25m read:5m)
**TODO:** t214

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p027,Email Testing Suite,completed,4,4,,email|testing|services|playwright|eoa,2h,1.5h,25m,5m,2026-02-10T00:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Add comprehensive email testing capabilities to aidevops, covering both visual rendering (design) and deliverability (spam filters, inbox placement). Inspired by Email on Acid's feature set, implemented as a hybrid: free local testing via Playwright + paid authoritative testing via EOA's v5 REST API. Also enhance the existing email-health-check with content-level pre-send checks that EOA's Campaign Precheck covers but we currently lack.

#### Context

**Problem:** aidevops has email infrastructure validation (SPF/DKIM/DMARC via email-health-check) and sending (SES), but zero coverage for "does this email HTML render correctly across clients" or "will this email pass spam filters." The marketing.md agent mentions "test across email clients" as a troubleshooting step but provides no tooling.

**Email on Acid capabilities mapped to implementation tiers:**

| EOA Feature                                                        | Our Implementation                                         | Tier         |
| ------------------------------------------------------------------ | ---------------------------------------------------------- | ------------ |
| 100+ client screenshots (Outlook, Gmail, Apple Mail, mobile)       | EOA API v5 — POST HTML, poll results, download screenshots | API (paid)   |
| Webmail rendering (Gmail/Outlook.com/Yahoo in Chrome/Edge/Firefox) | Playwright device emulation + logged-in webmail accounts   | Local (free) |
| Dark mode previews                                                 | Playwright `colorScheme: 'dark'` + EOA dark mode clients   | Both         |
| Mobile viewport previews                                           | Playwright 100+ device presets (iPhone/Pixel/iPad)         | Local (free) |
| Outlook Word rendering engine                                      | EOA API only — no local emulator exists                    | API only     |
| Native mobile app rendering (Gmail app, Outlook app)               | EOA API only — proprietary rendering engines               | API only     |
| Spam filter testing (SpamAssassin, Barracuda, etc.)                | EOA spam API (3 methods: eoa, smtp, seed)                  | API (paid)   |
| Accessibility checks (WCAG, contrast ratio, table roles)           | axe-core via Playwright + custom email-specific rules      | Local (free) |
| Image validation (broken src, alt text, file sizes)                | HTML parsing + URL validation                              | Local (free) |
| Link validation                                                    | Playwright crawl or curl                                   | Local (free) |
| CSS inlining check                                                 | HTML parsing                                               | Local (free) |
| Subject line analysis                                              | Custom rules (length, spam triggers, personalization)      | Local (free) |
| Unsubscribe header validation                                      | Header parsing                                             | Local (free) |
| HTML weight/size analysis                                          | File size + ratio calculations                             | Local (free) |
| Campaign Precheck workflow                                         | Orchestrated multi-step check                              | Local (free) |

**Existing email agents (naming context):**

| File                                                             | Purpose                       | Naming Pattern       |
| ---------------------------------------------------------------- | ----------------------------- | -------------------- |
| `services/email/email-health-check.md`                           | DNS/auth/blacklist validation | `email-health-check` |
| `services/email/ses.md`                                          | SES sending provider          | `ses`                |
| `content/distribution/email.md`                                  | Newsletter strategy/content   | `email` (content)    |
| `services/hosting/cloudflare-platform/references/email-routing/` | CF email routing              | infrastructure       |

**New agents follow the same `services/email/` pattern:**

| New File                                | Purpose                       |
| --------------------------------------- | ----------------------------- |
| `services/email/email-design-test.md`   | Visual rendering testing      |
| `services/email/email-delivery-test.md` | Spam filter + inbox placement |

**Email lifecycle in aidevops after this plan:**

```text
1. Infrastructure:   email-health-check (DNS, auth, blacklists)
2. Sending:          ses.md (provider config, quotas)
3. Design testing:   email-design-test (NEW — rendering across clients)
4. Delivery testing: email-delivery-test (NEW — spam filters, inbox placement)
5. Content:          content/distribution/email.md (strategy, copy)
```

**EOA API v5 key details:**

- Base URL: `https://api.emailonacid.com/v5/`
- Auth: HTTP Basic (API key + password, base64)
- Sandbox: username/password both "sandbox" for testing
- Create test: `POST /email/tests` with `{subject, html, clients[]}`
- Poll results: `GET /email/tests/{id}` (completed/processing/bounced arrays)
- Get screenshots: `GET /email/tests/{id}/results` (URLs with basic auth or 24h presigned)
- Client list: `GET /email/clients` (id, client, os, category, rotate, image_blocking)
- Spam test: `POST /spam/tests` with `{subject, html, test_method: "eoa"|"smtp"|"seed"}`
- Spam results: `GET /spam/tests/{id}` (per-filter: client, type b2b/b2c, spam 1/0/-1, details)
- Seed list: `GET /spam/seedlist` (reserve addresses before sending)
- Results stored 90 days
- Micro version v5.0.1 adds full_thumbnail field

#### Phases

**Phase 1: Email Design Test agent + helper script (t214.1, t214.2) ~35m**

- Create `services/email/email-design-test.md` subagent
- Create `scripts/email-design-test-helper.sh` CLI
- Local tier: Playwright multi-device screenshots, dark mode, HTML/CSS lint, accessibility, link/image validation
- API tier: EOA v5 integration (create test, poll, download screenshots, client list management)
- Desktop tier: Apple Mail via AppleScript (macOS only)

**Phase 2: Email Delivery Test agent + helper script (t214.3, t214.4) ~35m**

- Create `services/email/email-delivery-test.md` subagent
- Create `scripts/email-delivery-test-helper.sh` CLI
- EOA spam API integration (3 test methods)
- mail-tester.com automation via Playwright
- Seed list management

**Phase 3: Email Health Check enhancements (t214.5) ~15m**

- Subject line analysis (length, spam triggers, personalization tokens)
- HTML weight/size check + image-to-text ratio
- Unsubscribe header validation (List-Unsubscribe, List-Unsubscribe-Post)
- Plain text fallback verification
- URL validation (resolve all links, flag shorteners/suspicious redirects)
- Image hosting validation (CDN check, no temp URLs)
- Domain age check for sender domain
- Update email-health-check-helper.sh with new commands

**Phase 4: Cross-references + integration (t214.6) ~10m**

- Update AGENTS.md progressive disclosure table
- Update subagent-index.toon
- Update marketing.md troubleshooting references
- Add pre-send checklist to content/distribution/email.md

#### Decision Log

- **2026-02-10**: Chose hybrid local+API approach over API-only. Rationale: Playwright gives instant free feedback during development; EOA API provides authoritative results for Outlook/native mobile that cannot be emulated locally. Best ROI = fast iteration locally, EOA for final pre-send validation.
- **2026-02-10**: Named `email-design-test` and `email-delivery-test` (not `email-rendering` or `email-preview`) to match the existing `email-health-check` naming pattern and clearly distinguish design (visual) from delivery (spam/inbox) concerns.
- **2026-02-10**: Decided to enhance existing `email-health-check` rather than create a separate agent for content-level checks. The health check already covers DNS/auth; adding subject line analysis, HTML weight, unsubscribe headers, and URL validation keeps all pre-send validation in one place.
- **2026-02-10**: EOA API credentials stored via `aidevops secret set EOA_API_KEY` and `aidevops secret set EOA_API_PASSWORD`. Never in config files or conversation.

### [2026-02-10] Accessibility & Contrast Testing

**Status:** Completed
**Estimate:** ~2.5h (ai:2h test:25m read:5m)
**TODO:** t215

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p028,Accessibility & Contrast Testing,completed,5,5,,accessibility|testing|wcag|contrast|wave|axe-core|lighthouse,2.5h,2h,25m,5m,2026-02-10T00:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Add comprehensive accessibility and colour contrast testing to aidevops, covering both websites and email HTML. Inspired by WebAIM's tools (Contrast Checker, WAVE, WCAG 2.2 checklist), implemented as a multi-tool approach: free axe-core for automated WCAG rule checking, free WebAIM Contrast Checker API for individual colour pair validation, paid WAVE API for comprehensive analysis with element selectors, and Lighthouse accessibility category (already installed) for scoring. Also adds email-specific accessibility checks to the existing email agents (t214).

#### Context

**Problem:** aidevops has no dedicated accessibility testing capability. Lighthouse (via pagespeed-helper.sh) includes an accessibility category but it's buried in the overall report and never surfaced as first-class output. There's no contrast checking, no axe-core integration, no WAVE integration, and no WCAG compliance reporting. Email agents (existing and planned t214) have no accessibility validation beyond basic alt text presence.

**WebAIM tools mapped to implementation:**

| WebAIM Tool           | Our Implementation                                                                                                                | Cost                                |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- |
| Contrast Checker      | WebAIM API (fcolor/bcolor params, returns ratio + AA/AAA pass/fail)                                                               | Free, no key                        |
| Link Contrast Checker | WebAIM API + 3:1 ratio check for links distinguished by colour alone                                                              | Free, no key                        |
| WAVE                  | WAVE API (wave.webaim.org/api/) — reporttype 1-4, returns errors/contrast/alerts/features/structure/ARIA with XPath/CSS selectors | Paid ($0.025-0.04/credit, 100 free) |
| WCAG 2.2 Checklist    | axe-core rules mapped to WCAG success criteria, compliance report generator                                                       | Free (axe-core OSS)                 |

**WCAG 2.2 coverage by tool:**

| WCAG Principle                                                  | axe-core | WAVE    | Lighthouse | Manual Review                |
| --------------------------------------------------------------- | -------- | ------- | ---------- | ---------------------------- |
| 1. Perceivable (alt text, contrast, adaptable, distinguishable) | Strong   | Strong  | Partial    | Captions, audio descriptions |
| 2. Operable (keyboard, timing, seizures, navigation)            | Partial  | Partial | Partial    | Keyboard testing, timing     |
| 3. Understandable (readable, predictable, input assistance)     | Partial  | Partial | Minimal    | Language, error prevention   |
| 4. Robust (compatible, parsing, name/role/value)                | Strong   | Strong  | Partial    | AT compatibility             |

**Contrast ratio thresholds (WCAG 2.1):**

| Criterion                    | Level | Normal Text | Large Text | UI Components |
| ---------------------------- | ----- | ----------- | ---------- | ------------- |
| SC 1.4.3 Contrast (Minimum)  | AA    | 4.5:1       | 3:1        | —             |
| SC 1.4.6 Contrast (Enhanced) | AAA   | 7:1         | 4.5:1      | —             |
| SC 1.4.11 Non-text Contrast  | AA    | —           | —          | 3:1           |

Large text = >= 18pt (24px) or >= 14pt (18.66px) bold.

**Existing tools that touch accessibility:**

| Tool                           | What it does                                          | Gap                                                          |
| ------------------------------ | ----------------------------------------------------- | ------------------------------------------------------------ |
| `pagespeed-helper.sh`          | Runs Lighthouse (includes a11y category)              | A11y buried in report, no dedicated command, no WCAG mapping |
| `axe-cli.md`                   | iOS Simulator automation tool                         | NOT axe-core web accessibility — naming collision only       |
| `playwright-emulation.md`      | 100+ device presets, forced-colors/high-contrast mode | No a11y scanning, just visual emulation                      |
| `email-health-check-helper.sh` | DNS/auth/blacklist validation                         | No content-level a11y checks                                 |

**New agent location:** `services/accessibility/accessibility-audit.md` — new directory under services, parallel to `services/email/`, `services/hosting/`, etc.

**Accessibility testing lifecycle in aidevops after this plan:**

```text
1. Quick check:     lighthouse-a11y (pagespeed-helper.sh accessibility command)
2. Automated scan:  axe-core via Playwright (comprehensive WCAG 2.2 A/AA rules)
3. Contrast audit:  Playwright computed style extraction + WebAIM API validation
4. Deep analysis:   WAVE API (errors, contrast, alerts, features, structure, ARIA)
5. Email a11y:      email-health-check + email-design-test accessibility commands
6. Compliance:      WCAG report generator (pass/fail per success criterion)
```

**Tool installation:**

- axe-core: `npm install -g @axe-core/cli` or inject `axe-core` via Playwright `page.evaluate()`
- WebAIM Contrast Checker API: no installation, HTTP GET with colour params
- WAVE API: key via `aidevops secret set WAVE_API_KEY`, HTTP GET
- Lighthouse: already installed via pagespeed-helper.sh

**WebAIM Contrast Checker API details:**

- URL: `https://webaim.org/resources/contrastchecker/?fcolor=0000FF&bcolor=FFFFFF&api`
- Response: `{"ratio":"8.59","AA":"pass","AALarge":"pass","AAA":"pass","AAALarge":"pass"}`
- No auth required, no rate limit documented (be respectful)
- Hex colours without # prefix

**WAVE API details:**

- URL: `https://wave.webaim.org/api/request?key=KEY&url=URL&reporttype=2`
- Report types: 1 (stats only, 1 credit), 2 (stats + items with selectors, 1 credit), 3 (annotated page source, 2 credits), 4 (full, 3 credits)
- Response categories: error, contrast, alert, feature, structure, aria
- Each item: id (rule code like "alt_missing"), description, count, selectors (XPath + CSS)
- New accounts: 100 free credits
- Pricing: $0.04/credit (100), $0.035/credit (1000), $0.025/credit (10000+)

#### Phases

**Phase 1: Accessibility audit agent + helper script (t215.1, t215.2) ~40m**

- Create `services/accessibility/accessibility-audit.md` subagent with tool decision tree
- Create `scripts/accessibility-audit-helper.sh` CLI
- axe-core integration: inject via Playwright `page.evaluate()` for URL or local HTML file scanning
- WebAIM Contrast Checker API integration for individual colour pair validation
- WCAG compliance report generator (pass/fail per success criterion, grouped by principle)
- Output formats: JSON, Markdown, HTML

**Phase 2: Playwright contrast extraction (t215.3) ~20m**

- Traverse all visible DOM elements via `page.evaluate()`
- Extract computed `color`, `backgroundColor` (walk ancestors for transparent), `fontSize`, `fontWeight`
- Calculate contrast ratio per WCAG formula: `(L1 + 0.05) / (L2 + 0.05)` where L = relative luminance
- Determine large text threshold (>= 18pt or >= 14pt bold)
- Check against AA (4.5:1 normal, 3:1 large) and AAA (7:1 normal, 4.5:1 large)
- Check non-text contrast (SC 1.4.11) for UI components at 3:1
- Handle edge cases: gradients (sample multiple points), background images (flag manual review), opacity, CSS filters
- Cross-validate sample pairs against WebAIM API for accuracy
- Output: element selector, actual colours, computed ratio, threshold, pass/fail, WCAG criterion

**Phase 3: WAVE API integration (t215.4) ~15m**

- Submit URL to WAVE API with reporttype 2 (stats + items with selectors)
- Parse response categories: error, contrast, alert, feature, structure, aria
- Map WAVE rule IDs to WCAG 2.2 success criteria
- Cache results to avoid burning credits on repeated scans of same URL
- Credit usage tracking and warnings
- Integrate into accessibility-audit-helper.sh `wave` command

**Phase 4: Lighthouse + email accessibility (t215.5, t215.6) ~30m**

- Enhance pagespeed-helper.sh: add `accessibility` command running `--only-categories=accessibility`
- Surface individual Lighthouse a11y audits with element selectors and fix guidance
- Add `--wcag-level` flag to filter by WCAG level
- Email accessibility checks in email-health-check-helper.sh: lang attribute, table role=presentation, alt text quality, semantic headings, inline style contrast, link text quality, font size minimum
- Email accessibility checks in email-design-test-helper.sh: axe-core on rendered HTML, contrast overlay on screenshots

**Phase 5: Cross-references + integration (t215.7) ~10m**

- Add Accessibility row to AGENTS.md progressive disclosure table
- Update subagent-index.toon with new accessibility entries
- Cross-reference from pagespeed.md, email-health-check.md, email-design-test.md
- Add accessibility to content/distribution/email.md pre-send checklist
- Update marketing.md with accessibility audit capability

#### Decision Log

- **2026-02-10**: Chose multi-tool approach (axe-core + WebAIM API + WAVE API + Lighthouse) over single-tool. Rationale: axe-core is the de facto standard but misses some issues WAVE catches (and vice versa). WebAIM Contrast Checker API is free and authoritative for individual colour pairs. Lighthouse is already installed. Using all four gives the most comprehensive coverage with minimal additional cost.
- **2026-02-10**: Located agent at `services/accessibility/` (new directory) rather than under `tools/` or `services/testing/`. Rationale: accessibility is a cross-cutting concern like email or hosting — it deserves its own service directory. The helper script pattern (`accessibility-audit-helper.sh`) matches existing conventions.
- **2026-02-10**: Chose Playwright `page.evaluate()` for contrast extraction over headless browser screenshots + image analysis. Rationale: computed styles give exact colour values and element selectors; image analysis would require OCR and colour sampling with lower accuracy and no element mapping.
- **2026-02-10**: Decided to enhance existing `pagespeed-helper.sh` rather than duplicate Lighthouse functionality. Lighthouse already runs axe-core internally (subset of rules) — we surface those results and supplement with full axe-core + WAVE for comprehensive coverage.
- **2026-02-10**: WAVE API credentials stored via `aidevops secret set WAVE_API_KEY`. Never in config files or conversation. Credit tracking built into helper script to avoid unexpected costs.
- **2026-02-10**: Email accessibility checks split between email-health-check (static HTML analysis — lang, tables, alt, headings, inline styles) and email-design-test (rendered analysis — axe-core scan, contrast overlay on screenshots). This matches the existing split: health-check = pre-send validation, design-test = visual rendering verification.

### [2026-02-09] Content Creation Agent Architecture

**Status:** Completed
**Estimate:** ~8h (ai:5h test:2h read:1h)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p026,Content Creation Agent Architecture,completed,5,5,,content|architecture|multimedia|agents,8h,5h,2h,1h,2026-02-09T00:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Redesign the content creation agent layer to support multi-media (text, image, video, audio) and multi-channel (YouTube, TikTok, Instagram, blog, podcast, social, email, forums) content production from a single research-and-story foundation. Currently, content knowledge is scattered across domain-specific agents (youtube/, video.md, content/, seo/, social-media.md, voice/). This plan unifies them under a layered architecture: Research -> Story -> Production -> Distribution -> Optimization.

#### Context

**Problem:** Content isn't "a video" or "a blog post" -- it's a story expressed through different media and distributed across channels. The same research, narrative, and hooks can become a YouTube video, a blog post, a podcast episode, a social thread, a newsletter, a slideshow, or a book chapter. Current agent structure treats each output format as independent, duplicating research and strategy work.

**Knowledge sources ingested (session 2026-02-09):**

- 14 AI content creation guides (Miko's Lab) covering: niche selection, audience research (Reddit mining, 11-dimension framework), competitor reverse-engineering (Gemini 3), facial engineering for character consistency, Sora 2 Pro prompt structure (6-section master template), Veo 3.1 ingredients-to-video, seed bracketing (60% cost reduction), 8K camera model prompting, emotional block cues for natural AI speech, Nanobanana Pro JSON prompts for image gen, voice pipeline (CapCut -> ElevenLabs), slideshow workflows, UGC conversion frameworks, content agency production pipelines, A/B hook testing methodology
- YouTube competitor research system (channel intel, topic research, script writing, SEO optimization) -- merged as PR #811
- YouTube Data API v3 integration (youtube-helper.sh) with SA auth, quota tracking, 8 commands

**Existing agents that touch content creation:**

- `youtube.md` + `youtube/` -- YouTube-specific (channel-intel, topic-research, script-writer, optimizer, pipeline)
- `video.md` + `tools/video/` -- Remotion, Higgsfield, yt-dlp, video prompt design
- `tools/vision/` -- Image gen, understanding, editing
- `tools/voice/` -- TTS/STT, voice bridge, transcription
- `content.md` + `content/` -- Copywriting, editorial, platform personas
- `social-media.md` + `tools/social-media/` -- X, LinkedIn, Reddit
- `seo.md` + `seo/` -- SEO optimization
- `marketing.md` -- Marketing strategy

**Key design principle:** Tools stay in `tools/`, creative workflows live in `content/`, domain strategy stays in domain agents. Three layers, clean separation. The content layer orchestrates production using tools, and distribution agents adapt output for specific channels.

**The multi-media multiplier:** One research session produces one story, which fans out to: YouTube long-form, YouTube Short, blog post, X thread, LinkedIn article, Reddit post, newsletter, podcast segment, carousel, forum answer. The pipeline agent orchestrates this fan-out.

#### Decision Log

- **Decision:** Layered architecture (Research -> Story -> Production -> Distribution -> Optimization) not flat agent list
  **Rationale:** Content creation is a pipeline, not a collection of independent tools. Each layer feeds the next. Research is media-agnostic, Story is media-agnostic, Production is media-specific, Distribution is channel-specific. This prevents duplication and enables the multi-media multiplier.
  **Date:** 2026-02-09

- **Decision:** Extend existing `content.md` + `content/` rather than creating new top-level agent
  **Rationale:** `content.md` already exists as a domain agent. Expanding it preserves the existing agent hierarchy and avoids proliferating top-level agents. YouTube, SEO, social-media remain as distribution-layer references.
  **Date:** 2026-02-09

- **Decision:** YouTube agents stay YouTube-specific, reference general content layer
  **Rationale:** YouTube channel-intel, topic-research, script-writer, optimizer have YouTube-specific knowledge (API, algorithm, metadata). They should reference the general content production layer for media creation but keep their platform expertise. Same pattern for future TikTok, podcast, blog agents.
  **Date:** 2026-02-09

- **Decision:** PDF knowledge stored in memory + agent files, not referenced by source name
  **Rationale:** The guides are session inspiration. The extracted frameworks, prompts, and tactics become native aidevops knowledge attributed to the agent system, not to external products or creators.
  **Date:** 2026-02-09

<!--TOON:decisions[4]{id,plan_id,decision,rationale,date,impact}:
d063,p026,Layered architecture not flat agent list,Content creation is a pipeline where each layer feeds the next,2026-02-09,Architecture
d064,p026,Extend existing content.md not new top-level agent,Preserves hierarchy and avoids agent proliferation,2026-02-09,Architecture
d065,p026,YouTube agents stay YouTube-specific,Platform expertise stays in platform agents and references general layer,2026-02-09,Architecture
d066,p026,PDF knowledge stored natively not by source name,Extracted knowledge becomes native aidevops knowledge,2026-02-09,Scope
-->

#### Proposed Structure

```text
content.md (orchestrator -- multi-media, multi-channel content creation)
├── content/
│   ├── research.md          — Audience research, niche validation, competitor analysis
│   │                          Reddit mining (11-dimension framework), pain extraction,
│   │                          trend detection, creator brain cloning (transcript corpus),
│   │                          Gemini 3 video reverse-engineering, Whop/Google Trends validation
│   │
│   ├── story.md             — Narrative design: hooks, angles, frameworks, arcs
│   │                          Media-agnostic "what are we saying and why"
│   │                          Hook formulas (6-12 words), pattern interrupts,
│   │                          Before/During/After arcs, pain vs aspiration angles,
│   │                          4-part script framework, campaign audit process
│   │
│   ├── production/
│   │   ├── writing.md       — Long-form, short-form, scripts, copy, captions
│   │   ├── image.md         — Thumbnails, social graphics, illustrations
│   │   │                      Nanobanana Pro JSON, Midjourney, Ideogram, Seedream, Flux
│   │   │                      Style library system, annotated frame workflow
│   │   ├── video.md         — AI video generation, editing, post-production
│   │   │                      Sora 2 Pro (UGC), Veo 3.1 (cinematic), Higgsfield
│   │   │                      Seed bracketing, 8K camera prompting, model routing
│   │   │                      Shot-by-shot prompt structure, ingredients-to-video
│   │   ├── audio.md         — Voice, music, sound design
│   │   │                      ElevenLabs cloning, CapCut cleanup, emotional block cues
│   │   │                      4-layer audio design (dialogue, ambient, SFX, music)
│   │   └── characters.md    — Personas, facial engineering, character bibles,
│   │                          brand identity, visual consistency across outputs
│   │                          Sora 2 cameos, Veo 3.1 ingredients, character context profiles
│   │
│   ├── distribution/        — Channel-specific adaptation (references existing agents)
│   │   ├── youtube.md       → youtube/ subagents (channel-intel, topic-research, etc.)
│   │   ├── short-form.md    — TikTok, Reels, Shorts formatting + strategy
│   │   ├── social.md        → tools/social-media/ (X, LinkedIn, Reddit)
│   │   ├── blog.md          → seo/ for SEO writing, CMS publishing
│   │   ├── email.md         — Newsletter, sequences, campaigns
│   │   └── podcast.md       — Audio-first distribution
│   │
│   └── optimization.md      — A/B testing, analytics, iteration loops
│                               Hook testing (5-10 variants), seed bracketing,
│                               variant generation, kill/scale thresholds,
│                               slide-level retention, platform-specific metrics
```

#### Progress

- [ ] Phase 1: Research + Story agents ~2h (t199.1, t199.2)
  - Create `content/research.md` with Reddit mining framework, niche validation, competitor analysis, creator brain clone, Gemini 3 reverse-engineering
  - Create `content/story.md` with hook formulas, narrative arcs, pain/aspiration angles, campaign audit
  - Migrate relevant knowledge from existing `content/` editorial agents
- [ ] Phase 2: Production agents ~3h (t199.3, t199.4, t199.5, t199.6, t199.7)
  - Create `content/production/writing.md` -- scripts, copy, captions, long-form
  - Create `content/production/image.md` -- Nanobanana JSON, style libraries, thumbnail factory
  - Create `content/production/video.md` -- Sora 2/Veo 3.1/Higgsfield routing, seed bracketing, prompt structures
  - Create `content/production/audio.md` -- voice pipeline, emotional cues, sound design
  - Create `content/production/characters.md` -- facial engineering, character bibles, persona consistency
- [ ] Phase 3: Distribution + Optimization agents ~1.5h (t199.8, t199.9)
  - Create distribution reference agents (youtube, short-form, social, blog, email, podcast)
  - Create `content/optimization.md` -- A/B testing, variant generation, analytics loops
- [ ] Phase 4: Orchestrator + Integration ~1h (t199.10)
  - Rewrite `content.md` as the orchestrator that routes to research -> story -> production -> distribution
  - Update `subagent-index.toon` with new content/ structure
  - Update AGENTS.md progressive disclosure table
- [ ] Phase 5: Verify + PR ~30m (t199.11)
  - ShellCheck any new scripts
  - Verify all cross-references resolve
  - Create PR

#### Surprises & Discoveries

- Google silently changed OAuth2 JWT grant type URI from `urn:ietf:params:oauth:2.0:jwt-bearer` to `urn:ietf:params:oauth:grant-type:jwt-bearer` -- documented in youtube-helper.sh
- Seed bracketing (testing seeds 1000-1010 per prompt) reduces AI video generation costs by 60% and raises success rate from 15% to 70%+
- Veo 3.1 "Ingredients to Video" has solved character consistency -- upload face as ingredient, stays consistent across scenes. Frame-to-video produces inferior grainy output.
- The 8K camera model prompt technique (appending specific camera model like "RED Komodo 6K") is described as the single biggest quality uplift for AI video generation
- Emotional block cues (per-word emotion tagging) dramatically improve AI speech naturalness
- Nanobanana Pro's visual annotation on starting frames is more effective than text-only prompts for controlling video model output
- Reddit audience research (exact pain language, failed solutions, purchase triggers) is the #1 differentiator between content that converts and content that doesn't

### [2026-02-08] Git Issues Bi-directional Sync

**Status:** In Progress (Phase 1/7)
**Estimate:** ~3h (ai:1.5h test:1h read:30m)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started}:
p025,Git Issues Bi-directional Sync,in_progress,1,7,,git|sync|planning|github,3h,1.5h,1h,30m,2025-12-21T16:30Z,2026-02-08T00:00Z
-->

#### Purpose

Create `issue-sync-helper.sh` — a dedicated bi-directional sync tool between TODO.md/PLANS.md and GitHub issues. Consolidates scattered issue sync code from supervisor-helper.sh, github-cli-helper.sh, and log-issue-helper.sh into a single authoritative helper. Composes rich GitHub issue bodies that include subtasks, plan context (purpose, decisions, discoveries), and related PRD/task files.

#### Context

**Existing pieces to consolidate:**

- `supervisor-helper.sh` `create_github_issue()` (line 4612) — creates bare-bones issues from task ID + one-liner
- `supervisor-helper.sh` `update_todo_with_issue_ref()` (line 4712) — adds `ref:GH#NNN` to TODO.md
- `github-cli-helper.sh` `create_issue()` / `close_issue()` — generic gh wrapper, no TODO awareness
- `log-issue-helper.sh` — diagnostics + issue search for bug reporting
- `beads-sync-helper.sh` — bi-directional TODO.md ↔ Beads (pattern to follow)
- `workflows/plans.md` lines 733-778 — documents the sync convention (spec to implement)

**Current state:** 46 open GitHub issues (#496-#541) created manually from TODO.md. Issue bodies contain only the one-liner from TODO.md. No PLANS.md context, no subtask lists, no `#tag` → label mapping, no close-on-complete, no drift detection.

**Absorbs t047** (cross-platform tools research) — GitHub first, GitLab/Gitea deferred to Phase 2.

#### Decision Log

- **Decision:** Dedicated helper script, not extension of supervisor-helper.sh
  **Rationale:** supervisor-helper.sh is already 4700+ lines. Issue sync is a standalone concern usable by humans, supervisor, and other scripts. Supervisor delegates to it.
  **Date:** 2026-02-08

- **Decision:** GitHub first, platform abstraction later
  **Rationale:** All current repos are on GitHub. GitLab/Gitea support (t047 scope) deferred until GitHub sync is proven. Platform abstraction via function dispatch (github_create_issue, gitlab_create_issue, etc.).
  **Date:** 2026-02-08

- **Decision:** TODO.md is source of truth, GitHub issues are projections
  **Rationale:** Consistent with existing beads-sync pattern. TODO.md has richer structure (subtasks, TOON blocks, plan links). Issues are the public-facing view.
  **Date:** 2026-02-08

<!--TOON:decisions[3]{id,plan_id,decision,rationale,date,impact}:
d060,p025,Dedicated helper script not supervisor extension,Supervisor is 4700+ lines and issue sync is standalone concern,2026-02-08,Architecture
d061,p025,GitHub first platform abstraction later,All repos on GitHub and GitLab/Gitea deferred until proven,2026-02-08,Scope
d062,p025,TODO.md is source of truth,Consistent with beads-sync and richer structure,2026-02-08,Architecture
-->

#### Progress

- [ ] (2026-02-08) Phase 1: Build core TODO.md parser + rich issue body composer ~45m (t020.1)
  - Parse task line: ID, description, tags, estimate, status, refs, plan link
  - Parse all subtasks (indented `- [ ]` lines) with their status
  - Parse Notes blocks
  - Compose structured GitHub issue body with sections
- [ ] (2026-02-08) Phase 2: PLANS.md section extraction + todo/tasks/ lookup ~30m (t020.2)
  - Follow `→ [todo/PLANS.md#anchor]` links to extract plan section
  - Include: Purpose, Progress (with checkbox status), Decision Log, Discoveries
  - Check `todo/tasks/` for matching `prd-*.md` and `tasks-*.md` files
  - Append as collapsible `<details>` sections in issue body
- [ ] (2026-02-08) Phase 3: #tag → GitHub label mapping + push/enrich ~30m (t020.3)
  - Map TODO.md `#tags` to existing GitHub labels
  - `push` command: create issues for tasks without `ref:GH#`
  - `enrich` command: update existing issue bodies with full context
- [ ] (2026-02-08) Phase 4: Pull command (GH → TODO.md) ~30m (t020.4)
  - Detect issues created on GitHub without TODO.md entry
  - Add `ref:GH#NNN` to TODO.md tasks missing it
  - Sync label changes back to `#tags`
- [ ] (2026-02-08) Phase 5: Close + status commands ~30m (t020.5)
  - `close`: when TODO.md task marked `[x]`, close matching GH issue
  - `status`: show drift (tasks without issues, issues without tasks, stale)
- [ ] (2026-02-08) Phase 6: Wire supervisor delegation ~15m (t020.6)
  - Supervisor's `create_github_issue()` calls `issue-sync-helper.sh push tNNN`
  - Remove duplicated logic from supervisor-helper.sh
- [ ] (2026-02-08) Phase 7: Test + enrich existing 46 issues ~15m (t020.7)
  - Run `enrich` on all plan-linked issues (#496, #497, #498, #500, #501, #504)
  - Verify all 46 issues have matching `ref:GH#` in TODO.md

<!--TOON:milestones[7]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m114,p025,Phase 1: Core TODO.md parser + rich issue body composer,45m,,2026-02-08T00:00Z,,in_progress
m115,p025,Phase 2: PLANS.md section extraction + todo/tasks/ lookup,30m,,2026-02-08T00:00Z,,pending
m116,p025,Phase 3: Tag-to-label mapping + push/enrich commands,30m,,2026-02-08T00:00Z,,pending
m117,p025,Phase 4: Pull command (GH → TODO.md),30m,,2026-02-08T00:00Z,,pending
m118,p025,Phase 5: Close + status commands,30m,,2026-02-08T00:00Z,,pending
m119,p025,Phase 6: Wire supervisor delegation,15m,,2026-02-08T00:00Z,,pending
m120,p025,Phase 7: Test + enrich existing 46 issues,15m,,2026-02-08T00:00Z,,pending
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

### [2026-02-07] Plugin System for Private Extension Repos

**Status:** Completed
**Estimate:** ~1d (ai:6h test:3h read:3h)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p024,Plugin System for Private Extension Repos,completed,5,5,,architecture|plugins|private-repos|extensibility,1d,6h,3h,3h,2026-02-07T00:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Create a plugin architecture for aidevops that allows private extension repos (`aidevops-pro`, `aidevops-anon`) to overlay additional agents and scripts onto the base framework. Plugins are git repos that extend aidevops without modifying the core, enabling tiered access (public/pro/private) and fast evolution of specialized features.

#### Context from Discussion

**Repos to support:**

- `~/Git/aidevops-pro` (github.com/marcusquinn/aidevops-pro) - Pro features
- `~/Git/aidevops-anon` (gitea.marcusquinn.com/marcus/aidevops-anon) - Anonymous/private features

**Key design decisions:**

1. **Namespaced directories** - Plugins get their own namespace to avoid clashes:

   ```
   ~/.aidevops/agents/
   ├── tools/              # Main repo
   ├── pro.md              # Plugin entry point (like wordpress.md)
   ├── pro/                # Plugin subagents
   │   ├── enterprise.md
   │   └── advanced.md
   └── scripts/
       └── pro-*.sh        # Prefixed scripts
   ```

2. **Plugin structure mirrors main** - Same `.agents/` pattern:

   ```
   ~/Git/aidevops-pro/
   ├── AGENTS.md           # Points to main framework
   ├── README.md
   ├── VERSION
   ├── .aidevops.json      # Plugin config with base_repo reference
   └── .agents/
       ├── pro.md          # Main plugin agent
       ├── pro/            # Subagents
       └── scripts/
           └── pro-*.sh    # Prefixed scripts
   ```

3. **Plugin AGENTS.md points to base** - Minimal, references main framework:

   ```markdown
   # aidevops-pro Plugin

   For framework documentation: `~/.aidevops/agents/AGENTS.md`
   For architecture: `~/.aidevops/agents/aidevops/architecture.md`

   ## Plugin Development

   This plugin deploys to `~/.aidevops/agents/pro/` (namespaced).
   ```

4. **`.aidevops.json` plugin config**:

   ```json
   {
     "version": "2.93.2",
     "features": ["planning"],
     "plugin": {
       "name": "pro",
       "base_repo": "~/Git/aidevops",
       "namespace": "pro"
     }
   }
   ```

5. **`aidevops update` deploys main + plugins** - Single command updates everything

**CI/CD for private repos (simplified):**

- No SonarCloud/Codacy/CodeRabbit (require public repos for free tier)
- Local-only: `linters-local.sh` (ShellCheck, Secretlint, Markdownlint)
- Minimal GHA: ShellCheck + Secretlint + Markdownlint only
- Gitea: Local linting only (or Gitea Actions if enabled)

**Development workflow:**

- Work in plugin repo directly (`~/Git/aidevops-pro/`)
- Run `aidevops update` to redeploy all (main + plugins)
- Plugin changes immediately visible in `~/.aidevops/agents/pro/`
- AI assistant reads plugin AGENTS.md which points to main framework docs

**Symlink option for rapid iteration:**

- `.plugin-dev/` in main repo (gitignored)
- Symlinks to plugin `.agents/` directories
- Useful when testing plugin content against main repo changes

#### Decision Log

- **Decision:** Namespaced directories (`pro.md` + `pro/`) not overlay
  **Rationale:** Overlay model causes collisions if main adds same path later. Namespace guarantees no conflicts.
  **Date:** 2026-02-07

- **Decision:** Plugin AGENTS.md points to main framework, not duplicates
  **Rationale:** Single source of truth for framework docs. Plugins only document their additions.
  **Date:** 2026-02-07

- **Decision:** Minimal CI for private repos (local linting only)
  **Rationale:** SonarCloud/Codacy/CodeRabbit require public repos for free tier. ShellCheck/Secretlint/Markdownlint work locally.
  **Date:** 2026-02-07

- **Decision:** `aidevops init` detects plugin repos via `.aidevops.json` plugin field
  **Rationale:** Consistent initialization, AI assistants know it's a plugin context.
  **Date:** 2026-02-07

<!--TOON:decisions[4]{id,plan_id,decision,rationale,date,impact}:
d056,p024,Namespaced directories not overlay,Overlay causes collisions if main adds same path later,2026-02-07,Architecture
d057,p024,Plugin AGENTS.md points to main framework,Single source of truth for framework docs,2026-02-07,Maintenance
d058,p024,Minimal CI for private repos,Cloud tools require public repos for free tier,2026-02-07,DevOps
d059,p024,aidevops init detects plugin repos,Consistent initialization and AI context,2026-02-07,UX
-->

#### Open Questions

1. **License** - Same MIT for plugins, or proprietary for pro/anon?
2. **Gitea Actions** - Is it enabled on gitea.marcusquinn.com, or local-only linting?
3. **Plugin order** - If multiple plugins, what's the deploy order? (alphabetical? config-defined?)
4. **Subagent index** - Should plugins add entries to main `subagent-index.toon` or have their own?

#### Progress

- [ ] (2026-02-07) Phase 1: Add plugin support to `.aidevops.json` schema ~1h (t136.1)
  - Add `plugin` field with `name`, `base_repo`, `namespace`
  - Update `aidevops init` to detect and configure plugin repos
  - Add `features: ["plugin"]` option
- [ ] (2026-02-07) Phase 2: Add `plugins.json` config and CLI commands ~2h (t136.2)
  - Create `~/.config/aidevops/plugins.json` schema
  - Add `aidevops plugin add/list/enable/disable/remove/update` commands
  - Support GitHub and Gitea URLs
- [ ] (2026-02-07) Phase 3: Extend `setup.sh` to deploy plugins ~2h (t136.3)
  - Add `deploy_plugins()` function after `deploy_aidevops_agents()`
  - Respect namespace (deploy to `~/.aidevops/agents/{namespace}/`)
  - Handle script prefix convention (`{namespace}-*.sh`)
- [ ] (2026-02-07) Phase 4: Create plugin template ~1h (t136.4)
  - `aidevops plugin create <name>` scaffolds structure
  - Template AGENTS.md, README.md, .aidevops.json, .github/workflows/ci.yml
  - Minimal GHA (ShellCheck + Secretlint + Markdownlint)
- [ ] (2026-02-07) Phase 5: Scaffold aidevops-pro and aidevops-anon repos ~2h (t136.5)
  - Create repos on GitHub and Gitea
  - Initialize with plugin template
  - Test full workflow: clone → init → update → verify deployment

<!--TOON:milestones[5]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m109,p024,Phase 1: Add plugin support to .aidevops.json schema,1h,,2026-02-07T00:00Z,,pending
m110,p024,Phase 2: Add plugins.json config and CLI commands,2h,,2026-02-07T00:00Z,,pending
m111,p024,Phase 3: Extend setup.sh to deploy plugins,2h,,2026-02-07T00:00Z,,pending
m112,p024,Phase 4: Create plugin template,1h,,2026-02-07T00:00Z,,pending
m113,p024,Phase 5: Scaffold aidevops-pro and aidevops-anon repos,2h,,2026-02-07T00:00Z,,pending
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

### [2026-02-07] Codebase Quality Hardening

**Status:** Completed
**Estimate:** ~3d (ai:1.5d test:1d read:0.5d)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p023,Codebase Quality Hardening,completed,14,14,,quality|hardening|shell|security|testing|ci,3d,1.5d,1d,0.5d,2026-02-07T00:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Address findings from Claude Opus 4.6 full codebase review. Harden shell script quality, fix security issues, improve CI enforcement, and build test infrastructure. All tasks designed for autonomous `/runners` dispatch with non-destructive approach (archive, don't delete).

#### Context from Review

**Review corrections (verified against actual codebase):**

- Review claimed 168/170 scripts missing `set -e` -- actual count is **70/170** (100 already have it)
- Review claimed 17% shared-constants.sh adoption -- confirmed **29/170 scripts** source it
- Review claimed 95 scripts with blanket ShellCheck disable -- confirmed **95 scripts**
- Review claimed 12 dead fix scripts -- confirmed **12 scripts with 0 non-script references**, all only touched by `.agent->.agents` rename commit

**Rejected recommendation:**

- **#10 (organize scripts by domain subdirectories)** -- REJECTED. Scripts are intentionally cross-domain (e.g., `seo-export-helper.sh` used by SEO, git, and content workflows). Flat namespace with `{service}-helper.sh` naming convention is the design pattern. Subdirectories would create import path complexity and break existing references.

**Key design principles for all changes:**

1. Read existing code to understand intent before modifying
2. Non-destructive: archive, don't delete; preserve knowledge
3. Test for regressions after every change
4. Each subtask is self-contained for `/runners` dispatch
5. Respect existing patterns -- don't impose new conventions without understanding why current ones exist

#### Decision Log

- (2026-02-07) REJECTED script subdirectory organization -- cross-domain usage makes flat namespace correct
- (2026-02-07) Changed "remove dead scripts" to "archive non-destructively" -- scripts contain fix patterns that may be useful reference
- (2026-02-07) Corrected review's `set -e` count from 168 to 70 missing -- review overcounted significantly

#### Progress

- [ ] (2026-02-07) Phase 1 (P0-A): Add `set -euo pipefail` to 70 scripts ~4h (t135.1)
  - Audit each script for commands that intentionally return non-zero (grep no-match, diff, test)
  - Add `|| true` guards where needed before enabling strict mode
  - Add `set -euo pipefail` after shebang/shellcheck-disable line
  - Run `bash -n` syntax check + shellcheck on all modified scripts
  - Smoke test `help` command for each modified script
  - **Scripts without set -e:** 101domains-helper, add-missing-returns, agent-browser-helper, agno-setup, ampcode-cli, auto-version-bump, closte-helper, cloudron-helper, codacy-cli-chunked, codacy-cli, code-audit-helper, coderabbit-cli, coderabbit-pro-analysis, comprehensive-quality-fix, coolify-helper, crawl4ai-examples, crawl4ai-helper, dns-helper, domain-research-helper, dspy-helper, dspyground-helper, efficient-return-fix, find-missing-returns, fix-auth-headers, fix-common-strings, fix-content-type, fix-error-messages, fix-misplaced-returns, fix-remaining-literals, fix-return-statements, fix-s131-default-cases, fix-sc2155-simple, fix-shellcheck-critical, fix-string-literals, git-platforms-helper, hetzner-helper, hostinger-helper, linter-manager, localhost-helper, markdown-formatter, markdown-lint-fix, mass-fix-returns, monitor-code-review, pandoc-helper, peekaboo-helper, qlty-cli, quality-cli-manager, secretlint-helper, servers-helper, ses-helper, setup-linters-wizard, setup-local-api-keys, shared-constants, sonarscanner-cli, spaceship-helper, stagehand-helper, stagehand-python-helper, stagehand-python-setup, stagehand-setup, test-stagehand-both-integration, test-stagehand-integration, test-stagehand-python-integration, toon-helper, twilio-helper, vaultwarden-helper, version-manager, watercrawl-helper, webhosting-helper, webhosting-verify, wordpress-mcp-helper, yt-dlp-helper
- [ ] (2026-02-07) Phase 2 (P0-B): Replace blanket ShellCheck disables ~8h (t135.2)
  - Run shellcheck without blanket disable on each of 95 scripts
  - Categorize violations: genuine bugs vs intentional patterns
  - Fix SC2086 (unquoted vars) and SC2155 (declare/assign) where safe
  - Add targeted inline `# shellcheck disable=SCXXXX` with reason comments
  - Remove blanket disable line from each script
  - Verify zero violations with `linters-local.sh`
- [ ] (2026-02-07) Phase 3 (P0-C): SQLite WAL mode + busy_timeout ~2h (t135.3)
  - Read DB init in supervisor-helper.sh, memory-helper.sh, mail-helper.sh
  - Add `PRAGMA journal_mode=WAL; PRAGMA busy_timeout=5000;` to init functions
  - Test concurrent access from parallel agent sessions
  - Currently: no WAL mode, no busy_timeout in any of the 3 SQLite-backed systems
- [ ] (2026-02-07) Phase 4 (P1-A): Fix corrupted JSON configs ~1h (t135.4)
  - `configs/pandoc-config.json` -- invalid control character at line 5 column 6
  - `configs/mcp-templates/chrome-devtools.json` -- shell code (`return 0`) appended after valid JSON at line 15
  - Add JSON validation step to CI workflow
- [ ] (2026-02-07) Phase 5 (P1-B): Remove tracked artifacts ~30m (t135.5)
  - `git rm --cached` 6 files: `.scannerwork/.sonar_lock`, `.scannerwork/report-task.txt`, `.playwright-cli/` (4 files)
  - Add `.playwright-cli/` to `.gitignore`
  - `.scannerwork/` already in `.gitignore` (just needs cache clearing)
- [ ] (2026-02-07) Phase 6 (P1-C): Fix CI code-quality.yml ~1h (t135.6)
  - Line 31: `.agent` typo (should be `.agents`)
  - References to non-existent `.agents/spec` and `docs/` directories
  - Add enforcement steps that actually fail the build on violations
- [ ] (2026-02-07) Phase 7 (P2-A): Eliminate eval in 4 scripts ~3h (t135.7)
  - `wp-helper.sh:240` -- `eval "$ssh_command"` (SSH command construction)
  - `coderabbit-cli.sh:322,365` -- `eval "$cmd"` (CLI command construction)
  - `codacy-cli.sh:260,315` -- `eval "$cmd"` (CLI command construction)
  - `pandoc-helper.sh:120` -- `eval "$pandoc_cmd"` (pandoc command construction)
  - Replace with array-based command construction (same pattern used in t105 for ampcode-cli.sh)
  - Read each context first to understand what's being constructed and why
- [ ] (2026-02-07) Phase 8 (P2-B): Increase shared-constants.sh adoption ~4h (t135.8)
  - Currently 29/170 scripts source shared-constants.sh (17%)
  - 431 duplicate print_info/error/success/warning definitions across scripts
  - Audit what shared-constants.sh provides vs what scripts duplicate
  - Create migration script, run in batches with regression testing
- [ ] (2026-02-07) Phase 9 (P2-C): Add trap cleanup for temp files ~1h (t135.9)
  - 14 mktemp usages in setup.sh, only 4 scripts total have trap cleanup
  - Add `trap 'rm -f "$tmpfile"' EXIT` patterns
  - Respect existing cleanup logic (don't double-cleanup)
- [ ] (2026-02-07) Phase 10 (P2-D): Fix package.json main field ~15m (t135.10)
  - `"main": "index.js"` but index.js doesn't exist
  - Determine if index.js is needed or remove main field
- [ ] (2026-02-07) Phase 11 (P2-E): Fix Homebrew formula ~2h (t135.11)
  - Frozen at v2.52.1 with `PLACEHOLDER_SHA256`
  - Current version is v2.104.0
  - Add formula version/SHA update to version-manager.sh release workflow
- [ ] (2026-02-07) Phase 12 (P3-A): Archive fix scripts non-destructively ~1h (t135.12)
  - 12 scripts with 0 references outside scripts/: add-missing-returns, comprehensive-quality-fix, efficient-return-fix, find-missing-returns, fix-common-strings, fix-misplaced-returns, fix-remaining-literals, fix-return-statements, fix-sc2155-simple, fix-shellcheck-critical, fix-string-literals, mass-fix-returns
  - All only touched by `.agent->.agents` rename commit (c91e0be)
  - Read each to document purpose and patterns (preserve knowledge)
  - Create `.agents/scripts/_archive/` with README (underscore prefix sorts to top of file lists)
  - Move (not delete) so git history and fix patterns are preserved
- [ ] (2026-02-07) Phase 13 (P3-B): Build test suite ~4h (t135.13)
  - Fix `tests/docker/run-tests.sh:5` path case (`git` vs `Git`)
  - Add help command smoke tests for all 170 scripts
  - Add unit tests for supervisor-helper.sh state machine
  - Add unit tests for memory-helper.sh and mail-helper.sh
- [ ] (2026-02-07) Phase 14 (P3-C): Standardize shebangs ~30m (t135.14)
  - Most use `#!/bin/bash`, supervisor-helper.sh uses `#!/usr/bin/env bash`
  - Standardize all to `#!/usr/bin/env bash` for portability

### [2026-02-06] Cross-Provider Model Routing with Fallbacks

**Status:** Completed
**Estimate:** ~1.5d (ai:8h test:4h read:2h)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p022,Cross-Provider Model Routing with Fallbacks,completed,8,8,,orchestration|multi-model|routing|fallback|opencode,1.5d,8h,4h,2h,2026-02-06T22:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Enable cross-provider model routing so that any aidevops session can dispatch tasks to the optimal model regardless of which provider the parent session runs on. A Claude session should be able to request a Gemini code review; a Gemini session should be able to escalate complex reasoning to Claude Opus. Models should fall back gracefully when unavailable, and the system should detect when provider/model names change upstream.

#### Context from Discussion

**Current state:**

- `model-routing.md` exists as a design doc with 5 tiers (haiku/flash/sonnet/pro/opus) and routing rules
- All 195 subagents have `model:` in YAML frontmatter, but it's advisory only
- `runner-helper.sh` supports `--model` but hardcodes `DEFAULT_MODEL` to a single Claude model
- No fallback, no availability checking, no quality-based escalation

**Key discovery (Context7 research):**

- OpenCode already supports per-agent model selection natively across 75+ providers
- The Task tool does NOT accept a model parameter -- by design
- Instead, each subagent definition in `opencode.json` can specify its own `model:` field
- The primary agent selects a model by choosing WHICH subagent to invoke
- Provider-level fallback is available via gateway providers (OpenRouter `allow_fallbacks`, Vercel AI Gateway `order`)
- No application-level automatic fallback exists in OpenCode itself

**Implication:** We don't need to patch the Task tool. We need to:

1. Define model-specific subagents in opencode.json (e.g., `gemini-reviewer`, `claude-auditor`)
2. Map our tier system to concrete agent definitions
3. Build fallback/escalation logic in supervisor-helper.sh
4. Periodically reconcile our model registry against upstream provider changes

#### Progress

- [ ] (2026-02-06) Phase 1: Define model-specific subagents in opencode.json ~2h (t132.1)
  - Create subagent definitions: gemini-reviewer, gemini-analyst, gpt-reviewer, claude-auditor, etc.
  - Map model-routing.md tiers to concrete agent definitions
  - Each agent gets appropriate tool permissions and instructions
  - Test cross-provider dispatch from Claude session to Gemini subagent
- [ ] (2026-02-06) Phase 2: Provider/model registry with periodic sync ~2h (t132.2)
  - Create model-registry-helper.sh
  - Scrape available models from OpenCode config / Models.dev / provider APIs
  - Compare against configured models in opencode.json and model-routing.md
  - Flag deprecated/renamed/unavailable models
  - Suggest new models worth adding (e.g., new Gemini/Claude/GPT releases)
  - Run on `aidevops update` and optionally via cron
  - Store registry in SQLite alongside memory/mail DBs
- [ ] (2026-02-06) Phase 3: Model availability checker ~2h (t132.3)
  - Probe provider endpoints before dispatch (lightweight health check)
  - Check API key validity, rate limits, model availability
  - Support: Anthropic, Google, OpenAI, local (Ollama)
  - Return latency estimate, cache results with short TTL
  - Integrate with registry (skip probing models already flagged unavailable)
- [ ] (2026-02-06) Phase 4: Fallback chain configuration ~2h (t132.4)
  - Define fallback chains: gemini-3-pro -> gemini-2.5-pro -> claude-sonnet-4 -> claude-haiku
  - Configurable per subagent (frontmatter `fallback:` field), per runner, and global default
  - Triggers: API error, timeout, rate limit, empty/malformed response
  - Gateway-level fallback via OpenRouter/Vercel for provider failures
  - Supervisor-level fallback via re-dispatch to different subagent for task failures
- [ ] (2026-02-06) Phase 5: Supervisor model resolution ~2h (t132.5)
  - supervisor-helper.sh reads `model:` from subagent frontmatter
  - Maps tier names to corresponding subagent definitions in opencode.json
  - Uses availability checker before dispatch
  - Falls back through chain by re-dispatching to different model-specific subagent
- [ ] (2026-02-06) Phase 6: Quality gate with model escalation ~3h (t132.6)
  - After task completion, evaluate output quality (heuristic + AI eval)
  - If unsatisfactory, re-dispatch to next tier up via higher-tier subagent
  - Criteria: empty output, error patterns, token-to-substance ratio, user-defined checks
  - Max escalation depth configurable (default: 2 levels)
- [ ] (2026-02-06) Phase 7: Runner and cron-helper multi-provider support ~2h (t132.7)
  - Extend --model flag to accept tier names (not just provider/model strings)
  - Add --provider flag for explicit provider selection
  - Support Gemini CLI, OpenCode server, Claude CLI as dispatch backends
  - Auto-detect available backends at startup
- [ ] (2026-02-06) Phase 8: Cross-model review workflow ~2h (t132.8)
  - Second-opinion pattern: dispatch same task to multiple models
  - Collect results, merge/diff findings
  - Use cases: code review, security audit, architecture review
  - Configurable via `review-models:` in task metadata or CLI flag

<!--TOON:milestones[8]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m101,p022,Phase 1: Define model-specific subagents in opencode.json,2h,,2026-02-06T22:00Z,,pending
m102,p022,Phase 2: Provider/model registry with periodic sync,2h,,2026-02-06T22:00Z,,pending
m103,p022,Phase 3: Model availability checker,2h,,2026-02-06T22:00Z,,pending
m104,p022,Phase 4: Fallback chain configuration,2h,,2026-02-06T22:00Z,,pending
m105,p022,Phase 5: Supervisor model resolution,2h,,2026-02-06T22:00Z,,pending
m106,p022,Phase 6: Quality gate with model escalation,3h,,2026-02-06T22:00Z,,pending
m107,p022,Phase 7: Runner and cron-helper multi-provider support,2h,,2026-02-06T22:00Z,,pending
m108,p022,Phase 8: Cross-model review workflow,2h,,2026-02-06T22:00Z,,pending
-->

#### Decision Log

- **Decision:** Use OpenCode per-agent model selection, not Task tool model parameter
  **Rationale:** OpenCode's architecture routes models via agent definitions, not per-call parameters. The Task tool selects a model by invoking a subagent that has that model configured. This is by design and works across 75+ providers.
  **Date:** 2026-02-06

- **Decision:** Periodic model registry sync rather than static configuration
  **Rationale:** Provider/model names are a moving target -- models get renamed (e.g., gemini-2.0-flash-001 -> gemini-2.0-flash), deprecated, or replaced by new versions. A registry that periodically reconciles against upstream prevents silent dispatch failures.
  **Date:** 2026-02-06

- **Decision:** Two-layer fallback (gateway + supervisor)
  **Rationale:** Gateway-level fallback (OpenRouter/Vercel) handles provider outages transparently. Supervisor-level fallback handles task-quality failures by re-dispatching to a different model-specific subagent. Neither layer alone covers both failure modes.
  **Date:** 2026-02-06

<!--TOON:decisions[3]{id,plan_id,decision,rationale,date,impact}:
d053,p022,Use OpenCode per-agent model selection not Task tool param,Architecture routes models via agent definitions across 75+ providers,2026-02-06,Architecture
d054,p022,Periodic model registry sync,Provider/model names change -- prevents silent dispatch failures,2026-02-06,Reliability
d055,p022,Two-layer fallback gateway + supervisor,Gateway handles provider outages and supervisor handles task-quality failures,2026-02-06,Architecture
-->

#### Surprises & Discoveries

- **Discovery:** OpenCode per-agent model selection already works but we never configured it
  **Evidence:** Context7 research confirmed `model:` field in agent JSON config is a first-class feature. Our opencode.json has no model fields on any agent definition despite having 12+ agents configured.
  **Impact:** Phase 1 is immediately actionable -- no upstream changes needed.
  **Date:** 2026-02-06

- **Discovery:** Duplicate TOON milestone IDs (m095-097) between p019 and p021
  **Evidence:** Both Voice Integration Pipeline (p019) and gopass Integration (p021) use m095-097.
  **Impact:** Need to renumber p021 milestones in a future cleanup. Using m101+ for this plan.
  **Date:** 2026-02-06

<!--TOON:discoveries[2]{id,plan_id,observation,evidence,impact,date}:
s015,p022,OpenCode per-agent model selection already works but unconfigured,Context7 confirmed model field is first-class feature,Phase 1 immediately actionable,2026-02-06
s016,p022,Duplicate TOON milestone IDs m095-097 between p019 and p021,Both plans use same IDs,Need renumbering cleanup,2026-02-06
-->

### [2026-02-06] gopass Integration & Credentials Rename

**Status:** Completed
**Estimate:** ~2d (ai:1d test:4h read:4h)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p021,gopass Integration & Credentials Rename,completed,3,3,,security|credentials|gopass|rename,2d,1d,4h,4h,2026-02-06T20:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Replace plaintext `mcp-env.sh` credential storage with gopass (GPG-encrypted, git-versioned, team-shareable). Build an AI-native wrapper (`aidevops secret`) that keeps secret values out of agent context windows via subprocess injection and output redaction. Rename `mcp-env.sh` to `credentials.sh` across the entire codebase for accuracy.

#### Context from Discussion

Evaluated 5 tools: gopass (6.7k stars, 8+ years, GPG/age, team-ready), psst (61 stars, AI-native but v0.3.0), mcp-secrets-vault (4 stars, env var wrapper), rsec (7 stars, cloud vaults only), cross-keychain (library, not CLI). gopass selected as primary for maturity, zero runtime deps, team sharing, and ecosystem (browser integration, git credentials, Kubernetes, Terraform). psst documented as alternative for solo devs who prefer simpler UX.

Key design decisions:

- gopass as encrypted backend, thin shell wrapper for AI-native features (subprocess injection + output redaction)
- Rename mcp-env.sh to credentials.sh (83 files, 261 references) with backward-compatible symlink
- credentials.sh kept as fallback for MCP server launching and non-gopass workflows
- Agent instructions mandate: never accept secrets in conversation context

#### Progress

- [ ] (2026-02-06) Part A: Rename mcp-env.sh to credentials.sh ~4.5h
  - 7 scripts: variable rename `MCP_ENV_FILE` to `CREDENTIALS_FILE`
  - ~18 scripts: path string updates
  - ~65 docs: path reference updates
  - setup.sh: migration logic + symlink
  - Verification: `rg 'mcp-env'` returns 0
- [ ] (2026-02-06) Part B: gopass integration + aidevops secret wrapper ~6h
  - gopass.md subagent documentation
  - secret-helper.sh (init, set, list, run, import-credentials)
  - Output redaction function
  - credential-helper.sh gopass detection
  - setup.sh gopass installation
  - api-keys tool update
- [ ] (2026-02-06) Part C: Agent instructions + documentation ~2h
  - AGENTS.md: mandatory "never accept secrets in context" rule
  - psst.md: documented alternative
  - Security docs update
  - Onboarding update

<!--TOON:milestones[3]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m095,p021,Part A: Rename mcp-env.sh to credentials.sh,4.5h,,2026-02-06T20:00Z,,pending
m096,p021,Part B: gopass integration + aidevops secret wrapper,6h,,2026-02-06T20:00Z,,pending
m097,p021,Part C: Agent instructions + documentation,2h,,2026-02-06T20:00Z,,pending
-->

#### Decision Log

- **Decision:** gopass over psst as primary secrets backend
  **Rationale:** 6.7k stars, 224 contributors, GPG/age encryption (audited), git-versioned, team-shareable, single Go binary (zero runtime deps), 8+ years production use. psst is v0.3.0 with 61 stars, Bun dependency, no team features, custom unaudited AES-256-GCM.
  **Date:** 2026-02-06

- **Decision:** Rename mcp-env.sh to credentials.sh
  **Rationale:** File stores credentials for agents, scripts, skills, MCP servers, and CLI tools -- not just MCP environment variables. "credentials.sh" is accurate and tool-agnostic.
  **Date:** 2026-02-06

- **Decision:** Keep credentials.sh as fallback alongside gopass
  **Rationale:** MCP server configs need env vars at launch time (can't wrap in subprocess). credentials.sh remains the backward-compatible bridge.
  **Date:** 2026-02-06

- **Decision:** Build thin shell wrapper, not fork psst
  **Rationale:** The AI-native gap (subprocess injection + output redaction) is ~50 lines of shell on top of gopass. The hard part (encryption, key management, team sharing, auditing) is what gopass already does.
  **Date:** 2026-02-06

<!--TOON:decisions[4]{id,plan_id,decision,rationale,date,impact}:
d028,p021,gopass over psst as primary,Mature GPG encryption + team sharing + zero deps vs immature AI-native tool,2026-02-06,high
d029,p021,Rename mcp-env.sh to credentials.sh,File stores credentials for all tools not just MCP,2026-02-06,medium
d030,p021,Keep credentials.sh as fallback,MCP server configs need env vars at launch time,2026-02-06,medium
d031,p021,Build thin shell wrapper not fork psst,AI-native gap is ~50 lines of shell on top of gopass,2026-02-06,high
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

### [2026-02-03] Install Script Integrity Hardening

**Status:** Completed
**Estimate:** ~4h (ai:2h test:1h read:1h)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p016,Install Script Integrity Hardening,completed,4,4,,security|supply-chain|setup,4h,2h,1h,1h,2026-02-03T00:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Eliminate `curl | sh` installs by downloading scripts to disk, verifying integrity (checksum or signature), and executing locally. This reduces supply-chain exposure in setup and helper scripts.

#### Context from Discussion

Targets include:

- `setup.sh` (multiple install blocks)
- `.agents/scripts/qlty-cli.sh`
- `.agents/scripts/coderabbit-cli.sh`
- `.agents/scripts/dev-browser-helper.sh`

#### Progress

- [ ] (2026-02-03) Phase 1: Inventory all `curl|sh` usages and vendor verification options ~45m
- [ ] (2026-02-03) Phase 2: Replace with download → verify → execute flow ~2h
- [ ] (2026-02-03) Phase 3: Add fallback behavior and clear error messages ~45m
- [ ] (2026-02-03) Phase 4: Update docs/tests and verify behavior ~30m

<!--TOON:milestones[4]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m084,p016,Phase 1: Inventory curl|sh usages and verification options,45m,,2026-02-03T00:00Z,,pending
m085,p016,Phase 2: Replace with download-verify-execute flow,2h,,2026-02-03T00:00Z,,pending
m086,p016,Phase 3: Add fallback behavior and error messages,45m,,2026-02-03T00:00Z,,pending
m087,p016,Phase 4: Update docs/tests and verify behavior,30m,,2026-02-03T00:00Z,,pending
-->

#### Decision Log

(To be populated during implementation)

<!--TOON:decisions[0]{id,plan_id,decision,rationale,date,impact}:
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

### [2026-02-06] Autonomous Supervisor Loop

**Status:** Completed
**Estimate:** ~8h (ai:5h test:2h read:1h)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p018,Autonomous Supervisor Loop,completed,7,7,,orchestration|runners|autonomy,8h,5h,2h,1h,2026-02-06T04:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Build a stateless supervisor pulse that manages long-running parallel objectives from dispatch through completion. Ties together existing components (runners, worktrees, mail, memory, full-loop, cron, Matrix) into an autonomous system that evaluates outcomes, retries failures, escalates blockers, and learns from mistakes. Token-efficient: supervisor is bash + SQLite, AI only invoked for worker execution and ambiguous outcome evaluation.

#### Context from Discussion

Discovered during Tabby tab dispatch experiments that aidevops has all the worker components but no supervisor loop. The gap: nothing evaluates whether a dispatched task succeeded, retries on failure, or updates TODO.md on completion. This is the "brain stem" connecting the existing "limbs."

Key design decisions:

- Supervisor is stateless bash pulse (not a long-running AI session) for token efficiency
- State lives in SQLite (supervisor.db), not in-memory
- Workers are opencode run in isolated worktrees
- Evaluation uses cheap model (Sonnet) for ambiguous outcomes
- Cron-triggered (\*/5 min) or fswatch on TODO.md

#### Progress

- [ ] (2026-02-06) Phase 1: SQLite schema and state machine (t128.1) ~1h
- [ ] (2026-02-06) Phase 2: Worker dispatch with worktree isolation (t128.2) ~1.5h
- [ ] (2026-02-06) Phase 3: Outcome evaluation and re-prompt cycle (t128.3) ~2h
- [ ] (2026-02-06) Phase 4: TODO.md auto-update on completion/failure (t128.4) ~1h
- [ ] (2026-02-06) Phase 5: Cron integration and auto-pickup (t128.5) ~30m
- [ ] (2026-02-06) Phase 6: Memory and self-assessment (t128.6) ~1h
- [ ] (2026-02-06) Phase 7: Integration test with t083-t094 batch (t128.7) ~1h

<!--TOON:milestones[7]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m088,p018,Phase 1: SQLite schema and state machine,1h,,2026-02-06T04:00Z,,pending
m089,p018,Phase 2: Worker dispatch with worktree isolation,1.5h,,2026-02-06T04:00Z,,pending
m090,p018,Phase 3: Outcome evaluation and re-prompt cycle,2h,,2026-02-06T04:00Z,,pending
m091,p018,Phase 4: TODO.md auto-update on completion/failure,1h,,2026-02-06T04:00Z,,pending
m092,p018,Phase 5: Cron integration and auto-pickup,30m,,2026-02-06T04:00Z,,pending
m093,p018,Phase 6: Memory and self-assessment,1h,,2026-02-06T04:00Z,,pending
m094,p018,Phase 7: Integration test with t083-t094 batch,1h,,2026-02-06T04:00Z,,pending
-->

#### Decision Log

- D1: Supervisor is bash + SQLite, not an AI session. Rationale: token efficiency - orchestration logic is deterministic, AI only needed for evaluation. (2026-02-06)
- D2: Workers use opencode run --format json, not TUI. Rationale: parseable output for outcome classification. Tabby visual mode is optional overlay. (2026-02-06)
- D3: Evaluation uses Sonnet, not Opus. Rationale: outcome classification is a simple task, ~5K tokens max. (2026-02-06)

<!--TOON:decisions[3]{id,plan_id,decision,rationale,date,impact}:
d018,p018,Supervisor is bash+SQLite not AI session,Token efficiency - orchestration is deterministic,2026-02-06,high
d019,p018,Workers use opencode run --format json,Parseable output for outcome classification,2026-02-06,high
d020,p018,Evaluation uses Sonnet not Opus,Outcome classification is simple ~5K tokens,2026-02-06,medium
-->

#### Surprises & Discoveries

- S1: opencode supports --prompt flag for TUI seeding and --session --continue for re-prompting existing sessions. Both confirmed working. (2026-02-06)
- S2: Tabby CLI supports `Tabby run <script>` and `Tabby profile <name>` but doesn't hot-reload config changes. (2026-02-06)
- S3: opencode run --format json streams structured events (step_start, text, tool_call, step_finish) with session IDs, enabling programmatic monitoring. (2026-02-06)

<!--TOON:discoveries[3]{id,plan_id,observation,evidence,impact,date}:
s018,p018,opencode --prompt and --session --continue both work,Tested in Tabby dispatch experiments,high,2026-02-06
s019,p018,Tabby CLI doesn't hot-reload config,New profiles not visible until restart,low,2026-02-06
s020,p018,opencode run --format json streams structured events,Captured step_start/text/step_finish with session IDs,high,2026-02-06
-->

### [2026-02-03] Dashboard Token Storage Hardening

**Status:** Completed
**Estimate:** ~3h (ai:1.5h test:1h read:30m)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started}:
p017,Dashboard Token Storage Hardening,completed,3,3,,security|auth|dashboard,3h,1.5h,1h,30m,2026-02-03T00:00Z,2026-02-07T00:00Z
-->

#### Purpose

Replace persistent `localStorage` token usage with session/memory-based storage and add a clear/reset flow to reduce XSS exposure and leaked tokens on shared machines.

#### Context from Discussion

Current usage persists `dashboardToken` in `localStorage` in the MCP dashboard UI. Update to session-scoped storage and ensure logout/reset clears state.

#### Progress

- [x] (2026-02-07) Phase 1: Trace token flow and identify all storage/read paths ~45m actual:5m
- [x] (2026-02-07) Phase 2: Migrate to session/memory storage and update auth flow ~1.5h actual:10m
- [x] (2026-02-07) Phase 3: Add reset/clear UI flow and verify behavior ~45m actual:5m

<!--TOON:milestones[3]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m088,p017,Phase 1: Trace token flow and storage paths,45m,5m,2026-02-03T00:00Z,2026-02-07T00:00Z,completed
m089,p017,Phase 2: Migrate to session/memory storage and update auth flow,1.5h,10m,2026-02-03T00:00Z,2026-02-07T00:00Z,completed
m090,p017,Phase 3: Add reset/clear UI flow and verify behavior,45m,5m,2026-02-03T00:00Z,2026-02-07T00:00Z,completed
-->

#### Decision Log

(To be populated during implementation)

<!--TOON:decisions[0]{id,plan_id,decision,rationale,date,impact}:
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

### [2025-12-21] aidevops-opencode Plugin

**Status:** Completed
**Estimate:** ~2d (ai:1d test:0.5d read:0.5d)
**Architecture:** [.agents/build-mcp/aidevops-plugin.md](../.agents/build-mcp/aidevops-plugin.md)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p001,aidevops-opencode Plugin,completed,4,4,,opencode|plugin,2d,1d,0.5d,0.5d,2025-12-21T01:50Z,,2026-03-21T00:00Z
-->

#### Purpose

Create an optional OpenCode plugin that provides native integration for aidevops. This enables lifecycle hooks (pre-commit quality checks), dynamic agent loading, and cleaner npm-based installation for OpenCode users who want tighter integration.

#### Context from Discussion

**Key decisions:**

- Plugin is **optional enhancement**, not replacement for current multi-tool approach
- aidevops remains compatible with Claude, Cursor, Windsurf, etc.
- Plugin loads agents from `~/.aidevops/agents/` at runtime
- Should detect and complement oh-my-opencode if both installed

**Architecture (from aidevops-plugin.md):**

- Agent loader from `~/.aidevops/agents/`
- MCP registration programmatically
- Pre-commit quality hooks (ShellCheck)
- aidevops CLI exposed as tool

**When to build:**

- When OpenCode becomes dominant enough
- When users request native plugin experience
- When hooks become essential (quality gates)

#### Progress

- [ ] (2025-12-21) Phase 1: Core plugin structure + agent loader ~4h
- [ ] (2025-12-21) Phase 2: MCP registration ~2h
- [ ] (2025-12-21) Phase 3: Quality hooks (pre-commit) ~3h
- [ ] (2025-12-21) Phase 4: oh-my-opencode compatibility ~2h

<!--TOON:milestones[4]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m001,p001,Phase 1: Core plugin structure + agent loader,4h,,2025-12-21T00:00Z,,pending
m002,p001,Phase 2: MCP registration,2h,,2025-12-21T00:00Z,,pending
m003,p001,Phase 3: Quality hooks (pre-commit),3h,,2025-12-21T00:00Z,,pending
m004,p001,Phase 4: oh-my-opencode compatibility,2h,,2025-12-21T00:00Z,,pending
-->

#### Decision Log

- **Decision:** Keep as optional plugin, not replace current approach
  **Rationale:** aidevops must remain multi-tool compatible (Claude, Cursor, etc.)
  **Date:** 2025-12-21

<!--TOON:decisions[1]{id,plan_id,decision,rationale,date,impact}:
d001,p001,Keep as optional plugin,aidevops must remain multi-tool compatible,2025-12-21,None - additive feature
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

### [2025-12-21] Claude Code Destructive Command Hooks

**Status:** Complete
**Estimate:** ~4h (ai:2h test:1h read:1h)
**Source:** [Dicklesworthstone's guide](https://github.com/Dicklesworthstone/misc_coding_agent_tips_and_scripts/blob/main/DESTRUCTIVE_GIT_COMMAND_CLAUDE_HOOKS_SETUP.md)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started}:
p002,Claude Code Destructive Command Hooks,complete,4,4,,claude|git|security,4h,2h,1h,1h,2025-12-21T12:00Z,2026-02-08T00:00Z
-->

#### Purpose

Implement Claude Code PreToolUse hooks to mechanically block destructive git and filesystem commands. Instructions in AGENTS.md don't prevent execution - this provides enforcement at the tool level.

**Problem:** On Dec 17, 2025, an AI agent ran `git checkout --` on files with hours of uncommitted work, destroying it instantly. AGENTS.md forbade this, but instructions alone don't prevent accidents.

**Solution:** Python hook script that intercepts Bash commands before execution and blocks dangerous patterns.

#### Context from Discussion

**Commands to block:**

- `git checkout -- <files>` - discards uncommitted changes
- `git restore <files>` - same as checkout (newer syntax)
- `git reset --hard` - destroys all uncommitted changes
- `git clean -f` - removes untracked files permanently
- `git push --force` / `-f` - destroys remote history
- `git branch -D` - force-deletes without merge check
- `rm -rf` (non-temp paths) - recursive deletion
- `git stash drop/clear` - permanently deletes stashes

**Safe patterns (allowlisted):**

- `git checkout -b <branch>` - creates new branch
- `git restore --staged` - only unstages, doesn't discard
- `git clean -n` / `--dry-run` - preview only
- `rm -rf /tmp/...`, `/var/tmp/...`, `$TMPDIR/...` - temp dirs

**Key decisions:**

- Adapt for aidevops: install to `~/.aidevops/hooks/` not `.claude/hooks/`
- Support both Claude Code and OpenCode (if hooks compatible)
- Add installer to `setup.sh` for automatic deployment
- Document in `workflows/git-workflow.md`

#### Progress

- [x] (2026-02-08) Phase 1: Create git_safety_guard.py adapted for aidevops ~1h
- [x] (2026-02-08) Phase 2: Create installer script with global/project options ~1h
- [x] (2026-02-08) Phase 3: Integrate into setup.sh ~30m
- [x] (2026-02-08) Phase 4: Document in workflows and test ~1.5h

<!--TOON:milestones[4]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m005,p002,Phase 1: Create git_safety_guard.py adapted for aidevops,1h,15m,2025-12-21T12:00Z,2026-02-08,complete
m006,p002,Phase 2: Create installer script with global/project options,1h,15m,2025-12-21T12:00Z,2026-02-08,complete
m007,p002,Phase 3: Integrate into setup.sh,30m,5m,2025-12-21T12:00Z,2026-02-08,complete
m008,p002,Phase 4: Document in workflows and test,1.5h,10m,2025-12-21T12:00Z,2026-02-08,complete
-->

#### Decision Log

- **Decision:** Install hooks to `~/.aidevops/hooks/` by default
  **Rationale:** Consistent with aidevops directory structure, global protection
  **Date:** 2025-12-21

- **Decision:** Keep original Python implementation (not Bash)
  **Rationale:** JSON parsing is cleaner in Python, original is well-tested
  **Date:** 2025-12-21

<!--TOON:decisions[2]{id,plan_id,decision,rationale,date,impact}:
d002,p002,Install hooks to ~/.aidevops/hooks/,Consistent with aidevops directory structure,2025-12-21,None
d003,p002,Keep original Python implementation,JSON parsing cleaner in Python - original well-tested,2025-12-21,None
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

### [2025-12-21] Evaluate Merging build-agent and build-mcp into aidevops

**Status:** Completed
**Estimate:** ~4h (ai:2h test:1h read:1h)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p003,Evaluate Merging build-agent and build-mcp into aidevops,completed,3,3,,architecture|agents,4h,2h,1h,1h,2025-12-21T14:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Evaluate whether `build-agent.md` and `build-mcp.md` should be merged into `aidevops.md`. When enhancing aidevops, we often build agents and MCPs - these are tightly coupled activities that may benefit from consolidation.

#### Context from Discussion

**Current structure:**

- `build-agent.md` - Agent design, ~50-100 instruction budget, subagent: `agent-review.md`
- `build-mcp.md` - MCP development (TypeScript/Bun/Elysia), subagents: server-patterns, transports, deployment, api-wrapper
- `aidevops.md` - Framework operations, already references build-agent as "Related Main Agent"
- All three are `mode: subagent` - called from aidevops context

**Options to evaluate:**

1. **Merge fully** - Combine into aidevops.md with expanded subagent folders
2. **Keep separate but link better** - Improve cross-references, keep modularity
3. **Hybrid** - Move build-agent into aidevops/, keep build-mcp separate (MCP is more specialized)

**Key considerations:**

- Token efficiency: Fewer main agents = less context switching
- Modularity: build-mcp has specialized TypeScript/Bun stack knowledge
- User mental model: Are these distinct domains or one "framework development" domain?
- Progressive disclosure: Current structure already uses subagent pattern

#### Progress

- [ ] (2025-12-21) Phase 1: Analyze usage patterns and cross-references ~1h
- [ ] (2025-12-21) Phase 2: Design merged/improved structure ~1.5h
- [ ] (2025-12-21) Phase 3: Implement chosen approach and test ~1.5h

<!--TOON:milestones[3]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m009,p003,Phase 1: Analyze usage patterns and cross-references,1h,,2025-12-21T14:00Z,,pending
m010,p003,Phase 2: Design merged/improved structure,1.5h,,2025-12-21T14:00Z,,pending
m011,p003,Phase 3: Implement chosen approach and test,1.5h,,2025-12-21T14:00Z,,pending
-->

#### Decision Log

- **d001**: Use `sessionStorage` over in-memory variable. Rationale: sessionStorage auto-clears on tab close (matching security goal) while surviving in-page navigation/refresh (better UX than pure in-memory). Still scoped to same-origin, not accessible cross-tab.
- **d002**: Clear input field after token submission. Rationale: prevents token from sitting in a visible/inspectable input field. Status indicator shows "Token set (session only)" instead.

<!--TOON:decisions[2]{id,plan_id,decision,rationale,date,impact}:
d001,p017,sessionStorage over in-memory variable,Auto-clears on tab close while surviving refresh; same-origin scoped,2026-02-07,security+ux
d002,p017,Clear input after token set,Prevents token sitting in inspectable input field,2026-02-07,security
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

### [2025-12-21] OCR Invoice/Receipt Extraction Pipeline

**Status:** Completed
**Estimate:** ~3d (ai:1.5d test:1d read:0.5d)
**Source:** [pontusab's X post](https://x.com/pontusab/status/2002345525174284449)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p004,OCR Invoice/Receipt Extraction Pipeline,completed,5,5,,accounting|ocr|automation,3d,1.5d,1d,0.5d,2025-12-21T22:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Add OCR extraction capabilities to the accounting agent for automated invoice and receipt processing. This enables:

- Scanning/photographing paper receipts and invoices
- Automatic extraction of vendor, amount, date, VAT, line items
- Integration with QuickFile for expense recording and purchase invoice creation
- Reducing manual data entry for accounting workflows

#### Context from Discussion

**Reference:** @pontusab's OCR extraction pipeline approach (X post - details to be added when available)

**Integration points:**

- `accounts.md` - Main agent, add OCR as new capability
- `services/accounting/quickfile.md` - Target for extracted data (purchases, expenses)
- `tools/browser/` - Potential for receipt image capture workflows

**Key considerations:**

- OCR accuracy requirements for financial data
- Multi-currency and VAT handling
- Receipt image storage and retention
- Privacy/security of financial documents
- Batch processing vs real-time extraction

#### Progress

- [ ] (2025-12-21) Phase 1: Research OCR approaches and @pontusab's implementation ~4h
- [ ] (2025-12-21) Phase 2: Design extraction schema (vendor, amount, date, VAT, items) ~4h
- [ ] (2025-12-21) Phase 3: Implement OCR extraction pipeline ~8h
- [ ] (2025-12-21) Phase 4: QuickFile integration (purchases/expenses) ~4h
- [ ] (2025-12-21) Phase 5: Testing with various invoice/receipt formats ~4h

<!--TOON:milestones[5]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m012,p004,Phase 1: Research OCR approaches and @pontusab's implementation,4h,,2025-12-21T22:00Z,,pending
m013,p004,Phase 2: Design extraction schema (vendor; amount; date; VAT; items),4h,,2025-12-21T22:00Z,,pending
m014,p004,Phase 3: Implement OCR extraction pipeline,8h,,2025-12-21T22:00Z,,pending
m015,p004,Phase 4: QuickFile integration (purchases/expenses),4h,,2025-12-21T22:00Z,,pending
m016,p004,Phase 5: Testing with various invoice/receipt formats,4h,,2025-12-21T22:00Z,,pending
-->

#### Decision Log

(To be populated during implementation)

<!--TOON:decisions[0]{id,plan_id,decision,rationale,date,impact}:
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

### [2025-12-21] Image SEO Enhancement with AI Vision

**Status:** Complete
**Estimate:** ~6h (ai:3h test:2h read:1h)
**Actual:** ~25m

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started}:
p005,Image SEO Enhancement with AI Vision,complete,4,4,,seo|images|ai|accessibility,6h,3h,2h,1h,2025-12-21T23:30Z,2026-02-08T00:00Z
-->

### [2025-12-21] Uncloud Integration for aidevops

**Status:** Completed
**Estimate:** ~1d (ai:4h test:4h read:2h)
**Actual:** ~45m (ai:25m test:10m read:10m)
**Source:** [psviderski/uncloud](https://github.com/psviderski/uncloud)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p006,Uncloud Integration for aidevops,completed,4,4,,deployment|docker|orchestration,1d,4h,4h,2h,2025-12-21T04:00Z,2026-02-08T00:00Z,2026-02-08T00:00Z
-->

#### Purpose

Add Uncloud as a deployment provider option in aidevops. Uncloud is a lightweight container orchestration tool that enables multi-machine Docker deployments without complex Kubernetes infrastructure. It aligns with aidevops philosophy of simplicity and developer experience.

**Why Uncloud:**

- Docker Compose format (familiar, no new DSL)
- WireGuard mesh networking (zero-config, secure)
- No control plane (decentralized, fewer failure points)
- CLI-based with Docker-like commands (`uc run`, `uc deploy`, `uc ls`)
- Self-hosted, Apache 2.0 licensed
- Complements Coolify (PaaS) and Vercel (serverless) as infrastructure-level orchestration

#### Context from Discussion

**Key capabilities identified:**

- Deploy anywhere: cloud VMs, bare metal, hybrid
- Zero-downtime rolling deployments
- Built-in Caddy reverse proxy with auto HTTPS
- Service discovery via internal DNS
- Managed DNS subdomain (\*.uncld.dev) for quick access
- Direct image push to machines without registry (Unregistry)

**Integration architecture:**

- `tools/deployment/uncloud.md` - Main subagent (alongside coolify.md, vercel.md)
- `tools/deployment/uncloud-setup.md` - Installation and machine setup
- `scripts/uncloud-helper.sh` - CLI wrapper for common operations
- `configs/uncloud-config.json.txt` - Configuration template

**Comparison with existing providers:**

| Provider | Type                        | Best For                                  |
| -------- | --------------------------- | ----------------------------------------- |
| Coolify  | Self-hosted PaaS            | Single-server apps, managed experience    |
| Vercel   | Serverless                  | Static sites, JAMstack, Next.js           |
| Uncloud  | Multi-machine orchestration | Cross-server deployments, Docker clusters |

#### Progress

- [x] (2026-02-08) Phase 1: Create uncloud.md subagent with Quick Reference ~2h actual:10m
- [x] (2026-02-08) Phase 2: Create uncloud-helper.sh script ~2h actual:10m
- [x] (2026-02-08) Phase 3: Create uncloud-config.json.txt template ~1h actual:5m
- [x] (2026-02-08) Phase 4: Update deployment docs and test workflows ~3h actual:10m

<!--TOON:milestones[4]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m021,p006,Phase 1: Create uncloud.md subagent with Quick Reference,2h,10m,2025-12-21T04:00Z,2026-02-08T00:00Z,completed
m022,p006,Phase 2: Create uncloud-helper.sh script,2h,10m,2025-12-21T04:00Z,2026-02-08T00:00Z,completed
m023,p006,Phase 3: Create uncloud-config.json.txt template,1h,5m,2025-12-21T04:00Z,2026-02-08T00:00Z,completed
m024,p006,Phase 4: Update deployment docs and test workflows,3h,10m,2025-12-21T04:00Z,2026-02-08T00:00Z,completed
-->

#### Decision Log

- **Decision:** Place in tools/deployment/ alongside Coolify and Vercel
  **Rationale:** Uncloud is a deployment tool, not a hosting provider (like Hetzner/Hostinger)
  **Date:** 2025-12-21

- **Decision:** Focus on CLI integration, not MCP server initially
  **Rationale:** Uncloud is pre-production; CLI wrapper provides immediate value without MCP complexity
  **Date:** 2025-12-21

<!--TOON:decisions[2]{id,plan_id,decision,rationale,date,impact}:
d006,p006,Place in tools/deployment/ alongside Coolify and Vercel,Uncloud is a deployment tool not a hosting provider,2025-12-21,None
d007,p006,Focus on CLI integration not MCP server initially,Uncloud is pre-production; CLI wrapper provides immediate value,2025-12-21,None
-->

#### Surprises & Discoveries

- Uncloud has grown significantly since initial planning (4.6k stars, v0.16.0, 900 commits, 14 contributors). Still marked "not ready for production use" but actively developed.
- CLI is `uc` (not `uncloud`). Install via Homebrew tap or curl script.
- Unregistry feature allows pushing images directly to machines without an external Docker registry.
- Decided to skip separate `uncloud-setup.md` file -- the main `uncloud.md` subagent covers installation and setup inline, matching the pattern of `vercel.md` (single file) rather than `coolify.md` + `coolify-setup.md` (split). Uncloud's setup is simpler (single `uc machine init` command vs Coolify's multi-step server provisioning).

#### Outcomes & Retrospective

- Created 3 files: `uncloud.md` (subagent), `uncloud-helper.sh` (CLI wrapper), `uncloud-config.json.txt` (config template)
- Updated `subagent-index.toon` with uncloud entries
- Zero ShellCheck violations, valid JSON config, help command tested
- Actual time ~45m vs estimated ~1d -- plan was over-scoped for what turned out to be a straightforward integration following established patterns

---

#### Purpose

Add AI-powered image SEO capabilities to the SEO agent. Use Moondream.ai vision model to analyze images and generate SEO-optimized filenames, alt text, and tags for better search visibility and accessibility. Include image upscaling for quality enhancement when needed.

#### Context from Discussion

**Architecture:**

- `seo/moondream.md` - Moondream.ai vision API integration subagent
- `seo/image-seo.md` - Image SEO orchestrator (coordinates moondream + upscale)
- `seo/upscale.md` - Image upscaling services (API provider TBD after research)

**Integration points:**

- Update `seo.md` main agent to reference image-seo capabilities
- `image-seo.md` can call both `moondream.md` and `upscale.md` as needed
- Workflow: analyze image → generate names/tags → optionally upscale

**Key capabilities:**

- SEO-friendly filename generation from image content
- Alt text generation for accessibility (WCAG compliance)
- Tag/keyword extraction for image metadata
- Quality upscaling before publishing (optional)

**Research needed:**

- Moondream.ai API documentation and integration patterns
- Best upscaling API services (candidates: Replicate, DeepAI, Let's Enhance, etc.)

#### Progress

- [x] (2026-02-08) Phase 1: Research Moondream.ai API and create moondream.md subagent ~1.5h actual:10m
  - Moondream 3 Preview: 9B params, 2B active (MoE), 32k context. API at api.moondream.ai/v1/ with 5 skills: query, caption, detect, point, segment. Python/Node SDKs. $0.30/M input, $2.50/M output tokens, $5/mo free credits. Local via Moondream Station.
- [x] (2026-02-08) Phase 2: Create image-seo.md orchestrator subagent ~1.5h actual:10m
  - Orchestrates Moondream for alt text (WCAG 2.1 guidelines, <125 chars), SEO filenames (lowercase-hyphenated, 3-6 words), keyword tags (5-10 per image). Includes batch processing, WordPress integration (WP-CLI + REST API), Schema.org ImageObject output.
- [x] (2026-02-08) Phase 3: Research upscaling APIs and create upscale.md subagent ~1.5h actual:5m
  - Real-ESRGAN (local, free, batch), Replicate API (~$0.002/image), Cloudflare Images (CDN-integrated), Sharp (Node.js format conversion). Decision tree: local for bulk/privacy, Replicate for quality, Cloudflare for CDN.
- [x] (2026-02-08) Phase 4: Update seo.md and test integration ~1.5h actual:5m
  - Added 3 subagents to YAML frontmatter, 3 rows to subagent table, Image SEO workflow section, image-seo key operation.

<!--TOON:milestones[4]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m017,p005,Phase 1: Research Moondream.ai API and create moondream.md subagent,1.5h,10m,2025-12-21T23:30Z,2026-02-08,complete
m018,p005,Phase 2: Create image-seo.md orchestrator subagent,1.5h,10m,2025-12-21T23:30Z,2026-02-08,complete
m019,p005,Phase 3: Research upscaling APIs and create upscale.md subagent,1.5h,5m,2025-12-21T23:30Z,2026-02-08,complete
m020,p005,Phase 4: Update seo.md and test integration,1.5h,5m,2025-12-21T23:30Z,2026-02-08,complete
-->

#### Decision Log

- **Decision:** Create three separate subagents (moondream, image-seo, upscale)
  **Rationale:** Separation of concerns - moondream for vision, upscale for quality, image-seo as orchestrator
  **Date:** 2025-12-21

- **Decision:** image-seo.md orchestrates moondream and upscale
  **Rationale:** Single entry point for image optimization, can selectively call subagents as needed
  **Date:** 2025-12-21

<!--TOON:decisions[2]{id,plan_id,decision,rationale,date,impact}:
d004,p005,Create three separate subagents (moondream; image-seo; upscale),Separation of concerns - moondream for vision; upscale for quality; image-seo as orchestrator,2025-12-21,None
d005,p005,image-seo.md orchestrates moondream and upscale,Single entry point for image optimization; can selectively call subagents,2025-12-21,None
-->

#### Surprises & Discoveries

- **Discovery:** Moondream 3 Preview outperforms GPT 5, Gemini 2.5 Flash, and Claude 4 Sonnet on object detection and counting benchmarks
  **Evidence:** RefCOCO 91.1 vs GPT 5 57.2, CountbenchQA 93.2 vs GPT 5 89.3
  **Impact:** Moondream is the right choice for image analysis -- specialized VLM beats general-purpose LLMs for vision tasks
  **Date:** 2026-02-08

- **Discovery:** Moondream has a Segment skill (SVG path masks) not in original plan
  **Evidence:** /v1/segment endpoint generates precise object masks for background removal
  **Impact:** Enables product image cleanup workflow (segment product -> remove background -> optimize)
  **Date:** 2026-02-08

- **Discovery:** Original estimate of 6h was 14x overestimated (actual: ~25m)
  **Evidence:** All 4 phases completed in single session. Moondream API is well-documented with clear curl examples.
  **Impact:** Plan estimates should account for documentation-only tasks being faster than code implementation tasks
  **Date:** 2026-02-08

<!--TOON:discoveries[3]{id,plan_id,observation,evidence,impact,date}:
s021,p005,Moondream 3 outperforms GPT5/Gemini/Claude on vision benchmarks,RefCOCO 91.1 vs GPT5 57.2,Right tool choice for image analysis,2026-02-08
s022,p005,Moondream Segment skill not in original plan,/v1/segment endpoint for SVG masks,Enables product image cleanup workflow,2026-02-08
s023,p005,6h estimate was 14x over (actual 25m),All 4 phases in single session,Adjust estimates for docs-only tasks,2026-02-08
-->

#### Outcomes & Retrospective

**Delivered:**

- `seo/moondream.md` (230 lines) - Full Moondream 3 API reference with SEO-specific prompts for alt text, filename, and tag generation
- `seo/image-seo.md` (200 lines) - Orchestrator with single/batch workflows, WordPress integration, WCAG guidelines, Schema.org output
- `seo/upscale.md` (175 lines) - 4 upscaling providers with decision tree and complete optimization pipeline
- `seo.md` updated with 3 new subagents in frontmatter, table, and workflow section

**What went well:** Moondream docs are excellent -- clear API, curl examples, SDK for Python/Node. The 3-subagent architecture from the original plan was the right call.

**What to improve:** Original 6h estimate was based on assuming code implementation. Documentation-only tasks (subagent creation) are much faster.

### [2025-12-21] SEO Machine Integration for aidevops

**Status:** Completed
**Estimate:** ~2d (ai:1d test:0.5d read:0.5d)
**Source:** [TheCraigHewitt/seomachine](https://github.com/TheCraigHewitt/seomachine)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p007,SEO Machine Integration for aidevops,completed,5,5,,seo|content|agents,2d,1d,0.5d,0.5d,2025-12-21T15:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Fork and adapt SEO Machine capabilities into aidevops to add comprehensive SEO content creation workflows. SEO Machine is a Claude Code workspace with specialized agents and Python analysis modules that fill significant gaps in aidevops content capabilities.

**What SEO Machine provides:**

- 6 custom commands (`/research`, `/write`, `/rewrite`, `/analyze-existing`, `/optimize`, `/performance-review`)
- 7 specialized agents (content-analyzer, seo-optimizer, meta-creator, internal-linker, keyword-mapper, editor, performance)
- 5 Python analysis modules (search intent, keyword density, readability, content length, SEO quality rating)
- Context-driven system (brand voice, style guide, examples, internal links map)

**Why fork vs integrate:**

- SEO Machine is Claude Code-specific (`.claude/` structure)
- aidevops needs multi-tool compatibility (OpenCode, Cursor, Windsurf, etc.)
- Can leverage existing aidevops SEO tools (DataForSEO, GSC, E-E-A-T, site-crawler)
- Opportunity to improve with aidevops patterns (subagent architecture, TOON, scripts)

#### Context from Discussion

**Gap analysis - what aidevops gains:**

| Capability                | SEO Machine              | aidevops Current           | Action                  |
| ------------------------- | ------------------------ | -------------------------- | ----------------------- |
| Content Writing           | `/write` command         | Basic `content.md`         | Add writing workflow    |
| Content Optimization      | `/optimize` with scoring | Missing                    | Add optimization agents |
| Readability Scoring       | Python (Flesch, etc.)    | Missing                    | Port to scripts/        |
| Keyword Density           | Python analyzer          | Missing                    | Port to scripts/        |
| Search Intent             | Python classifier        | Missing                    | Port to scripts/        |
| Content Length Comparison | SERP competitor analysis | Missing                    | Port to scripts/        |
| SEO Quality Rating        | 0-100 scoring            | Missing                    | Port to scripts/        |
| Brand Voice/Context       | Context files system     | Missing                    | Add context management  |
| Internal Linking          | Agent + map file         | Missing                    | Add linking strategy    |
| Meta Creator              | Dedicated agent          | Missing                    | Add meta generation     |
| Editor (Human Voice)      | Dedicated agent          | Missing                    | Add humanization        |
| E-E-A-T Analysis          | Not mentioned            | ✅ `eeat-score.md`         | Keep existing           |
| Site Crawling             | Not mentioned            | ✅ `site-crawler.md`       | Keep existing           |
| Keyword Research          | DataForSEO               | ✅ DataForSEO, Serper, GSC | Keep existing           |

**Architecture decisions:**

- Adapt agents to aidevops subagent pattern under `seo/` and `content/`
- Port Python modules to `~/.aidevops/agents/scripts/seo-*.py`
- Create context system compatible with multi-project use
- Integrate with existing `content.md` main agent

#### Progress

- [ ] (2025-12-21) Phase 1: Port Python analysis modules to scripts/ ~4h
  - `seo-readability.py` - Flesch scores, sentence analysis
  - `seo-keyword-density.py` - Keyword analysis, clustering
  - `seo-search-intent.py` - Intent classification
  - `seo-content-length.py` - SERP competitor comparison
  - `seo-quality-rater.py` - 0-100 SEO scoring
- [ ] (2025-12-21) Phase 2: Create content writing subagents ~4h
  - `content/seo-writer.md` - SEO-optimized content creation
  - `content/meta-creator.md` - Meta title/description generation
  - `content/editor.md` - Human voice optimization
  - `content/internal-linker.md` - Internal linking strategy
- [ ] (2025-12-21) Phase 3: Create SEO analysis subagents ~3h
  - `seo/content-analyzer.md` - Comprehensive content analysis
  - `seo/seo-optimizer.md` - On-page SEO recommendations
  - `seo/keyword-mapper.md` - Keyword placement analysis
- [ ] (2025-12-21) Phase 4: Add context management system ~3h
  - Context file templates (brand-voice, style-guide, internal-links-map)
  - Per-project context in `.aidevops/context/`
  - Integration with content agents
- [ ] (2025-12-21) Phase 5: Update main agents and test ~2h
  - Update `content.md` with new capabilities
  - Update `seo.md` with content analysis
  - Integration testing

<!--TOON:milestones[5]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m025,p007,Phase 1: Port Python analysis modules to scripts/,4h,,2025-12-21T15:00Z,,pending
m026,p007,Phase 2: Create content writing subagents,4h,,2025-12-21T15:00Z,,pending
m027,p007,Phase 3: Create SEO analysis subagents,3h,,2025-12-21T15:00Z,,pending
m028,p007,Phase 4: Add context management system,3h,,2025-12-21T15:00Z,,pending
m029,p007,Phase 5: Update main agents and test,2h,,2025-12-21T15:00Z,,pending
-->

#### Decision Log

- **Decision:** Fork and adapt rather than integrate directly
  **Rationale:** SEO Machine is Claude Code-specific; aidevops needs multi-tool compatibility
  **Date:** 2025-12-21

- **Decision:** Port Python modules to scripts/ rather than keeping as separate package
  **Rationale:** Consistent with aidevops pattern; scripts are self-contained and portable
  **Date:** 2025-12-21

- **Decision:** Split agents between content/ and seo/ folders
  **Rationale:** Writing/editing belongs in content domain; analysis belongs in SEO domain
  **Date:** 2025-12-21

<!--TOON:decisions[3]{id,plan_id,decision,rationale,date,impact}:
d008,p007,Fork and adapt rather than integrate directly,SEO Machine is Claude Code-specific; aidevops needs multi-tool compatibility,2025-12-21,None
d009,p007,Port Python modules to scripts/,Consistent with aidevops pattern; scripts are self-contained and portable,2025-12-21,None
d010,p007,Split agents between content/ and seo/ folders,Writing/editing belongs in content domain; analysis belongs in SEO domain,2025-12-21,None
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

### [2025-12-21] Enhance Plan+ and Build+ with OpenCode's Latest Features

**Status:** Superseded (Plan+ merged into Build+; OpenCode dropped in favour of Claude Code)
**Estimate:** ~3h (ai:1.5h test:1h read:30m)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p008,Enhance Plan+ and Build+ with OpenCode's Latest Features,superseded,0,4,,opencode|agents|enhancement,3h,1.5h,1h,30m,2025-12-21T04:30Z,,2026-03-21T00:00Z
-->

#### Purpose

Apply OpenCode's latest agent configuration features to our Build+ and Plan+ agents, and configure agent ordering so our enhanced agents appear first in the Tab-cycled list (displacing OpenCode's default build/plan agents).

#### Context from Discussion

**Research findings from OpenCode docs (2025-12-21):**

| Feature                   | OpenCode Latest                      | Our Current State     | Action                              |
| ------------------------- | ------------------------------------ | --------------------- | ----------------------------------- |
| `disable` option          | Supports `"disable": true` per agent | Not using             | Disable built-in `build` and `plan` |
| `default_agent`           | Supports `"default_agent": "Build+"` | Not set               | Set Build+ as default               |
| `maxSteps`                | Cost control for expensive ops       | Not configured        | Consider adding for subagents       |
| Granular bash permissions | `"git status": "allow"` patterns     | Plan+ denies all bash | Allow read-only git commands        |
| Agent ordering            | JSON key order determines Tab order  | Build+ first          | Already correct                     |

**Key decisions:**

- Disable OpenCode's default `build` and `plan` agents so only our Build+ and Plan+ appear
- Set `default_agent` to `Build+` for consistent startup behavior
- Add granular bash permissions to Plan+ allowing read-only git commands (`git status`, `git log*`, `git diff`, `git branch`)
- Update `generate-opencode-agents.sh` to apply these settings automatically

**Granular bash permissions for Plan+ (read-only git):**

```json
"permission": {
  "edit": "deny",
  "write": "deny",
  "bash": {
    "git status": "allow",
    "git log*": "allow",
    "git diff*": "allow",
    "git branch*": "allow",
    "git show*": "allow",
    "*": "deny"
  }
}
```

#### Progress

- [ ] (2025-12-21) Phase 1: Add `disable: true` for built-in build/plan agents ~30m
- [ ] (2025-12-21) Phase 2: Set `default_agent` to Build+ ~15m
- [ ] (2025-12-21) Phase 3: Add granular bash permissions to Plan+ ~45m
- [ ] (2025-12-21) Phase 4: Update generate-opencode-agents.sh and test ~1.5h

<!--TOON:milestones[4]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m030,p008,Phase 1: Add disable:true for built-in build/plan agents,30m,,2025-12-21T04:30Z,,pending
m031,p008,Phase 2: Set default_agent to Build+,15m,,2025-12-21T04:30Z,,pending
m032,p008,Phase 3: Add granular bash permissions to Plan+,45m,,2025-12-21T04:30Z,,pending
m033,p008,Phase 4: Update generate-opencode-agents.sh and test,1.5h,,2025-12-21T04:30Z,,pending
-->

#### Decision Log

- **Decision:** Disable OpenCode's default build/plan rather than rename our agents
  **Rationale:** Keeps our naming (Build+, Plan+) which indicates enhanced versions; cleaner than competing names
  **Date:** 2025-12-21

- **Decision:** Allow read-only git commands in Plan+ via granular bash permissions
  **Rationale:** Plan+ needs to inspect git state (status, log, diff) for planning without modification risk
  **Date:** 2025-12-21

<!--TOON:decisions[2]{id,plan_id,decision,rationale,date,impact}:
d011,p008,Disable OpenCode's default build/plan rather than rename our agents,Keeps our naming (Build+ Plan+) which indicates enhanced versions,2025-12-21,None
d012,p008,Allow read-only git commands in Plan+ via granular bash permissions,Plan+ needs to inspect git state for planning without modification risk,2025-12-21,None
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

### [2025-12-21] Beads Integration for aidevops Tasks & Plans

**Status:** Completed
**Estimate:** ~2d (ai:1d test:0.5d read:0.5d)
**Actual:** ~1.5d
**Source:** [steveyegge/beads](https://github.com/steveyegge/beads)
**Completed:** 2025-12-22

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p009,Beads Integration for aidevops Tasks & Plans,completed,3,3,,beads|tasks|sync|planning,2d,1d,0.5d,0.5d,2025-12-21T16:00Z,2025-12-21T16:00Z,2025-12-22T00:00Z
-->

#### Purpose

Integrate Beads task management concepts and bi-directional sync into aidevops Tasks & Plans system. This provides:

- Dependency graph awareness (blocked-by, blocks, parent-child)
- Hierarchical task IDs with sub-sub-task support (t001.1.1)
- Automatic "ready" detection for unblocked tasks
- Rich UI ecosystem (beads_viewer, beads-ui, bdui, perles, beads.el)
- Graph analytics (PageRank, betweenness, critical path)

**Key decision:** Keep aidevops markdown as source of truth, sync bi-directionally to Beads for visualization and graph features. Include Beads as default with aidevops (not optional).

#### Context from Discussion

**Ecosystem reviewed:**

- `steveyegge/beads` - Core CLI, Go, SQLite + JSONL, MCP server
- `Dicklesworthstone/beads_viewer` - Advanced TUI with graph analytics
- `mantoni/beads-ui` - Web UI with live updates
- `ctietze/beads.el` - Emacs client
- `assimelha/bdui` - React/Ink TUI
- `zjrosen/perles` - BQL query language TUI

**What aidevops gains:**

- Dependency graph (blocks, parent-child, discovered-from)
- Hash-based IDs for conflict-free merging
- `bd ready` for unblocked task detection
- Graph visualization via beads_viewer
- MCP server for Claude Desktop

**What aidevops keeps:**

- Time tracking with breakdown (`~4h (ai:2h test:1h)`)
- Decision logs and retrospectives
- TOON machine-readable blocks
- Human-readable markdown
- Multi-tool compatibility

**Sync architecture:**

```text
TODO.md ←→ beads-sync-helper.sh ←→ .beads/beads.db
PLANS.md ←→ (command-led sync) ←→ .beads/issues.jsonl
```

**Sync guarantees:**

- Command-led only (no automatic sync to prevent race conditions)
- Lock file during sync operations
- Checksum verification before/after
- Conflict detection with manual resolution
- Audit log of all sync operations

#### Progress

- [x] (2025-12-21 16:00Z) Phase 1: Enhanced TODO.md format ~4h actual:3h
  - [x] 1.1 Add `blocked-by:` and `blocks:` syntax
  - [x] 1.2 Add hierarchical IDs (t001.1.1 for sub-sub-tasks)
  - [x] 1.3 Update TOON dependencies block schema
  - [x] 1.4 Add `/ready` command to show unblocked tasks
  - [x] 1.5 Update workflows/plans.md documentation
- [x] (2025-12-21) Phase 2: Bi-directional sync script ~8h actual:6h
  - [x] 2.1 Create beads-sync-helper.sh with lock file
  - [x] 2.2 Implement TODO.md → Beads sync
  - [x] 2.3 Implement Beads → TODO.md sync
  - [x] 2.4 Add checksum verification
  - [x] 2.5 Add conflict detection and resolution
  - [x] 2.6 Add audit logging
  - [x] 2.7 Comprehensive testing (race conditions, edge cases)
- [x] (2025-12-21) Phase 3: Default installation ~4h actual:3h
  - [x] 3.1 Add Beads installation to setup.sh
  - [x] 3.2 Add `aidevops init beads` feature
  - [x] 3.3 Create tools/task-management/beads.md subagent
  - [x] 3.4 Update AGENTS.md with Beads integration docs

<!--TOON:milestones[14]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m034,p009,Phase 1: Enhanced TODO.md format,4h,3h,2025-12-21T16:00Z,2025-12-22T00:00Z,done
m035,p009,1.1 Add blocked-by and blocks syntax,1h,1h,2025-12-21T16:00Z,2025-12-22T00:00Z,done
m036,p009,1.2 Add hierarchical IDs (t001.1.1),1h,1h,2025-12-21T16:00Z,2025-12-22T00:00Z,done
m037,p009,1.3 Update TOON dependencies block schema,30m,30m,2025-12-21T16:00Z,2025-12-22T00:00Z,done
m038,p009,1.4 Add /ready command,1h,1h,2025-12-21T16:00Z,2025-12-22T00:00Z,done
m039,p009,1.5 Update workflows/plans.md documentation,30m,30m,2025-12-21T16:00Z,2025-12-22T00:00Z,done
m040,p009,Phase 2: Bi-directional sync script,8h,6h,2025-12-21T16:00Z,2025-12-22T00:00Z,done
m041,p009,2.1-2.6 Sync implementation,6h,5h,2025-12-21T16:00Z,2025-12-22T00:00Z,done
m042,p009,2.7 Comprehensive testing,2h,1h,2025-12-21T16:00Z,2025-12-22T00:00Z,done
m043,p009,Phase 3: Default installation,4h,3h,2025-12-21T16:00Z,2025-12-22T00:00Z,done
m044,p009,3.1 Add Beads to setup.sh,1h,45m,2025-12-21T16:00Z,2025-12-22T00:00Z,done
m045,p009,3.2 Add aidevops init beads,1h,45m,2025-12-21T16:00Z,2025-12-22T00:00Z,done
m046,p009,3.3 Create beads.md subagent,1h,45m,2025-12-21T16:00Z,2025-12-22T00:00Z,done
m047,p009,3.4 Update AGENTS.md,1h,45m,2025-12-21T16:00Z,2025-12-22T00:00Z,done
-->

#### Decision Log

- **Decision:** Keep aidevops markdown as source of truth, Beads as sync target
  **Rationale:** Markdown is portable, human-readable, works without CLI; Beads provides graph features
  **Date:** 2025-12-21

- **Decision:** Command-led sync only (no automatic)
  **Rationale:** Prevents race conditions, ensures data integrity, user controls when sync happens
  **Date:** 2025-12-21

- **Decision:** Include Beads as default with aidevops (not optional)
  **Rationale:** Graph features are valuable enough to justify default installation
  **Date:** 2025-12-21

- **Decision:** Support sub-sub-tasks (t001.1.1)
  **Rationale:** Complex projects need deeper hierarchy than just parent-child
  **Date:** 2025-12-21

<!--TOON:decisions[4]{id,plan_id,decision,rationale,date,impact}:
d013,p009,Keep aidevops markdown as source of truth,Markdown is portable and human-readable; Beads provides graph features,2025-12-21,None
d014,p009,Command-led sync only (no automatic),Prevents race conditions and ensures data integrity,2025-12-21,None
d015,p009,Include Beads as default with aidevops,Graph features valuable enough to justify default installation,2025-12-21,None
d016,p009,Support sub-sub-tasks (t001.1.1),Complex projects need deeper hierarchy than just parent-child,2025-12-21,None
-->

#### Surprises & Discoveries

- **Observation:** Implementation was faster than estimated (~1.5d vs ~2d)
  **Evidence:** All core functionality already existed, just needed documentation updates
  **Impact:** Positive - ready for production use
  **Date:** 2025-12-22

<!--TOON:discoveries[1]{id,plan_id,observation,evidence,impact,date}:
disc001,p009,Implementation faster than estimated,All core functionality already existed,Positive - ready for production,2025-12-22
-->

#### Outcomes & Retrospective

**What was delivered:**

- `beads-sync-helper.sh` (597 lines) - bi-directional sync with lock file, checksums, conflict detection
- `todo-ready.sh` - show tasks with no open blockers
- `beads.md` subagent (289 lines) - comprehensive documentation
- `blocked-by:` and `blocks:` syntax in TODO.md
- Hierarchical task IDs (t001.1.1)
- TOON dependencies block schema
- Beads CLI installation in setup.sh
- AGENTS.md integration docs

**What went well:**

- Core sync script is robust with proper locking and checksums
- Documentation is comprehensive with install commands for all UI repos
- Integration with existing TODO.md format is seamless

**What could improve:**

- Beads UI repos (beads_viewer, beads-ui, bdui, perles) are documented but not auto-installed
- Could add optional UI installation to setup.sh

**Time Summary:**

- Estimated: 2d
- Actual: 1.5d
- Variance: -25% (faster)
- Lead time: 1 day (logged to completed)

<!--TOON:retrospective{plan_id,delivered,went_well,improve,est,actual,variance_pct,lead_time_days}:
p009,beads-sync-helper.sh; todo-ready.sh; beads.md subagent; blocked-by/blocks syntax; hierarchical IDs; TOON schema; setup.sh integration; AGENTS.md docs,Robust sync script; comprehensive docs; seamless integration,Add optional UI installation to setup.sh,2d,1.5d,-25,1
-->

<!--TOON:active_plans[0]{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started}:
-->

### [2026-02-05] MCP Auto-Installation in setup.sh

**Status:** Completed
**Estimate:** ~4h (ai:2h test:1h read:1h)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p018,MCP Auto-Installation in setup.sh,completed,4,4,,mcp|setup|installation,4h,2h,1h,1h,2026-02-05T03:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Add automatic MCP installation/configuration to setup.sh so users get working MCPs out of the box. Currently many MCPs are configured but not installed, leading to "Disabled" status.

#### Context from Discussion

**MCP Categories:**

| Category                | MCPs                   | Install Method                       | Auth               |
| ----------------------- | ---------------------- | ------------------------------------ | ------------------ |
| **Remote (no install)** | context7, socket       | Just enable                          | No                 |
| **Bun packages**        | chrome-devtools, gsc   | `bun install -g`                     | gsc needs OAuth    |
| **Brew packages**       | localwp                | `brew install`                       | Needs Local WP app |
| **Docker**              | MCP_DOCKER             | Docker Desktop                       | No                 |
| **NPX**                 | sentry                 | `npx @sentry/mcp-server`             | Access token       |
| **NPM + Auth**          | augment-context-engine | `npm install -g @augmentcode/auggie` | `auggie login`     |
| **Custom**              | amazon-order-history   | Git clone + build                    | Amazon auth        |

**Priority Order:**

1. Remote MCPs (context7, socket) - just enable, no install
2. Simple packages (chrome-devtools) - auto-install
3. Auth-required (gsc, sentry) - install + guide user to auth
4. App-dependent (localwp, MCP_DOCKER) - check prereqs, guide setup
5. Complex (augment, amazon) - document manual setup

#### Progress

- [ ] (2026-02-05) Phase 1: Enable remote MCPs (context7, socket) ~30m
  - Add to opencode.json with `enabled: true`
  - No installation needed
- [ ] (2026-02-05) Phase 2: Auto-install simple MCPs ~1h
  - chrome-devtools: `bun install -g chrome-devtools-mcp`
  - Add setup functions to setup.sh
- [ ] (2026-02-05) Phase 3: Auth-required MCPs ~1.5h
  - gsc: Install + OAuth setup guide
  - sentry: Install + token prompt
  - localwp: Check Local WP app, install MCP
  - MCP_DOCKER: Check Docker Desktop
- [ ] (2026-02-05) Phase 4: Documentation ~1h
  - Update subagent docs with install status
  - Add troubleshooting for common issues

<!--TOON:milestones[4]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m091,p018,Phase 1: Enable remote MCPs (context7 socket),30m,,2026-02-05T03:00Z,,pending
m092,p018,Phase 2: Auto-install simple MCPs (chrome-devtools),1h,,2026-02-05T03:00Z,,pending
m093,p018,Phase 3: Auth-required MCPs (gsc sentry localwp MCP_DOCKER),1.5h,,2026-02-05T03:00Z,,pending
m094,p018,Phase 4: Documentation updates,1h,,2026-02-05T03:00Z,,pending
-->

#### Decision Log

- **Decision:** Remote MCPs (context7, socket) should be enabled by default
  **Rationale:** No installation needed, free services, useful for all users
  **Date:** 2026-02-05

- **Decision:** Auth-required MCPs get installed but disabled until auth configured
  **Rationale:** Reduces friction; user can enable after setting up credentials
  **Date:** 2026-02-05

<!--TOON:decisions[2]{id,plan_id,decision,rationale,date,impact}:
d026,p018,Remote MCPs enabled by default,No install needed; free services; useful for all,2026-02-05,None
d027,p018,Auth-required MCPs installed but disabled,Reduces friction; enable after credentials,2026-02-05,None
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

### [2025-01-11] Agent Design Pattern Improvements

**Status:** Completed
**Estimate:** ~1d (ai:6h test:4h read:2h)
**Source:** [Lance Martin's "Effective Agent Design" (Jan 2025)](https://x.com/RLanceMartin/status/2009683038272401719)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p010,Agent Design Pattern Improvements,completed,5,5,,architecture|agents|context|optimization,1d,6h,4h,2h,2025-01-11T00:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Implement remaining agent design pattern improvements identified from Lance Martin's analysis of successful agents (Claude Code, Manus, Cursor). While aidevops already implements most patterns, these enhancements will further optimize context efficiency and enable automatic learning.

#### Context from Discussion

**What aidevops already does well:**

- Give agents a computer (filesystem + shell)
- Multi-layer action space (per-agent MCP filtering)
- Progressive disclosure (subagent tables, read-on-demand)
- Offload context to filesystem
- Ralph Loop (iterative execution)
- Memory system (/remember, /recall)

**Remaining opportunities:**

| Priority | Improvement                          | Estimate | Description                                                                |
| -------- | ------------------------------------ | -------- | -------------------------------------------------------------------------- |
| Medium   | YAML frontmatter in source subagents | ~2h      | Add frontmatter to all `.agents/**/*.md` for better progressive disclosure |
| Medium   | Automatic session reflection         | ~4h      | Auto-distill sessions to memory on completion                              |
| Low      | Cache-aware prompt structure         | ~1h      | Document stable-prefix patterns for better cache hits                      |
| Low      | Tool description indexing            | ~3h      | Cursor-style MCP description sync for on-demand retrieval                  |
| Low      | Memory consolidation                 | ~2h      | Periodic reflection over memories to merge/prune                           |

#### Progress

- [ ] (2025-01-11) Phase 1: Add YAML frontmatter to source subagents ~2h
  - Add `description`, `triggers`, `tools` to all `.agents/**/*.md` files
  - Update `generate-opencode-agents.sh` to parse frontmatter
- [ ] (2025-01-11) Phase 2: Automatic session reflection ~4h
  - Create `session-distill-helper.sh` to extract learnings
  - Integrate with `/session-review` command
  - Auto-call `/remember` with distilled insights
- [ ] (2025-01-11) Phase 3: Cache-aware prompt documentation ~1h
  - Document stable-prefix patterns in `build-agent.md`
  - Add guidance for avoiding instruction reordering
- [ ] (2025-01-11) Phase 4: Tool description indexing ~3h
  - Create MCP description sync to `.agent-workspace/mcp-descriptions/`
  - Add search tool for on-demand MCP discovery
- [ ] (2025-01-11) Phase 5: Memory consolidation ~2h
  - Add `memory-helper.sh consolidate` command
  - Periodic reflection to merge similar memories
  - Prune stale or superseded entries

<!--TOON:milestones[5]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m048,p010,Phase 1: Add YAML frontmatter to source subagents,2h,,2025-01-11T00:00Z,,pending
m049,p010,Phase 2: Automatic session reflection,4h,,2025-01-11T00:00Z,,pending
m050,p010,Phase 3: Cache-aware prompt documentation,1h,,2025-01-11T00:00Z,,pending
m051,p010,Phase 4: Tool description indexing,3h,,2025-01-11T00:00Z,,pending
m052,p010,Phase 5: Memory consolidation,2h,,2025-01-11T00:00Z,,pending
-->

#### Decision Log

- **Decision:** Document patterns before implementing improvements
  **Rationale:** Establishes baseline, validates alignment, provides reference for future work
  **Date:** 2025-01-11

- **Decision:** Prioritize automatic session reflection over other improvements
  **Rationale:** Highest impact for continual learning; other patterns already well-implemented
  **Date:** 2025-01-11

<!--TOON:decisions[2]{id,plan_id,decision,rationale,date,impact}:
d017,p010,Document patterns before implementing improvements,Establishes baseline and validates alignment,2025-01-11,None
d018,p010,Prioritize automatic session reflection,Highest impact for continual learning,2025-01-11,None
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

### [2026-01-21] /add-skill System for External Skill Import

**Status:** Completed
**Estimate:** ~2d (ai:1d test:0.5d read:0.5d)
**Branch:** `feature/add-skill-command` (worktree at `~/Git/aidevops.feature-add-skill-command/`)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p012,/add-skill System for External Skill Import,completed,6,6,,skills|agents|import|multi-assistant,2d,1d,0.5d,0.5d,2026-01-21T00:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Create a comprehensive skill import system that allows rapid adoption of external AI agent skills into aidevops, with upstream tracking for updates and multi-assistant compatibility.

**Problem:** Many people are creating and sharing Claude Code skills, OpenCode skills, and other AI assistant configurations. aidevops has its own superior `.agents/` folder structure. We need to rapidly import external skills, convert to aidevops format, handle conflicts intelligently, and track upstream for updates.

#### Research Completed (2026-01-21)

**AI Assistant Compatibility Matrix:**

| Assistant                   | Config Location                           | Skills Format       | AGENTS.md          | Pointer Support   |
| --------------------------- | ----------------------------------------- | ------------------- | ------------------ | ----------------- |
| OpenCode                    | `.opencode/skills/`                       | SKILL.md            | Yes                | Yes (description) |
| Codex (OpenAI)              | `.codex/skills/`                          | SKILL.md            | Yes (hierarchical) | Yes               |
| Claude Code                 | `.claude/skills/`                         | SKILL.md            | Yes                | Yes               |
| Amp (Sourcegraph)           | `.claude/skills/`, `~/.config/amp/tools/` | SKILL.md            | Yes                | Yes               |
| Droid (Factory)             | `.factory/droids/`                        | Markdown+YAML       | Yes                | Yes               |
| Cursor                      | `.cursorrules`                            | Plain MD            | No                 | Symlinks only     |
| Windsurf                    | `.windsurf/rules/`                        | MD+frontmatter      | Yes                | Yes               |
| Cline                       | `.clinerules/`                            | Markdown            | No                 | Symlinks only     |
| Continue                    | `config.yaml`                             | YAML rules          | No                 | No                |
| Aider                       | `.aider.conf.yml`                         | YAML+CONVENTIONS.md | No                 | Yes (read:)       |
| Roo, Goose, Copilot, Gemini | SKILL.md                                  | SKILL.md            | Yes                | Yes               |

**Key Standards:**

- **agentskills.io specification**: Universal SKILL.md format with YAML frontmatter
- **skills.sh CLI**: `npx skills add <owner/repo>` - supports 17+ AI assistants
- **AGENTS.md hierarchical**: Codex, Amp, Droid, Windsurf support directory-scoped AGENTS.md

**Example Skills to Import:**

- `dmmulroy/cloudflare-skill` - 60+ Cloudflare products (conflicts with existing cloudflare.md)
- `remotion-dev/skills` - Video creation in React
- `vercel-labs/agent-skills` - React best practices
- `expo/skills` - React Native/Expo
- `anthropics/skills` - Official Anthropic skills
- `trailofbits/skills` - Security auditing

**Architecture Decision:**

- Source of truth: `.agents/` (aidevops format)
- `setup.sh` generates symlinks to `~/.config/opencode/skills/`, `~/.codex/skills/`, `~/.claude/skills/`, `~/.config/amp/tools/`
- Nesting: Simple skills → single .md file; Complex skills → folder with subagents
- Tracking: `skill-sources.json` with upstream URL, version, last-checked

#### Progress

- [ ] (2026-01-21) Phase 1: Create skill-sources.json schema and registry ~2h
  - Define JSON schema for tracking upstream skills
  - Add existing humanise.md as first tracked skill
  - Create `.agents/configs/skill-sources.json`
- [ ] (2026-01-21) Phase 2: Create add-skill-helper.sh ~4h
  - Fetch via `npx skills add` or direct GitHub
  - Detect format (SKILL.md, AGENTS.md, .cursorrules, raw)
  - Extract metadata, instructions, resources
  - Check for conflicts with existing .agents/ files
- [ ] (2026-01-21) Phase 3: Create /add-skill command ~2h
  - Create `scripts/commands/add-skill.md`
  - Present merge options when conflicts detected
  - Register in skill-sources.json after import
- [ ] (2026-01-21) Phase 4: Create add-skill.md subagent ~3h
  - Create `tools/build-agent/add-skill.md`
  - Conversion logic for different formats
  - Merge strategies (add/replace/separate)
  - Follow build-agent.md and agent-review.md guidance
- [ ] (2026-01-21) Phase 5: Create skill-update-helper.sh ~2h
  - Check all tracked skills for upstream updates
  - Compare commits/versions
  - Show diff and update options
- [ ] (2026-01-21) Phase 6: Update setup.sh for symlinks ~3h
  - Generate symlinks to all AI assistant skill locations
  - Update generate-skills.sh for SKILL.md stubs
  - Document in AGENTS.md

<!--TOON:milestones[6]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m058,p012,Phase 1: Create skill-sources.json schema and registry,2h,,2026-01-21T00:00Z,,pending
m059,p012,Phase 2: Create add-skill-helper.sh,4h,,2026-01-21T00:00Z,,pending
m060,p012,Phase 3: Create /add-skill command,2h,,2026-01-21T00:00Z,,pending
m061,p012,Phase 4: Create add-skill.md subagent,3h,,2026-01-21T00:00Z,,pending
m062,p012,Phase 5: Create skill-update-helper.sh,2h,,2026-01-21T00:00Z,,pending
m063,p012,Phase 6: Update setup.sh for symlinks,3h,,2026-01-21T00:00Z,,pending
-->

#### Decision Log

- **Decision:** Use symlinks by default, pointer fallback for Windows
  **Rationale:** Single source of truth; updates to .agents/ automatically reflected
  **Date:** 2026-01-21

- **Decision:** Use `npx skills add` as fetch mechanism when available
  **Rationale:** skills.sh is emerging standard; supports 17+ AI assistants
  **Date:** 2026-01-21

- **Decision:** Complex skills become folders with subagents
  **Rationale:** Follows aidevops nesting convention (parent.md + parent/)
  **Date:** 2026-01-21

- **Decision:** Merge conflicts require human decision (add/replace/separate/skip)
  **Rationale:** Preserves existing knowledge; prevents accidental overwrites
  **Date:** 2026-01-21

<!--TOON:decisions[4]{id,plan_id,decision,rationale,date,impact}:
d022,p012,Use symlinks by default pointer fallback for Windows,Single source of truth; auto-reflects updates,2026-01-21,None
d023,p012,Use npx skills add as fetch mechanism,skills.sh is emerging standard,2026-01-21,None
d024,p012,Complex skills become folders with subagents,Follows aidevops nesting convention,2026-01-21,None
d025,p012,Merge conflicts require human decision,Preserves existing knowledge,2026-01-21,None
-->

#### Files to Create

| File                                     | Purpose                                            |
| ---------------------------------------- | -------------------------------------------------- |
| `.agents/configs/skill-sources.json`     | Registry of imported skills with upstream tracking |
| `.agents/scripts/add-skill-helper.sh`    | Fetch, analyse, convert, merge skills              |
| `.agents/scripts/skill-update-helper.sh` | Check all tracked skills for updates               |
| `.agents/scripts/commands/add-skill.md`  | `/add-skill` command definition                    |
| `.agents/tools/build-agent/add-skill.md` | Subagent with conversion/merge logic               |

#### Files to Update

| File                 | Changes                                               |
| -------------------- | ----------------------------------------------------- |
| `setup.sh`           | Generate symlinks to all AI assistant skill locations |
| `generate-skills.sh` | Create SKILL.md stubs pointing to .agents/ source     |
| `AGENTS.md`          | Document /add-skill command in quick reference        |

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

---

### [2026-01-11] Memory Auto-Capture

**Status:** Completed
**Estimate:** ~1d (ai:6h test:4h read:2h)
**PRD:** [todo/tasks/prd-memory-auto-capture.md](tasks/prd-memory-auto-capture.md)
**Source:** [claude-mem](https://github.com/thedotmack/claude-mem) - inspiration for auto-capture patterns

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started}:
p011,Memory Auto-Capture,completed,5,5,,memory|automation|context,1d,6h,4h,2h,2026-01-11T12:00Z,2026-02-06T01:30Z
-->

#### Purpose

Add automatic memory capture to aidevops, inspired by claude-mem but tool-agnostic. Currently, memory requires manual `/remember` invocation. Auto-capture will:

- Capture working solutions, failed approaches, and decisions automatically
- Work across all AI tools (OpenCode, Cursor, Claude Code, Windsurf)
- Use progressive disclosure to minimize token usage
- Maintain minimal dependencies (bash + sqlite3)

#### Context from Discussion

**Why not use claude-mem as dependency:**

- Claude Code only (plugin architecture)
- Heavy dependencies (Bun, uv, Chroma, Node.js worker)
- AGPL license (viral, requires source disclosure)
- aidevops needs tool-agnostic solution

**What we'll implement:**

- Agent instructions for auto-capture (not lifecycle hooks)
- Semantic classification into memory types
- Deduplication via FTS5 similarity
- Privacy controls (`<private>` tags, .gitignore patterns)
- `/memory-log` command for reviewing captures

**Architecture decision:** Use agent instructions (Option A) rather than shell wrappers or file watchers. This works with any AI tool that reads AGENTS.md.

#### Progress

- [x] (2026-01-11) Phase 1: Research & Design ~2h actual:0h completed:2026-02-06
  - Capture triggers defined in AGENTS.md "Proactive Memory Triggers" (t052)
  - 11 memory types classified in memory-helper.sh
  - Privacy patterns documented; privacy-filter-helper.sh created (t117)
- [x] (2026-01-11) Phase 2: memory-helper.sh updates ~3.5h actual:30m completed:2026-02-06
  - Added `--auto`/`--auto-captured` flag to store command
  - Deduplication via `consolidate` command (t057)
  - Auto-capture statistics in `stats` output
  - `--auto-only`/`--manual-only` recall filters
  - `log` command for auto-capture review
  - DB migration adds `auto_captured` column to `learning_access`
- [x] (2026-01-11) Phase 3: AGENTS.md instructions ~2h actual:0h completed:2026-02-06
  - Proactive Memory Triggers section added (t052/198b5a8)
  - Auto-capture with --auto flag documented
  - Privacy exclusion patterns documented
- [x] (2026-01-11) Phase 4: /memory-log command ~2h actual:15m completed:2026-02-06
  - Created `scripts/commands/memory-log.md`
  - Shows recent auto-captures with filtering
  - Prune command already existed in memory-helper.sh
- [x] (2026-01-11) Phase 5: Privacy filters ~2.5h actual:15m completed:2026-02-06
  - `<private>` tag stripping in memory-helper.sh store
  - Secret pattern rejection (API keys, tokens, AWS keys, GitHub tokens)
  - privacy-filter-helper.sh available for comprehensive scanning (t117)

<!--TOON:milestones[5]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m053,p011,Phase 1: Research & Design,2h,0h,2026-01-11T12:00Z,2026-02-06,completed
m054,p011,Phase 2: memory-helper.sh updates,3.5h,30m,2026-01-11T12:00Z,2026-02-06,completed
m055,p011,Phase 3: AGENTS.md instructions,2h,0h,2026-01-11T12:00Z,2026-02-06,completed
m056,p011,Phase 4: /memory-log command,2h,15m,2026-01-11T12:00Z,2026-02-06,completed
m057,p011,Phase 5: Privacy filters,2.5h,15m,2026-01-11T12:00Z,2026-02-06,completed
-->

#### Decision Log

- **Decision:** Use agent instructions instead of lifecycle hooks
  **Rationale:** Tool-agnostic; works with OpenCode, Cursor, Claude Code, Windsurf without plugins
  **Date:** 2026-01-11

- **Decision:** Keep FTS5 for search, no vector embeddings
  **Rationale:** Minimal dependencies; FTS5 is sufficient for keyword search; semantic search adds complexity
  **Date:** 2026-01-11

- **Decision:** Implement ourselves rather than depend on claude-mem
  **Rationale:** claude-mem is Claude Code-only; aidevops needs multi-tool support
  **Date:** 2026-01-11

<!--TOON:decisions[3]{id,plan_id,decision,rationale,date,impact}:
d019,p011,Use agent instructions instead of lifecycle hooks,Tool-agnostic; works with all AI tools,2026-01-11,None
d020,p011,Keep FTS5 for search no vector embeddings,Minimal dependencies; FTS5 sufficient,2026-01-11,None
d021,p011,Implement ourselves rather than depend on claude-mem,claude-mem is Claude Code-only,2026-01-11,None
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

### [2026-01-23] Multi-Agent Orchestration & Token Efficiency

**Status:** Completed
**Estimate:** ~5d (ai:3d test:1d read:1d)
**Source:** [steveyegge/gastown](https://github.com/steveyegge/gastown) (inspiration, not wholesale adoption)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p013,Multi-Agent Orchestration & Token Efficiency,completed,8,8,,orchestration|tokens|agents|mailbox|toon|compaction,5d,3d,1d,1d,2026-01-23T00:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Evolve aidevops from single-session workflows to scalable multi-agent orchestration with:

- Inter-agent communication (TOON mailbox with lifecycle cleanup)
- Token-efficient AGENTS.md (lossless compression, ~60% reduction)
- Custom system prompt (eliminates harness tool preference conflicts)
- Compaction-surviving rules (OpenCode plugin hook)
- Stateless coordinator pattern (never hits context limits)
- Agent specialization with model routing
- TUI dashboard for zero-token monitoring
- User feedback loop pipeline for continuous improvement

**Key principles (user preferences):**

- Shell scripts over compiled binaries (transparency, editability)
- TOON format for structured data (token efficiency)
- TUI over web UI for visualization
- Lossless compression only (no knowledge/detail removed)
- Sessions must complete within context before compaction
- Memory system as long-term brain
- Specialized agents/models per task type
- Extend existing systems, don't re-implement

**Inspiration from Gas Town (cherry-picked, not wholesale):**

- Mailbox pattern for inter-agent communication
- Convoy concept for grouping related tasks
- Stateless coordinator (but NOT persistent Mayor - avoids context bloat)
- Agent registry with identity
- Formulas for repeatable workflows

**What we already have (extend, don't rebuild):**

- Worktrees: `worktree-helper.sh`, `wt` (Worktrunk)
- Task tracking: Beads + TODO.md + PLANS.md
- Iterative loops: Ralph Loop v2 + Full Loop
- Session management: `session-manager.md`, handoff pattern
- Memory: SQLite FTS5 (`memory-helper.sh`)
- Context guardrails: `context-guardrails.md`
- Re-anchor system: `loop-common.sh` (fresh context per iteration)
- TUI viewers: `beads_viewer`, `bdui`, `perles`

#### Context from Discussion

**The harness conflict problem:**

- OpenCode's anthropic-auth plugin enables `claude-code-20250219` beta flag
- This activates Claude Code's system prompt which says "use specialized tools"
- Our AGENTS.md says "NEVER use mcp_glob, use git ls-files/fd/rg instead"
- After compaction, the system prompt wins (negative constraints lost first)
- Solution: Custom `prompt` field replaces default system prompt entirely

**The compaction problem:**

- Sessions routinely hit 200K tokens with multiple compactions
- Critical rules (tool preferences, git check) lost after compaction
- OpenCode's `experimental.session.compacting` hook can inject rules
- Solution: aidevops plugin injects critical rules into every compaction

**Token efficiency analysis (current AGENTS.md):**

- 778 lines (~10K tokens) loaded every session
- Violates "50-100 instructions" principle from build-agent.md
- ~360 lines are duplicated content (already in subagents)
- ~41 lines of tables convertible to TOON (~50% savings)
- Target: ~300 lines (~3.5K tokens) with zero content loss

**Multi-agent scaling design:**

- Coordinator is STATELESS (pulse, not persistent) - reads state, dispatches, exits
- Workers are Ralph Loops with mailbox awareness
- Mailbox is TOON files with archive→remember→prune lifecycle
- Memory is the only persistent brain (everything else ephemeral)
- TUI dashboard reads files directly (zero AI token cost)

#### Decision Log

- **Decision:** Shell scripts for orchestration, not Go binary
  **Rationale:** Transparency, editability, no compile step; bottleneck is model inference not script speed
  **Date:** 2026-01-23

- **Decision:** Stateless coordinator (pulse) not persistent Mayor
  **Rationale:** Persistent coordinator accumulates context → compaction → drift. Stateless reads files, dispatches, exits (~20K tokens per pulse)
  **Date:** 2026-01-23

- **Decision:** TOON format for mailbox messages
  **Rationale:** 40-60% token savings vs JSON; human-readable; schema-aware
  **Date:** 2026-01-23

- **Decision:** Custom system prompt via OpenCode `prompt` field
  **Rationale:** Eliminates harness conflict entirely; our rules become highest priority
  **Date:** 2026-01-23

- **Decision:** Compaction plugin to preserve critical rules
  **Rationale:** Rules lost after compaction can be re-injected via `experimental.session.compacting` hook
  **Date:** 2026-01-23

- **Decision:** Lossless AGENTS.md compression (structural, not content removal)
  **Rationale:** User preference - all session learnings and detail must be preserved
  **Date:** 2026-01-23

- **Decision:** TUI for monitoring, not web UI
  **Rationale:** User preference; zero AI token cost; extend existing bdui/beads_viewer ecosystem
  **Date:** 2026-01-23

- **Decision:** Archive→remember→prune lifecycle for mailbox
  **Rationale:** Nothing lost (memory captures notable outcomes); context stays lean
  **Date:** 2026-01-23

- **Decision:** Model routing via subagent YAML frontmatter
  **Rationale:** Cheap models (Haiku) for routing/triage; capable models (Sonnet) for code; zero overhead
  **Date:** 2026-01-23

<!--TOON:decisions[9]{id,plan_id,decision,rationale,date,impact}:
d026,p013,Shell scripts for orchestration not Go binary,Transparency editability no compile step,2026-01-23,None
d027,p013,Stateless coordinator not persistent Mayor,Persistent coordinator accumulates context and drifts,2026-01-23,Architecture
d028,p013,TOON format for mailbox messages,40-60% token savings vs JSON,2026-01-23,None
d029,p013,Custom system prompt via OpenCode prompt field,Eliminates harness conflict entirely,2026-01-23,Architecture
d030,p013,Compaction plugin to preserve critical rules,Rules re-injected after every compaction,2026-01-23,Architecture
d031,p013,Lossless AGENTS.md compression,All session learnings and detail preserved,2026-01-23,None
d032,p013,TUI for monitoring not web UI,Zero AI token cost; extend existing ecosystem,2026-01-23,None
d033,p013,Archive-remember-prune lifecycle for mailbox,Nothing lost; context stays lean,2026-01-23,None
d034,p013,Model routing via subagent YAML frontmatter,Cheap models for routing; capable for code,2026-01-23,None
-->

#### Progress

- [ ] (2026-01-23) Phase 1: Custom System Prompt ~2h
  - Create `prompts/build.txt` with tool preferences and context rules
  - Update `opencode.json` to use `"prompt": "{file:./prompts/build.txt}"`
  - Move file discovery rules from AGENTS.md to system prompt
  - Move context budget rules to system prompt
  - Move security rules to system prompt
  - Test: verify tool preferences are enforced (glob never used)
  - **Session budget: ~40K tokens (small, focused)**

- [ ] (2026-01-23) Phase 2: Compaction Plugin ~4h
  - Create `opencode-aidevops-plugin/` package (TypeScript)
  - Implement `experimental.session.compacting` hook
  - Inject: tool preferences, git check trigger, context budget, security rules
  - Inject: current agent state from registry.toon (if exists)
  - Inject: guardrails from loop state (if exists)
  - Inject: relevant memories via memory-helper.sh recall
  - Test: verify rules survive compaction in long session
  - **Session budget: ~60K tokens (plugin dev + testing)**

- [ ] (2026-01-23) Phase 3: Lossless AGENTS.md Compression ~3h
  - Create `subagent-index.toon` (replaces 41-line markdown table)
  - Move pre-edit git check detail to `workflows/pre-edit.md` (keep 20-line trigger)
  - Remove duplicated content (planning, memory, quality, session sections)
  - Convert remaining markdown tables to TOON inline
  - Verify: every line removed exists in a subagent or system prompt
  - Update progressive disclosure instruction to reference index
  - Target: 778 lines → ~300 lines (~3.5K tokens)
  - **Session budget: ~50K tokens (careful restructuring)**

- [ ] (2026-01-23) Phase 4: TOON Mailbox System ~4h
  - Create `mail-helper.sh` with send|check|archive|prune|status|watch commands
  - Define message format (TOON): id, from, to, type, priority, convoy, timestamp, payload
  - Create directory structure: `~/.aidevops/.agent-workspace/mail/{inbox,outbox,archive}/`
  - Implement cleanup lifecycle: read→archive, 7-day prune, remember-before-prune
  - Create `registry.toon` format for active agent tracking
  - Test: send/receive between two terminal sessions
  - **Session budget: ~60K tokens (new script + testing)**

- [ ] (2026-01-23) Phase 5: Agent Registry & Worker Mailbox Awareness ~3h
  - Extend `worktree-sessions.sh` with agent identity (id, role, status)
  - Add mailbox check to Ralph Loop startup (read inbox before re-anchor)
  - Add status report to Ralph Loop completion (write outbox on finish)
  - Update `loop-common.sh` re-anchor to include pending messages
  - Create agent registration on worktree creation
  - Create agent deregistration on worktree cleanup
  - **Session budget: ~50K tokens (extending existing scripts)**

- [ ] (2026-01-23) Phase 6: Stateless Coordinator ~4h
  - Create `coordinator-helper.sh` (pulse script, not persistent)
  - Reads: registry.toon + outbox/\*.toon + TODO.md
  - Writes: inbox/\*.toon (dispatch instructions)
  - Stores: /remember (notable outcomes from worker reports)
  - Trigger: manual, cron, or fswatch on outbox/
  - Context budget per pulse: ~20K tokens (reads state, dispatches, exits)
  - Convoy grouping: bundle related beads for batch assignment
  - **Session budget: ~60K tokens (new orchestration logic)**

- [ ] (2026-01-23) Phase 7: Model Routing ~2h
  - Add `model:` field to subagent YAML frontmatter
  - Define model tiers: haiku (triage/routing), sonnet (code/review), opus (architecture)
  - Update `generate-opencode-agents.sh` to set model per agent
  - Create routing table in subagent-index.toon
  - Update coordinator to dispatch with model preference
  - **Session budget: ~30K tokens (config changes)**

- [ ] (2026-01-23) Phase 8: TUI Dashboard ~6h
  - Extend bdui or create new React/Ink TUI app
  - Display: agent registry (status, branch, last-seen)
  - Display: convoy progress (beads complete/total)
  - Display: mailbox status (unread count per agent)
  - Display: memory stats (entry count, last distill)
  - Reads: registry.toon, inbox/, outbox/, beads DB, memory.db
  - Zero AI token cost (separate process, reads files directly)
  - **Session budget: ~80K tokens (new TUI app)**

<!--TOON:milestones[8]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m064,p013,Phase 1: Custom System Prompt,2h,,2026-01-23T00:00Z,,pending
m065,p013,Phase 2: Compaction Plugin,4h,,2026-01-23T00:00Z,,pending
m066,p013,Phase 3: Lossless AGENTS.md Compression,3h,,2026-01-23T00:00Z,,pending
m067,p013,Phase 4: TOON Mailbox System,4h,,2026-01-23T00:00Z,,pending
m068,p013,Phase 5: Agent Registry & Worker Mailbox Awareness,3h,,2026-01-23T00:00Z,,pending
m069,p013,Phase 6: Stateless Coordinator,4h,,2026-01-23T00:00Z,,pending
m070,p013,Phase 7: Model Routing,2h,,2026-01-23T00:00Z,,pending
m071,p013,Phase 8: TUI Dashboard,6h,,2026-01-23T00:00Z,,pending
-->

#### Surprises & Discoveries

- **Observation:** OpenCode's `prompt` field completely replaces default system prompt
  **Evidence:** Context7 docs show `"prompt": "{file:./prompts/build.txt}"` on build agent
  **Impact:** Eliminates harness conflict entirely - our rules become highest priority
  **Date:** 2026-01-23

- **Observation:** OpenCode has `experimental.session.compacting` plugin hook
  **Evidence:** Context7 docs show output.context.push() and output.prompt replacement
  **Impact:** Critical rules can survive every compaction - solves instruction drift
  **Date:** 2026-01-23

- **Observation:** Anthropic auth plugin's `claude-code-20250219` beta flag activates Claude Code system prompt
  **Evidence:** Plugin code adds beta flag to anthropic-beta header
  **Impact:** This is root cause of tool preference conflicts (glob vs git ls-files)
  **Date:** 2026-01-23

- **Observation:** Gas Town uses same Beads ecosystem we already integrate
  **Evidence:** `.beads/` directory, `bd` CLI, convoy concept built on beads
  **Impact:** Validates our architecture; convoy is just a grouping layer on existing beads
  **Date:** 2026-01-23

<!--TOON:discoveries[4]{id,plan_id,observation,evidence,impact,date}:
disc002,p013,OpenCode prompt field replaces default system prompt,Context7 docs show file reference syntax,Eliminates harness conflict,2026-01-23
disc003,p013,OpenCode has experimental.session.compacting hook,Context7 docs show context injection,Rules survive compaction,2026-01-23
disc004,p013,Anthropic auth beta flag activates Claude Code prompt,Plugin code adds claude-code-20250219,Root cause of tool preference conflicts,2026-01-23
disc005,p013,Gas Town uses same Beads ecosystem,beads directory and bd CLI in gastown repo,Validates our architecture,2026-01-23
-->

#### Files to Create

| File                                    | Purpose                                                     | Phase |
| --------------------------------------- | ----------------------------------------------------------- | ----- |
| `prompts/build.txt`                     | Custom system prompt (tool prefs, context budget, security) | 1     |
| `opencode-aidevops-plugin/index.ts`     | Compaction hook plugin                                      | 2     |
| `opencode-aidevops-plugin/package.json` | Plugin package manifest                                     | 2     |
| `subagent-index.toon`                   | Compressed subagent discovery index                         | 3     |
| `workflows/pre-edit.md`                 | Detailed pre-edit git check (moved from AGENTS.md)          | 3     |
| `scripts/mail-helper.sh`                | Mailbox send/check/archive/prune/status/watch               | 4     |
| `scripts/coordinator-helper.sh`         | Stateless coordinator pulse script                          | 6     |
| TUI app (bdui extension or new)         | Agent/convoy/mailbox dashboard                              | 8     |

#### Files to Modify

| File                                  | Changes                                                     | Phase |
| ------------------------------------- | ----------------------------------------------------------- | ----- |
| `opencode.json`                       | Add `"prompt": "{file:./prompts/build.txt}"` to build agent | 1     |
| `AGENTS.md`                           | Compress to ~300 lines (pointers only, TOON tables)         | 3     |
| `scripts/loop-common.sh`              | Add mailbox check to re-anchor, status report on completion | 5     |
| `scripts/worktree-sessions.sh`        | Add agent identity and registration                         | 5     |
| `scripts/ralph-loop-helper.sh`        | Add mailbox awareness to worker startup/completion          | 5     |
| `scripts/generate-opencode-agents.sh` | Add model routing from frontmatter                          | 7     |

#### User Feedback Loop (Future Phase 9+)

Once phases 1-8 are complete, the orchestration layer enables:

```text
User Feedback (email, form, GitHub issue)
    → Feedback Processor (Haiku - categorize, extract actionable items)
    → Triage Agent (Haiku - priority, route to correct domain)
    → Coordinator pulse (Sonnet - plan response, create convoy)
    → Worker(s) (Sonnet - implement fix/feature via Ralph Loop)
    → PR → Review → Merge → Deploy (Full Loop)
    → Notify user (automated via mail-helper.sh)
    → /remember outcome (Memory captures pattern for future)
```

This reuses all infrastructure from phases 1-8 and adds only an ingestion pipeline.

---

### [2026-01-25] Document Extraction Subagent & Workflow

**Status:** Completed
**Estimate:** ~3h (ai:1h test:2h)
**PRD:** [todo/tasks/prd-document-extraction.md](tasks/prd-document-extraction.md)
**Source:** [On-Premise Document Intelligence Stack](https://pub.towardsai.net/building-an-on-premise-document-intelligence-stack-with-docling-ollama-phi-4-extractthinker-6ab60b495751)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,logged,started,completed}:
p014,Document Extraction Subagent & Workflow,completed,2,2,,document-extraction|docling|extractthinker|presidio|pii|local-llm|privacy,3h,1h,2h,2026-01-25T01:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Create a comprehensive document extraction capability in aidevops that:

1. Supports fully local/on-premise processing for sensitive documents (GDPR/HIPAA compliance)
2. Integrates PII detection and anonymization (Microsoft Presidio)
3. Uses advanced document parsing (Docling) for layout understanding
4. Provides LLM-powered extraction (ExtractThinker) with contract-based schemas
5. Supports multiple LLM backends (Ollama local, Cloudflare Workers AI, cloud APIs)

**Key components:**

- **Docling** (51k stars): Parse PDF, DOCX, PPTX, XLSX, HTML, images with layout understanding
- **ExtractThinker** (1.5k stars): LLM-powered extraction with Pydantic contracts
- **Presidio** (6.7k stars): PII detection and anonymization (Microsoft)
- **Local LLMs**: Ollama (Phi-4, Llama 3.x, Qwen 2.5) or Cloudflare Workers AI

**Pipeline flow:**

```text
Document → Docling (parse) → Presidio (PII scan) → ExtractThinker (extract) → Structured JSON
```

**Relationship to existing Unstract subagent:**

- Unstract = cloud/self-hosted platform with visual Prompt Studio
- This = code-first, fully local, privacy-preserving alternative
- Both can coexist - Unstract for complex workflows, this for quick local extraction

#### Context from Discussion

**Why build this:**

- Existing Unstract integration requires Docker and platform setup
- Need lightweight, code-first extraction for quick tasks
- Privacy requirements demand fully local processing option
- PII detection should happen BEFORE any cloud API calls

**Technology choices:**

| Component           | Tool                  | Why                                                 |
| ------------------- | --------------------- | --------------------------------------------------- |
| Document Parsing    | Docling               | Best layout understanding, 51k stars, LF AI project |
| LLM Extraction      | ExtractThinker        | ORM-style contracts, multi-loader support           |
| PII Detection       | Presidio              | Microsoft-backed, extensible, MIT license           |
| Local LLM           | Ollama                | Easy setup, wide model support                      |
| Cloud LLM (private) | Cloudflare Workers AI | Data doesn't leave Cloudflare, no logging           |

**Architecture:**

```text
tools/document-extraction/
├── document-extraction.md      # Main orchestrator subagent
├── docling.md                  # Document parsing subagent
├── extractthinker.md           # LLM extraction subagent
├── presidio.md                 # PII detection/anonymization subagent
├── local-llm.md                # Local LLM configuration subagent
└── contracts/                  # Example extraction contracts
    ├── invoice.md
    ├── receipt.md
    ├── driver-license.md
    └── contract.md

scripts/
├── document-extraction-helper.sh  # CLI wrapper
├── docling-helper.sh              # Docling operations
├── presidio-helper.sh             # PII operations
└── extractthinker-helper.sh       # Extraction operations
```

#### Progress

- [ ] (2026-01-25) Phase 1: Research & Environment Setup ~4h
  - Create Python venv at `~/.aidevops/.agent-workspace/python-env/document-extraction/`
  - Install dependencies: docling, extract-thinker, presidio-analyzer, presidio-anonymizer
  - Test basic imports and verify versions
  - Document hardware requirements and compatibility

- [ ] (2026-01-25) Phase 2: Docling Subagent ~5.5h
  - Create `tools/document-extraction/docling.md` subagent
  - Create `scripts/docling-helper.sh` with commands: parse, convert, ocr, info
  - Support formats: PDF, DOCX, PPTX, XLSX, HTML, PNG, JPEG, TIFF
  - Export to: Markdown, JSON, DocTags
  - Test with sample documents (invoice, receipt, contract)

- [ ] (2026-01-25) Phase 3: Presidio Subagent (PII) ~5.5h
  - Create `tools/document-extraction/presidio.md` subagent
  - Create `scripts/presidio-helper.sh` with commands: analyze, anonymize, deanonymize, entities
  - Support entities: names, SSN, credit cards, phone, email, addresses, etc.
  - Support operators: redact, replace, hash, encrypt, mask
  - Add custom recognizer examples for domain-specific PII
  - Test with PII-laden sample documents

- [ ] (2026-01-25) Phase 4: ExtractThinker Subagent ~7.5h
  - Create `tools/document-extraction/extractthinker.md` subagent
  - Create `scripts/extractthinker-helper.sh` with commands: extract, classify, batch
  - Create example contracts in `contracts/` folder
  - Support document loaders: DocumentLoaderDocling, DocumentLoaderPyPdf
  - Support LLM backends: Ollama, OpenAI, Anthropic, Azure
  - Implement splitting strategies: lazy, eager
  - Implement pagination for small context windows
  - Test extraction accuracy on sample documents

- [ ] (2026-01-25) Phase 5: Local LLM Subagent ~3.5h
  - Create `tools/document-extraction/local-llm.md` subagent
  - Document Ollama setup and model recommendations
  - Document Cloudflare Workers AI setup (privacy-preserving cloud)
  - Create model selection guide (text vs vision, context window, speed)
  - Test with Phi-4, Llama 3.x, Moondream (vision)

- [ ] (2026-01-25) Phase 6: Orchestrator & Main Script ~8h
  - Create `tools/document-extraction/document-extraction.md` main subagent
  - Create `scripts/document-extraction-helper.sh` with commands:
    - `extract <file> <contract>` - Full pipeline
    - `extract --local <file> <contract>` - Force local LLM
    - `extract --no-pii <file> <contract>` - Skip PII scan
    - `batch <folder> <contract>` - Batch processing
    - `pii-scan <file>` - PII detection only
    - `parse <file>` - Document parsing only
    - `models` - List available LLM backends
    - `contracts` - List available contracts
  - Implement configurable pipeline stages
  - Add progress tracking for batch operations
  - Add error handling and retry logic

- [ ] (2026-01-25) Phase 7: Integration Testing ~4h
  - Test full pipeline with various document types
  - Test PII detection accuracy (target: >98% recall)
  - Test extraction accuracy (target: >95% on invoices)
  - Test local-only mode (no network calls)
  - Test batch processing performance
  - Document known limitations

- [ ] (2026-01-25) Phase 8: Documentation & Integration ~3h
  - Update `subagent-index.toon` with new subagents
  - Add to AGENTS.md progressive disclosure table
  - Create usage examples in subagent docs
  - Document relationship with existing Unstract subagent
  - Add to setup.sh (optional Python env setup)

<!--TOON:milestones[8]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m072,p014,Phase 1: Research & Environment Setup,4h,,2026-01-25T01:00Z,,pending
m073,p014,Phase 2: Docling Subagent,5.5h,,2026-01-25T01:00Z,,pending
m074,p014,Phase 3: Presidio Subagent (PII),5.5h,,2026-01-25T01:00Z,,pending
m075,p014,Phase 4: ExtractThinker Subagent,7.5h,,2026-01-25T01:00Z,,pending
m076,p014,Phase 5: Local LLM Subagent,3.5h,,2026-01-25T01:00Z,,pending
m077,p014,Phase 6: Orchestrator & Main Script,8h,,2026-01-25T01:00Z,,pending
m078,p014,Phase 7: Integration Testing,4h,,2026-01-25T01:00Z,,pending
m079,p014,Phase 8: Documentation & Integration,3h,,2026-01-25T01:00Z,,pending
-->

#### Decision Log

- **Decision:** Create separate subagent ecosystem rather than extending Unstract
  **Rationale:** Unstract is a platform (Docker, UI, API); this is code-first for quick local extraction
  **Date:** 2026-01-25

- **Decision:** Use Docling over MarkItDown for document parsing
  **Rationale:** Docling has superior layout understanding, multi-OCR support, 51k stars, LF AI project
  **Date:** 2026-01-25

- **Decision:** Presidio for PII detection over custom regex
  **Rationale:** Microsoft-backed, extensible, supports 50+ entity types, MIT license
  **Date:** 2026-01-25

- **Decision:** ExtractThinker over direct LLM calls
  **Rationale:** ORM-style contracts, handles pagination/splitting, supports multiple loaders
  **Date:** 2026-01-25

- **Decision:** Python venv in agent-workspace rather than global install
  **Rationale:** Isolation prevents dependency conflicts; easy cleanup; reproducible
  **Date:** 2026-01-25

- **Decision:** Cloudflare Workers AI as privacy-preserving cloud option
  **Rationale:** Data processed at edge, no logging, GDPR-friendly alternative to OpenAI
  **Date:** 2026-01-25

<!--TOON:decisions[6]{id,plan_id,decision,rationale,date,impact}:
d035,p014,Create separate subagent ecosystem rather than extending Unstract,Unstract is a platform; this is code-first for quick local extraction,2026-01-25,Architecture
d036,p014,Use Docling over MarkItDown for document parsing,Superior layout understanding; 51k stars; LF AI project,2026-01-25,None
d037,p014,Presidio for PII detection over custom regex,Microsoft-backed; extensible; 50+ entity types,2026-01-25,None
d038,p014,ExtractThinker over direct LLM calls,ORM-style contracts; handles pagination/splitting,2026-01-25,None
d039,p014,Python venv in agent-workspace,Isolation prevents conflicts; easy cleanup,2026-01-25,None
d040,p014,Cloudflare Workers AI as privacy-preserving cloud,Data at edge; no logging; GDPR-friendly,2026-01-25,None
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

#### Files to Create

| File                                                    | Purpose                              | Phase |
| ------------------------------------------------------- | ------------------------------------ | ----- |
| `tools/document-extraction/document-extraction.md`      | Main orchestrator subagent           | 6     |
| `tools/document-extraction/docling.md`                  | Document parsing subagent            | 2     |
| `tools/document-extraction/extractthinker.md`           | LLM extraction subagent              | 4     |
| `tools/document-extraction/presidio.md`                 | PII detection/anonymization subagent | 3     |
| `tools/document-extraction/local-llm.md`                | Local LLM configuration subagent     | 5     |
| `tools/document-extraction/contracts/invoice.md`        | Invoice extraction contract          | 4     |
| `tools/document-extraction/contracts/receipt.md`        | Receipt extraction contract          | 4     |
| `tools/document-extraction/contracts/driver-license.md` | ID extraction contract               | 4     |
| `tools/document-extraction/contracts/contract.md`       | Legal contract extraction            | 4     |
| `scripts/document-extraction-helper.sh`                 | Main CLI wrapper                     | 6     |
| `scripts/docling-helper.sh`                             | Docling operations                   | 2     |
| `scripts/presidio-helper.sh`                            | PII operations                       | 3     |
| `scripts/extractthinker-helper.sh`                      | Extraction operations                | 4     |

#### Files to Modify

| File                  | Changes                             | Phase |
| --------------------- | ----------------------------------- | ----- |
| `subagent-index.toon` | Add document-extraction subagents   | 8     |
| `AGENTS.md`           | Add to progressive disclosure table | 8     |
| `setup.sh`            | Add optional Python env setup       | 8     |

---

### [2026-01-31] Claude-Flow Inspirations - Selective Feature Adoption

**Status:** Completed
**Estimate:** ~3d (ai:2d test:0.5d read:0.5d)
**Source:** [ruvnet/claude-flow](https://github.com/ruvnet/claude-flow) - Analysis of v3 features

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p015,Claude-Flow Inspirations - Selective Feature Adoption,completed,4,4,,memory|embeddings|routing|optimization|learning,3d,2d,0.5d,0.5d,2026-01-31T00:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Selectively adopt high-value concepts from Claude-Flow v3 while maintaining aidevops' lightweight, shell-script-based philosophy. Claude-Flow is a heavy orchestration platform (~340MB, TypeScript) - we cherry-pick concepts, not implementation.

**What Claude-Flow does well:**

- HNSW vector memory (150x-12,500x faster semantic search)
- 3-tier cost-aware routing (WASM → Haiku → Opus)
- Self-learning routing (SONA neural architecture)
- Swarm consensus (Byzantine fault-tolerant coordination)

**What aidevops already has:**

- SQLite FTS5 memory (fast keyword search)
- Task tool with model parameter
- Session distillation for pattern capture
- Inter-agent mailbox (TOON-based)

**Philosophy:** Borrow concepts, keep lightweight. No 340MB dependencies.

#### Context from Discussion

**Analysis summary (2026-01-31):**

| Feature         | Claude-Flow      | aidevops Current   | Adoption Priority |
| --------------- | ---------------- | ------------------ | ----------------- |
| Vector memory   | HNSW (semantic)  | FTS5 (keyword)     | Medium            |
| Cost routing    | 3-tier automatic | Manual model param | High              |
| Self-learning   | SONA neural      | Manual patterns    | Medium            |
| Swarm consensus | Byzantine/Raft   | Mailbox async      | Low               |
| WASM transforms | Agent Booster    | N/A                | Low               |

**Key decisions:**

- **Vector memory**: Add optional HNSW alongside FTS5, not replace
- **Cost routing**: Add model hints to Task tool, document routing guidance
- **Self-learning**: Track success patterns in memory, surface in `/recall`
- **Swarm consensus**: Skip - aidevops philosophy is simpler async coordination
- **WASM transforms**: Skip - Edit tool is already fast enough

#### Progress

- [ ] (2026-01-31) Phase 1: Cost-Aware Model Routing ~4h
  - Document model tier guidance in `tools/context/model-routing.md`
  - Define task complexity → model mapping (simple→haiku, code→sonnet, architecture→opus)
  - Add `model:` field to subagent YAML frontmatter (extend existing)
  - Update Task tool documentation with model parameter best practices
  - Create `/route` command to suggest optimal model for a task description
  - **Deliverable:** Agents can specify preferred model tier, users get routing guidance

- [ ] (2026-01-31) Phase 2: Semantic Memory with Embeddings ~8h
  - Research lightweight embedding options (all-MiniLM-L6-v2 via ONNX, ~90MB)
  - Create `memory-embeddings-helper.sh` for vector operations
  - Add optional HNSW index to `~/.aidevops/.agent-workspace/memory/`
  - Extend `memory-helper.sh` with `--semantic` flag for similarity search
  - Keep FTS5 as default, embeddings as opt-in enhancement
  - Add `/recall --similar "query"` for semantic search
  - **Deliverable:** Semantic memory search without heavy dependencies

- [ ] (2026-01-31) Phase 3: Success Pattern Tracking ~6h
  - Extend memory types with `SUCCESS_PATTERN` and `FAILURE_PATTERN`
  - Auto-tag memories with task type, model used, outcome
  - Create `pattern-tracker-helper.sh` to analyze memory for patterns
  - Add `/patterns` command to show what works for different task types
  - Surface relevant patterns in `/recall` results
  - **Deliverable:** System learns which approaches work over time

- [ ] (2026-01-31) Phase 4: Documentation & Integration ~6h
  - Create `aidevops/claude-flow-comparison.md` documenting differences
  - Update `memory/README.md` with semantic search docs
  - Update `AGENTS.md` with model routing guidance
  - Add to `subagent-index.toon`
  - Test full workflow: store pattern → recall semantically → route optimally
  - **Deliverable:** Complete documentation, tested integration

<!--TOON:milestones[4]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m080,p015,Phase 1: Cost-Aware Model Routing,4h,,2026-01-31T00:00Z,,pending
m081,p015,Phase 2: Semantic Memory with Embeddings,8h,,2026-01-31T00:00Z,,pending
m082,p015,Phase 3: Success Pattern Tracking,6h,,2026-01-31T00:00Z,,pending
m083,p015,Phase 4: Documentation & Integration,6h,,2026-01-31T00:00Z,,pending
-->

#### Decision Log

- **Decision:** Cherry-pick concepts, not implementation
  **Rationale:** Claude-Flow is 340MB TypeScript; aidevops is lightweight shell scripts. Different philosophies.
  **Date:** 2026-01-31

- **Decision:** Keep FTS5 as default, embeddings as opt-in
  **Rationale:** FTS5 is fast, zero dependencies, works for most cases. Embeddings add ~90MB.
  **Date:** 2026-01-31

- **Decision:** Skip swarm consensus and WASM transforms
  **Rationale:** aidevops uses simpler async mailbox; Edit tool is already fast enough.
  **Date:** 2026-01-31

- **Decision:** Use all-MiniLM-L6-v2 via ONNX for embeddings
  **Rationale:** Small (~90MB), fast, no Python required, good quality for code/text.
  **Date:** 2026-01-31

<!--TOON:decisions[4]{id,plan_id,decision,rationale,date,impact}:
d035,p015,Cherry-pick concepts not implementation,Claude-Flow is 340MB TypeScript; aidevops is lightweight shell,2026-01-31,Architecture
d036,p015,Keep FTS5 as default embeddings as opt-in,FTS5 is fast zero dependencies works for most cases,2026-01-31,None
d037,p015,Skip swarm consensus and WASM transforms,aidevops uses simpler async mailbox; Edit tool fast enough,2026-01-31,None
d038,p015,Use all-MiniLM-L6-v2 via ONNX for embeddings,Small fast no Python required good quality,2026-01-31,None
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

#### Files to Create

| File                                  | Purpose                                | Phase |
| ------------------------------------- | -------------------------------------- | ----- |
| `tools/context/model-routing.md`      | Model tier guidance and routing logic  | 1     |
| `scripts/commands/route.md`           | `/route` command for model suggestions | 1     |
| `scripts/memory-embeddings-helper.sh` | Vector embedding operations            | 2     |
| `scripts/pattern-tracker-helper.sh`   | Success/failure pattern analysis       | 3     |
| `scripts/commands/patterns.md`        | `/patterns` command definition         | 3     |
| `aidevops/claude-flow-comparison.md`  | Feature comparison documentation       | 4     |

#### Files to Modify

| File                       | Changes                              | Phase |
| -------------------------- | ------------------------------------ | ----- |
| Subagent YAML frontmatter  | Add `model:` field where appropriate | 1     |
| `scripts/memory-helper.sh` | Add `--semantic` flag, pattern types | 2, 3  |
| `memory/README.md`         | Document semantic search, patterns   | 4     |
| `AGENTS.md`                | Add model routing guidance           | 4     |
| `subagent-index.toon`      | Add new subagents                    | 4     |

---

### [2026-02-03] Parallel Agents & Headless Dispatch

**Status:** Completed
**Estimate:** ~3d (ai:1.5d test:1d read:0.5d)
**Source:** [alexfazio's X post on droids](https://gist.github.com/alexfazio/dcf2f253d346d8ed2702935b57184582)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p016,Parallel Agents & Headless Dispatch,completed,5,5,,agents|parallel|headless|dispatch|runners|memory,3d,1.5d,1d,0.5d,2026-02-03T00:00Z,2026-02-05T00:00Z,2026-03-21T00:00Z
-->

#### Purpose

Document and implement patterns for running parallel OpenCode sessions locally, with optional Matrix chat integration. Inspired by alexfazio's "droids" architecture but adapted for local-first, low-complexity use.

**Naming decision:** Renamed from "droids" to "runners" to avoid conflict with Factory.ai's branded "Droids" product. "Runner" maps to the CI/CD mental model (named execution environments that pick up tasks).

**Key insight from source:** `opencode run "prompt"` enables headless dispatch without containers or hosting costs. `opencode run --attach` connects to a warm server for faster dispatch. Each session can have its own AGENTS.md and memory namespace.

**What we're NOT doing:**

- Fly.io Sprites or cloud hosting (overkill for local use)
- Containers (unnecessary complexity for trusted code)
- New orchestration frameworks (extend existing mailbox)

**What we ARE doing:**

- Document `opencode run` headless patterns and `opencode serve` server mode
- Create runner-helper.sh for namespaced agent dispatch
- Integrate with existing memory system (per-runner namespaces)
- Optional Matrix bot for chat-triggered dispatch
- Document model provider flexibility (any provider via `opencode auth login`)

#### Context from Discussion

**Complexity/Maintenance/Context Analysis:**

| Approach                  | Complexity | Maintenance | Context Hazard     | User Attention         |
| ------------------------- | ---------- | ----------- | ------------------ | ---------------------- |
| Fly.io Sprites            | High       | High        | Low (isolated)     | High (new concepts)    |
| Local containers          | Medium     | Medium      | Low (isolated)     | Medium                 |
| Local parallel sessions   | Low        | Low         | Medium (shared fs) | Low                    |
| Matrix bot + local claude | Medium     | Low         | Low (per-room)     | Medium (initial setup) |

**Decision:** Start with local parallel sessions. Add Matrix bot if chat-triggered UX is desired. Skip containers unless isolation is required.

**Architecture:**

```text
~/.aidevops/.agent-workspace/
├── runners/
│   ├── code-reviewer/
│   │   ├── AGENTS.md      # Runner personality/instructions
│   │   ├── config.json    # Runner configuration
│   │   ├── session.id     # Last session ID (for --continue)
│   │   └── runs/          # Run logs
│   └── seo-analyst/
│       ├── AGENTS.md
│       ├── config.json
│       └── runs/
```

**Key patterns from source post (adapted for OpenCode):**

1. `opencode run "prompt"` - headless dispatch
2. `opencode run --attach http://localhost:4096` - warm server dispatch
3. `opencode run -s $session_id` - session resumption
4. `opencode serve` - persistent server for parallel sessions
5. Self-editing AGENTS.md - agents that improve themselves
6. Chat-triggered dispatch - reduce friction vs terminal

**Model provider flexibility:**

```bash
# Configure via opencode auth login (interactive)
opencode auth login

# Or override per-dispatch
opencode run -m openrouter/anthropic/claude-sonnet-4-20250514 "task"
```

Users can choose any provider supported by OpenCode via `opencode auth login`.

#### Progress

- [x] (2026-02-05) Phase 1: Document headless dispatch patterns ~4h
  - Created `tools/ai-assistants/headless-dispatch.md`
  - Documented `opencode run` flags and `--format json` output
  - Documented session resumption with `-s` and `-c`
  - Documented `opencode serve` + `--attach` warm server pattern
  - Added SDK parallel dispatch examples
  - Added CI/CD integration (GitHub Actions)
- [x] (2026-02-05) Phase 2: Create runner-helper.sh ~4h
  - Namespaced agent dispatch with per-runner AGENTS.md
  - Commands: create, run, status, list, edit, logs, stop, destroy
  - Integration with `opencode run --attach` for warm server dispatch
  - Run logging and metadata tracking
- [x] (2026-02-05) Phase 3: Memory namespace integration ~3h
  - Added `--namespace/-n` flag to memory-helper.sh and memory-embeddings-helper.sh
  - Per-runner isolated DBs at `memory/namespaces/<name>/memory.db`
  - `--shared` flag on recall searches both namespace and global
  - `namespaces` command (list/prune/migrate)
- [x] (2026-02-06) Phase 4: Matrix bot integration (optional) ~6h
  - Created `scripts/matrix-dispatch-helper.sh` (setup, start, stop, map, test, logs)
  - Created `services/communications/matrix-bot.md` subagent documentation
  - Room-to-runner mapping with configurable bot prefix (`!ai`)
  - Node.js bot using `matrix-bot-sdk` with auto-join, typing indicators, reactions
  - Dispatch via `runner-helper.sh` with fallback to OpenCode HTTP API
  - Cloudron Synapse setup guide included
  - User allowlist, concurrency control, response truncation
- [x] (2026-02-05) Phase 5: Documentation & examples ~3h
  - Updated AGENTS.md with parallel agent guidance
  - Created example runners (code-reviewer, seo-analyst) in `tools/ai-assistants/runners/`
  - Documented when to use parallel vs sequential in headless-dispatch.md

<!--TOON:milestones[5]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m064,p016,Phase 1: Document headless dispatch patterns,4h,,2026-02-03T00:00Z,,pending
m065,p016,Phase 2: Create droid-helper.sh,4h,,2026-02-03T00:00Z,,pending
m066,p016,Phase 3: Memory namespace integration,3h,,2026-02-03T00:00Z,2026-02-05T00:00Z,completed
m067,p016,Phase 4: Matrix bot integration (optional),6h,,2026-02-03T00:00Z,2026-02-06T00:00Z,completed
m068,p016,Phase 5: Documentation & examples,3h,,2026-02-03T00:00Z,2026-02-05T00:00Z,completed
-->

#### Decision Log

- **Decision:** Local parallel sessions over containers/cloud
  **Rationale:** Zero hosting cost, shared filesystem, no sync needed, existing credentials work
  **Date:** 2026-02-03

- **Decision:** Extend existing memory system with namespaces
  **Rationale:** Reuse proven SQLite FTS5 infrastructure, avoid new dependencies
  **Date:** 2026-02-03

- **Decision:** Matrix over Discord/Slack for chat integration
  **Rationale:** Self-hosted on Cloudron, no platform risk, already in user's stack
  **Date:** 2026-02-03

- **Decision:** Document model providers generically, not specific versions
  **Rationale:** Models evolve quickly (minimax, kimi, qwen, deepseek, etc.), keep options open
  **Date:** 2026-02-03

<!--TOON:decisions[4]{id,plan_id,decision,rationale,date,impact}:
d039,p016,Local parallel sessions over containers/cloud,Zero hosting cost shared filesystem no sync needed,2026-02-03,Architecture
d040,p016,Extend existing memory system with namespaces,Reuse proven SQLite FTS5 infrastructure,2026-02-03,None
d041,p016,Matrix over Discord/Slack for chat integration,Self-hosted on Cloudron no platform risk,2026-02-03,None
d042,p016,Document model providers generically,Models evolve quickly keep options open,2026-02-03,None
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

#### Files to Create

| File                                         | Purpose                       | Phase |
| -------------------------------------------- | ----------------------------- | ----- |
| `tools/ai-assistants/headless-dispatch.md`   | Document `claude -p` patterns | 1     |
| `scripts/droid-helper.sh`                    | Namespaced agent dispatch     | 2     |
| `scripts/matrix-dispatch-helper.sh`          | Matrix bot integration        | 4     |
| Example droids in `.agent-workspace/droids/` | Reference implementations     | 5     |

#### Files to Modify

| File                       | Changes                     | Phase |
| -------------------------- | --------------------------- | ----- |
| `scripts/memory-helper.sh` | Add `--namespace` flag      | 3     |
| `memory/README.md`         | Document namespace feature  | 3     |
| `AGENTS.md`                | Add parallel agent guidance | 5     |
| `subagent-index.toon`      | Add new subagents           | 5     |

---

### [2026-02-04] Self-Improving Agent System

**Status:** Completed
**Estimate:** ~2d (ai:1d test:0.5d read:0.5d)
**Source:** Discussion on parallel agents, OpenCode server, and community contributions

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p017,Self-Improving Agent System,completed,6,6,,agents|self-improvement|automation|privacy|testing|opencode,2d,1d,0.5d,0.5d,2026-02-04T00:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Create a self-improving agent system that can review its own performance, refine agents based on learnings, test changes in isolated sessions, and contribute improvements back to the community with proper privacy filtering.

**Key capabilities:**

1. **Review** - Analyze memory for success/failure patterns, identify gaps
2. **Refine** - Generate and apply improvements to agents/scripts
3. **Test** - Validate changes in isolated OpenCode sessions
4. **PR** - Contribute improvements with privacy filtering for public repos

**Safety guardrails:**

- Worktree isolation for all changes
- Human approval required for PRs
- Mandatory privacy filter before public contributions
- Dry-run default (must explicitly enable PR creation)
- Scope limits (agents-only or scripts-only)
- Audit log to memory

#### Context from Discussion

**Architecture:**

```text
┌─────────────────────────────────────────────────────────────────────────┐
│                        Self-Improvement Loop                             │
│                                                                          │
│  ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐          │
│  │  REVIEW  │───▶│  REFINE  │───▶│  TEST    │───▶│  PR      │          │
│  │          │    │          │    │          │    │          │          │
│  │ Memory   │    │ Edit     │    │ OpenCode │    │ Privacy  │          │
│  │ Patterns │    │ Agents   │    │ Sessions │    │ Filter   │          │
│  │ Failures │    │ Scripts  │    │ Validate │    │ gh CLI   │          │
│  └──────────┘    └──────────┘    └──────────┘    └──────────┘          │
│       ▲                                               │                  │
│       └───────────────────────────────────────────────┘                  │
│                         Iterate until quality gates pass                 │
└─────────────────────────────────────────────────────────────────────────┘
```

**What we already have:**

- `agent-review.md` - Manual review process
- `memory-helper.sh` - Pattern storage (SUCCESS/FAILURE types)
- `session-distill-helper.sh` - Extract learnings
- `secretlint` - Credential detection
- OpenCode server API - Isolated session testing

**Privacy filter components:**

1. Secretlint scan for credentials
2. Pattern-based redaction (emails, IPs, local URLs, home paths, API keys)
3. Project-specific patterns from `.aidevops/privacy-patterns.txt`
4. Dry-run review before PR creation

**Example workflow:**

```bash
# Agent notices repeated failure pattern
/remember type:FAILURE "ShellCheck SC2086 errors keep appearing in new scripts"

# Later, self-improvement runs
/self-improve --scope scripts --dry-run

# Output:
# === Self-Improvement Analysis ===
#
# FAILURE patterns found: 3
# - SC2086 unquoted variables (5 occurrences)
# - SC2155 declare and assign separately (2 occurrences)
# - Missing 'local' in functions (3 occurrences)
#
# Proposed changes:
# 1. Update build-agent.md with ShellCheck reminder
# 2. Add pre-commit hook for ShellCheck
# 3. Create shellcheck-patterns.md subagent
#
# Test results: PASS (3/3 quality gates)
# Privacy filter: CLEAN (no secrets/PII detected)
#
# Run without --dry-run to create PR
```

#### Progress

- [ ] (2026-02-04) Phase 1: Review phase - pattern analysis ~1.5h
  - Query memory for FAILURE/SUCCESS patterns
  - Identify gaps (failures without solutions)
  - Check agent-review suggestions
  - Create self-improve-helper.sh with analyze command
- [ ] (2026-02-04) Phase 2: Refine phase - generate improvements ~2h
  - Generate improvement proposals from patterns
  - Edit agents/scripts in worktree
  - Run linters-local.sh for validation
  - Add refine command to self-improve-helper.sh
- [ ] (2026-02-04) Phase 3: Test phase - isolated sessions ~1.5h
  - Create OpenCode test session via API
  - Run test prompts against improved agents
  - Validate quality gates pass
  - Compare before/after behavior
  - Add test command to self-improve-helper.sh
- [ ] (2026-02-04) Phase 4: Privacy filter implementation ~3h
  - Create privacy-filter-helper.sh
  - Integrate secretlint for credential detection
  - Add pattern-based redaction (emails, IPs, paths, keys)
  - Support project-specific patterns
  - Dry-run review mode
- [ ] (2026-02-04) Phase 5: PR phase - community contributions ~1h
  - Run privacy filter (mandatory)
  - Show redacted diff for approval
  - Create PR with evidence from memory
  - Include test results and privacy attestation
  - Add pr command to self-improve-helper.sh
- [ ] (2026-02-04) Phase 6: Documentation & /self-improve command ~2h
  - Create tools/build-agent/self-improvement.md subagent
  - Create scripts/commands/self-improve.md
  - Update AGENTS.md with self-improvement guidance
  - Add examples and safety documentation

<!--TOON:milestones[6]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m069,p017,Phase 1: Review phase - pattern analysis,1.5h,,2026-02-04T00:00Z,,pending
m070,p017,Phase 2: Refine phase - generate improvements,2h,,2026-02-04T00:00Z,,pending
m071,p017,Phase 3: Test phase - isolated sessions,1.5h,,2026-02-04T00:00Z,,pending
m072,p017,Phase 4: Privacy filter implementation,3h,,2026-02-04T00:00Z,,pending
m073,p017,Phase 5: PR phase - community contributions,1h,,2026-02-04T00:00Z,,pending
m074,p017,Phase 6: Documentation & /self-improve command,2h,,2026-02-04T00:00Z,,pending
-->

#### Decision Log

- **Decision:** Use OpenCode server API for isolated testing
  **Rationale:** Provides session management, async prompts, and SSE events without spawning CLI processes
  **Date:** 2026-02-04

- **Decision:** Mandatory privacy filter before any public PR
  **Rationale:** Prevents accidental exposure of credentials, PII, or internal paths
  **Date:** 2026-02-04

- **Decision:** Dry-run default for self-improvement
  **Rationale:** Human must explicitly approve PR creation, prevents runaway automation
  **Date:** 2026-02-04

- **Decision:** Worktree isolation for all changes
  **Rationale:** Easy rollback, doesn't affect main branch until PR merged
  **Date:** 2026-02-04

<!--TOON:decisions[4]{id,plan_id,decision,rationale,date,impact}:
d043,p017,Use OpenCode server API for isolated testing,Provides session management and SSE events without CLI spawning,2026-02-04,Architecture
d044,p017,Mandatory privacy filter before any public PR,Prevents accidental exposure of credentials or PII,2026-02-04,Security
d045,p017,Dry-run default for self-improvement,Human must explicitly approve PR creation,2026-02-04,Safety
d046,p017,Worktree isolation for all changes,Easy rollback and doesn't affect main branch,2026-02-04,Safety
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

#### Files to Create

| File                                    | Purpose                      | Phase |
| --------------------------------------- | ---------------------------- | ----- |
| `scripts/self-improve-helper.sh`        | Main self-improvement script | 1-5   |
| `scripts/privacy-filter-helper.sh`      | Privacy filtering for PRs    | 4     |
| `scripts/agent-test-helper.sh`          | Agent testing framework      | 3     |
| `scripts/commands/self-improve.md`      | /self-improve command        | 6     |
| `tools/build-agent/self-improvement.md` | Self-improvement subagent    | 6     |
| `tools/security/privacy-filter.md`      | Privacy filter documentation | 4     |

#### Files to Modify

| File                  | Changes                       | Phase |
| --------------------- | ----------------------------- | ----- |
| `memory-helper.sh`    | Add pattern query helpers     | 1     |
| `agent-review.md`     | Link to self-improvement      | 6     |
| `AGENTS.md`           | Add self-improvement guidance | 6     |
| `subagent-index.toon` | Add new subagents             | 6     |

#### Related Tasks

| Task | Description                             | Dependency             |
| ---- | --------------------------------------- | ---------------------- |
| t116 | Self-improving agent system (main task) | This plan              |
| t117 | Privacy filter for public PRs           | Blocks t116.4          |
| t118 | Agent testing framework                 | Related                |
| t115 | OpenCode server documentation           | Prerequisite knowledge |

---

### [2026-02-05] SEO Tool Subagents Sprint

**Status:** Completed
**Estimate:** ~1.5d (ai:1d test:4h read:2h)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p020,SEO Tool Subagents Sprint,completed,3,3,,seo|tools|subagents|sprint,1.5d,1d,4h,2h,2026-02-05T00:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Batch-create 12 SEO tool subagents (t083-t094) in a single sprint. All follow an identical pattern: create a markdown subagent with API docs, install commands, usage examples, and integration notes. The existing 16 SEO subagents in `seo/` provide perfect templates.

**Estimated total:** ~11.5h across 12 tasks, but parallelizable to ~4-5h actual since they follow the same pattern and an AI agent can generate multiple in a single session.

#### Context from Discussion

**Corrections identified during audit (2026-02-05):**

| Task                   | Issue                                | Fix                                                              |
| ---------------------- | ------------------------------------ | ---------------------------------------------------------------- |
| t084 Rich Results Test | Google deprecated the standalone API | Use URL-based testing only; document browser automation approach |
| t086 Screaming Frog    | CLI requires paid license ($259/yr)  | Document free tier limits (500 URLs); note license requirement   |
| t088 Sitebulb          | No public API or CLI exists          | Change scope to "document manual workflow" or decline            |
| t089 ContentKing       | Acquired by Conductor in 2022        | Verify post-acquisition API status; may need different endpoint  |
| t087 Semrush           | API has pricing tiers                | Document free tier (10 requests/day) and paid tiers              |

#### Progress

- [ ] (2026-02-05) Phase 1: API-based subagents (7 tasks, ~6h) ~6h
  - t083 Bing Webmaster Tools - API key from Bing portal, URL submission, indexation, analytics
  - t084 Rich Results Test - URL-based testing (API deprecated), browser automation for validation
  - t085 Schema Validator - schema.org validator + Google structured data testing tool
  - t087 Semrush - API integration, note pricing tiers (free: 10 req/day)
  - t090 WebPageTest - API integration, differentiate from existing pagespeed.md
  - t092 Schema Markup - JSON-LD templates for Article, Product, FAQ, HowTo, Organization, LocalBusiness
  - t094 Analytics Tracking - GA4 setup, event tracking, UTM parameters, attribution

- [ ] (2026-02-05) Phase 2: Workflow-based subagents (3 tasks, ~4h) ~4h
  - t091 Programmatic SEO - Template engine decision, keyword clustering, internal linking automation
  - t093 Page CRO - A/B testing setup, CTA optimization, landing page best practices
  - t089 ContentKing/Conductor - Verify API status post-acquisition, real-time SEO monitoring

- [ ] (2026-02-05) Phase 3: Special cases + integration (2 tasks, ~2h) ~2h
  - t086 Screaming Frog - Document CLI with license requirement, free tier limits (500 URLs)
  - t088 Sitebulb - Document manual workflow only (no API/CLI exists), or decline
  - Update subagent-index.toon with all new subagents
  - Update seo.md main agent with references to new subagents

<!--TOON:milestones[3]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m101,p020,Phase 1: API-based subagents (7 tasks),6h,,2026-02-05T00:00Z,,pending
m102,p020,Phase 2: Workflow-based subagents (3 tasks),4h,,2026-02-05T00:00Z,,pending
m103,p020,Phase 3: Special cases + integration (2 tasks),2h,,2026-02-05T00:00Z,,pending
-->

#### Decision Log

- **Decision:** Batch all 12 SEO tasks into a single sprint
  **Rationale:** All follow identical subagent creation pattern; existing 16 SEO subagents provide templates. Parallelizable to ~4-5h actual.
  **Date:** 2026-02-05

- **Decision:** t088 (Sitebulb) scope changed to manual workflow documentation
  **Rationale:** Sitebulb has no public API or CLI. Desktop-only application.
  **Date:** 2026-02-05

<!--TOON:decisions[2]{id,plan_id,decision,rationale,date,impact}:
d051,p020,Batch all 12 SEO tasks into single sprint,Identical pattern; existing templates; parallelizable,2026-02-05,Efficiency
d052,p020,t088 Sitebulb scope changed to manual workflow,No public API or CLI exists,2026-02-05,Scope
-->

#### Surprises & Discoveries

(To be populated during implementation)

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

#### Related Tasks

| Task | Description           | Phase |
| ---- | --------------------- | ----- |
| t083 | Bing Webmaster Tools  | 1     |
| t084 | Rich Results Test     | 1     |
| t085 | Schema Validator      | 1     |
| t086 | Screaming Frog        | 3     |
| t087 | Semrush               | 1     |
| t088 | Sitebulb              | 3     |
| t089 | ContentKing/Conductor | 2     |
| t090 | WebPageTest           | 1     |
| t091 | Programmatic SEO      | 2     |
| t092 | Schema Markup         | 1     |
| t093 | Page CRO              | 2     |
| t094 | Analytics Tracking    | 1     |

---

### [2026-02-05] Voice Integration Pipeline

**Status:** Completed
**Estimate:** ~3d (ai:1.5d test:1d read:0.5d)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p019,Voice Integration Pipeline,completed,6,6,,voice|ai|pipecat|transcription|tts|stt|local|api,3d,1.5d,1d,0.5d,2026-02-05T00:00Z,,2026-03-21T00:00Z
-->

#### Purpose

Create a comprehensive voice integration for aidevops supporting both local and cloud-based speech capabilities. This enables hands-free AI interaction via voice-to-text, text-to-speech, and full speech-to-speech conversation loops with OpenCode.

**Dual-track philosophy:** Every voice capability should have both a local option (privacy, offline, no cost) and an API option (higher quality, lower latency, easier setup). Users choose based on their needs.

**Key capabilities:**

1. **Transcription** (audio/video → text) - Local: Whisper/faster-whisper. API: Groq, ElevenLabs Scribe, Deepgram, Soniox
2. **TTS** (text → speech) - Local: Qwen3-TTS, Piper. API: Cartesia Sonic, ElevenLabs, OpenAI TTS
3. **STT** (realtime speech → text) - Local: Whisper.cpp. API: Soniox, Deepgram, Google
4. **S2S** (speech → speech, no intermediate text) - API: OpenAI Realtime, AWS Nova Sonic, Gemini Multimodal Live, Ultravox
5. **Voice agent pipeline** - Pipecat framework orchestrating STT+LLM+TTS or S2S
6. **Dispatch shortcuts** - macOS/iOS shortcuts for voice-triggered OpenCode commands

#### Context from Discussion

**Pipecat ecosystem (v0.0.101, 10.2k stars, Feb 2026):**

- Python framework for voice/multimodal AI agents
- 50+ service integrations (STT, TTS, LLM, S2S, transport)
- Daily.co WebRTC transport for real-time audio
- S2S support: OpenAI Realtime, AWS Nova Sonic, Gemini Multimodal Live, Grok Voice Agent, Ultravox
- Voice UI Kit for web-based voice interfaces

**Local model options:**

- **Qwen3-TTS** (0.6B/1.7B, Apache-2.0): 10 languages, voice clone/design, streaming, vLLM support
- **Piper** (MIT): Fast local TTS, many voices, low resource usage
- **Whisper Large v3 Turbo** (1.5GB): Best accuracy/speed tradeoff for local transcription
- **faster-whisper**: CTranslate2-optimized Whisper, 4x faster than original

**Task sequencing:**

| Phase | Tasks                | Dependency                   | Rationale                          |
| ----- | -------------------- | ---------------------------- | ---------------------------------- |
| 1     | t072 Transcription   | None                         | Foundation - most broadly useful   |
| 2     | t071 TTS/STT Models  | None (parallel with Phase 1) | Model catalog for other phases     |
| 3     | t081 Local Pipecat   | t071, t072                   | Local voice agent pipeline         |
| 4     | t080 NVIDIA Nemotron | t081                         | Cloud voice agent with open models |
| 5     | t114 OpenCode bridge | t081                         | Connect voice pipeline to AI       |
| 6     | t112, t113 Shortcuts | t114                         | Quick dispatch from desktop/mobile |

#### Progress

- [ ] (2026-02-05) Phase 1: Transcription subagent (t072) ~6h
  - Create `tools/voice/transcription.md` subagent
  - Create `scripts/transcription-helper.sh` (transcribe, models, configure)
  - Document local models: Whisper Large v3 Turbo (recommended), faster-whisper, NVIDIA Parakeet
  - Document cloud APIs: Groq Whisper, ElevenLabs Scribe v2, Deepgram Nova, Soniox
  - Support inputs: YouTube (yt-dlp), URLs, local audio/video files
  - Output formats: plain text, SRT, VTT

- [ ] (2026-02-05) Phase 2: Voice AI models catalog (t071) ~4h
  - Create `tools/voice/voice-models.md` subagent
  - Document TTS options: local (Qwen3-TTS, Piper) vs API (Cartesia Sonic, ElevenLabs, OpenAI)
  - Document STT options: local (Whisper.cpp, faster-whisper) vs API (Soniox, Deepgram)
  - Document S2S options: OpenAI Realtime, AWS Nova Sonic, Gemini Multimodal Live, Ultravox
  - Include model selection guide (quality vs speed vs cost vs privacy)
  - GPU requirements and benchmarks for local models

- [ ] (2026-02-05) Phase 3: Local Pipecat voice agent (t081) ~4h
  - Create `tools/voice/pipecat.md` subagent
  - Create `scripts/pipecat-helper.sh` (setup, start, stop, configure)
  - Document pipeline: Mic → STT → LLM → TTS → Speaker
  - Support both STT+LLM+TTS pipeline and S2S mode (OpenAI Realtime)
  - Configure local fallback: Whisper.cpp + llama.cpp + Piper for offline use
  - Configure cloud default: Soniox + OpenAI/Anthropic + Cartesia Sonic
  - Test on macOS using kwindla/macos-local-voice-agents as reference

- [ ] (2026-02-05) Phase 4: Cloud voice agents and S2S models (t080) ~6h
  - Extend pipecat.md with cloud S2S provider configurations
  - **S2S providers (no separate STT/TTS needed):** GPT-4o-Realtime (OpenAI), AWS Nova Sonic, Gemini Multimodal Live, Ultravox
  - **NVIDIA Nemotron:** Cloud-only via NVIDIA API (requires NVIDIA GPU for local; use cloud credits for low usage). Clone pipecat-ai/nemotron-january-2026 repo
  - **Local S2S alternative:** MiniCPM-o 4.5 (23k stars, Apache-2.0, 9B params) - runs on Mac via llama.cpp-omni, supports full-duplex voice+vision+text, WebRTC demo available. Also MiniCPM-o 2.6 for lighter-weight local use
  - Test voice pipeline with Daily.co WebRTC transport
  - Build customer service agent template with configurable personas
  - Document integration with OpenClaw for messaging platform voice calls

- [ ] (2026-02-05) Phase 5: OpenCode voice bridge (t114) ~4h
  - Create `tools/voice/pipecat-opencode.md` subagent
  - Pipeline: Mic → Soniox STT → OpenCode API → Cartesia TTS → Speaker
  - Use OpenCode server API for prompt submission and response streaming
  - Support session continuity (resume voice conversation)
  - Handle long responses (streaming TTS as text arrives)

- [ ] (2026-02-05) Phase 6: Voice dispatch shortcuts (t112, t113) ~2h
  - Create `tools/voice/voiceink-shortcut.md` (macOS)
  - Create `tools/voice/ios-shortcut.md` (iPhone)
  - macOS: VoiceInk transcription → Shortcut → HTTP POST to OpenCode → response
  - iOS: Dictate → HTTP POST to OpenCode (via Tailscale) → Speak response
  - Include AppleScript/Shortcuts app instructions

<!--TOON:milestones[6]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m095,p019,Phase 1: Transcription subagent (t072),6h,,2026-02-05T00:00Z,,pending
m096,p019,Phase 2: Voice AI models catalog (t071),4h,,2026-02-05T00:00Z,,pending
m097,p019,Phase 3: Local Pipecat voice agent (t081),4h,,2026-02-05T00:00Z,,pending
m098,p019,Phase 4: NVIDIA Nemotron voice agents (t080),6h,,2026-02-05T00:00Z,,pending
m099,p019,Phase 5: OpenCode voice bridge (t114),4h,,2026-02-05T00:00Z,,pending
m100,p019,Phase 6: Voice dispatch shortcuts (t112 t113),2h,,2026-02-05T00:00Z,,pending
-->

#### Decision Log

- **Decision:** Dual-track local + API for every capability
  **Rationale:** Privacy-sensitive users need local options; quality-focused users need cloud APIs. Both must be first-class.
  **Date:** 2026-02-05

- **Decision:** Pipecat as the orchestration framework
  **Rationale:** 10.2k stars, 50+ service integrations, Python, actively maintained, S2S support. No viable alternative at this scale.
  **Date:** 2026-02-05

- **Decision:** Whisper Large v3 Turbo as default local transcription model
  **Rationale:** Best accuracy/speed tradeoff (9.7 accuracy, 7.5 speed). Half the size of Large v3 (1.5GB vs 2.9GB) with near-identical accuracy.
  **Date:** 2026-02-05

- **Decision:** S2S as preferred mode when available
  **Rationale:** OpenAI Realtime, AWS Nova Sonic, and Gemini Multimodal Live provide lower latency and more natural conversation than STT+LLM+TTS pipeline. Fall back to pipeline when S2S unavailable.
  **Date:** 2026-02-05

<!--TOON:decisions[4]{id,plan_id,decision,rationale,date,impact}:
d047,p019,Dual-track local + API for every capability,Privacy-sensitive users need local; quality-focused need cloud,2026-02-05,Architecture
d048,p019,Pipecat as orchestration framework,10.2k stars 50+ integrations Python actively maintained,2026-02-05,Architecture
d049,p019,Whisper Large v3 Turbo as default local model,Best accuracy/speed tradeoff at half the size,2026-02-05,None
d050,p019,S2S as preferred mode when available,Lower latency and more natural than STT+LLM+TTS pipeline,2026-02-05,Architecture
-->

#### Surprises & Discoveries

- **Observation:** Pipecat v0.0.101 now supports 5 S2S providers natively
  **Evidence:** OpenAI Realtime, AWS Nova Sonic, Gemini Multimodal Live, Grok Voice Agent, Ultravox all documented in pipecat.ai/docs
  **Impact:** Simplifies t081 significantly - S2S may replace STT+LLM+TTS for cloud use
  **Date:** 2026-02-05

- **Observation:** MiniCPM-o 4.5 (23k stars, Apache-2.0) provides local full-duplex S2S on Mac
  **Evidence:** 9B param model runs via llama.cpp-omni with WebRTC demo. Supports simultaneous vision+audio+text. Approaches Gemini 2.5 Flash quality.
  **Impact:** Provides a strong local S2S alternative to cloud-only options. NVIDIA Nemotron requires NVIDIA GPU locally but MiniCPM-o runs on Mac/CPU.
  **Date:** 2026-02-05

- **Observation:** GPT-4o-Realtime is the most mature S2S option via Pipecat
  **Evidence:** First S2S provider supported by Pipecat, well-documented, lowest latency
  **Impact:** Recommended as default cloud S2S provider for Phase 4
  **Date:** 2026-02-05

<!--TOON:discoveries[3]{id,plan_id,observation,evidence,impact,date}:
disc006,p019,Pipecat v0.0.101 supports 5 S2S providers natively,All documented in pipecat.ai/docs,Simplifies t081 - S2S may replace STT+LLM+TTS for cloud,2026-02-05
disc007,p019,MiniCPM-o 4.5 provides local full-duplex S2S on Mac,9B params via llama.cpp-omni with WebRTC demo,Strong local S2S alternative - runs on Mac/CPU unlike Nemotron,2026-02-05
disc008,p019,GPT-4o-Realtime is most mature S2S option,First Pipecat S2S provider well-documented lowest latency,Recommended as default cloud S2S provider,2026-02-05
-->

#### Files to Create

| File                               | Purpose                      | Phase |
| ---------------------------------- | ---------------------------- | ----- |
| `tools/voice/transcription.md`     | Transcription subagent       | 1     |
| `scripts/transcription-helper.sh`  | Transcription CLI            | 1     |
| `tools/voice/voice-models.md`      | Voice AI model catalog       | 2     |
| `tools/voice/pipecat.md`           | Pipecat voice agent subagent | 3     |
| `scripts/pipecat-helper.sh`        | Pipecat CLI                  | 3     |
| `tools/voice/pipecat-opencode.md`  | OpenCode voice bridge        | 5     |
| `tools/voice/voiceink-shortcut.md` | macOS voice shortcut         | 6     |
| `tools/voice/ios-shortcut.md`      | iPhone voice shortcut        | 6     |

#### Files to Modify

| File                  | Changes                                               | Phase |
| --------------------- | ----------------------------------------------------- | ----- |
| `subagent-index.toon` | Add voice subagents                                   | 1-6   |
| `AGENTS.md`           | Add voice integration to progressive disclosure table | 6     |
| `README.md`           | Update Voice Integration section                      | 6     |

#### Related Tasks

| Task | Description                        | Phase |
| ---- | ---------------------------------- | ----- |
| t072 | Audio/Video Transcription subagent | 1     |
| t071 | Voice AI models catalog            | 2     |
| t081 | Local Pipecat voice agent          | 3     |
| t080 | NVIDIA Nemotron voice agents       | 4     |
| t114 | Pipecat-OpenCode bridge            | 5     |
| t112 | VoiceInk macOS shortcut            | 6     |
| t113 | iPhone voice shortcut              | 6     |
| t027 | hyprwhspr Linux STT (related)      | -     |

---

### [2026-02-10] Higgsfield Automator Production Hardening

**Status:** In Progress (Phase 1/5)
**Estimate:** ~6h (ai:4h test:1.5h read:30m)
**TODO:** t236

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started}:
p029,Higgsfield Automator Production Hardening,in_progress,1,5,,higgsfield|automation|reliability|video|image,6h,4h,1.5h,30m,2026-02-10T18:00Z,2026-02-10T18:00Z
-->

#### Purpose

Harden the Higgsfield Playwright automator from "works in testing" to "reliable production tool." The automator covers 100% of Higgsfield UI features (27 CLI commands, 70+ apps, 271 motion presets, 32 mixed media presets, 10 image models, 11 lipsync models) but lacks error recovery, cost awareness, batch operations, and output organization needed for real content production workflows.

#### Context

**Current state:** 27 CLI commands covering all Higgsfield UI features. PRs #926, #942, #956, #958 merged. Auth working, 5,924/6,000 credits remaining, 19 unlimited models available. All commands navigate and click correctly after overlay/dialog fixes.

**Gaps identified:** No retry logic, no credit guards, no unlimited model auto-selection, no batch mode, no output organization, no dry-run mode, no auth resilience.

#### Phases

- [ ] **Phase 1: Retry Logic + Credit Guard** ~1.5h `t236.1`
  - Add retry wrapper with exponential backoff for transient failures
  - Pre-operation credit check (abort if insufficient credits for the operation)
  - Credit cost map per operation type (image: 1-2, video: 10-40, lipsync: 5-20, upscale: 2)
  - Handle "Failed - unsupported content" by logging and skipping (not retrying)
  - Handle rate limits / queue full with backoff

- [ ] **Phase 2: Unlimited Model Auto-Selection** ~1h `t236.2`
  - Parse unlimited models from credits page (already extracted: 19 models)
  - Cache unlimited model list in state dir
  - Auto-select unlimited model when available for the requested operation type
  - `--prefer-unlimited` flag (default: true) and `--model` override
  - Map unlimited model names to UI model selector values

- [ ] **Phase 3: Batch Operations** ~1.5h `t236.3`
  - `batch-image` command: generate N images across M models with prompt variations
  - `batch-video` command: animate a set of images (from dir or asset library)
  - `batch-lipsync` command: apply audio to multiple video assets
  - Concurrency control (1 at a time for credit safety, parallel for unlimited)
  - Progress reporting and summary output

- [ ] **Phase 4: Output Organization + Metadata** ~1h `t236.4`
  - Project-based output directories (`--project <name>` flag)
  - Descriptive filenames: `{project}_{model}_{prompt-slug}_{timestamp}.{ext}`
  - JSON sidecar metadata files (model, prompt, settings, credits used, duration)
  - Deduplication: skip download if file with same CDN URL already exists
  - Manifest file per batch run

- [ ] **Phase 5: Dry-Run + Auth Resilience** ~1h `t236.5`
  - `--dry-run` flag: navigate to tool, configure settings, screenshot, but don't click Generate
  - Auth health check before long operations (re-login if session expired)
  - Smoke test command: `higgsfield smoke-test` runs dry-run on 5 key workflows
  - Auto-refresh auth state after successful operations

#### Decision Log

| Date       | Decision                               | Rationale                                 |
| ---------- | -------------------------------------- | ----------------------------------------- |
| 2026-02-10 | Start with retry + credit guard        | Prevents wasted credits, highest ROI      |
| 2026-02-10 | Unlimited model auto-select as Phase 2 | Maximizes Creator plan value              |
| 2026-02-10 | Batch ops before output org            | Productivity multiplier > file management |

---

### [2026-02-25] SimpleX Chat Agent and Command Integration

**Status:** Completed
**Estimate:** ~29h (ai:21h test:5h read:3h)
**TODO:** t1327
**Logged:** 2026-02-25
**Reference:** https://simplex.chat/ | https://github.com/simplex-chat/simplex-chat | [Bot API](https://github.com/simplex-chat/simplex-chat/tree/stable/bots) | [TypeScript SDK](https://github.com/simplex-chat/simplex-chat/tree/stable/packages/simplex-chat-client/typescript) | [Whitepaper](https://github.com/simplex-chat/simplexmq/blob/stable/protocol/overview-tjr.md) | [mail-helper.sh](.agents/scripts/mail-helper.sh) | [IronClaw](https://github.com/nearai/ironclaw) | [OpenClaw](https://github.com/openclaw/openclaw)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started,completed}:
p032,SimpleX Chat Agent and Command Integration,completed,8,8,,feature|communications|security|bots|opsec|mailbox|chat-security,29h,21h,5h,3h,2026-02-25T00:00Z,,2026-03-21T00:00Z
-->

#### Purpose

SimpleX Chat is the most privacy-respecting messaging platform available — no user identifiers (not even random ones), no phone numbers, no central metadata storage. This integration brings secure, zero-knowledge communications to aidevops for:

1. **Secure remote AI agent control** — initiate sessions on remote devices running aidevops without exposing management interfaces to the public internet
2. **Private device-to-device agent communication** — extend existing `mail-helper.sh` mailbox system with SimpleX/Matrix transport so agents on different machines coordinate over encrypted channels with zero metadata leakage
3. **AI-powered bots** for direct and group channels — customer support, information retrieval, service automation, moderation
4. **Business bot deployment** — per-customer support chats with agent escalation (SimpleX business addresses)
5. **Opsec-first communications** — for users who need secure channels without trusting a central provider
6. **Voice/file/attachment exchange** between users and AI agents
7. **Future: real-time voice/video calls** between users and AI agents (when aidevops gains those capabilities)

No existing aidevops integration covers secure messaging at this level. Matrix (existing agent) is federated but has user identifiers and server-side metadata. SimpleX fills the zero-knowledge gap.

#### Context

**SimpleX Protocol Key Properties:**

| Property   | Detail                                                                |
| ---------- | --------------------------------------------------------------------- |
| Identity   | No user identifiers — connections are pairs of uni-directional queues |
| Encryption | Double ratchet (X3DH, Curve448) + AES-GCM + per-queue NaCl layer      |
| Routing    | 2-hop onion routing — sender IP hidden from recipient's server        |
| Servers    | Stateless — messages in memory only, deleted after delivery           |
| Files      | XFTP — separate protocol, files split across multiple servers         |
| Calls      | WebRTC with E2E encryption, ICE via chat protocol                     |
| Platforms  | iOS, Android, Desktop (Mac/Win/Linux), Terminal CLI                   |

**Bot API Architecture:**

```
User (SimpleX mobile/desktop/CLI)
    |
    | SimpleX Protocol (E2E encrypted, no user IDs)
    |
SimpleX CLI (WebSocket server, port 5225)
    |
    | WebSocket JSON API (corrId request/response)
    |
aidevops SimpleX Bot (TypeScript/Bun)
    |--- aidevops CLI commands (/run, /status, /deploy)
    |--- AI model queries (/ask, /analyze)
    |--- File/voice handling (/voice, /file)
    |--- Group management (/invite, /role, /broadcast)
    |--- Task management (/task, /tasks)
```

**Slash Command Design (no conflicts):**

SimpleX bot commands use `/` in SimpleX chat context. aidevops commands use `/` in terminal context. Separate environments, no collision. Bot command menu configured via `/set bot commands` with hierarchical structure (similar to Telegram inline keyboards).

Starter commands: `/help`, `/status`, `/ask <q>`, `/run <cmd>`, `/task <desc>`, `/tasks`, `/deploy <project>`, `/logs <service>`, `/voice`, `/file`, `/broadcast <msg>`, `/invite @user`, `/role @user <role>`.

**Known Limitations:**

1. **Cross-device sync**: Cannot access same profile from multiple devices simultaneously. Workaround: CLI in cloud + Remote Control Protocol from desktop.
2. **Owner role recovery**: Lost device = lost group ownership. Mitigation: owner profiles on multiple devices.
3. **Group stability**: Decentralized groups can have delayed delivery, member list desync at scale.
4. **Bot WebSocket API unauthenticated**: Must run localhost or behind TLS proxy with basic auth.
5. **No server-side search**: E2E encryption means local search only.

**Opsec Agent Scope (existing aidevops tools + confirmed additions):**

| Category        | Tools / Existing Agents                                                         |
| --------------- | ------------------------------------------------------------------------------- |
| Messaging       | SimpleX (this task), Matrix (`matrix-bot.md`)                                   |
| Mesh VPN        | NetBird (`services/networking/netbird.md`)                                      |
| VPN             | Mullvad, IVPN (confirmed for use)                                               |
| Secrets         | gopass, Bitwarden/Vaultwarden, Enpass, SOPS, multi-tenant                       |
| Encryption      | gocryptfs, encryption-stack, SOPS                                               |
| Browsers        | Brave (recommended), CamoFox/anti-detect, fingerprint-profiles, stealth-patches |
| Network         | proxy-integration, IP reputation, CDN origin IP                                 |
| Security        | privacy-filter, Shannon entropy, Tirith                                         |
| Threat modeling | STRIDE, attack trees, risk matrices (guidance, not tooling)                     |

Note: Additional tools (Tor, YubiKey, Whonix, Tails, etc.) assessed and added as needs arise.

#### Execution Phases

**Phase 1: Research & Foundation** (~2h)

- [ ] Deep-read SimpleX bot API types reference (COMMANDS.md, EVENTS.md, TYPES.md)
- [ ] Review TypeScript SDK source (`simplex-chat` npm package)
- [ ] Test SimpleX CLI installation and basic operations
- [ ] Review existing `matrix-bot.md`, `ip-reputation-helper.sh`, and `mail-helper.sh` patterns

**Phase 2: Subagent Documentation** (~4h)

- [ ] Create `.agents/services/communications/simplex.md` — comprehensive knowledge base
  - Installation (CLI, desktop, mobile)
  - Bot API reference (WebSocket protocol, commands, events)
  - Business addresses and multi-agent support
  - Protocol overview (SMP, XFTP, WebRTC)
  - Voice notes, file attachments, media handling
  - Multi-platform usage (desktop, mobile, CLI)
  - Cross-device workarounds (Remote Control Protocol)
  - Self-hosted SMP/XFTP server setup
  - Upstream contribution guidance (AGPL, issue templates, PR workflow)
  - Limitations and mitigations
  - Integration with other aidevops capabilities

**Phase 3: Helper Script** (~3h)

- [ ] Create `simplex-helper.sh` with subcommands:
  - `install` — download and install SimpleX CLI
  - `init` — guided setup wizard (create profile, configure servers, create address)
  - `bot-start` / `bot-stop` — manage bot process
  - `send <contact> <message>` — send message
  - `connect <address>` — connect to contact/group
  - `group <create|list|invite>` — group management
  - `status` — show connection status, active chats, bot health
  - `server <setup|status>` — self-hosted SMP server management

**Phase 4: Bot Framework** (~4h)

- [ ] Create TypeScript/Bun bot scaffold as **channel-agnostic gateway** (inspired by OpenClaw/IronClaw gateway pattern):
  - Channel abstraction layer — SimpleX as first adapter, Matrix/others plug in later
  - WebSocket connection to SimpleX CLI (first channel adapter)
  - Session-per-sender/group isolation (each contact/group gets own state)
  - Command router with `/` prefix handling
  - Event handler for NewChatItems, contact requests, file transfers
  - Starter commands: `/help`, `/status`, `/ask`, `/run`, `/task`, `/tasks`
  - Command menu configuration (hierarchical, Telegram-style)
  - DM pairing flow — unknown contacts get pairing code, admin approves via `aidevops simplex pairing approve`
  - Mention-based activation in groups (respond to `/` commands and @mentions only)
  - Typing indicators while AI processes
  - Voice note handling (receive -> transcribe -> respond)
  - File attachment handling (receive -> analyze/store -> respond)
  - Business address support (per-customer group chats)
  - Error handling and reconnection logic
  - Reference: OpenClaw gateway pattern (225K stars), IronClaw WASM channels

**Phase 4b: Mailbox Transport Adapter** (~3h)

- [ ] Extend `mail-helper.sh` with SimpleX transport:
  - New subcommand: `mail-helper.sh transport <simplex|matrix|local>` to configure transport
  - `local` (default): existing SQLite-only, same-machine mailbox
  - `simplex`: send/receive mailbox messages over SimpleX (E2E encrypted, cross-machine)
  - `matrix`: send/receive mailbox messages over Matrix (cross-machine, existing rooms)
  - Preserve existing message types: task_dispatch, status_report, discovery, request, broadcast
  - Serialize mailbox messages as JSON over SimpleX/Matrix text messages
  - Agent registration includes transport preference and remote address
  - Convoy tracking works across transports (local convoy ID maps to remote message thread)
  - Fallback: if remote transport unavailable, queue locally and retry
- [ ] Design: SimpleX transport uses `simplex-helper.sh send` under the hood
- [ ] Design: Matrix transport uses existing matrix-bot.md capabilities
- [ ] Test: agent on machine A sends task_dispatch via SimpleX to agent on machine B

**Phase 5: Opsec Agent** (~3h)

- [ ] Create `.agents/tools/security/opsec.md`:
  - Threat modeling frameworks (STRIDE, attack trees, risk matrices)
  - Secure communications (SimpleX vs Matrix — comparison, when to use which)
  - Platform trust matrix: E2E encryption status, metadata collection, data training policies, phone number requirements — recommend secure apps (SimpleX, Matrix), caution others (Telegram, WhatsApp), warn about unencrypted (Discord, Slack, IRC)
  - Chat-connected AI security model (inspired by IronClaw/OpenClaw):
    - DM pairing by default — unknown senders must be approved
    - Prompt injection defense — chat messages are untrusted input
    - Tool sandboxing — commands from chat run in restricted environment
    - Credential isolation — secrets never exposed to chat context
    - Leak detection — scan outbound messages for credential patterns
    - Per-group tool policies — different groups get different permissions
    - Exec approvals — dangerous commands require explicit approval
  - Network privacy (NetBird mesh VPN, existing proxy-integration, IP reputation, CDN origin IP agents)
  - VPN guidance (Mullvad, IVPN — when and how to use)
  - Browser privacy (Brave recommended, CamoFox/anti-detect, fingerprint-profiles, stealth-patches)
  - Secret management (existing gopass, Bitwarden/Vaultwarden, SOPS, gocryptfs, encryption-stack agents)
  - Operational security practices (compartmentalization, metadata hygiene, credential rotation)
  - aidevops-specific opsec (multi-tenant credentials, privacy-filter, audit trails)
  - Cross-references to all existing security/credentials/browser agents
  - Reference: IronClaw security model, OpenClaw security defaults
  - Note: additional tools (Tor, YubiKey, Whonix, Tails) assessed as needs arise

**Phase 6: Chat Security** (~6h, inspired by IronClaw/OpenClaw)

- [ ] Prompt injection defense for chat inputs (t1327.8):
  - Pattern detection: role-play attacks, instruction override, delimiter injection, encoding tricks
  - Content sanitization before passing to AI model
  - Severity-based policy: block (reject message), warn (process but flag), sanitize (strip dangerous patterns)
  - Log flagged attempts for audit
  - Reference: IronClaw's multi-layer prompt injection defense
- [ ] Outbound leak detection (t1327.9):
  - Scan AI responses before sending to chat for: API keys, credentials, file paths, internal IPs, DB connection strings
  - Extend existing Shannon entropy detection pattern (`tools/security/shannon.md`)
  - Gate at bot's send boundary — if leak detected, redact and warn operator
  - Reference: IronClaw's host-boundary leak scanning
- [ ] Exec approval flow for remote chat commands (t1327.10):
  - When user sends `/run <command>` via chat, classify command risk level
  - Safe commands (e.g., `/status`, `/tasks`, `/help`) — execute immediately
  - Approval-required commands (e.g., `/run`, `/deploy`) — send approval request back to chat, wait for confirmation (configurable timeout, default reject)
  - Blocked commands (configurable) — reject with explanation
  - Approval can come from same user (if owner) or designated approver contact
  - Reference: IronClaw TUI approval overlay, OpenClaw `/approve` flow

**Phase 7: Matterbridge Integration** — split to t1328

**Phase 8: Integration & Testing** (~4h)

- [ ] Update `subagent-index.toon` with simplex and opsec entries
- [ ] Update both `AGENTS.md` files (domain index)
- [ ] End-to-end test: install CLI, create bot, send/receive messages
- [ ] Test voice note and file attachment handling
- [ ] Test business address flow
- [ ] ShellCheck all scripts, markdown lint all docs
- [ ] Document in simplex.md: how to contribute upstream (issue templates, PR workflow, feedback logging via `gh issue create`)

#### Decision Log

| Date       | Decision                                            | Rationale                                                                                                                                  |
| ---------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| 2026-02-25 | SimpleX over Signal/Telegram                        | Only platform with zero user identifiers — true anonymity                                                                                  |
| 2026-02-25 | Bot via WebSocket API, not direct SMP               | Officially supported, avoids reimplementing complex protocol                                                                               |
| 2026-02-25 | TypeScript/Bun for bot, not Haskell                 | Aligns with aidevops ecosystem, TypeScript SDK available                                                                                   |
| 2026-02-25 | No MCP server — CLI agents sufficient               | MCP adds context bloat with no capability the bot + helper script don't provide                                                            |
| 2026-02-25 | Extend existing mailbox, not new protocol           | mail-helper.sh already has message types, agent registration, convoy tracking — add SimpleX/Matrix as transport adapters                   |
| 2026-02-25 | Opsec scoped to existing aidevops tools + confirmed | NetBird, Mullvad, IVPN, Brave, CamoFox + existing agents. Others assessed as needs arise                                                   |
| 2026-02-25 | Slash commands coexist without conflict             | Separate contexts (SimpleX chat vs terminal) — document clearly                                                                            |
| 2026-02-25 | Business address for multi-agent support            | Per-customer group chats ideal for support bots with escalation                                                                            |
| 2026-02-25 | Voice/video calls as future phase                   | Depends on aidevops gaining real-time audio/video processing                                                                               |
| 2026-02-25 | Self-hosted SMP server guidance included            | Maximum privacy requires own infrastructure — document setup                                                                               |
| 2026-02-25 | Matterbridge for SimpleX-Matrix bridging            | Existing adapter (matterbridge-simplex) bridges SimpleX to 40+ platforms via Matterbridge — unifies with existing Matrix integration       |
| 2026-02-25 | Privacy gradient via bridging                       | Users choose SimpleX (max privacy) or Matrix/Telegram (convenience) — same conversation, different privacy levels                          |
| 2026-02-25 | Bot as channel-agnostic gateway                     | Inspired by OpenClaw (225K stars) gateway pattern — SimpleX as first adapter, Matrix/others plug in later without rewriting core           |
| 2026-02-25 | Chat security as dedicated phase                    | IronClaw/OpenClaw both treat inbound DMs as untrusted — prompt injection defense, leak detection, exec approvals are real gaps in aidevops |
| 2026-02-25 | Matterbridge split to t1328                         | Separate agent — Matterbridge is a general-purpose bridge tool, not SimpleX-specific                                                       |

#### Surprises & Discoveries

- SimpleX bot command menus support nested hierarchical structure — more capable than expected, similar to Telegram inline keyboards
- Business addresses create per-customer GROUP chats (not direct chats) — enables multi-agent support scenarios
- Remote Control Protocol (XRCP) allows controlling CLI from desktop app via SSH tunnel — solves cross-device limitation for bot management
- SimpleX has a TypeScript types package (`@simplex-chat/types`) auto-generated from the bot API — reduces manual type definitions
- 2-hop onion routing is built into the protocol — sender IP protection without requiring Tor
- AGPL license means any bot framework we build and distribute must be open source — aligns with aidevops's open approach
- matterbridge-simplex already exists (MIT, 52 commits, Docker-compose ready) — no need to build a custom SimpleX-Matrix bridge from scratch
- Matterbridge supports 40+ platforms — one bridge config gives us SimpleX + Matrix + Telegram + Discord + Slack + IRC simultaneously
- `/hide` prefix in SimpleX messages prevents bridging — useful for private comms that should stay on SimpleX only

---

### [2026-04-07] Qlty Maintainability A-Grade Recovery

**Goal:** Recover the Qlty maintainability badge from C to A and keep it there permanently through process tightening.

**Status:** Active — tasks created, dependency-ordered dispatch.

**Root Cause Analysis (2026-04-07):**
- 224 smell findings across 45 files (Python/JS/TS/MJS)
- Top contributor: `oauth-pool.mjs` (complexity 440, t1860 — never completed despite being marked closed)
- 15 of 45 files in `.agents/plugins/opencode-aidevops/` (~1,300 combined complexity)
- Completed tasks (t1858, t1861) didn't fully resolve — Qlty still flags them
- `complexity-scan-helper.sh` only scans `.sh`/`.md` — blind to Qlty-scored file types
- No CI gate prevents new smells from landing
- `complexity-thresholds.conf` bumped UP 11 times, never ratcheted down

**Tasks (dependency order):**

| Task | Title | Tier | Blocked by | GH# |
|------|-------|------|------------|-----|
| t1860 | Reduce oauth-pool.mjs complexity (440→120) | reasoning | — | #440 |
| t1915 | Add Qlty verification to simplification templates | simple | — | #17704 |
| t1910 | Extend scanner to .py/.mjs/.js/.ts | standard | — | #17699 |
| t1911 | Add Qlty smells CI gate (diff mode) | standard | — | #17700 |
| t1913 | Automate ratchet-down | standard | — | #17702 |
| t1912 | Post-merge re-queue for persistent smells | standard | t1910 | #17701 |
| t1914 | Plugin directory decomposition | reasoning | t1860 | #17703 |

**Scope/Direction:**
- t1860 + t1914 address the smell backlog (cure)
- t1911 + t1912 prevent regression (gate)
- t1910 + t1913 + t1915 close process gaps (infrastructure)

#### Decision Log

| Date | Decision | Rationale |
|------|----------|-----------|
| 2026-04-07 | Scanner must cover Qlty-scored types | Scanner was blind to 100% of badge-relevant files |
| 2026-04-07 | CI gate in diff mode, not --all | --all would fail every PR (224 pre-existing smells) |
| 2026-04-07 | Re-queue with pass limit (3) then escalate | Prevents infinite re-simplification loops |
| 2026-04-07 | Plugin decomposition at tier:reasoning | Architectural work requiring dependency graph analysis |
| 2026-04-07 | Ratchet-down proposed at actual+2 buffer | Prevents flapping from concurrent PRs |
| 2026-04-07 | GH#440 was never completed (PR#13932 was wrong file) | Worker closed with wrong evidence — re-opened |

---

## Completed Plans

### [2025-12-21] Beads Integration for aidevops Tasks & Plans ✓

See [Active Plans > Beads Integration](#2025-12-21-beads-integration-for-aidevops-tasks--plans) for full details.

**Summary:** Integrated Beads task management with bi-directional sync, dependency tracking, and graph visualization.
**Estimate:** 2d | **Actual:** 1.5d | **Variance:** -25%

<!--TOON:completed_plans[1]{id,title,owner,tags,est,actual,logged,started,completed,lead_time_days}:
p009,Beads Integration for aidevops Tasks & Plans,,beads|tasks|sync|planning,2d,1.5d,2025-12-21T16:00Z,2025-12-21T16:00Z,2025-12-22T00:00Z,1
-->

## Archived Plans

<!-- Plans that were abandoned or superseded -->

<!--TOON:archived_plans[0]{id,title,reason,logged,archived}:
-->

---

## Plan Template

Copy this template when creating a new plan:

```markdown
### [YYYY-MM-DD] Plan Title

**Status:** Planning
**Owner:** @username
**Tags:** #tag1 #tag2
**Estimate:** ~Xd (ai:Xd test:Xd read:Xd)
**PRD:** [todo/tasks/prd-{slug}.md](tasks/prd-{slug}.md)
**Tasks:** [todo/tasks/tasks-{slug}.md](tasks/tasks-{slug}.md)

<!--TOON:plan{id,title,status,phase,total_phases,owner,tags,est,est_ai,est_test,est_read,logged,started}:
p00X,Plan Title,planning,0,N,username,tag1|tag2,Xd,Xd,Xd,Xd,YYYY-MM-DDTHH:MMZ,
-->

#### Purpose

Brief description of why this work matters and what problem it solves.

#### Progress

- [ ] (YYYY-MM-DD HH:MMZ) Phase 1: Description ~Xh
- [ ] (YYYY-MM-DD HH:MMZ) Phase 2: Description ~Xh

<!--TOON:milestones[N]{id,plan_id,desc,est,actual,scheduled,completed,status}:
m001,p00X,Phase 1: Description,Xh,,YYYY-MM-DDTHH:MMZ,,pending
-->

#### Decision Log

- **Decision:** What was decided
  **Rationale:** Why this choice was made
  **Date:** YYYY-MM-DD
  **Impact:** Effect on timeline/scope

<!--TOON:decisions[0]{id,plan_id,decision,rationale,date,impact}:
-->

#### Surprises & Discoveries

- **Observation:** What was unexpected
  **Evidence:** How we know this
  **Impact:** How it affects the plan

<!--TOON:discoveries[0]{id,plan_id,observation,evidence,impact,date}:
-->

#### Time Tracking

| Phase     | Estimated | Actual | Variance |
| --------- | --------- | ------ | -------- |
| Phase 1   | Xh        | -      | -        |
| Phase 2   | Xh        | -      | -        |
| **Total** | **Xh**    | **-**  | **-**    |

<!--TOON:time_tracking{plan_id,total_est,total_actual,variance_pct}:
p00X,Xh,,
-->
```

### Completing a Plan

When a plan is complete, add this section and move to Completed Plans:

```markdown
#### Outcomes & Retrospective

**What was delivered:**

- Deliverable 1
- Deliverable 2

**What went well:**

- Success 1
- Success 2

**What could improve:**

- Learning 1
- Learning 2

**Time Summary:**

- Estimated: Xd
- Actual: Xd
- Variance: ±X%
- Lead time: X days (logged to completed)

<!--TOON:retrospective{plan_id,delivered,went_well,improve,est,actual,variance_pct,lead_time_days}:
p00X,Deliverable 1; Deliverable 2,Success 1; Success 2,Learning 1; Learning 2,Xd,Xd,X,X
-->
```

---

## Analytics

<!--TOON:analytics{total_plans,active,completed,archived,avg_lead_time_days,avg_variance_pct}:
10,10,0,0,,
-->
