Skip to content

fix([triage-gemini-pr515-out-of-scope-findings]): atomic writes for sub-agent index/metadata + quoted-arg shell parsing#521

Merged
atomantic merged 1 commit into
mainfrom
claim/triage-gemini-pr515-out-of-scope-findings
May 29, 2026
Merged

fix([triage-gemini-pr515-out-of-scope-findings]): atomic writes for sub-agent index/metadata + quoted-arg shell parsing#521
atomantic merged 1 commit into
mainfrom
claim/triage-gemini-pr515-out-of-scope-findings

Conversation

@atomantic

Copy link
Copy Markdown
Owner

Summary

Triage the four out-of-scope findings gemini surfaced during the PR #515 review. All verified reproducible before edit.

  • server/services/commands.jsexecuteCommand was splitting commands on whitespace and ignoring quoted arguments, so e.g. git commit -m "msg with spaces" was passed to spawn as five separate tokens. Now routes through the canonical validateCommand() in commandSecurity.js, which already does quote-aware parsing plus the allowlist + metachar checks.
  • server/lib/fileUtils.jscreateCachedStore.save was writing via plain writeFile, so a mid-write crash truncated the cache. Swapped to the existing atomicWrite helper (temp + rename, with the Windows backup-swap fallback).
  • server/services/cosAgents.jssaveAgentIndex was re-implementing the temp+rename dance with no Windows fallback. completeAgent and several sibling paths wrote metadata.json / index.json non-atomically. All converted to atomicWrite for uniform crash safety. The cross-filesystem writeFile calls inside the rename-failure error handlers stay on plain writeFile (write-once data inside a fallback path).

Gemini also flagged the body-size limit and * CORS in server/index.js; both are intentional per CLAUDE.md's single-user / private-network trust model and were explicitly dismissed when the PLAN entry was written.

Test plan

  • cd server && npm test — 364 files / 8097 pass / 7 skipped
  • Focused: commandSecurity.test.js (41), fileUtils.test.js (85), cosAgents.test.js (1) all pass

…ub-agent index/metadata + quoted-arg shell parsing

Four crash-safety / parsing bugs gemini surfaced during the PR #515 review.
All confirmed reproducible in the current code (verified before edit).

1. server/services/commands.js — executeCommand was hand-rolling allowlist
   + metachar checks against a naive split(/\s+/), so any quoted argument
   containing whitespace (e.g. `git commit -m "msg with spaces"`) was
   chopped and passed to spawn as separate tokens. Now routes through the
   canonical validateCommand() in commandSecurity.js, which parses
   quoted args and runs both safety checks.

2. server/lib/fileUtils.js — createCachedStore.save was writing via
   writeFile, so a mid-write crash truncated the cache file. Swapped to
   atomicWrite (temp + rename, with the existing Windows backup-swap
   fallback).

3. server/services/cosAgents.js — saveAgentIndex was reimplementing the
   temp+rename dance with no Windows backup-swap fallback, and several
   sibling paths wrote agent metadata.json + index.json directly via
   writeFile. All converted to atomicWrite for uniform crash safety —
   completeAgent, the empty/initial migration writes, cleanupZombieAgents,
   submitAgentFeedback, archiveStaleAgents. Cross-filesystem fallback
   inside the rename-failure branches stays on plain writeFile (write-once
   data inside an error handler).

Gemini also flagged the body-size limit and `*` CORS in server/index.js;
both are intentional per CLAUDE.md's single-user/private-network trust
model and were explicitly dismissed when the PLAN entry was written.

Tests: server suite 364 files / 8097 pass.
@atomantic atomantic merged commit 4000e63 into main May 29, 2026
2 checks passed
@atomantic atomantic deleted the claim/triage-gemini-pr515-out-of-scope-findings branch May 29, 2026 05:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant