# 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: <idea>" (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?
