feat(security): atomic writes, input validators, and static analysis tooling#118
feat(security): atomic writes, input validators, and static analysis tooling#118brooksc wants to merge 1 commit into
Conversation
…tooling
Standalone security utilities with no coordinator dependencies — intended as
the foundation PR before the coordinator engine lands.
### atomic.ts
Crash-safe file writes via temp file + rename:
- Temp file written to same directory as target (avoids EXDEV across mounts)
- fsync before rename for file durability
- Directory fsync after rename for directory-entry durability (platform-safe catch)
- Sync variant for use in catch blocks; async variant for normal paths
### validation.ts
- validateBranchName(): mirrors git check-ref-format --branch rules — rejects shell
metacharacters (:, ^, ~, etc.), double dots, path components starting with ".",
any path component ending in ".lock", and other git-illegal patterns
- validateUUID(): enforces v4 UUID format (version nibble=4, variant nibble∈{8,9,a,b})
### Static analysis configs
- .semgrep/: rules for unsafe Electron APIs, IPC auth, and filesystem operations
scoped to electron/mcp/** and electron/ipc/register.ts
- .gitleaks.toml: token/secret leak detection with ASCII quote character classes
- .dependency-cruiser.cjs: architecture linting with orphan exemptions for new files
- knip.config.ts: dead code detection
### Tests (35 cases)
- electron/mcp/validation.test.ts: accepted names, all rejection cases, UUID v4 format
- electron/mcp/atomic.test.ts: write, overwrite, mode, no temp-file residue
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Thanks for splitting this out. I took another careful pass over the PR and found a few things worth addressing before merge:
Verification run locally on the PR head:
|
Overview
Standalone security utilities and static analysis tooling — no coordinator logic, no UI. This is PR 1 of 4 splitting #100 as requested in the round-4 review.
PR sequence:
coordinator-1-securitycoordinator-2-mcp-backendcoordinator-3-store-ipccoordinator-4-uiPRs 2–4 are stacked on each other; nothing coordinator-related is user-visible until PR 4 adds the
NewTaskDialogcheckbox and Settings toggle.What's in this PR
electron/mcp/atomic.tsCrash-safe file writes via temp file + rename:
fsyncbefore rename for file durability; directoryfsyncafter rename for directory-entry durability (platform-safe catch for Windows/network mounts)electron/mcp/validation.tsvalidateBranchName()— mirrorsgit check-ref-format --branch: rejects shell metacharacters (:,^,~, etc.), double dots, path components starting with., any path component ending in.lock, and other git-illegal patternsvalidateUUID()— enforces v4 UUID (version nibble=4, variant nibble∈{8,9,a,b})Static analysis configs
.semgrep/— rules for unsafe Electron APIs, IPC auth, and unsafefsoperations (scoped toelectron/mcp/**+electron/ipc/register.ts).gitleaks.toml— token/secret leak detection.dependency-cruiser.cjs— architecture lintingknip.config.ts— dead code detectionNote: the static analysis tools (
semgrep,gitleaks,dependency-cruiser,knip) are not yet wired into CI — they require system/devDependency setup that lands in PR 2. Configs are included here as they're used to validate the coordinator code in PR 2.Tests (35 cases)
electron/mcp/validation.test.ts— accepted names, all rejection cases, UUID v4 enforcementelectron/mcp/atomic.test.ts— write, overwrite, mode, no temp-file residueTest plan
npm run typecheck && npm test && npm run lint— all passelectron/mcp/validation.test.tsandelectron/mcp/atomic.test.ts— 35/35🤖 Generated with Claude Code