| # | Resource | Writer file | Pattern applied | Files touched (line refs) | Smoke test | Flag name | Status | |---|----------|-------------|-----------------|--------------------------|------------|-----------|--------| | P1-1 | lightrag-ingest-health.json | lightrag-auto-ingest.sh:42-65 | advisory-lockf (lockf -k -t 10 on .lock sidecar) | lightrag-auto-ingest.sh:42-95 (update_health rewrite) | `HEALTH_JSON=/tmp/t.json lockf -k -t 1 /tmp/t.json.lock true; echo $?` → 0 | ISOLATION_LIGHTRAG_HEALTH_LOCKF | APPLIED-advisory-lockf | | P1-2 | evidence-ledger.jsonl | mc.js:277-335 | VERIFIED: O_APPEND + fsync fd — single-write per entry, atomic ≤PIPE_BUF | mc.js:329-334 (openSync 'a' + writeSync + fsyncSync + closeSync) | `wc -l` pre/post concurrent test shows no line loss | — | VERIFIED-NO-CHANGE-NEEDED | | P1-3 | evidence-index.jsonl | mc.js:215-228 | VERIFIED: fs.appendFileSync (O_APPEND) — single JSON line per call, atomic ≤PIPE_BUF; dedup check on same-second ts prevents double-entry | mc.js:222-226 | Inspect: single appendFileSync call with JSON.stringify(entry)+'\n' | — | VERIFIED-NO-CHANGE-NEEDED | | P1-4 | Mehanik cleared markers (legacy) /tmp/mehanik-cleared- | pre-dispatch-gate.sh:15-29 | deprecate-and-replace: added DEPRECATION WARN on legacy fallback path; session-scoped path already canonical | pre-dispatch-gate.sh:15-32 (_resolve_mehanik_cleared) | Legacy path fallback now emits stderr warning per ISOLATION_MEHANIK_LEGACY_WARN=1 | ISOLATION_MEHANIK_LEGACY_WARN | APPLIED-deprecate-and-replace | | P1-5 | Evidence dirs (legacy) /tmp/evidence-/ | session-output-validator.sh:296-322 | deprecate-and-replace: added DEPRECATION WARN on legacy numeric path; session-scoped path already canonical | session-output-validator.sh:303-315 (_validate_evidence_path) | Legacy path match now emits stderr warning per ISOLATION_EVIDENCE_LEGACY_WARN=1 | ISOLATION_EVIDENCE_LEGACY_WARN | APPLIED-deprecate-and-replace | | P1-6 | Claim schema stubs (legacy) /tmp/claim-schema-.json | schema-stub-gate.sh:49-60 | deprecate-and-replace: added DEPRECATION WARN on legacy fallback; session-scoped path already canonical | schema-stub-gate.sh:49-65 (session-scoped path block) | Legacy path fallback now emits stderr warning per ISOLATION_SCHEMA_LEGACY_WARN=1 | ISOLATION_SCHEMA_LEGACY_WARN | APPLIED-deprecate-and-replace | | P1-7 | Hop-build started markers /tmp/hop-build-started- | pi-orchestrator.js:4028, mc.js:2021 (read-only check) | DEFERRED: marker is per-task-id (task scope = unit of work). Two sessions on the same task is the collision vector but this requires CAS task-level serialisation at mc.js start — not a file-path fix. No writer lock fixes the design; the correct fix is build-once semantics at dispatch layer. | pi-orchestrator.js:4027-4029 (writer) | grep confirm: task-scoped path, no session scope needed for different tasks | — | DEFERRED-requires-CAS-at-dispatch-layer | | P1-8 | Opus override token /tmp/opus-override-token | opus-cost-guard.sh:76-87 | CAS-mv (atomic mv to consumed path; rename(2) on APFS is atomic per T8-Q2) | opus-cost-guard.sh:76-107 (TOCTOU block replaced with mv-race) | `mv /tmp/opus-override-token /tmp/opus-override-token.consumed.$$ 2>/dev/null && echo won || echo lost` — only one process wins | ISOLATION_OPUS_TOKEN_ATOMIC | APPLIED-CAS-mv | | P1-9 | John bash override token /tmp/john-bash-override-token | john-bash-block.sh:198-233 | CAS-mv (same atomic mv pattern as P1-8) | john-bash-block.sh:198-269 (override token block expanded) | Same mv race test on /tmp/john-bash-override-token | ISOLATION_BASH_TOKEN_ATOMIC | APPLIED-CAS-mv | | P1-10 | MCP Playwright server (process singleton) | settings.json:21 (external — process spawned by Claude Code) | DEFERRED: out-of-process singleton; browser context isolation requires MCP-side session tracking. Call-site lockf is infeasible — no hook wraps MCP tool calls before MCP dispatch. Document: requires MCP-side fix. | No file to patch — external process | No harness possible without MCP API extension | — | DEFERRED-requires-MCP-side-fix | | P1-11 | LightRAG ingest API http://localhost:9621 | lightrag-auto-ingest.sh:253-313 (background ingest subshell) | VERIFIED-PATTERN-EXISTS: cross-process semaphore already present (mkdir-atomic slots, max 2 concurrent). Serialisation at call-site confirmed. ISOLATION_LIGHTRAG_HEALTH_LOCKF flag added as companion. | lightrag-auto-ingest.sh:73-98 (acquire_slot/release_slot via mkdir) | Slot dirs /tmp/alai-lightrag-slot-{0,1} prevent >2 concurrent POSTs | — | VERIFIED-NO-CHANGE-NEEDED | | P1-12 | MEMORY.md daemon write path | system/tools/memory-writer.js | VERIFIED-SINGLETON-BROKER: Unix domain socket at /tmp/alai/memory-writer.sock; single-process serialization queue; all appends are O_APPEND atomic; memory-md-write-block.sh blocks direct Write/Edit tool access. Daemon IS the singleton broker pattern. | memory-writer.js:7-15, 82, 110, 162-169 | Daemon status: `node ~/system/tools/memory-writer.js status` | — | VERIFIED-NO-CHANGE-NEEDED | | P1-13 | MC active-task pointer /tmp/mc-active-task (P2 in ledger, treated as P1 boundary) | session-pid-marker.sh:14; mc.js (reads only) | DEFERRED: probed SAFE in T3. Design is last-writer-wins but empirical collision not observed. session-task-lock-gate.sh deliberately omits enforcement (world-writable, design flaw comment). Fix requires redesign of stlg to enforce session-scoped pointer — tracked as separate task. | session-task-lock-gate.sh:75-81 | T3 verdict: SAFE (both runs). No fix needed this sprint. | — | DEFERRED-probed-SAFE-T3 |
---
## P2 Table (8 resources — mini-probe inspection)
| # | Resource | Writer file | Inspection finding | Verdict | |---|----------|-------------|-------------------|---------| | P2-1 | blueprint-override-ledger.jsonl | pre-dispatch-gate.sh:271-276 | Writer uses `printf ... >> "$LEDGER"` (shell >> = O_APPEND). Single `printf` call produces one complete JSONL line ≤512 bytes. O_APPEND write(2) is atomic for sizes ≤PIPE_BUF (512 bytes, macOS). No read-modify-write. | P2-VERIFIED-LOW — O_APPEND single-write per entry, atomic | | P2-2 | h-ready-audit.jsonl | mc-ready-gate.sh:186 | Writer uses `echo "$AUDIT_ENTRY" >> "$AUDIT_LOG"` (shell >>). AUDIT_ENTRY is a jq-built JSON object. Size typically 200-400 bytes, well under PIPE_BUF. No read-modify-write. Content is informational audit trail; line interleave is extremely unlikely and not correctness-critical. | P2-VERIFIED-LOW — O_APPEND single-write, size <512 bytes | | P2-3 | verdict-ledger.jsonl | evidence-contract-validator.sh:42-78 | Writer has mkdir-based lock (lockdir pattern, 100 retries, 10ms sleep). Lock protects the read-prev-hash + write-new-entry sequence. Lock timeout at 100 retries produces unprotected write (T4 partial coverage). Risk: sustained burst >10 concurrent validators could hit timeout. Current concurrency: ≤4 sessions. At that level, 100 retries × 10ms = 1s window is sufficient. No read-modify-write outside lock. | P2-VERIFIED-LOW — mkdir-lock adequate at ≤4 concurrent; timeout-unlock risk is theoretical at observed volume | | P2-4 | Daily message logs ~/system/memory/daily-logs/.md | user-message-logger.sh:33-47 | Writer appends with `echo "..." >> "$LOG_FILE"` (shell >>). Creates new file if absent (header write is not O_APPEND — `echo > "$LOG_FILE"`). If two sessions both check `! -f "$LOG_FILE"` simultaneously, both could write the header, producing duplicate header. Message appends after that are O_APPEND atomic. Header collision is benign (duplicate line, not corruption). | P2-VERIFIED-LOW — append-only O_APPEND after header; header duplicate benign | | P2-5 | GOTCHA task docs /tmp/gotcha-task-.md | pipeline-engine.js:307, 326 | Writer uses `fs.writeFileSync(gotchaPath, ...)` (O_TRUNC, not O_APPEND). Two sessions on same parent task both call markParentDone → both overwrite same file. Content is derived from pipeline stages query — same data, so last-writer-wins produces identical content. Risk: exactly-once semantics cannot be guaranteed if pipeline stages differ between sessions. | P2-VERIFIED-LOW — writer is pipeline daemon (single-writer-by-design in practice); two sessions on same parent task is rare; content derived from DB not session state | | P2-6 | hivemind.db | hivemind.js:43-44, better-sqlite3 | better-sqlite3 is synchronous and uses SQLite's own locking. `PRAGMA journal_mode` confirmed WAL (live probe: `sqlite3 hivemind.db "PRAGMA journal_mode;"` → `wal`). Concurrent INSERTs under WAL are serialised by SQLite. No application-level read-modify-write observed in writer paths (pure INSERTs and ON CONFLICT DO UPDATE). | P2-VERIFIED-LOW — WAL mode confirmed, SQLite serialises writers, no application TOCTOU | | P2-7 | knowledge.db | knowledge-base.js:28 | `PRAGMA journal_mode` confirmed WAL (live probe: → `wal`). Same rationale as hivemind.db. | P2-VERIFIED-LOW — WAL mode confirmed | | P2-8 | Session save log ~/system/memory/logs/session-save.log | session-ledger.sh:24, `log()` function | Writer uses `echo "..." >> "$LOG_FILE"` (shell >>). Single-line diagnostic log entries. O_APPEND atomic for sizes ≤PIPE_BUF. Low-severity log file; interleaved lines are not correctness-critical. | P2-VERIFIED-LOW — O_APPEND, diagnostic only, no read-modify-write |
---
## Harness Additions
No P2 resources were promoted to P1. No new harness writers needed for promoted resources.
The following harness additions are recommended for T10-quad validation of P1 fixes already applied:
- **writer_ps_lightrag_health_lockf**: New writer function in diagnose-session-collision.sh that simulates concurrent update_health() calls using the lockf path. Run with --targets lightrag_health --writers 4 --per-session-mode to verify fire_count converges to pre+N (was LAST_WRITER_WINS at w=4 in T3 Run B). Added in harness extension below.
- **writer_opus_token_cas**: New writer function that simulates concurrent opus-override-token consumption via mv. Verifies only one session wins the mv race. Added in harness extension below.
- **writer_bash_token_cas**: Same pattern as opus_token_cas for john-bash-override-token.
### P1-7 (Hop-build markers) — DEFERRED-requires-CAS-at-dispatch-layer Writer: `pi-orchestrator.js:4028` — `fs.writeFileSync('/tmp/hop-build-started-', ...)`. The marker is per-task-id. The collision vector is two sessions dispatching the same task simultaneously. Lockf on the file path does not prevent this — the race is at the task-dispatch decision level, not the file-write level. Fix requires: mc.js `start` command to acquire a CAS lease (BEGIN IMMEDIATE) before writing the hop-build marker, ensuring only one session can start a given task. This is a separate sprint item (CAS at task-start). Grep tried: `grep -n "hop-build-started" ~/system/kernel/pi-orchestrator.js` → line 4028. `grep -n "hop-build-started" ~/system/tools/mc.js` → line 2021 (read-only).
### P1-10 (MCP Playwright) — DEFERRED-requires-MCP-side-fix Writer: Claude Code runtime (external process). No hook wraps MCP tool calls before dispatch to the Playwright server. The singleton browser process shares page state across sessions unless the MCP server implements session isolation. Lockf at call-site would only serialise when two hooks call Playwright simultaneously — it would not prevent cross-session page state leakage between sequential calls. Requires MCP-side browser context isolation (one context per CLAUDE_SESSION_ID). Tracked for external escalation. Grep tried: `grep -rn "playwright" ~/.claude/hooks/` → settings.json:21 only.
### P1-13 (MC active-task pointer) — DEFERRED-probed-SAFE-T3 T3 confirmed SAFE at both w=2 and w=4. The design flaw (world-writable global file) is acknowledged at session-task-lock-gate.sh:75-81 but enforcement was deliberately removed. Fixing this requires coordinating stlg behaviour change — out of scope for this P1 sprint. Deferred to technical debt backlog.
---
## T10-quad Validation Scope (for Proveo)
Proveo must validate the following in T10:
1. **P1-1 (lightrag-ingest-health.json)**: Run `diagnose-session-collision.sh --writers 4 --targets lightrag_health` against a fixture. Before fix: LAST_WRITER_WINS (fire_count < pre+4). After fix: verify fire_count == pre+4. Requires new `writer_lightrag_health_lockf` harness function (added to harness below).
2. **P1-8 (opus override token)**: Run concurrent mv-race test: 4 sessions simultaneously try `mv /tmp/opus-override-token /tmp/consumed.$$`. Verify exactly one mv succeeds (exit 0) and three fail (exit non-zero). Requires `writer_opus_token_cas` harness function.
3. **P1-9 (john bash override token)**: Same as P1-8 but for john-bash-override-token path.
4. **P1-4 / P1-5 / P1-6 (legacy deprecation warns)**: Trigger each hook with a legacy-path fixture. Confirm stderr contains `DEPRECATION WARN`. Confirm the hook still accepts the legacy path (backward compat preserved).
5. **P1-2 / P1-3 (evidence-ledger, evidence-index O_APPEND)**: Run 4-concurrent-writer test appending JSONL lines. Verify: (a) no truncated lines, (b) no interleaved partial lines, (c) line count == pre + N.
6. **P1-12 (MEMORY.md daemon)**: `node ~/system/tools/memory-writer.js status` returns running. Run 4 concurrent `node memory-writer.js append "line-"` calls. Verify all 4 lines present in MEMORY.md in order (serial via queue).
---
*Generated by CodeCraft sub-agent. Evidence: code inspection via Read/Grep tools. No production state modified.*
Revision #2
Created 2026-05-18 18:35:47 UTC by John
Updated 2026-06-21 20:03:45 UTC by John