Skip to content

test(security): catalog invariants + fill negative-test gaps (M1.2)#3

Merged
wusijian007 merged 1 commit into
mainfrom
sec/m1.2-security-catalog
May 14, 2026
Merged

test(security): catalog invariants + fill negative-test gaps (M1.2)#3
wusijian007 merged 1 commit into
mainfrom
sec/m1.2-security-catalog

Conversation

@wusijian007

Copy link
Copy Markdown
Owner

Introduces packages/{core,tools}/test/security/ as the single index for the project's load-bearing safety invariants:

README.md -- catalogue of every invariant
and the test that pins it
bash-parser-rejections.test.ts -- per-syntax rejections: ; | & > <
$() backticks, null bytes,
parent traversal in path args,
absolute paths, rm/mv/git commit
path-traversal.test.ts -- Read/Glob/Edit/Write/Grep reject
.. escapes outside cwd
hook-preuse-blocks-tool.test.ts -- PreToolUse exit-2 stops Write
before the file is touched
scheduler-write-serialization.test.ts-- partitionToolCalls never groups
two writes in a parallel batch;
executeToolBatch keeps them
strictly sequential
test-file-hygiene.test.ts -- meta-check: no test embeds a
Windows drive-letter,
/home//, or /Users//
literal (the M1.1 lesson)

Also fixes a Windows-only TaskStore race surfaced under the new test load: concurrent patch calls on the same task could interleave their load+save sequences and roll back a "killed" patch with a stale "running" snapshot from an appendOutput patch. Two defenses:

  1. Per-task lock around patch so load+save is atomic per task id.
  2. renameWithRetry for the atomic write tempfile rename, since Windows transiently returns EBUSY/EPERM/EACCES on the destination when AV, indexer, or another handle has it open.

Verified 10/10 green locally before pushing.

Introduces packages/{core,tools}/test/security/ as the single index
for the project's load-bearing safety invariants:

  README.md                            -- catalogue of every invariant
                                          and the test that pins it
  bash-parser-rejections.test.ts       -- per-syntax rejections: ; | & > <
                                          $() backticks, null bytes,
                                          parent traversal in path args,
                                          absolute paths, rm/mv/git commit
  path-traversal.test.ts               -- Read/Glob/Edit/Write/Grep reject
                                          .. escapes outside cwd
  hook-preuse-blocks-tool.test.ts      -- PreToolUse exit-2 stops Write
                                          before the file is touched
  scheduler-write-serialization.test.ts-- partitionToolCalls never groups
                                          two writes in a parallel batch;
                                          executeToolBatch keeps them
                                          strictly sequential
  test-file-hygiene.test.ts            -- meta-check: no test embeds a
                                          Windows drive-letter,
                                          /home/<user>/, or /Users/<user>/
                                          literal (the M1.1 lesson)

Also fixes a Windows-only TaskStore race surfaced under the new test
load: concurrent `patch` calls on the same task could interleave their
load+save sequences and roll back a "killed" patch with a stale
"running" snapshot from an appendOutput patch. Two defenses:

  1. Per-task lock around `patch` so load+save is atomic per task id.
  2. `renameWithRetry` for the atomic write tempfile rename, since
     Windows transiently returns EBUSY/EPERM/EACCES on the destination
     when AV, indexer, or another handle has it open.

Verified 10/10 green locally before pushing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@wusijian007 wusijian007 merged commit 1f066b9 into main May 14, 2026
3 checks passed
@wusijian007 wusijian007 deleted the sec/m1.2-security-catalog branch May 14, 2026 06:03
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