From 7dcad0f52f32653f72e972aaa3afb8a86a9e6b7a Mon Sep 17 00:00:00 2001 From: Joseph Mearman Date: Fri, 11 Sep 2026 21:02:41 +0100 Subject: [PATCH 1/2] docs: correct identity description to device-id, flag the v2 breaking change The Identity section still described the retired fingerprint-based peer-ID derivation (agent-comms#47's P2 substrate swap replaced it with the device-id already canonical in wire-mesh-core), and nothing in the project's own history had marked that change as breaking for semantic-release's benefit, so it shipped across several releases as ordinary patch/minor bumps despite orphaning every existing agent-comms identity on upgrade. BREAKING CHANGE: peer IDs are now derived from SHA-256 of the raw public key (device-id), not the SHA-256 fingerprint of the self-signed X.509 certificate. Every agent ID, room membership, and pending delivery queue tied to a pre-v2 identity is orphaned on upgrade, with no migration path. A v2 bridge cannot interoperate with a v1 one at all. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f070df2..a5c69a6 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,9 @@ sequenceDiagram ### Identity -Each bridge derives its peer ID from the fingerprint of its TLS certificate: ECDSA P-256, self-signed, generated locally. The key material persists per bridge slot (`~/.agent-comms/identity---.json`, owner-only permissions), so the fingerprint — and with it the agent ID, room memberships, and peers' ability to keep delivering to the agent — survives restarts. Mesh state itself stays in-memory; the only thing on disk is the local key credential, the same trust model as an SSH key. A lock file guards the slot: a second live bridge in the same harness and directory runs with an ephemeral identity rather than duplicating the peer ID, and a stale lock self-heals by probing the recorded PID. +Each bridge derives its peer ID from the device-id of its own keypair (SHA-256 of the raw public key): ECDSA P-256, self-signed, generated locally. The key material persists per bridge slot (`~/.agent-comms/identity---.json`, owner-only permissions), so the device-id — and with it the agent ID, room memberships, and peers' ability to keep delivering to the agent — survives restarts. Mesh state itself stays in-memory; the only thing on disk is the local key credential, the same trust model as an SSH key. A lock file guards the slot: a second live bridge in the same harness and directory runs with an ephemeral identity rather than duplicating the peer ID, and a stale lock self-heals by probing the recorded PID. + +**Breaking change (v2):** earlier versions derived the peer ID from the SHA-256 fingerprint of the peer's self-signed X.509 certificate rather than its raw public key. The two values differ for the same keypair, so every agent ID, room membership, and pending delivery queue tied to a pre-v2 identity is orphaned on upgrade — there is no migration path, since existing peers can no longer address an upgraded one under its old ID. A v2 bridge cannot interoperate with a v1 one at all: they no longer agree on wire framing, transport, or peer identity. ## Install From 844e765c3ec34af5f7d796494ab7c1e6733767ff Mon Sep 17 00:00:00 2001 From: Joseph Mearman Date: Fri, 11 Sep 2026 21:03:54 +0100 Subject: [PATCH 2/2] chore: stop pre-push from building and running a hardcoded compiled test The hook still ran a partial manual build (build:frontend only, assuming dist/cli.js already existed from an earlier full build) then executed a single hardcoded compiled test file, dist/test/coordinator-socket-error.integration.test.js -- both left over from before the test suite moved to running directly against TypeScript source via tsx, with no build step. On a fresh checkout or worktree with no prior dist/ output, the hook failed outright on the missing dist/cli.js rather than running any real check. Runs eslint, tsc --noEmit, and the actual pnpm test suite directly against source, matching what test now means everywhere else in the project. --- .husky/pre-push | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.husky/pre-push b/.husky/pre-push index 8675367..56098c3 100644 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -1 +1 @@ -node node_modules/.bin/eslint . 2>&1 && node node_modules/.bin/tsc --noEmit 2>&1 && node node_modules/.bin/tsx src/bridges/user/web/build.ts 2>&1 && printf '#!/usr/bin/env node\n' | cat - dist/cli.js > dist/cli.tmp && mv dist/cli.tmp dist/cli.js && node --test dist/test/coordinator-socket-error.integration.test.js 2>&1 +node node_modules/.bin/eslint . 2>&1 && node node_modules/.bin/tsc --noEmit 2>&1 && node node_modules/.bin/tsx --test --test-concurrency=1 'src/test/**/*.test.ts' 2>&1