# claudemesh internal roadmap — 2026-05-02

Strategic counterpart to `docs/roadmap.md` (which is the public, marketing-tone roadmap). This file captures the *why*, the dependencies, the costs, and the things we deliberately won't do.

Anchored in the v0.2.0 backend cut + `#general` auto-creation + filename-tracked migrator + owner-member backfill that all shipped 2026-05-02.

---

## Forcing function

> **Ship v1.6.x in 2 weeks. Ship v1.7.0 in a month. Make the demo. Then commit the daemon.**

Each release stands on its own — usable and shippable even if the next slips. That's the property to optimize for, not "fastest path to v3.0.0."

---

## Schedule

| When | Version | Theme | Status |
|---|---|---|---|
| Now | 1.6.0 | v0.2.0 backend cut | ✅ shipped 2026-05-02 |
| +2w | 1.6.x | Demo polish (SSE, unread, sidebar) | Active |
| +5w | 1.7.0 | First marketing-ready version | Planned |
| +9w | 2.0.0 | Daemon redesign | Planned |
| +15w | 0.3.0 | Self-hosted + per-topic encryption + gateways | Planned |
| TBD | 3.0.0 | Native Claude channels | Anthropic-gated |

≈4 months from today to a teams-can-self-host shape. The MCP bridge stays load-bearing the whole time but stops being the user's problem at v2.0.0.

---

## v1.6.x patch line — 0-2 weeks, polish what's deployed

| Item | Effort | Why now |
|---|---|---|
| Real-time push (SSE on `/api/v1/topics/:name/stream`) | 2 days | Chat lag is the only user-visible v0.2.0 wart. Replaces 5s polling. |
| Unread counts via `last_read_at` | ½ day | Schema column already exists. PATCH on scroll-to-bottom + chip on topic list. |
| Bridge end-to-end smoke (two-mesh forwarding test) | ½ day | Feature shipped, never validated. Catches obvious bugs before any external demo. |
| Drizzle journal + `meta/` cleanup | 1 hour | Inert dead files since the new runner. Low-risk cosmetic. |
| `/v1/peers` includes humans (synthetic presence rows for active apikeys) | 1 day | Today the dashboard chat user is invisible to other peers. |

Total: ~1 week of focused work. Closes the v0.2.0 backend chapter cleanly.

---

## v1.7.0 — 2-3 weeks, the demo cut

The release that turns claudemesh into a thing you can record and show.

**Scope:**
- Member sidebar in the chat panel — names, online dots, presence summaries. Comes nearly free with SSE from v1.6.x.
- Topic search + member-mention autocomplete — `@Mou` hot-keys to `claudemesh send Mou ...`.
- Notification feed at `/dashboard` — "you have N unread in #deploys, 2 mentions in #incident." Purely aggregate; no new schema.
- One-line marketing site refresh — capture screenshots from the now-real-time UI, drop the v0.2.0 stamp from the chat footer, update README/landing.
- First public blog post + recorded demo — "claudemesh in 90 seconds" video. Triggers the first proper user-acquisition push.

**Not in scope:** any architectural change. v1.7.0 is pure UX polish on top of the v1.6.x foundation. Architecture work waits for v2.0.0.

**Why this comes before v2.0.0:** without users, the daemon is a solution for nobody. v1.7.0 produces the first real user signal so v2.0.0 has data to optimize against.

---

## v2.0.0 — 3-4 weeks, the daemon redesign

The single largest architectural shift on the roadmap. Background and rationale captured at length elsewhere this session; summary here.

### Single load-bearing principle

> **The user is the unit of mesh participation, not the Claude session.**

Every weird edge case from this session — the launch tax, the orphan owner, the per-session keypair churn, the MCP install/uninstall ritual, multi-Claude config corruption — comes from getting this one thing wrong today. Fix it once, structurally, and 70% of accumulated complexity vanishes.

### Architecture

```
claudemesh.com (web identity + workspace admin)
        │
        ▼ JWT
broker (unchanged) — wss://ic.claudemesh.com/ws
        │
        ▼ ws per workspace
claudemesh-daemon (per user, launchd/systemd, persistent)
        │
        ▼ unix socket
   ┌────┴────┐
   ▼         ▼
CLI verbs    MCP push-pipe (~50 LoC)
             │
             ▼
        claude (any number of sessions)
```

### What v2.0.0 ships

- **`claudemesh-daemon`** — long-lived per-user process. One WS per workspace, kept alive across Claude session lifetimes. Listens on `~/.claudemesh/sockets/<workspace>.sock`. Started by `claudemesh login`, persists across reboots.
- **HKDF-derived peer keypairs from JWT** — same identity across machines, no key copy ritual. Web sign-up = CLI sign-up = same row in `mesh_member`.
- **Stateless CLI verbs** — each existing command (`send`, `peers`, `topic`, `apikey`, `bridge`, `state`, `remember`, etc.) retargeted to dial the daemon socket. ~3000 LoC of plumbing deleted, ~500 LoC of glue added.
- **50-line MCP server** — dial daemon, forward inbound peer messages as `experimental.claude/channel` notifications. The push-pipe shrinks from ~150 LoC to ~50.
- **`claudemesh launch` deprecated** — replaced by ambient mode: `claude` with no flags. Launch becomes a one-line alias that prints "ambient mode now, just run `claude`" and exits.
- **"Mesh" → "workspace"** in the public surface. DB tables keep `mesh_*` names for migration sanity.

### What v2.0.0 kills

- `claudemesh launch` command — the 8-thing bootstrap was paying for state the daemon now owns persistently.
- `--dangerously-skip-permissions` — set once at install in `settings.json` allowedTools, never seen by the user again.
- `--dangerously-load-development-channels` — written into `~/.claude.json` once at install, never seen again.
- Per-session `CLAUDEMESH_CONFIG_DIR` tmpdir — daemon owns config.
- Per-session `CLAUDEMESH_DISPLAY_NAME` env var — daemon stores it.
- MCP install/uninstall ritual on every launch — MCP entry is permanent.
- Multi-Claude config corruption — only the daemon writes config.
- Orphan-owner bug (just fixed via backfill) — structurally impossible because web sign-up creates the member row.

### What v2.0.0 keeps

- Wire protocol, crypto primitives, broker schema — 100% unchanged.
- All CLI verb names — 100% unchanged (just retargeted).
- REST `/api/v1/*` surface — 100% unchanged.
- Web chat UI — 100% unchanged.
- Bridge peer feature — 100% unchanged.
- Topic semantics, ciphertext field, ephemeral DMs — 100% unchanged.

### Cost

- ~3 weeks focused engineering
- ~30% LoC reduction in the CLI package
- ~80% reduction in support load for "launch flags," "config corruption," "peer keypair lost," "owner has no member row"
- ~0 cost to broker, web app, schema, protocol — none of the deep parts change

### Migration path (backwards-compatible at every step)

1. **Week 1** — daemon binary + unix socket protocol + retarget two CLI verbs (`send`, `peers`) as the smoke test. Ship to alpha testers.
2. **Week 2** — retarget remaining verbs. HKDF-keypair migration with a one-shot `claudemesh migrate-identity` command for existing users.
3. **Week 3** — `claudemesh launch` becomes a deprecated alias. MCP server retargeted to daemon socket. Backfill: every existing user's daemon spins up on first `claudemesh` invocation.
4. **Cut v2.0.0**: remove deprecated launch alias one minor release later (v2.1.0) once metrics show no one's hitting it.

---

## v0.3.0 — 4-6 weeks, the operator chapter

For teams that want to run their own broker, encrypt at the topic level, or wire claudemesh to messaging surfaces beyond Claude Code.

- **Per-topic HKDF encryption** — kills the "broker can read your messages" wart. Symmetric key derived from `mesh.root_key + topic.id`. Web client gets the topic key from the sealed root_key it already holds.
- **Self-hosted broker packaging** — single `docker-compose.yml`, postgres included. CLI accepts `--broker wss://...` to point anywhere. Federation primer.
- **WhatsApp gateway** — peer bot that forwards a topic to a WhatsApp group.
- **Telegram gateway** — same pattern.
- **Tag routing** — `claudemesh send tag:repo:billing "deployed"` lands at every peer working on that repo. Already protocol-supported, needs CLI ergonomics + dashboard surface.

v0.3.0 is when teams that want to run their own broker can do so without paying us. Counterintuitively important: it's also when we can charge for hosted with a clean conscience.

---

## v3.0.0 — Anthropic-blessed cut (conditional)

Conditional on Anthropic shipping first-class agent-to-agent channels in Claude Code. We don't control the timing.

### What's load-bearing about today's flag

`--dangerously-load-development-channels server:claudemesh` does two things:

1. Loads the claudemesh MCP server.
2. Tells Claude Code to treat its `experimental.claude/channel` notifications as runtime channel events.

The flag is named `dangerously-load-development-channels` *specifically because* the channel API is experimental and unstable. Some opt-in mechanism will always be required for Claude Code to receive external events from a third-party process — that's a security-model invariant, not a quirk of today's flag. What changes at v3.0.0 is the *form* of the opt-in, not its existence.

### Two scenarios depending on Anthropic's choice

**Scenario A — MCP-channel API graduates.** The same MCP-based push primitive becomes stable.
- MCP wrapper stays (still translates `ws://broker → MCP notification`).
- The `--dangerously-load-development-channels` flag is replaced by a stable settings.json entry — e.g. `mcpServers.claudemesh.acceptChannelNotifications = true`.
- The `experimental.` prefix on the notification namespace goes away.
- Net user-visible change: nothing, because we already write the flag once at install and the user never sees it. The migration is internal: swap the install logic to write the new settings entry instead of the old flag.

**Scenario B — non-MCP transport ships.** Anthropic introduces a sidecar IPC, a native WebSocket subscription declared in settings, or some other primitive.
- The 50-line MCP wrapper from v2.0.0 disappears.
- The daemon plugs into the new transport directly.
- Some opt-in config is still required (settings.json entry, environment variable, etc.) — Claude Code must know to subscribe to the daemon's channel.
- Net user-visible change: still nothing if our `claudemesh install` adapts to write the new opt-in form.

### What disappears regardless

- The `experimental.` prefix on the channel API (it stabilizes).
- The `dangerously-` framing of the flag (the API is no longer experimental).
- The "you have to pass a launch flag to load development channels" mental model.

### What stays regardless

- An opt-in mechanism somewhere (security model invariant).
- The daemon as the lifecycle owner.
- The protocol, schema, broker, topics, web chat — all unchanged.

### Marketing pivot

claudemesh becomes a "hosted backend for Claude's native multi-agent feature" rather than a "Claude Code extension." The product story simplifies regardless of which shape ships, because the user no longer has to think about MCP servers, dangerous flags, or experimental APIs — claudemesh is just there.

Until v3.0.0 lands, v2.x ships with the MCP bridge under the existing flag. v3.0.0 is the migration target, not a planned feature.

---

## Cross-cutting tracks (always-on, not version-gated)

| Track | What it covers | Target version |
|---|---|---|
| Mobile | iOS peer app (thin: push + reply, same JWT identity) | v2.x |
| Browser peer (proper) | IndexedDB ed25519 + WebCrypto crypto_box for the dashboard. Today's web is REST-only; this makes it a true peer. | v2.x |
| Peer transcript queries | "Hey Claude2, what have you touched in the last hour?" cross-session memory primitive | v0.3.0+ |
| Mesh analytics | Volume, presence, handoff latency dashboards | v0.3.0 |
| Slack peer (first-party) | Today: build-your-own. Shipped natively. | v0.3.0 |

---

## Deliberate exclusions

| Idea | Why deferred |
|---|---|
| Custom bot framework / plugin marketplace | Premature — claudemesh barely has organic users. Build the user base first, then platform. |
| Voice channels | Out of scope. Different product. |
| Video chat | Same. |
| Email-as-peer (incoming SMTP → mesh) | Has demand from one user; ship if 3+ ask. |
| AI summarization of channels | LLM cost + scope creep. Users can wire their own with the existing message API. |
| Mobile push notifications via APNs/FCM | Wait for the iOS peer app, then revisit. |
| Reactions / threading | Not yet — would muddle the protocol surface for marginal value. Reconsider after v0.3.0 user feedback. |

---

## Single-sentence summary

**Polish v1.6.x → ship v1.7.0 demo → commit v2.0.0 daemon → open the operator chapter at v0.3.0 → plug into native channels at v3.0.0 when Anthropic ships them.** Each release stands on its own. The protocol, the schema, the broker, and the topics are all already correct — what changes is the lifecycle owner around them.
