UNPKG

pi-lens

Version:

Real-time code feedback for pi — LSP, linters, formatters, type-checking, structural analysis & booboo

33 lines (29 loc) • 6.15 kB
# Durable-store cross-process audit (#1202) Atomic rename prevents torn files; it does not serialize read-modify-write. This audit classifies stores reachable by extension, MCP, CLI, and subagent processes. `<project>` means `getProjectDataDir(cwd)` and `<global>` means `getGlobalPiLensDir()`. | Store and path | Racing writers | Semantics | Risk | Existing mitigation / decision | |---|---|---|---|---| | Turn state — `<project>/turn-state.json` | extension, MCP, CLI; subagents use distinct owners | read-modify-write worklist | (a) impossible | **fixed here:** deferred-format writes now carry the pi session owner, and `clearTurnState` / `incrementTurnCycle` reject a foreign live owner just like `addModifiedRange`; MCP turn-end operations are FIFO-serialized. | | Scanner caches — `<project>/cache/{scanner}.json` + `{scanner}.meta.json` | extension, MCP, CLI, subagents | overwrite-only scan result + freshness metadata | (b) possible, benign | none; a losing cache publication is recoverable on the next scan. Data is written before metadata, so interruption cannot make old data newly fresh; concurrent last-finisher wins. | | Rule cache — `<project>/cache/{language}-rules-3.json` | all analysis processes | overwrite-only, content-hash validated | (a) impossible | rule hash rejects a cache for different inputs. | | Workspace diagnostics — `<project>/cache/lsp-workspace-diagnostics.json` | extension/MCP/CLI sweeps and subagents | read-merge-overwrite cache | (b) possible, benign | mtime/content/dependency freshness rejects stale entries; a lost entry causes a rescan. Accepted benign. | | Call graph — `<project>/cache/call-graph.json` + `.meta.json` | extension/MCP/CLI graph builds, subagents | overwrite-only derived graph | (b) possible, benign | source freshness validation; a loss rebuilds from source. Accepted benign. | | Codebase model — `<project>/cache/codebase-model.json` + `.meta.json` | extension/MCP/CLI builds, subagents | overwrite-only derived model | (b) possible, benign | source/file-set validation; a loss rebuilds. Accepted benign. | | Actionable-warning state — `<project>/cache/actionable-warning-state.json` | dispatches in every process | read-merge-overwrite behavior gate | (c) possible, harmful | **fixed here:** bounded exclusive pid lock, in-lock disk re-read, and per-warning merge preserve concurrent suppression fields before atomic replacement. | | Actionable-warning history — `<project>/actionable-warnings.jsonl` | every dispatcher | append-only telemetry | (b) possible, benign | one append call per batch; malformed/truncated telemetry lines are ignored. Accepted benign. | | Metrics history — `<project>/metrics-history.json` | session scans and `/lens-metrics` in every process | read-modify-overwrite trend cache | (c) possible, harmful | **accepted loss:** telemetry only; a race can leave a user-visible gap in trend history, but gaps are self-healing after the next scan restores the latest snapshot. Locking every passive capture or restructuring the established bounded JSON format is disproportionate to advisory history. | | Project diagnostics — `<project>/cache/project-diagnostics.json` and `project-diagnostics-delta.json` | extension/MCP/CLI scans, subagents | overwrite-only derived snapshots | (b) possible, benign | per-file mtime filtering; next scan replaces loss. Accepted benign. | | Worklog — `<project>/worklog.jsonl` | all dispatchers | append-only best-effort telemetry | (b) possible, benign | OS append operation per batch; readers skip malformed lines. Accepted benign. | | Widget/read-guard session state — `<project>/sessions/{sessionId}.json` | one extension host per stable session id | overwrite-only session snapshot | (a) impossible | session-id sharding; read guard and widget are co-snapshotted atomically. | | Diagnostic dispositions — `<project>/cache/diagnostic-dispositions.json` | extension, MCP, CLI tools, subagents | read-modify-write behavior gate | (c) possible, harmful | **fixed here:** exclusive pid lock, in-lock disk re-read, and per-anchor merge refuse stale whole-file promotion. | | Recent touches — `<project>/recent-touches.json` | every extension/subagent publisher | read-append-overwrite bounded attribution ring | (b) possible, benign | explicitly best-effort nudge attribution; lost entries do not gate edits/checks and later touches replenish it. Accepted benign. | | Instance registry — `<global>/instances.json` | every host/MCP/subagent process and reaper | read-modify-overwrite observability registry | (b) possible, benign | explicitly best-effort. Backstop orphan reaping intentionally kills untracked managed processes on dead-parent confirmation; missing registry entries allow this (intentional, #1267-adjacent; no fix needed). | | Project snapshot — `<project>/cache/project-snapshot.json.gz` + `.meta.json` | extension/MCP/CLI builders, subagents | monotonic derived snapshot | (a) impossible | durable project sequence/source identity, one active plus latest queued request per root, worker-earned semantic fingerprint dedupe, and generation-gated staged promotion; body embeds its seq so mismatched metadata is rejected. | | Review graph + checkpoint — `<project>/cache/review-graph.json.gz`, `review-graph.checkpoint.json.gz` | extension/MCP/CLI builders, subagents | overwrite-only derived graph | (a) impossible | source signature/project-seq validation plus staged, generation-gated promotion; stale content is rejected on load. | | Probe cache — `<global>/probe-cache.json` | every installer/prober | read-modify-write tool availability | (a) impossible | existing bounded cross-process lock + in-lock re-read/change merge (#1263). | | Stop-hook status — OS temp `pi-lens-turn-end-*.json` | concurrent CLI Stop hooks | read-modify-overwrite counters | (b) possible, benign | atomic publication; explicitly bounded best-effort telemetry. Accepted benign. | The grammar/WASM destination files are immutable content assets, not shared mutable stores. Atomic staging artifacts are covered separately by the bounded session-start stage GC and are not authoritative stores.