Skip to content

Commit 1164098

Browse files
committed
fix: remove identity file persistence — incompatible with concurrent sessions
Multiple sessions in the same directory would collide on the identity file. In a TCP mesh, state is in-memory so recovering a previous ID is meaningless — the peer's state is already gone. Each instance gets a fresh peer ID on startup.
1 parent 5600f08 commit 1164098

3 files changed

Lines changed: 7 additions & 44 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ All state is held in memory and synchronised between peers. Delivery events are
2929
- On graceful shutdown, coordinator hands over to the longest-running peer
3030
- On crash, remaining peers race to bind the port (~100ms recovery)
3131

32-
### Identity persistence
32+
### Identity
3333

34-
Peer IDs are persisted to `~/.agents/identity/{harness}--{cwd}.json` so agents can recover their identity across restarts.
34+
Each instance gets a unique peer ID on startup. Mesh state is in-memory — when a process exits, its peer is gone. Identity is not persisted because the mesh state dies with the process.
3535

3636
## Install
3737

src/core/mesh-store.ts

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
* Falls back to FileStore if the mesh is unavailable.
1010
*/
1111

12-
import * as fs from "node:fs/promises";
13-
import * as os from "node:os";
14-
import * as path from "node:path";
1512
import * as net from "node:net";
1613
import { nanoid } from "./nanoid.js";
1714
import type { CommsStore } from "./comms-store.js";
@@ -137,7 +134,7 @@ export class MeshStore implements CommsStore {
137134
private messages = new Map<string, RoomMessage[]>();
138135
private dms = new Map<string, DmMessage[]>();
139136
private deliveryQueues = new Map<string, DeliveryEvent[]>();
140-
private identityDir = path.join(os.homedir(), ".agents", "identity");
137+
private identityCache = new Map<string, { id: string }>();
141138

142139
private dataServer: net.Server | undefined;
143140
private dataPort = 0;
@@ -494,26 +491,13 @@ export class MeshStore implements CommsStore {
494491
harness: string,
495492
cwd: string,
496493
): Promise<{ id: string } | undefined> {
497-
const key = `${harness}--${cwd.replace(/[^a-zA-Z0-9]/g, "_")}`;
498-
const filePath = path.join(this.identityDir, `${key}.json`);
499-
try {
500-
const raw = await fs.readFile(filePath, "utf-8");
501-
const parsed: unknown = JSON.parse(raw);
502-
if (typeof parsed === "object" && parsed !== null && "id" in parsed) {
503-
const id = parsed.id;
504-
if (typeof id === "string") return { id };
505-
}
506-
return undefined;
507-
} catch {
508-
return undefined;
509-
}
494+
await Promise.resolve();
495+
return this.identityCache.get(`${harness}--${cwd}`);
510496
}
511497

512498
async writeIdentity(harness: string, cwd: string, id: string): Promise<void> {
513-
const key = `${harness}--${cwd.replace(/[^a-zA-Z0-9]/g, "_")}`;
514-
const filePath = path.join(this.identityDir, `${key}.json`);
515-
await fs.mkdir(this.identityDir, { recursive: true });
516-
await fs.writeFile(filePath, JSON.stringify({ id }), "utf-8");
499+
await Promise.resolve();
500+
this.identityCache.set(`${harness}--${cwd}`, { id });
517501
}
518502

519503
// -----------------------------------------------------------------------

src/test/mesh-e2e.test.ts

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,12 @@ import { CommsTool } from "../core/tool.js";
1010
import { buildAction } from "../core/bridge.js";
1111
import type { DeliveryEvent } from "../core/types.js";
1212
import * as assert from "node:assert/strict";
13-
import * as fs from "node:fs/promises";
14-
import * as path from "node:path";
15-
import * as os from "node:os";
16-
17-
const TEST_IDENTITY_DIR = path.join(
18-
os.homedir(),
19-
".agents",
20-
"identity-test-" + String(Date.now()),
21-
);
2213

2314
async function createStore(
2415
name: string,
2516
harness: string,
2617
): Promise<{ store: MeshStore; tool: CommsTool; deliveries: DeliveryEvent[] }> {
2718
const store = new MeshStore();
28-
// Override identity dir to avoid polluting real state
29-
Object.defineProperty(store, "identityDir", {
30-
value: TEST_IDENTITY_DIR,
31-
writable: true,
32-
});
3319

3420
const deliveries: DeliveryEvent[] = [];
3521
store.onDelivery = (_agentId: string, event: DeliveryEvent) => {
@@ -163,13 +149,6 @@ async function main(): Promise<void> {
163149
await a.store.shutdown();
164150
await b.store.shutdown();
165151

166-
// Clean up test identity files
167-
try {
168-
await fs.rm(TEST_IDENTITY_DIR, { recursive: true });
169-
} catch {
170-
/* ignore */
171-
}
172-
173152
console.log("\n✓ All tests passed!");
174153
}
175154

0 commit comments

Comments
 (0)