Skip to content

fix(test): flag fs.promises.rm and wrapped or optional-chained rm callees - #848

Merged
ScriptedAlchemy merged 3 commits into
mainfrom
fix/remove-tree-gate-callee
Sep 25, 2026
Merged

ScriptedAlchemy merged 3 commits into
mainfrom
fix/remove-tree-gate-callee

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Owner

Follow-up to #846 and #847. This closes the callee-side false negatives in the scripts/check-test-remove-tree.mjs lint gate. All of the changes are in isNodeBoundRmCall:

  • Wrapped callees: the callee now goes through the same unwrapExpression as the options argument (parentheses, as, satisfies, <T>x, !, instantiation expressions). This flags (rm)(…), rm!(…), (rm as typeof rm)(…), (rm satisfies F)(…), (<F>rm)(…), ((rm)!)(…), and (fs.rm)(…).
  • Wrapped callee objects: the object of X.rm is unwrapped too. This flags fs!.rm(…) and (fs as typeof fs).rm(…).
  • fs.promises.rm: when the object is Y.promises, Y must be an fs namespace or default import. This flags fs.promises.rm(…) for import fs from 'node:fs' and import * as fs from 'node:fs', plus fs.promises!.rm(…) and (fs.promises as T).rm(…). On a /promises namespace the same shape is an extra flag, for a call that would throw anyway.
  • Optional member access: the !expression.questionDotToken exclusion from test: canonical removeTree helper and a lint gate on bare recursive rm #823 is removed, so fs?.rm(…) counts. It was a real removal with no documented reason for the exclusion. rm?.(…) was already flagged.

import fsp from 'node:fs/promises' with fsp.rm(…) was already flagged and is now covered by a test.

Shadowing still runs on the unwrapped identifier. The new test's controls stay unflagged: a parameter fs with fs.promises.rm, a local rm with (rm)!(…), a parameter fs with (fs as Mock)!.rm, other.promises.rm, and fs.other.rm. The new test failed on main before the fix.

Remaining misses (out of scope)

These were confirmed by probe:

  • rmSync(dir, { recursive: true }). Three test files use this form today: rsc-runtime/tests/plugin-root.test.ts, agent-bundle/tests/playground-service.test.ts, and agent-bundle/tests/support/shared-pack.ts.
  • Options through a variable (rm(root, opts)) or a non-literal recursive: deep.
  • maxRetries: 0 counting as retried.
  • rmdir(dir, { recursive: true }).
  • Aliasing through a local (const remove = rm), destructuring (const { rm } = fs.promises), dynamic import() or require, import { default as fs }, fs['rm'], and rm.call(…).

Checks

Run on the merged head 9d1bb93f30, which contains origin/main 3b667c8019:

  • pnpm build: exit 0
  • pnpm typecheck: exit 0
  • pnpm lint (includes the gate; no new flags in the real test tree): exit 0
  • pnpm test:unit: 4432 passed, 0 failed, 6 skipped
  • rstest packages/agent-bundle/tests/check-test-remove-tree.test.ts: 19/19

Independent review by change-risk-reviewer (Claude Opus 5.5) found no material findings: no new false negatives, no crash path, and removing ?. is safe. Its one wording nit in the header comment is fixed.

No changeset: only root scripts/ and packages/agent-bundle/tests/** change, and both are exempt per .changeset/README.md.

@changeset-bot

changeset-bot Bot commented Sep 25, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 9d1bb93

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@ScriptedAlchemy
ScriptedAlchemy merged commit ccccd79 into main Sep 25, 2026
5 checks passed
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-25T03:03:07.715935Z 9d1bb93 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

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