Files
claude-projects/agent-builder/.claude/context.md
T
2026-06-22 16:09:56 -05:00

232 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
project_name: agent-builder
# Agent Builder — Session Context
## What this project does
Design, build, and test autonomous N8N agents on server-01 sandbox before any production promotion.
First two agents: Agent Builder Agent + N8N Builder Agent.
## Scheduled work (2026-06-16, running behind — started ~6:38 PM)
1. Vision Alignment Grill-Me — Agent Builder + N8N Builder vision + testing methodology
2. Agent Builder Agent — Deploy + Test (server-01 sandbox)
3. N8N Builder Agent — Deploy + Test (server-01 sandbox)
## Architecture
- Agents run as N8N workflows on server-01 (n8n-sandbox, port 5679)
- Sandbox-first: all agents tested in sandbox before any production promotion
- server-01 sandbox stack: n8n-sandbox, postgres-sandbox, vault-sandbox, bitwarden-bridge-sandbox, vaultwarden-sandbox
- Sandbox N8N API key: prod Vault at secret/sandbox/n8n
- Sandbox reachable at 192.168.1.90
## Key decisions (set during vision grill-me — 2026-06-16)
- Agent Builder Agent: builds `claude_agent` and `script` types — Ollama (llama3.1:8b) does the building, `claude -p` is overseer/validator
- N8N Builder Agent: builds `n8n_automation` types — Ollama generates workflow JSON, imports via N8N API, assigns credentials
- automation_ideas schema changes needed: rename `description``task_description` (full structured spec), add `type` (n8n_automation/claude_agent/script), add `builder_status`
- New `agent_test_results` table needed in api_business DB
- Sandbox must mirror production: AppRole, Vaultwarden, bridge all configured before any agent deploys
- Promotion = user approval required after all 4 test levels pass (not auto-promote in v1)
- Dedicated backfill session needed for all 48 existing automation_ideas rows (type + task_description)
- claude -p uses SDK credits (Pro = $20/month hard limit) — use sparingly, Ollama does the heavy lifting
- Local model: llama3.1:8b already pulled on server-01 (4.9GB, fits in RTX 2060 Super 8GB VRAM)
## Testing methodology
- Four levels: Structure → Deployment → Smoke → Assertion
- LLM outputs validated on structure/side-effects only, never exact string match
- All results logged to agent_test_results table
- NTFY notification on pass and fail
- Full methodology: .claude/playbook_testing_methodology.md
## Agents
### Agent Builder Agent
- Status: pending — prereqs not complete
- Purpose: Receives automation spec from automation_ideas DB, uses Ollama to build claude_agent or script type automations, deploys to sandbox, runs automated tests, notifies user for promotion approval
- Builds: claude agents (via claude -p) and Python scripts (Docker containers)
### N8N Builder Agent
- Status: pending — prereqs not complete
- Purpose: Receives automation spec from automation_ideas DB, uses Ollama to generate N8N workflow JSON using n8n_automations playbook as context, imports to sandbox N8N via API, assigns credentials, runs automated tests
- Will be used to build: id=12 (Media Pipeline Learning), id=7 (Friday Research Session Prep)
## Related personal_projects DB rows
- id=4: N8N Workflow Builder Script (pending, weekend_block1)
## Prereq checklist (must complete before any agent deployment)
- [x] Schema: rename automation_ideas.description → task_description, add type, add builder_status, add priority
- [x] Create agent_test_results table in api_business
- [x] Sandbox Vault: set up AppRole auth method (credentials at /opt/appdata/docker/docker-compose/vault/approle/ on server-01)
- [x] Sandbox Vault: store sandbox N8N API key at secret/sandbox/n8n (key name: claude-sandbox, verified working)
- [x] Verify sandbox Bitwarden bridge ↔ Vaultwarden sandbox end-to-end (bridge on port 8080, returns [] for empty vault — correct)
- [x] Write Agent Builder Agent playbook → .claude/playbook_agent_builder_agent.md
- [x] Write N8N Builder Agent playbook → .claude/playbook_n8n_builder_agent.md
- [x] Backfill session: **COMPLETE.** All pending rows reviewed across sessions 1-3. Blocked rows verified (32, 30, 13, 27, 23, 24, 22, 2, 21, 35, 36, 55, 56, 18 — all still blocked, no changes without proper review). Admin done: id=28 → p10, id=57 keeps p9, dummy row id=16 deleted. Session 3 (2026-06-18) final batch: ids 47, 48, 31, 26, 54.
- id=25: type→n8n_automation, status→pending (8b model lifts hardware block), full rewrite with SDK credit model, model router + cost gate + subscription monitor, model_effort_routing_log training table
- id=17: type→n8n_automation, expanded with token_waste_patterns DB table (evolution mechanism), JSONL-based detection, NTFY claude-audit gate, fan-out plan noted
- id=42: expanded with hybrid trigger (Claude flags + asks), B+C output (DB + wrap-up surface), human gate permanent, hard boundary (business research = id=55 only), voice note
- id=46: type→n8n_automation, Hermes ref removed, playbook_schema.md bootstrap design, three risk tiers, id=52 detector/id=46 executor boundary, fan-out plan noted
- id=43: Vault AppRole required (youtube-oauth-script, new policy), vault_registry entries, port 8085 (8080 reserved for bridge), dynamic Vault IP, write verification, token refresh companion
- id=45: hard dep on id=43 (Vault auth), niche_saturation_thresholds DB table (evolution), niche_check_results table, three-signal output (saturated/viable/unclear), id=18 stage 2 integration
## New automation_ideas rows added 2026-06-18 (ids 5967)
- id=59: Claude Audit Research Prep (n8n_automation, p12) — Saturday briefing for 12:45 PM review
- id=60: Claude Audit Topic Detector (n8n_automation, p11) — detects new topics → claude_config.audit_topics; must build first
- id=61: Claude Config Dev Work Scheduler (n8n_automation, p13) — Sunday session prep from Saturday decisions
- id=62: Monthly Security Audit (n8n_automation, p7) — first Monday of month, 7-area audit → security_audit DB
- id=63: Security Patch Backlog Handler (claude_agent, p7) — works security_audit.findings; Vault/prod always human-gate
- id=64: Business Projects Worker (claude_agent, BLOCKED p29) — 12:454:30 PM daily; blocked pending business_projects schema
- id=65: Personal Projects Worker (claude_agent, BLOCKED p29) — 5:308:00 PM daily; blocked pending personal_projects schema
- id=66: Media Pipeline Project Worker (claude_agent, BLOCKED p29) — Wednesday 5:308:00 PM; blocked pending id=65 + scope
- id=67: N8N Builder Agent (claude_agent, p2, ready_to_build) — builds all n8n_automation rows; deploy Monday June 22 alongside id=24
## Readiness check — COMPLETE (2026-06-18 evening)
All 8 prereq checklist items verified live on server-01:
- Vault AppRole: token acquired, N8N secret readable
- N8N sandbox API: returns 200 with real key
- Bridge /items: returns [] (correct for empty sandbox vault)
- Ollama: llama3.1:8b loaded
- agent_test_results table: confirmed correct schema + FK
## June 20 (Saturday) — Session progress
**id=57 partially complete.** Carried over from June 19 (sick day).
### id=57 — DONE this session:
- Production N8N migrated from primary server → server-01 port 5678
- Vault-backed start.sh: secrets pulled from production Vault at runtime, nothing on disk
- n8n-server01 AppRole created in production Vault (scoped to secret/data/n8n read-only)
- Stale root token in Bitwarden replaced — regenerated via generate-root (3/5 keys), updated, revoked
- Traefik static route live: /traefik/dynamic/n8n.yaml → 192.168.1.90:5678
- Rollback procedure documented + all 4 checks passed: /opt/appdata/docker/docker-compose/n8n/ROLLBACK.md
- claude-policy extended: AppRole management + sys/generate-root paths added
### id=57 — REMAINING (next session):
- Sandbox Vaultwarden bridge fix: 53 ciphers seeded (DB confirmed), but bw CLI WASM crash on list — bridge /items returns 500. Fix: update Vaultwarden image OR rebuild bridge with newer bw CLI OR patch bridge /items to use REST API
- N8N sandbox credentials (-sandbox suffix names) — Bridge API Key already exists; need postgres, Vault, NTFY
- Sudo bridge deploy on server-01 (Phase 2) — then disable NOPASSWD:ALL in /etc/sudoers.d/administrator on server-01
### id=51 — NOT STARTED. Scope locked:
- Option B zero-exposure proxy: agent sends "run X using secret Y", proxy executes + injects secret, returns result only
- Must be live before builder agents deploy
## June 20 Session 2 (continuation)
- Sandbox Vault auto-unseal deployed: vault-sandbox-unseal.sh + vault-sandbox-watch-unseal.sh + 2 systemd services, unsealed and verified
- Sandbox Vault AppRole mirror: 9 policies + 5 roles recreated from production (claude-code, claude-policy, n8n, n8n-outreach-policy, n8n-policy, n8n-rotation-policy, n8n-scheduling-policy, n8n-server01-policy, nextcloud-init)
- Production Bitwarden audit: 294 items total, 53 infra items identified (all username/password, some with notes)
- Sandbox Vaultwarden population BLOCKED: bw CLI 2026.5.0 WASM crypto error on create — use Vaultwarden REST API next session (id=70)
- sudo bridge NOT on server-01: server-01 has NOPASSWD:ALL; plan = deploy bridge first (Phase 2), then disable NOPASSWD
- ids added: 69 (Vaultwarden Version Monitor, p16), 70 (Sandbox Vaultwarden Seeder, p17)
- feedback_bw_cli_vaultwarden_create.md added to docker MEMORY.md
## June 20 Session 3 (continuation)
### Sandbox Vaultwarden — 53/53 dummy ciphers seeded (DB confirmed)
- Root cause of login failure: Bitwarden-Client-Version header required by Vaultwarden 1.36.0
- Original akey was encrypted with unknown master key (registration vs unlock password mismatch)
- Fix: reset sandbox@test.local password_hash + akey in postgres-sandbox via /tmp/vw_reset_and_seed.py
- Script: derives keys from u8X_P_zlGBypRUXYq5iGIg + PBKDF2/HKDF, generates fresh user_sym_key,
updates DB directly, logs in via REST API, POSTs 53 AES-256-CBC encrypted ciphers
- Runs via: `docker run --rm --network n8n-sandbox_default -v /tmp/vw_reset_and_seed.py:/tmp/script.py bitwarden-bridge:sandbox sh -c 'pip install cryptography psycopg2-binary --quiet && python3 /tmp/script.py'`
- Script at /tmp/vw_reset_and_seed.py on server-01 (also /tmp/vw_reset_and_seed.py locally)
- 53 ciphers confirmed: `SELECT COUNT(*) FROM ciphers WHERE user_uuid='896b5bbb-...'` → 53
- Bridge unlocks successfully with new password on every restart
### BLOCKER: bw list items WASM crash (same as bw create)
- Error: "Invalid key, throwing away stored keys" × 2, then "invalid type: unit value, expected a valid string"
- Empty vault worked; non-empty vault fails — bw CLI 2026.5.0 can't decrypt Vaultwarden 1.36.0 ciphers
- Bridge /items returns 500 error; ciphers ARE in DB but not serveable via bridge
- Fix options (next session, pick one):
1. Pull updated vaultwarden/server:latest (Docker pull currently broken due to daemon instability on server-01 — containerd-based Docker 29.x; images intact at /var/lib/containerd 26G)
2. Rebuild bitwarden-bridge:sandbox with newer bw CLI version
3. Patch bridge /items endpoint to use Vaultwarden REST API instead of bw CLI
- /tmp/vw_reset_and_seed.py script is reusable — if Vaultwarden is updated, just re-run to re-seed after container recreate
### Docker daemon incident (unrelated to our work)
- All containers exited during session — Docker 29.x daemon crash (not caused by our actions)
- Images are in /var/lib/containerd (26G), not /var/lib/docker/overlay2 (new storage model)
- Stack brought back up via: `cd /opt/appdata/docker/docker-compose/server-01 && docker compose up -d`
- Compose file location confirmed: /opt/appdata/docker/docker-compose/server-01/docker-compose.yml
### id=57 — COMPLETE ✅ (June 20 Session 5)
All sandbox prereqs done. Sandbox mirrors production.
**Completed in Session 5:**
- Bridge switched to Bitwarden cloud (megafreeman12@proton.me) — unlocks cleanly, /items returns 53
- Compose updated: BW_SERVER and NODE_TLS_REJECT_UNAUTHORIZED removed; vaultwarden-sandbox depends_on removed
- 53 dummy items seeded (dummy-infra-01 through dummy-infra-53)
- sandbox Vault secret/bitwarden updated with new master_password
- N8N sandbox credentials created: postgres-sandbox, vault-sandbox, n8n-internal-sandbox, Bridge API Key (Sandbox)
- n8n_agent_worker postgres role — api_business DB, scoped to automation_ideas + agent_test_results
- Credential in production Vault: secret/postgres/n8n-agent-worker
### id=51 — MIGRATING TO PRIMARY (June 22 session 2)
**Decision: move proxy from server-01 → primary server.** Reasons: security infrastructure (not a test workload), Claude Code runs on primary, all deps (Vault, bridge, N8N, ntfy) already local. Cloudflare route stays `http://coolify-proxy:80`.
**June 22 session 2 facts:**
- gitea.local pulls from server-01 now work: iptables DNAT rule applied on primary (192.168.1.88:80 → 127.0.0.1:80 via enp1s0 route_localnet=1) — NOT persisted across reboot yet (needs iptables-persistent or systemd unit)
- Cloudflare route `secrets-proxy.reverseproxyserver.net` already exists but pointed to primary's coolify-proxy which doesn't know about server-01 container — confirms proxy should be on primary
- Coolify API: secrets-proxy is a SERVICE type (not application) — use /api/v1/services endpoint
- Server-01 service UUID: lv3xeu2manuimle458wbm9u9 (to be stopped/deleted after migration)
- Image at gitea.local/backtalk6858/secrets-proxy:latest (digest sha256:5bf92d2e...) — bridge_health_check fix included
- Caller keys: claude-code: 0ce8c396...591e9, agent-builder-agent: 473d9e1f...3573, n8n-builder-agent: 233e6aa9...cb
**NEXT SESSION — in order:**
1. Stop/delete secrets-proxy service on server-01 (Coolify UUID lv3xeu2manuimle458wbm9u9)
2. Deploy secrets-proxy on primary via Coolify (same docker-compose.yml, Traefik labels, coolify network)
3. Cloudflare route already correct (http://coolify-proxy:80) — no change needed
4. Full E2E test: bridge_health_check, bitwarden_item_exists, n8n_workflow_list, vault_secret_write
5. Persist iptables DNAT rule on primary (iptables-persistent or systemd unit) — so server-01 can always pull from gitea.local
6. Add sudo-bridge allowlist management endpoint (POST /allowlist) — gap discovered this session
7. id=24 Agent Builder Agent + id=67 N8N Builder Agent
- Bitwarden bridge LAN-exposed: 192.168.1.88:8083 ✅
### June 21 session 2 facts for next session:
- server-01 Coolify UUID: hvzbj1gkqb5696s7cc9lcf8y
- Sandbox stack Coolify service UUID: d2celewbvh7e4fer77fcp9b5
- n8n-prod Coolify service UUID: h10eww4au274owpxozgizysh
- Traefik on primary binds to 127.0.0.1:80 only (LAN push workaround: docker save | ssh | docker load on primary then push)
- sudo_bridge DB: server_id column added to executions + allowlist_changes, default='primary'
- app.py needs: server_id='server-01' + [server-01] NTFY prefix variant for server-01 deployment
- sudo-bridge image: gitea.local/backtalk6858/sudo-bridge:latest (same image, different env vars)
- sudo-bridge-server01 Coolify UUID: o2kz1puml1mmneyiqd96mouj (port 8082, pull_policy:never)
- Vault secret created: secret/data/sudo-bridge-server01 (api_key: 443ea35b43c3e640aac3c57ed3aae06b8822ab6f)
- Host daemon running: /opt/appdata/docker/sudo-bridge/sudo_bridge_daemon.py (systemd, enabled)
- vaultwarden-sandbox REMOVED from sandbox stack (no longer needed — Bitwarden cloud dummy account used)
- app.py updated: SERVER_ID, _server_prefix(), server_id audit writes, User-Agent for Cloudflare
- NTFY approval action buttons use BRIDGE_EXTERNAL_URL=http://192.168.1.90:8082 (LAN only until Tailscale)
- NOPASSWD:ALL disabled on server-01 ✅ (June 21 session 3)
- Both bridges now on public URLs via Traefik + Cloudflare: sudo-bridge.reverseproxyserver.net + sudo-bridge-server01.reverseproxyserver.net
- Danger veto in daemon blocks rm /etc/* regardless of allowlist — /etc sudoers removal done manually
- NEXT: id=51 Secrets Execution Proxy (grill-me DONE June 21 session 4 — build next session)
## June 20 Session 4 (continuation)
### Docker 29.6.0 crash — diagnosed and fixed
- Root cause: nala upgrade swept in Docker 29.6.0 which has SIGSEGV null pointer dereference bug in HTTP transport during docker pull
- Fix: downgraded to 29.5.3, pinned with `apt-mark hold docker-ce docker-ce-cli docker-ce-rootless-extras`
- Rule: never run nala/apt upgrade without holding docker-ce first
### bw CLI + Vaultwarden — permanently abandoned
- bw CLI 2026.4.1 AND 2026.5.0 both crash against Vaultwarden 1.36.0 with `orgKeys null` TypeError
- Root cause: Vaultwarden returns null for orgKeys in sync response for personal vaults; bw CLI expects {}
- Decision: drop Vaultwarden sandbox, use Bitwarden cloud dummy account (same as production)
- Dummy account created: megafreeman12@proton.me, master_password=Infra6746Dummy$
- All credentials stored at secret/sandbox/bitwarden in production Vault (4 fields: email, master_password, client_id, client_secret)
- Sandbox bridge Dockerfile.sandbox moved to /opt/appdata/docker/docker-compose/server-01/bitwarden-bridge/ (pinned bw CLI 2026.4.1 — moot now but kept for reference)
- bridge:sandbox image rebuilt and pushed to gitea.reverseproxyserver.net (still has bw CLI 2026.4.1)
## June 22 (Monday) — Builder Agents (extended session)
Build, test, and push both builder agents to production. Work as long as it takes.
- id=24 Agent Builder Agent (claude_agent + script types)
- id=67 N8N Builder Agent (n8n_automation types)
- Prerequisites: id=51 live, id=57 FULLY complete (sandbox mirrors production)
## Priority queue summary (as of 2026-06-18)
- p1: id=51 (manual), id=57 (manual) — infrastructure foundation
- p2: id=24, id=67 — builder agents (built in sessions, build everything else)
- p3: id=54 NTFY Provisioner, id=58 Human Action Gate
- p4: id=25 Cost Intelligence, id=38 Credential Emergency Rollout
- p5: id=3 Secrets Rotation, id=8 Vault Token Audit, id=52 Session Wrap-up
- p6: id=37 N8N Log Scanner, id=40 Coolify UUID Monitor
- p7: id=62 Monthly Security Audit, id=63 Security Patch Handler
- p8p17: non-blocked pending/ready items
- p20p29: all blocked items (builder agents skip these)
## Update instructions
Update at the end of every agent-builder session. Keep agent status, key decisions, and prereq checklist current.