Skip to content

#25: sensor spawn/timeout failure fails the run (exit 1) - #33

Merged
devill merged 3 commits into
mainfrom
issue-25-sensor-failure-exit
Jun 17, 2026
Merged

#25: sensor spawn/timeout failure fails the run (exit 1)#33
devill merged 3 commits into
mainfrom
issue-25-sensor-failure-exit

Conversation

@devill

@devill devill commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

Closes #25.

A sensor that fails to spawn or times out was fail-soft — it surfaced a notice and contributed zero issues, so the run could exit 0 and report "looks good" while a whole class of smells went unchecked. This makes a broken tool a failed run (exit 1), consistent with #18's command-fix policy.

Design

A shared SensorSink { notices; failures } threaded through the sensor layer. Spawn/timeout failures are recorded into failures (the message also stays in notices for display). run() forces exit 1 whenever failures is non-empty — independent of whether the successful sensors found violations. Every successful sensor still renders its full output. Benign skips (no config, no package.json, unparseable report) stay benign.

All sensors are covered: eslint / jscpd / knip (CheckOutcome wraps), ruff (declarative adapter) and deptry (sensor). Timeouts route through the same exitCode === -1 path as spawn failures.

Atomic commits

  1. #25: add the sensor-failure channelCheckOutcome.failures, SensorSink, spawnFailureOutcome / recordSpawnFailure, skipOutcome. Additive.
  2. #25: record spawn/timeout failures in the eslint/jscpd/knip wraps.
  3. #25: fail the run on a sensor spawn/timeout failure — thread the sink through both presets + ruff/deptry, fold failures into the exit code, tests, docs/sensors.md, DECISIONS.md.

Tests

  • New runner.run sensor failure e2e: forces a real spawn failure (a directory where the eslint bin is expected), asserts exit 1, the failure message shown, and the comment sensor's output still rendering.
  • Clean-run-unchanged covered by the existing clean-project test.
  • Python preset test asserts the failure is recorded and mirrored into notices.

Gates

  • pnpm build, pnpm lint — clean (all touched files under the 200-line cap)
  • pnpm test — 386 passed

🤖 Generated with Claude Code


Generated by Claude Code

claude added 3 commits June 17, 2026 17:07
A spawn/timeout failure must fail the run, not be a false-clean. Add the
plumbing: CheckOutcome.failures, a shared SensorSink { notices; failures },
spawnFailureOutcome / recordSpawnFailure helpers, and skipOutcome for the
spawnWrapped skip path. Additive; nothing consumes it yet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nq6xHU6JtSNpYWhMYjXB15
Their spawn-failure branches now return a failing outcome (message in
stderr plus a recorded failure) instead of a benign empty outcome. Still
unconsumed by the runner until the sink is wired.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nq6xHU6JtSNpYWhMYjXB15
ruff/deptry sensors so every spawn/timeout failure is recorded, then have
run() exit 1 whenever the sink has failures — independent of whether any
violations were found. Every successful sensor still renders its full
output and the failure notice is still shown. Update docs/sensors.md and
DECISIONS.md; collapse allowedFilesBySmell to one expression to stay
under the line cap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nq6xHU6JtSNpYWhMYjXB15
@devill
devill force-pushed the issue-25-sensor-failure-exit branch from 52443cd to b21ad15 Compare June 17, 2026 15:12
@devill
devill marked this pull request as ready for review June 17, 2026 15:12
@devill
devill merged commit 525e5e2 into main Jun 17, 2026
2 checks passed
@devill
devill deleted the issue-25-sensor-failure-exit branch June 19, 2026 12:21
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.

Sensor spawn/timeout failure should fail the run (exit 1), not produce a false-clean

2 participants