From 30933bd35df97c3096d17388ab110ee318f97694 Mon Sep 17 00:00:00 2001 From: Mike Swanson Date: Sun, 14 Jun 2026 10:33:49 -0700 Subject: [PATCH] sync: auto-sync from GURU-5070 at 2026-06-14 10:33:33 Author: Mike Swanson Machine: GURU-5070 Timestamp: 2026-06-14 10:33:33 --- .claude/memory/MEMORY.md | 4 +- .../memory/feedback_ct_thoughts_backlog.md | 18 ++ .../project_ai_auth_product_boundary.md | 28 +++ docs/CT_THOUGHTS.md | 212 ++++++++++++++++++ 4 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 .claude/memory/feedback_ct_thoughts_backlog.md create mode 100644 .claude/memory/project_ai_auth_product_boundary.md create mode 100644 docs/CT_THOUGHTS.md diff --git a/.claude/memory/MEMORY.md b/.claude/memory/MEMORY.md index be15c0f..0936538 100644 --- a/.claude/memory/MEMORY.md +++ b/.claude/memory/MEMORY.md @@ -139,4 +139,6 @@ - [IX WHM API access = 'ClaudeTools' token, not password](ix-whm-dns-api-access.md) — IX cPanel/WHM (ix.azcomputerguru.com:2087) DNS + all API work uses the FULL-ACCESS-root WHM API token at vault `infrastructure/ix-server` `credentials.whm-api-token` via header `Authorization: whm root:` (force curl -4). Password basic-auth on legacy json-api now 403s. Public NS ns1/ns2.acghosting.com = 52.52.94.202. - [Vault EVERY credential surfaced in-session](feedback-vault-every-credential.md) — any cred (pasted/created/discovered) -> store via the vault skill + document purpose & exact usage immediately; it's a standing job rule (reinforced in CORE CLAUDE.md). Lost IX creds wasted ~1h on 2026-06-12. - [GuruRMM install-report v1: reuse endpoint + failed-install agent](gururmm-install-report-failed-agent-v1.md) — legacy NSIS installer reuses /api/install-report (machine info + logs, success+fail); server upserts a visible "failed-install" device on failure reports (Mike: in v1); verify-connect-before-success; trend/near-fail analytics. Server side is a separate sequential SPEC after the legacy-agent branch lands. -- [DM wrapping commands to Mike in Discord](feedback_dm_wrapping_commands_to_mike.md) — long/wrapping one-liners go via Discord DM (code block copies clean), not just chat; bot token vault projects/discord-bot/bot-token, Mike uid 264814939619721216, MUST set User-Agent header or Cloudflare 403 errcode 1010; helper .claude/tmp/discord-dm.py +- [DM wrapping commands to Mike in Discord](feedback_dm_wrapping_commands_to_mike.md) — long/wrapping one-liners go via Discord DM (code block copies clean), not just chat; bot token vault projects/discord-bot/bot-token, Mike uid 264814939619721216, MUST set User-Agent header or Cloudflare 403 errcode 1010; helper .claude/tmp/discord-dm.py +- [CT Thoughts backlog](feedback_ct_thoughts_backlog.md) — ClaudeTools harness ideas go in docs/CT_THOUGHTS.md (trigger "ct thought:"); CT analogue of RMM_THOUGHTS. Don't build until explicit go. First entry = ClaudeTools 3.0 web co-work vision. +- [AI-auth product boundary](project_ai_auth_product_boundary.md) — ClaudeTools/ClaudeTools 3.0 = internal-only, per-person subscription OAuth ok; GuruRMM = sellable, customer brings own API key (never ACG's subscription); backend dev = internal. Anthropic ToS bans subscription auth in third-party products. diff --git a/.claude/memory/feedback_ct_thoughts_backlog.md b/.claude/memory/feedback_ct_thoughts_backlog.md new file mode 100644 index 0000000..45517d0 --- /dev/null +++ b/.claude/memory/feedback_ct_thoughts_backlog.md @@ -0,0 +1,18 @@ +--- +name: feedback_ct_thoughts_backlog +description: Where ClaudeTools harness ideas go (CT_THOUGHTS.md) and the trigger phrase to append one +metadata: + type: feedback +--- + +ClaudeTools harness ideas (the internal tooling itself, not client work) go in +`docs/CT_THOUGHTS.md` — the CT analogue of [[feedback_rmm_thoughts_backlog]]'s +RMM_THOUGHTS.md. Pipeline: thought (Status: Raw) -> discuss -> spec (`/shape-spec` or a +concept doc) -> roadmap -> build. + +**Why:** keeps ClaudeTools-self ideas in one durable backlog instead of evaporating into +session logs; parallels the GuruRMM thought pipeline. +**How to apply:** when Mike/Howard say "ct thought: " / "add to ct thoughts" / "park +this as a ct thought", append it to `docs/CT_THOUGHTS.md` with who/when + a Status. Don't +build until an explicit go (per [[feedback_stream_of_thought_design]]). First entry = +ClaudeTools 3.0 web co-work vision (see [[project_ai_auth_product_boundary]] for its auth model). diff --git a/.claude/memory/project_ai_auth_product_boundary.md b/.claude/memory/project_ai_auth_product_boundary.md new file mode 100644 index 0000000..12cacc9 --- /dev/null +++ b/.claude/memory/project_ai_auth_product_boundary.md @@ -0,0 +1,28 @@ +--- +name: project_ai_auth_product_boundary +description: Which ACG products may use Claude subscription OAuth vs must use customer/API-key auth, and why (Anthropic ToS) +metadata: + type: project +--- + +Firm product/AI-auth boundary Mike set 2026-06-14, decided by Anthropic's Agent SDK ToS +(third-party products may NOT offer claude.ai login / subscription rate limits without +written approval): + +- **ClaudeTools harness (incl. a future web "ClaudeTools 3.0" co-work app)** — + ALWAYS internal-only, internal users only. May use per-person Claude subscription OAuth + (`CLAUDE_CODE_OAUTH_TOKEN` via `claude setup-token`). Compliant pattern = each node/workstation + authenticates with THAT person's own token (Mike's on Mike's boxes, Howard's on his); the hub + never centralizes one subscription to serve many. Note: as of 2026-06-15 subscription-backed + Agent SDK usage draws on a separate monthly credit pool (~$100-200 Max), not unlimited — spill + to API key when exhausted. +- **GuruRMM** — SELLABLE product. AI features must use the CUSTOMER's own dropped-in API key + (per-tenant `ANTHROPIC_API_KEY`), never ACG's subscription. Build RMM AI auth around BYO-key + from day one. +- **Backend dev work (e.g. GuruRMM log-analysis dev side)** — always internal. + +**Why:** subscription OAuth is fine for internal/own use but ToS-banned for offering to external +users; getting this wrong on a sellable product is a hard compliance line, not grey. +**How to apply:** ClaudeTools 3.0 web design assumes per-person subscription tokens on each node +(internal). Anything customer-facing (GuruRMM) = customer-provided API keys. See +[[feedback_stream_of_thought_design]] for the design-partner posture on this early-stage vision. diff --git a/docs/CT_THOUGHTS.md b/docs/CT_THOUGHTS.md new file mode 100644 index 0000000..efb0452 --- /dev/null +++ b/docs/CT_THOUGHTS.md @@ -0,0 +1,212 @@ +# CT Thoughts — ClaudeTools idea backlog + +> The shared backlog of ClaudeTools harness ideas (the internal tooling itself, not +> client work). Nothing here is approved to build — ideas advance only by explicit +> decision. +> +> **Pipeline:** THOUGHT (raw idea dropped here) -> DISCUSS (chat it through) -> +> SPEC (`/shape-spec` or a concept doc) -> ROADMAP -> BUILD. +> +> **How to add a thought:** in any Claude session say "ct thought: " (or +> "add to ct thoughts" / "park this as a ct thought"). Claude appends it below with +> who/when and a Status. Howard's ideas land here too. +> +> **Status per entry:** Raw -> Discussed -> Spec'd -> Roadmapped -> Done. +> +> The entries below are the current thoughts: +> 1. ClaudeTools 3.0 — web-based co-work workspace (Mike, 2026-06-14) — **Discussed (vision-stage, no build go)** + +--- + +## Thought 1 — ClaudeTools 3.0: Web-Based Co-Work Workspace (Mike, 2026-06-14) + +**Status: Discussed — vision-stage, feeling out possibilities. NOT authorized to build.** + +### The want + +A web-based ClaudeTools that gives the team (Mike, Howard) real co-work — "think Claude +Co-Work, but tailored like ClaudeTools already is." Today co-work = N separate Claude Code +CLI terminals on N machines, glued together by the git-synced repo + the coord API +(`172.16.3.30:8001` — locks, todos, messages, component state) polled over HTTP. The +vision turns that into one shared room where you can see and drive sessions across the +fleet from a browser (incl. phone) over Tailscale. + +Odysseus (`D:\Odysseus`, AGPL-3.0 self-hosted AI workspace) is **inspiration for the shell +only** (auth, sessions, document editor, memory UI, mobile/PWA polish) — NOT the agent. +Its agent is a from-scratch loop; adopting it would throw away the Claude Code harness +(skills, slash commands, hooks, coord, the Opus agent itself) that is ClaudeTools' whole +value. Copying its code would also make ClaudeTools 3.0 AGPL + network-served (source-offer +obligation). Reimplement/take-inspiration only. + +### Agent backend + auth (decided constraints) + +- Agent = **Claude Agent SDK** (the supported way to embed the real Claude Code harness — + same skills/MCP/hooks/tools — into a server). NOT Odysseus's loop. +- ClaudeTools 3.0 is **internal-only**, so per-person **subscription OAuth** + (`CLAUDE_CODE_OAUTH_TOKEN` via `claude setup-token`) is compliant and is the auth model. + Each node authenticates with THAT person's own token (Mike's on Mike's boxes, Howard's on + his); the hub never centralizes one subscription to serve many. See memory + `project_ai_auth_product_boundary`. +- Cost ceiling = the post-2026-06-15 monthly Agent-SDK credit pool (~$100-200/Max), not + unlimited; eventual "spill to API key when the pool's dry" fallback in the node daemon. +- GuruRMM (sellable) is separate: customer brings their own API key. Does not entangle this. + +### The architecture: two axes, not one choice + +The instinct was "central host on Beast" vs. "per-workstation + peer-to-peer back-channel +replacing the coord DB." That conflates two independent axes: +- **Axis 1 — where the AGENT runs:** central on Beast vs. per-workstation. +- **Axis 2 — how SHARED STATE flows:** central coord service vs. peer-to-peer mesh. + +Recommended corners: **distributed agents + central coordination.** +- Don't replace the coord DB with a mesh. Connectivity isn't the hard part (Tailscale gives + direct node-to-node); **agreement + durability are.** A lock living only in a peer's memory + evaporates exactly when that peer crashes. Keep coordination central — it already works. +- Don't centralize the agent onto Beast. ClaudeTools sessions do machine-local work (SSH from + a specific network position, OS-specific skills, a per-machine vault age-key). Beast (a ROG + box, presumably Windows) can't run macOS/Kali-native work, and one host egress becomes a + chokepoint + SPOF. Keep the brain local where the work + creds are. + +### Topology — three tiers, two channels, one rule + +``` + TIER 1: CLIENTS TIER 2: HUB (Beast) TIER 3: AGENT HOSTS + (presentation + control) (always-on coordinator) (where work runs) + + +----------------+ +----------------------+ + | Browser (Mike) |==WSS==+ +=WSS=| GURU-5070 node daemon| + +----------------+ | +------------------+ | | - Agent SDK sessions| + +----------------+ +====>| Gateway (WSS) |<===+ | - vault age-key | + |Browser (Howard)|==WSS==+ | auth + terminate| | | - local fs/shell/net| + +----------------+ | +------------------+ | +----------------------+ + +----------------+ | | Session Registry| | +----------------------+ + | Phone (Mike) |==WSS==+ | + Presence | +=WSS=| MacBook node daemon | + +----------------+ +------------------+ | | (macOS-native work) | + | Relay (pipe) | | +----------------------+ + +------------------+ | +----------------------+ + | Coord (locks, | +=WSS=| GURU-KALI node daemon| + | todos, msgs) + | | (Linux-native work) | + | event log DB | +----------------------+ + +------------------+ + all on Tailscale (WireGuard) +``` + +**The one rule: Beast never dials out. Both clients and nodes dial IN to Beast.** Each +workstation's node daemon holds a persistent, auto-reconnecting **outbound** WSS to the +gateway — kills NAT traversal, inbound firewall rules, and reachability as problems. +Tailscale is the L3 fabric (encrypted + identity'd); WSS rides on top for the app layer. + +**What each tier is:** +- **Client** — pure glass. Renders sessions, sends input/approvals. Per-PERSON login here + (Mike, Howard); authz maps a person to the nodes/sessions they may drive. Holds no state + that can't be rebuilt from the hub. +- **Hub (Beast)** — the coordinator, NOT the brain. Terminates both WSS channels, tracks + presence, relays session streams, owns the durable shared state (coord + a per-session + event log). This is the existing coord API promoted from "polled over HTTP" to "pushes + events live." HTTP coord API can stay for backward-compat with existing CLI sessions. +- **Node daemon (each workstation)** — small long-lived process owning the local Agent SDK + session lifecycle + exposing local resources (vault, fs, shell, network position). Brain + runs here. + +### The envelope (one framing for both channels) + +``` +{ v:1, type, session_id?, node_id?, from, ts, payload } +``` + +| type | direction | meaning | +|---|---|---| +| `node.register` / `presence` | node -> hub | "GURU-5070 online, here are my sessions" | +| `session.start` | client -> hub -> node | spawn an Agent SDK session on node X | +| `session.list` | hub -> client | fleet inventory for the lobby | +| `session.attach` / `detach` | client -> hub | subscribe/unsubscribe a session stream | +| `stream.delta` / `tool_call` / `tool_result` / `status` | node -> hub -> client(s) | live output | +| `input.prompt` / `input.approval` | client -> hub -> node | drive the session, answer gates | +| `coord.lock` / `todo` / `message` | any -> hub -> subscribers | shared state, pushed live | + +### Attaching to a remote session (core flow) + +``` +Mike's browser Hub (Beast) GURU-5070 daemon Agent SDK session + | | | | + | attach(sess_42) --->| | | + | | replay event-log ---->| (already streaming) --| + |<-- replay + tail ---| | stream.delta -------| + | |<----------------------| (node->hub->clients)| + | input.prompt ------>| --------------------->| --------------------->| + |<-- stream.delta ----|<----------------------|<----------------------| +``` + +Node is source of truth for a LIVE session; hub MIRRORS every event into a per-session log +for durability + late-join replay. Attaching = replay the log, then tail live. A session +whose node drops shows "offline" with transcript intact, re-attaches on reconnect. + +### The co-work mechanic (the actual point) + +"Attach" is just *subscribe to a session_id*, so **N people can attach to the same session.** +Mike + Howard watch the same agent run live; either can send input. Add: +- **Presence-on-session** — "Howard is viewing", "Mike is typing". +- **A driving token** — a soft lock at session granularity (reuse the coord lock primitive): + one person "has the wheel," visibly; others can request it. Last-writer-wins underneath, + but the indicator stops collisions socially before they happen. + +That falls out of the relay design almost for free — it's the Claude Co-Work analogue. + +### What it looks like on the screen (the hard part: vision -> screen) + +**Lobby / fleet view** — "what's everyone doing": +``` ++- ClaudeTools --------------------------------------------+- Coord ----------+ +| NODES | LOCKS | +| * GURU-5070 Mike 2 sessions | valleywide-esxi | +| |- #42 [remediation] Valleywide ESXi < Mike | -> held: 5070 | +| \- #43 [client] Syncro triage idle | | +| * MacBook Mike 1 session | TODOS (3) | +| \- #44 [dev] GuruRMM build (waiting) | [ ] rotate B2 | +| * GURU-KALI - 0 sessions | [ ] wiki: VWP | +| o BEAST (hub) | [x] py.sh dep | +| | MESSAGES (1) | +| [ + New session on... v ] | KALI->fleet: .. | ++---------------------------------------------------------------------------+ +``` + +**Session room** — attach to #42: +``` ++- #42 remediation - Valleywide ESXi - on GURU-5070 ---- (eye) Mike, Howard -+ +| | +| [agent] Checking datastore free space on 192.168.3.24... | +| +- tool: ssh esxi - df -h --------------------------------+ > approved | +| | /vmfs/volumes/datastore1 3.6T 65% used | | +| +----------------------------------------------------------+ | +| [agent] 65% now - down from 87%. The 3 decommissioned VMs are gone. | +| | ++--------------------------------------------------------------------------- | +| Mike has the wheel [request wheel] | +| > _ [send] | ++---------------------------------------------------------------------------+ +``` + +If those two screens match the picture in Mike's head, the architecture is the diagram +above. If they don't, that mismatch is the cheapest thing to discover now, pre-code. + +### Failure modes (SPOF honesty) + +- **Hub down:** local agents keep working — degrade to local-only, queue coord events (the + softfail-queue idea already exists in ClaudeTools). Web UI dark, but work does NOT stop. +- **Node down:** its sessions pause; others unaffected; transcripts survive on the hub. +- **Partition:** outbound WSS reconnects with backoff; event log resyncs clients on return. + +### What to build first (prove the vision, cheaply) + +The one risky, novel slice: a node daemon running ONE Agent SDK session, streaming it over +a WSS to a dead-simple web page that can watch + send input. No auth, no coord, no +multi-node, localhost only. If watching a real session stream into a browser and typing back +matches the vision -> everything else on the diagram is known engineering. If it doesn't -> +a day spent, not a quarter. + +### Open questions (resolve before going past the prototype) + +1. **Transcript truth on partition** — node vs. hub when they disagree after a reconnect. +2. **Input arbitration** — is a soft driving-token enough, or do you want hard turns? +3. **CLI coexistence** — do existing Claude Code CLI sessions appear as first-class nodes, + or is the web the only entry point?