Skip to content

Make outbox-listener-delivery-required path-aware - #1040

Open
Jae-Hyuk-Jang wants to merge 3 commits into
fedify-dev:2.2-maintenancefrom
Jae-Hyuk-Jang:fix/lint-outbox-listener-path-aware
Open

Jae-Hyuk-Jang wants to merge 3 commits into
fedify-dev:2.2-maintenancefrom
Jae-Hyuk-Jang:fix/lint-outbox-listener-path-aware

Conversation

@Jae-Hyuk-Jang

Copy link
Copy Markdown
Contributor

Closes #900

Background

outbox-listener-delivery-required (@fedify/lint) decided whether a listener delivers a posted activity by scanning the whole listener source as text for a ctx.sendActivity()/forwardActivity() call, without checking whether that code actually runs.

Changes

  • Add a reachability scan that follows the listener's own control flow (if/else, try/catch, switch, loops), skips statically-dead branches and code after an unconditional return/throw, and does not descend into a nested function's body unless that function is itself called from reachable code.
  • Keep the existing text-based pattern matching for the delivery call itself (aliases, destructuring, bracket/template notation), now run only over this narrowed, reachable text.
  • Add regression tests for the three false-negative cases from the issue (unused nested helper, dead branch, delivery call only inside an unrelated callback), plus a case after an unconditional return, and a positive case for a helper function that is actually called.

Testing

  • mise run check-each lint
  • mise run test-each lint (Deno and Node.js, 515/515 pass)
  • Reverted the fix locally and reran the suite: exactly the 4 new regression tests fail, confirming they demonstrate the bug.

AI disclosure

This was implemented with Claude Code (claude-sonnet-5): I described the issue and reviewed the design and results at each step, and Claude Code designed the reachability-based rewrite, implemented it, found and fixed a bug during testing (Deno.lint exposes an AST node's children through prototype getters rather than own enumerable properties, so Object.entries() couldn't see them — for...in was needed instead), and verified the tests pass in both Deno and Node.js.

The rule decided whether an outbox listener delivers a posted
activity by scanning the listener's source text for a
ctx.sendActivity()/forwardActivity() call, regardless of whether that
code actually runs. A call inside an unused nested helper function,
behind a statically-dead branch, or inside a callback passed to an
unrelated function (e.g. array.map()) was enough to satisfy the
check.

Add a scan that follows the listener's own reachable control flow —
skipping dead branches and code after an unconditional return/throw,
and not descending into a nested function's body unless that
function is itself called from reachable code — before falling back
to the existing text-based pattern matching for the delivery call
itself.

fedify-dev#900

Assisted-by: Claude Code:claude-sonnet-5
@coderabbitai

coderabbitai Bot commented Sep 19, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 8e8db00e-f085-4422-935c-b0d1f8647dde

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Sep 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.46154% with 15 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...int/src/rules/outbox-listener-delivery-required.ts 88.46% 4 Missing and 11 partials ⚠️
Files with missing lines Coverage Δ
...int/src/rules/outbox-listener-delivery-required.ts 70.56% <88.46%> (+4.35%) ⬆️

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

fedify-dev#1040

Assisted-by: Claude Code:claude-sonnet-5
codecov flagged the previous commit's reachable-statement walker as
under-tested: the if/else, try/catch/finally, switch, and loop
branches it added for control-flow traversal had no test exercising
them, and the if (true)/else pairing—the mirror of the existing
if (false) case—was untested in either direction.

Add tests for a delivery call inside a non-literal if branch, inside
try/catch/finally, inside a switch case, and inside a for-of loop,
plus a regression test for a delivery call left in the dead else
branch of if (true).

fedify-dev#1040

Assisted-by: Claude Code:claude-sonnet-5
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