-
Notifications
You must be signed in to change notification settings - Fork 0
Unit ownership should use SQLite, not JSON file — read-modify-write race #16
Description
Summary
unit-ownership.ts stores claims in .gsd/unit-claims.json via read-modify-write on a flat file. Everything else in the engine uses SQLite. The claim mechanism has a lost-update race that defeats its purpose under concurrent multi-agent use.
The Race
- Agent A reads
unit-claims.json— unit is unclaimed - Agent B reads
unit-claims.json— unit is unclaimed - Agent A writes claim for itself — succeeds
- Agent B writes claim for itself — succeeds, overwrites Agent A's claim
atomicWriteSync() prevents torn writes (the file is never half-written) but does not prevent lost updates. The read-modify-write cycle is not atomic.
Current Code
unit-ownership.ts:62-68 — claimUnit():
readClaims() → mutate in memory → atomicWriteSync()
The code comments document this as "last writer wins" — which acknowledges the race rather than fixing it.
Fix
Move claims into a SQLite table:
CREATE TABLE IF NOT EXISTS unit_claims (
unit_key TEXT PRIMARY KEY,
agent_name TEXT NOT NULL,
claimed_at TEXT NOT NULL
);Use INSERT OR IGNORE or INSERT ... WHERE NOT EXISTS for atomic claim acquisition. The SQLite single-writer lock provides the serialization that the JSON file cannot.
This also eliminates the inconsistency of having one piece of engine state in a different storage backend than everything else.
Files
src/resources/extensions/gsd/unit-ownership.ts— lines 62-68
Confidence
81%