# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/).

## [Unreleased]

## [0.8.3] - 2026-04-08 -- Critical Delivery Fixes

Six bugs identified via Codex-assisted analysis. The v0.8.2 ack cursor introduced a class of permanent message loss; this release removes it and fixes related delivery issues.

### Fixed
- **CRITICAL: Removed ack cursor (permanent message loss)** -- The `last_acked_id` high-water-mark cursor introduced in v0.8.2 permanently skipped messages that failed channel push. If messages [100, 101, 102] were polled and push failed for 101, the cursor advanced to 102 and msg 101 was never returned again (`101 > 102` = false). Poll query now relies solely on the durable `delivered` column — no cursor.
- **Safety-net acks regardless of push success** -- The 30s safety-net loop acked messages and added them to the dedup set even when channel push failed (code was outside try-catch). Now only acks on successful push; failed messages are retried next cycle.
- **Dedup-before-ack strands messages** -- `rememberPushedId()` ran before the broker ack call. If ack failed, the message was stuck in the in-memory dedup set (never retried) but not marked delivered in the broker. Now dedup set is populated only after successful ack.
- **Broadcast cooldown burns quota on invalid requests** -- Cooldown counter incremented before type/size validation, so malformed broadcasts consumed rate limit slots. Validation now runs first; only valid broadcasts count toward the limit.

### Removed
- **`last_acked_id` column** -- No longer used by poll query or ack handler. Column remains in schema (SQLite doesn't support DROP COLUMN) but is inert.
- **`advanceAckCursor` prepared statement** -- Removed from broker and types.

### Stats
- Tests: 114 pass, 0 fail, 352 assertions (unchanged from v0.8.2)
- Bugs found: 6 (4 fixed, 1 accepted risk [wave delivery non-durable], 1 cosmetic [self-message in check_messages])

## [0.8.2] - 2026-04-07 -- Reliability & Fleet Management

### Added
- **Broker-side ack cursor** -- Added `last_acked_id` column to peers table. `poll-messages` now filters by `id > last_acked_id`, and `ack-messages` advances the cursor. Acked messages are never re-delivered after `/mcp` reconnect, eliminating duplicate delivery. **REVERTED in v0.8.3 — caused permanent message loss.** ([`1843e9e`](https://github.com/RichelynScott/claude-peers-mcp/commit/1843e9e))
- **Broadcast wave delivery** -- Broadcasts to many peers are now staggered in waves of 5 with 5-second intervals. First wave is immediate; remaining waves fire-and-forget. Prevents API rate limit errors when all agents respond simultaneously. ([`c695f2a`](https://github.com/RichelynScott/claude-peers-mcp/commit/c695f2a))
- **Per-sender broadcast cooldown** -- Rate-limits broadcasts to 10 per 60 seconds per sender (`from_id`). Prevents broadcast storm amplification where rate-limit warnings trigger more broadcasts. ([`1843e9e`](https://github.com/RichelynScott/claude-peers-mcp/commit/1843e9e))
- **Self-message filter** -- Server-side safety net skips messages where `from_id === myId` in both poll and safety-net loops. ([`1843e9e`](https://github.com/RichelynScott/claude-peers-mcp/commit/1843e9e))
- **`kick-peer` endpoint + CLI** -- New `/kick-peer` broker endpoint removes a peer and cleans up pending messages. CLI: `bun src/cli.ts kick <peer_id|name>` with case-insensitive name lookup. ([`60872f9`](https://github.com/RichelynScott/claude-peers-mcp/commit/60872f9))

### Fixed
- **Piggyback message truncation** -- Increased piggyback delivery preview from 200 to 2000 characters. When channel push fails and messages fall back to piggyback, task handoffs (500-800 chars typical) are no longer cut off. ([`6ed9ea0`](https://github.com/RichelynScott/claude-peers-mcp/commit/6ed9ea0))

### Stats
- Tests: 113 pass, 0 fail, 351 assertions (was 112/348 in v0.8.1)

## [0.8.1] - 2026-04-01 -- Community Bug Fixes

### Added
- **`whoami` MCP tool** -- Returns the calling instance's own peer ID, session name, CWD, and git root. Lets sessions discover their own identity when peers ask. Closes [#12](https://github.com/RichelynScott/claude-peers-mcp/issues/12). ([`a965336`](https://github.com/RichelynScott/claude-peers-mcp/commit/a965336))
- **npm publish** -- Package published to npm as `claude-peers@0.8.0`. Install with `bun add -g claude-peers`.

### Fixed
- **Worktree repo scope** -- `getGitRoot()` now uses `git rev-parse --git-common-dir` instead of `--show-toplevel`, so peers in different worktrees of the same repo correctly share scope. Closes [#23](https://github.com/RichelynScott/claude-peers-mcp/issues/23). ([`a965336`](https://github.com/RichelynScott/claude-peers-mcp/commit/a965336))
- **SendMessage disambiguation** -- MCP instructions now explicitly reference `mcp__claude-peers__send_message` with a warning against the built-in `SendMessage` tool, preventing mis-routed replies. Closes [#6](https://github.com/RichelynScott/claude-peers-mcp/issues/6). ([`a965336`](https://github.com/RichelynScott/claude-peers-mcp/commit/a965336))

### Stats
- Tests: 112 pass, 0 fail, 348 assertions (was 111/341 in v0.8.0)

## [0.8.0] - 2026-03-28 -- Metrics, CLI Search, and Documentation

### Added
- **Broker `/metrics` endpoint** -- New GET endpoint (no auth) returns uptime, peer count, message stats (total/delivered/pending/delivery rate), requests per minute, and federation status. Optional `?detailed=true` adds per-peer breakdown. ([`6207c7a`](https://github.com/RichelynScott/claude-peers-mcp/commit/6207c7a))
- **CLI `messages` subcommand** -- Search and filter message history directly from SQLite. Flags: `--from`, `--to`, `--since`, `--search`, `--limit`, `--json`. Opens DB read-only, no broker dependency. ([`0502c18`](https://github.com/RichelynScott/claude-peers-mcp/commit/0502c18))
- **CLI `metrics` subcommand** -- Human-readable broker metrics display with `--detailed` flag for per-peer info. ([`0502c18`](https://github.com/RichelynScott/claude-peers-mcp/commit/0502c18))
- **Architecture documentation** (`docs/ARCHITECTURE.md`) -- Mermaid diagrams for component layout, three-layer message flow, federation topology, hot-reload architecture, database schema, and authentication model. ([`3a630b6`](https://github.com/RichelynScott/claude-peers-mcp/commit/3a630b6))
- **API reference** (`docs/API.md`) -- Complete HTTP endpoint reference for all broker and federation endpoints with request/response schemas. ([`7808862`](https://github.com/RichelynScott/claude-peers-mcp/commit/7808862))
- **Federation guide** (`docs/FEDERATION.md`) -- Standalone setup guide covering quick start, manual setup, WSL2/macOS specifics, troubleshooting, and security model. ([`b93a30d`](https://github.com/RichelynScott/claude-peers-mcp/commit/b93a30d))

### Fixed
- **README accuracy** -- Corrected `send_message` param name (`text` -> `message`), updated `check_messages` description for three-layer delivery, clarified `set_name` behavior after `/rename`. ([`8c2379f`](https://github.com/RichelynScott/claude-peers-mcp/commit/8c2379f))

### Stats
- Tests: 111 pass, 0 fail, 341 assertions (was 104/318 in v0.7.0)

## [0.7.0] - 2026-03-27 -- npm Publish Ready

### Added
- **npm publish prep** -- `files` field in package.json specifying published contents (src/, dist/, README, LICENSE, CHANGELOG, GETTING_STARTED, SECURITY, CONTRIBUTING, docs/). Package is ready for `bun publish`. ([`d34454a`](https://github.com/RichelynScott/claude-peers-mcp/commit/d34454a))
- **Bundled CLI binary** -- `bun build` compiles `src/cli.ts` into a single `dist/cli.js` with shebang for direct execution. `bin` entry points to the bundled output. Build runs automatically via `prepublishOnly` on publish. ([`8933b26`](https://github.com/RichelynScott/claude-peers-mcp/commit/8933b26))

## [0.6.2] - 2026-03-27

### Fixed
- **Safety-net channel push for idle sessions** -- safety-net polling (every 30s) now attempts channel push directly before falling back to piggyback queue. Previously, idle sessions with no tool calls would never receive piggybacked messages. Now the safety-net retries channel push, giving idle sessions a delivery path without requiring active tool calls. Fixes the #1 reliability complaint: messages silently dropped to idle sessions. ([`d78b60e`](https://github.com/RichelynScott/claude-peers-mcp/commit/d78b60e))

## [0.6.1] - 2026-03-27

### Added
- **Version tracking in peer registration** -- MCP servers now report their CPM version to the broker on register. Visible in `list_peers` output as `Version: X.Y.Z`. Helps diagnose version mismatches across sessions. ([`f570f72`](https://github.com/RichelynScott/claude-peers-mcp/commit/f570f72))
- **GETTING_STARTED.md** -- step-by-step tutorial from zero to first message. Covers install, MCP registration, channel push setup, and first peer discovery. ([`4c88540`](https://github.com/RichelynScott/claude-peers-mcp/commit/4c88540))
- **SECURITY.md** -- threat model, authentication mechanisms, and audit results. ([`6a85a9e`](https://github.com/RichelynScott/claude-peers-mcp/commit/6a85a9e))
- **GitHub Actions CI** -- `bun test` runs on every push and PR to main. Issue/PR templates and CONTRIBUTING.md for public contributors. ([`71d0d57`](https://github.com/RichelynScott/claude-peers-mcp/commit/71d0d57))

### Fixed
- **Logging reliability** -- replaced `Bun.write` append with `appendFileSync` to prevent log corruption under concurrent writes. ([`4e0c529`](https://github.com/RichelynScott/claude-peers-mcp/commit/4e0c529))
- **Actionable error messages** -- startup failures now probe broker health, report peer count, and suggest specific fixes instead of generic errors. ([`e80841d`](https://github.com/RichelynScott/claude-peers-mcp/commit/e80841d))
- **Piggyback queue stale threshold** -- increased from 2 minutes to 10 minutes. The previous threshold caused 100+ messages per session to be evicted prematurely, defeating the piggyback delivery layer. ([`76444f4`](https://github.com/RichelynScott/claude-peers-mcp/commit/76444f4))

## [0.6.0] - 2026-03-27 -- Reliability Release

### Summary
Three-layer message delivery that mitigates Claude Code's ~30-50% silent notification drop rate. Messages now have three independent chances to reach the model: instant channel push, piggyback on the next tool call, and periodic safety-net polling. Also adds automatic broker reconnection -- no more manual `/mcp` after broker restarts.

### Added
- **Three-layer message delivery** -- messages now have three independent paths to reach the Claude model, each compensating for the previous layer's failure mode: ([`d5d1c9d`](https://github.com/RichelynScott/claude-peers-mcp/commit/d5d1c9d))
  1. **Layer 1 -- Channel push** (instant): `mcp.notification()` pushes messages into the session immediately. Works ~50-70% of the time due to Claude Code platform limitations.
  2. **Layer 2 -- Piggyback on tool call** (reliable): Messages that channel push may have missed are queued locally and prepended as a banner to the next tool call response. 5-second grace period avoids duplicating messages that channel push already delivered.
  3. **Layer 3 -- Safety-net polling** (periodic): Every 30 seconds, polls the broker for any undelivered messages that slipped through both previous layers. Queues them for piggyback delivery instead of re-attempting channel push. ([`ccd4e6e`](https://github.com/RichelynScott/claude-peers-mcp/commit/ccd4e6e))
- **Auto-reconnect to broker on disconnect** -- after 5 consecutive poll failures (~5 seconds), server.ts automatically re-registers with the broker. Handles broker restarts transparently without requiring manual `/mcp` reconnect. Session name and summary are restored after reconnect. Poll failure logging throttled to avoid log spam. ([`f8d165b`](https://github.com/RichelynScott/claude-peers-mcp/commit/f8d165b))

### Fixed
- **Silent message loss** -- the primary reliability problem since v0.1.0. Previously, if `mcp.notification()` succeeded at the stdio level but Claude Code dropped the notification internally, the message was lost forever. Now, piggyback delivery and safety-net polling provide two independent recovery paths.

## [0.5.1] - 2026-03-26

### Changed
- **Broker handler refactor**: Separated 1342-line `broker.ts` monolith into `broker.ts` (524 lines, state/timers/lifecycle) + `broker-handlers.ts` (720 lines, request handlers in factory closures). Architecture validated by 5-model PAL consensus (GPT-5.3-codex, GPT-5.4, Sonnet 4.6, GLM-5, Minimax). ([`1805548`](https://github.com/RichelynScott/claude-peers-mcp/commit/1805548))
- **SIGHUP code hot-reload**: SIGHUP now reloads handler code from disk via dynamic import cache-busting + `Bun.serve().reload()`, in addition to token/config refresh. Connections preserved, rollback on import failure. ([`3af8ac2`](https://github.com/RichelynScott/claude-peers-mcp/commit/3af8ac2))
- **BrokerContext pattern**: All handler state passed via typed `BrokerContext` object (db, 13 prepared statements, Maps, config refs). Enables unit-testable handlers with mock context. ([`5b2019a`](https://github.com/RichelynScott/claude-peers-mcp/commit/5b2019a))
- **Auto-summary disambiguation**: TTY identifier included in summary prefix (`[CPM_WORKER_2:pts/44]`) so sessions in the same directory are distinguishable. Registration age shown in `list_peers` output (`Active: 2h 15m`). MCP instructions updated to emphasize frequent, specific `set_summary` calls. ([`b9d9382`](https://github.com/RichelynScott/claude-peers-mcp/commit/b9d9382))
- **Immediate summary on set_name**: Calling `set_name` now auto-regenerates and pushes the summary with the new name. New sessions with a name get a fallback summary (`[Name] Awaiting tasks in project`) instead of nothing. ([`b9d9382`](https://github.com/RichelynScott/claude-peers-mcp/commit/b9d9382))

### Fixed
- **Dead route**: Removed duplicate POST `/federation/status` case (unreachable -- federation status is GET-only, handled before POST auth check).

## [0.5.0] - 2026-03-26 -- Stable Release

### Summary
Production-stable release after extensive reliability work, multi-model code review (GPT-5.4, Grok-4.20, Gemini-3.1-Pro, DeepSeek-v3.2, Minimax-m2.7, Kimi-k2.5, GLM-5), and security audit. 104 tests, 318 assertions. Simplified delivery model, deterministic peer IDs, broker hot-reload, and comprehensive CLI tooling.

### Added
- End-to-end integration tests for full message delivery pipeline (4 new tests)
- Broker SIGHUP hot-reload for config/token changes without restart
- `reload-broker` CLI command sends SIGHUP to running broker
- Federation relay validation (type, metadata, size limit) matching local send rules

### Security
- Final PAL security review (Gemini-3.1-Pro) -- no critical or high issues
- All 12 security checklist items verified (ack scoping, HMAC, timingSafeEqual, parameterized SQL, etc.)

## [0.4.2] - 2026-03-26

### Added
- **SIGHUP hot-reload for broker config**: Broker re-reads auth token and persistent config file on SIGHUP without dropping connections or requiring `/mcp` reconnect. Uses `Bun.serve().reload()` to swap fetch handler in-place. ([`e9af8f6`](https://github.com/RichelynScott/claude-peers-mcp/commit/e9af8f6))
- **`reload-broker` CLI command**: Finds broker PID via lsof, sends SIGHUP, reports success with peer count. ([`e9af8f6`](https://github.com/RichelynScott/claude-peers-mcp/commit/e9af8f6))

### Fixed
- **Federation relay validation (security)**: Federation `/relay` endpoint now validates metadata is a plain object (not array), enforces 10KB combined size limit (text + metadata), and uses the shared `VALID_MESSAGE_TYPES` set -- same rules as `/send-message`. Previously a malicious federated peer could relay oversized or malformed messages. ([`9375f11`](https://github.com/RichelynScott/claude-peers-mcp/commit/9375f11))
- **Zombie test broker cleanup**: All 4 test files now force-kill any process holding their test port in `beforeAll`, preventing cascading failures from interrupted test runs. ([`b1b9bee`](https://github.com/RichelynScott/claude-peers-mcp/commit/b1b9bee))

## [0.4.1] - 2026-03-26

### Changed
- **Simplified delivery model**: Stripped deferred ack system (-279 lines). Messages now push once, ack immediately, dedup via Set, with `check_messages` as fallback. Removed: pending buffers, delivery warnings, sender tracking, bug reports, piggyback inbox, retry push -- all caused cascading problems (duplicates, spam, constant pinging).
- **Deterministic peer IDs**: Peer IDs are now SHA-256 hashes of TTY, stable across `/mcp` reconnects. Messages sent to an old ID still arrive after reconnect.
- **Per-poll peer fetch**: Sender info fetched once per poll cycle with `scope: "lan"` instead of per-message with `scope: "machine"`. Reduces broker load and includes federated senders.
- **Session identification improvements**: Session names persist locally in MCP server and re-sent on register. Auto-summaries include `[SessionName]` prefix when set. `list_peers` output shows session name as prominent header (`**Name** (id)`). ([`37adc79`](https://github.com/RichelynScott/claude-peers-mcp/commit/37adc79))

### Fixed
- **Duplicate message delivery**: Added permanent `pushedMessageIds` Set with bounded cap (1000). Messages are never pushed twice regardless of ack state or buffer expiry.
- **Delivery warning spam**: Removed entirely. Warnings fired every second instead of once, and the underlying push unreliability is a Claude Code limitation, not fixable server-side.
- **Ack scoping**: `/ack-messages` now scopes by `to_id` -- peers can only ack their own messages.
- **Dead peer message bounce**: Broker bounces undelivered messages back to senders when target peer dies, with orphan cleanup on startup.
- **Dead code cleanup**: Removed all leftover references to removed systems (writeBugReport, SentMessage, FAILURE_LOG_PATH, etc.)
- **Stale tool descriptions**: Updated `check_messages` and `channel_health` descriptions to match simplified implementation.

## [0.4.0] - 2026-03-26

### Added
- **Deferred ack for channel push reliability** -- messages are no longer acked to the broker immediately after `mcp.notification()`. They enter a pending buffer and are only confirmed when evidence of receipt arrives: `check_messages` call, `reply_to` match, or 30s optimistic timeout. Eliminates ~30-50% silent message loss. ([`0aef487`](https://github.com/RichelynScott/claude-peers-mcp/commit/0aef487))
- **`check_messages` as a real fallback** -- now returns pending (pushed but unconfirmed) messages plus new broker messages, deduplicated. Previously returned empty because messages were already acked. ([`0aef487`](https://github.com/RichelynScott/claude-peers-mcp/commit/0aef487))
- **Startup retry logic** -- `/register` call wrapped in 3-attempt retry with exponential backoff (0ms, 1s, 3s) and 5s per-attempt timeout. Fixes "Failed to connect" errors with 6+ sessions. ([`68dc1ac`](https://github.com/RichelynScott/claude-peers-mcp/commit/68dc1ac))
- **Configurable startup timeout** -- `CLAUDE_PEERS_STARTUP_TIMEOUT_MS` env var and `server.startup_timeout_ms` config (default 15s, min 3s clamp). ([`68dc1ac`](https://github.com/RichelynScott/claude-peers-mcp/commit/68dc1ac))
- **Startup timing instrumentation** -- each startup phase timed and logged: `broker=Xms, token=Yms, register=Zms, total=Nms`. ([`68dc1ac`](https://github.com/RichelynScott/claude-peers-mcp/commit/68dc1ac))
- **Graceful startup error messages** -- on final failure, probes `/health` for peer count, reports broker reachability, suggests actionable fix. ([`68dc1ac`](https://github.com/RichelynScott/claude-peers-mcp/commit/68dc1ac))
- **Enhanced `/health` endpoint** -- returns `uptime_ms`, `requests_last_minute`, and `pending_messages` in addition to existing fields. ([`68dc1ac`](https://github.com/RichelynScott/claude-peers-mcp/commit/68dc1ac))
- **Broker request priority** -- `/heartbeat` and `/poll-messages` yield to event loop before body parsing, letting queued `/register` requests run first. ([`68dc1ac`](https://github.com/RichelynScott/claude-peers-mcp/commit/68dc1ac))
- **`federation init`** -- one-command setup: config file, certs, token, platform-specific firewall (WSL2/macOS/Linux), broker restart, outputs join URL. Replaces `federation setup` (which remains as alias). ([`5c5b49e`](https://github.com/RichelynScott/claude-peers-mcp/commit/5c5b49e))
- **`federation join <cpt-url>`** -- single command to join a federation using a `cpt://host:port/token` URL. Writes token, updates config, generates cert, restarts broker, connects. ([`5c5b49e`](https://github.com/RichelynScott/claude-peers-mcp/commit/5c5b49e))
- **`federation token`** -- generates a `cpt://` connection URL for sharing with other machines. ([`5c5b49e`](https://github.com/RichelynScott/claude-peers-mcp/commit/5c5b49e))
- **`federation doctor`** -- comprehensive health check: config, token, certs, broker, TLS, LAN IP, connected remotes, config/actual mismatch warnings. ([`5c5b49e`](https://github.com/RichelynScott/claude-peers-mcp/commit/5c5b49e))
- **Auto-reconnect on broker restart** -- broker reads `federation.remotes` from config file on startup and reconnects with exponential backoff (0s, 5s, 15s, 45s, then 60s). ([`5c5b49e`](https://github.com/RichelynScott/claude-peers-mcp/commit/5c5b49e))
- **Connect/disconnect persistence** -- `federation connect` saves to config file, `federation disconnect` removes. Survives broker restarts. ([`5c5b49e`](https://github.com/RichelynScott/claude-peers-mcp/commit/5c5b49e))
- **`federation refresh-wsl2`** -- updates stale port forwarding rules when WSL2 IP changes after reboot. ([`54f3a6d`](https://github.com/RichelynScott/claude-peers-mcp/commit/54f3a6d))
- **WSL2 mirrored networking detection** -- reads `.wslconfig` for `networkingMode=mirrored`, skips port forwarding when detected. ([`54f3a6d`](https://github.com/RichelynScott/claude-peers-mcp/commit/54f3a6d))
- **mDNS auto-discovery** -- new `src/mdns.ts` module with `MdnsManager`. Advertises `_claude-peers._tcp` service on LAN via `bonjour-service`. Auto-connects when matching PSK hash peers discovered. Backoff logic, dedup, WSL2 graceful degradation. ([`1fddddf`](https://github.com/RichelynScott/claude-peers-mcp/commit/1fddddf))
- **Sender delivery confirmation** -- broker `/message-status` endpoint, `message_status` MCP tool, automatic 30s delivery check with channel push warning to sender. ([`1657928`](https://github.com/RichelynScott/claude-peers-mcp/commit/1657928))
- **Auto bug reports** -- on send failure or unconfirmed delivery, writes diagnostics to `BUG_REPORTS/` and `cpm-logs/delivery-failures.log`. ([`1657928`](https://github.com/RichelynScott/claude-peers-mcp/commit/1657928))
- **`channel_health` MCP tool** -- diagnostic report: broker status, pending inbound/outbound, delivery warnings, recent failures, bug report count. ([`1657928`](https://github.com/RichelynScott/claude-peers-mcp/commit/1657928))

### Fixed
- **`FEDERATION_ENABLED=false` env var override** -- previously only checked for `true`/`1`, now respects `false`/`0` to explicitly disable federation even when config file says enabled. ([`1122b72`](https://github.com/RichelynScott/claude-peers-mcp/commit/1122b72))
- **Delivery warning surfacing** -- warnings now push a self-notification via channel to interrupt the sender immediately, not just log to stderr. ([`4f5546d`](https://github.com/RichelynScott/claude-peers-mcp/commit/4f5546d))
- **Better Windows LAN IP detection** -- uses default route method (`Get-NetIPConfiguration` with gateway) instead of pattern matching that misses `172.16-31.*` and hits VPN adapters. ([`54f3a6d`](https://github.com/RichelynScott/claude-peers-mcp/commit/54f3a6d))
- **WSL2 subnet warning** -- broker logs warning when user sets `CLAUDE_PEERS_FEDERATION_SUBNET` to non-`0.0.0.0/0` on WSL2 (unreliable due to NAT IP rewriting). ([`54f3a6d`](https://github.com/RichelynScott/claude-peers-mcp/commit/54f3a6d))

### Code Quality (7-model consensus review)
- 12 issues identified and fixed via multi-model consensus review (GPT-5.4, Grok-4.20, Gemini-3.1-Pro, DeepSeek-v3.2, Minimax-m2.7, Kimi-k2.5, GLM-5):
  - `sentMessages` Map bounded at MAX_SENT=200 (`server.ts`)
  - PSK hash comparison uses `timingSafeEqual` to prevent timing side-channel (`mdns.ts`)
  - `Peer.channel_push` made optional to prevent "undefined" display on remote peers (`types.ts`)
  - Config file permissions tightened to 0o600 (`config.ts`)
  - Bug report filename collision fixed for messageId=0 send failures (`server.ts`)
  - Warned `sentMessages` entries rechecked for late delivery (`server.ts`)
  - `as any` cast removed in message_status handler (`server.ts`)
  - Verification timer cleared on shutdown (`server.ts`)
  - `autoReconnectRemote` capped at 20 attempts and doubled backoff fixed (`broker.ts`)
  - Federation relay validates message type against allowed set (`broker.ts`)
  - Buffer overflow force-ack replaced with skip-and-re-poll to preserve deferred ack contract (`server.ts`)
  - MdnsManager `dedupMap`/`backoffMap` cleaned every 5 minutes (`mdns.ts`)

### Dependencies
- Added `bonjour-service@1.3.0` for mDNS auto-discovery (pure JS, no native addons)

## [0.3.0] - 2026-03-25

### Added
- LAN Federation Phase A -- manual cross-machine peer discovery via `connect <ip>` ([`c057ec7`](https://github.com/RichelynScott/claude-peers-mcp/commit/c057ec7))
- Federation CLI commands: `connect`, `disconnect`, `status` for managing LAN peers
- Cross-machine peer discovery with `list_peers(scope="lan")`
- Cross-machine messaging via `send_message` to remote peers (hostname:peer_id format)
- LAN broadcast with `broadcast_message(scope="lan")`
- TLS encrypted federation transport with self-signed certificates
- PSK (pre-shared key) authentication for federation endpoints
- HMAC-SHA256 message signing for federation requests
- Zombie MCP server prevention -- parent death detection and TTY-based eviction ([`844bc33`](https://github.com/RichelynScott/claude-peers-mcp/commit/844bc33))
- Persistent config file (`~/.claude-peers-config.json`) for federation settings
- Guided federation setup wizard (`bun src/cli.ts federation setup`)
- 21 federation-specific tests bringing total to 100 tests, 302 assertions

### Fixed
- TLS cert generation now defaults to RSA-2048 for macOS LibreSSL compatibility (Ed25519 caused handshake failures)
- WSL2 subnet auto-detection defaults to allow-all (172.x.x.x NAT range is not the LAN)
- Auto-detection and cleanup of stale MCP server processes on startup
- New CLI `restart` command kills broker + all MCP servers for clean reconnect
- Channel notification payload format -- null values silently dropped by Claude Code, now omitted cleanly ([`eb4c72b`](https://github.com/RichelynScott/claude-peers-mcp/commit/eb4c72b))
- IP spoofing vulnerability -- use `server.requestIP()` instead of `X-Forwarded-For` header
- HMAC canonicalization -- nested objects now preserved during signing
- Bun `fetch()` TLS workaround -- use `curl` for self-signed certificate connections
- Token rotation support (`bun src/cli.ts rotate-token`)

### Security
- Removed exposed PSK token from repository, rotated credentials

### Removed
- OpenAI dependency for auto-summary -- replaced with deterministic git-based summary generation ([`b629fee`](https://github.com/RichelynScott/claude-peers-mcp/commit/b629fee))

## [0.2.0] - 2026-03-24

### Added
- Bearer token authentication on all broker POST endpoints with auto-generated token at `~/.claude-peers-token` ([`8d52439`](https://github.com/RichelynScott/claude-peers-mcp/commit/8d52439))
- Token rotation support via SIGHUP signal
- Structured message protocol -- message types: text, query, response, handoff, broadcast ([`133d09e`](https://github.com/RichelynScott/claude-peers-mcp/commit/133d09e))
- JSON metadata field on messages for structured payloads
- `reply_to` field for message threading
- Broadcast endpoint (`/broadcast`) and `broadcast_message` MCP tool for scoped group messaging ([`133d09e`](https://github.com/RichelynScott/claude-peers-mcp/commit/133d09e))
- Auto-summary CLI command with deterministic git context ([`57ee55a`](https://github.com/RichelynScott/claude-peers-mcp/commit/57ee55a))
- MCP server integration test suite -- 18 tests via MCP Client over stdio ([`67baf9f`](https://github.com/RichelynScott/claude-peers-mcp/commit/67baf9f))
- Two-phase message delivery with poll + ack for at-least-once guarantee ([`de82a12`](https://github.com/RichelynScott/claude-peers-mcp/commit/de82a12))
- PID liveness check on send -- dead peers get immediate error instead of silent queueing ([`de82a12`](https://github.com/RichelynScott/claude-peers-mcp/commit/de82a12))
- Message ID returned on successful send for tracking ([`de82a12`](https://github.com/RichelynScott/claude-peers-mcp/commit/de82a12))
- Message cleanup -- delivered messages purged after 7 days on 60s interval ([`c54dd1a`](https://github.com/RichelynScott/claude-peers-mcp/commit/c54dd1a))
- Rate limiting -- 60 requests/min per IP on `/send-message` ([`c54dd1a`](https://github.com/RichelynScott/claude-peers-mcp/commit/c54dd1a))
- Message size limit -- 10KB max payload ([`c54dd1a`](https://github.com/RichelynScott/claude-peers-mcp/commit/c54dd1a))
- CLI `set-name` command ([`c54dd1a`](https://github.com/RichelynScott/claude-peers-mcp/commit/c54dd1a))
- Broker test suite -- 40 tests, 205 assertions ([`cca5691`](https://github.com/RichelynScott/claude-peers-mcp/commit/cca5691))
- CLI + auto-summary test suite -- 17 tests ([`57ee55a`](https://github.com/RichelynScott/claude-peers-mcp/commit/57ee55a))
- Centralized `cpm-logs/` directory for all observability ([`aafb332`](https://github.com/RichelynScott/claude-peers-mcp/commit/aafb332), [`bc045a1`](https://github.com/RichelynScott/claude-peers-mcp/commit/bc045a1))
- Session name preserved on re-register ([`df482b5`](https://github.com/RichelynScott/claude-peers-mcp/commit/df482b5))
- Message preview in channel notifications ([`df482b5`](https://github.com/RichelynScott/claude-peers-mcp/commit/df482b5))
- TROUBLESHOOTING.md for new session onboarding ([`6ba8316`](https://github.com/RichelynScott/claude-peers-mcp/commit/6ba8316))

### Fixed
- Rate limit map memory leak -- expired entries now cleaned on 60s interval ([`e7515e0`](https://github.com/RichelynScott/claude-peers-mcp/commit/e7515e0))
- O(1) log file append -- replaced read-then-write with Bun.write append mode ([`e7515e0`](https://github.com/RichelynScott/claude-peers-mcp/commit/e7515e0))
- Rate limiting scope -- exempt `/register`, `/heartbeat`, and internal endpoints ([`669b4fe`](https://github.com/RichelynScott/claude-peers-mcp/commit/669b4fe), [`46a740d`](https://github.com/RichelynScott/claude-peers-mcp/commit/46a740d))
- TDZ bug in broker -- `cleanDeliveredMessages` called before prepared statement declared ([`cca5691`](https://github.com/RichelynScott/claude-peers-mcp/commit/cca5691))
- `/health` endpoint now responds to any HTTP method ([`e7515e0`](https://github.com/RichelynScott/claude-peers-mcp/commit/e7515e0))

### Changed
- README fully rewritten for fork with 13 sections ([`cca5691`](https://github.com/RichelynScott/claude-peers-mcp/commit/cca5691))
- CLAUDE.md updated with fork divergence table, key files, and Bun conventions

## [0.1.0] - 2026-03-24

### Added
- Fork from [louislva/claude-peers-mcp](https://github.com/louislva/claude-peers-mcp)
- `session_name` as first-class field in peer registry with schema migration ([`6b8ec50`](https://github.com/RichelynScott/claude-peers-mcp/commit/6b8ec50))
- `set_name` MCP tool for setting human-friendly session names ([`6b8ec50`](https://github.com/RichelynScott/claude-peers-mcp/commit/6b8ec50))
- `from_name` metadata in channel push notifications ([`6b8ec50`](https://github.com/RichelynScott/claude-peers-mcp/commit/6b8ec50))
- `[SESSION_NAME]` tag display in CLI output ([`6b8ec50`](https://github.com/RichelynScott/claude-peers-mcp/commit/6b8ec50))
- Full message logging to stderr and `cpm-logs/messages.log` ([`c995316`](https://github.com/RichelynScott/claude-peers-mcp/commit/c995316))
- Project documentation: CLAUDE.md, FYI.md, PROJECT_INDEX.json ([`c995316`](https://github.com/RichelynScott/claude-peers-mcp/commit/c995316))
