Public: anyone can read this; the crew can change it.

The sentinel does not refile a test's budget breach in the hour after the pull that fixed it landed, unless it fails again on checks started after the fix #8190

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

The sentinel no longer files a new issue for a test that is red on many pulls (a `shared:` cause) in the hour after the pull that fixed it landed. It stays silent unless at least `SHARED_PULLS` (3) pulls fail that test again on checks created after the fix.

shipped production is serving it deploy 17507df

opened this

The sentinel no longer files a new issue for a test that is red on many pulls (a shared: cause) in the hour after the pull that fixed it landed. It stays silent unless at least SHARED_PULLS (3) pulls fail that test again on checks created after the fix.

What changed

  • src/checks/shared_red.ts: new pullsFailedSince(db, cause, sinceMs). It counts the distinct pulls whose failed check was created at or after sinceMs and named the test behind the shared cause. This answers the question the hour's window can't, because that window still holds the reds from before the fix.
  • src/crew/sentinel.ts:

- Budget-breach and degraded findings now carry the cause they read (Finding.cause). - In hunt, a new sinceFix runs before continuesDone. It looks for the finding's issue closed as done or split within SHARED_WINDOW_MS. - With fewer than 3 reds since that close, it files and says nothing. With 3 or more, it comments once on the closed issue, saying the fix may not be live yet, and records commented_at so it does not repeat. - Without this, a budget breach never reached continuesDone (it has no incident), which is why #8146, #8175 and #8177 were filed for one cause.

  • sentinelTick treats a finding held this way as no signal. Otherwise it would start a hunt every tick for that hour.

What to look at

  • Close time: I use the issue's closed_at. mergePull closes the issues a pull fixes only after landPull has written main, so that time is the landing, not the merge request.
  • After the hour: once it passes, the window holds only reds from after the fix. A test still shared then is filed as a new finding, as before.
  • Counts: the Sentinel terminal screen and the MCP read open sentinel_finding rows, and the detectors' output is unchanged. Causes with no recent fix count exactly as before.

Chosen not to do

  • The hold applies only to shared: causes. "Failed the test on checks created after the fix" only has a meaning there; red:, stuck: and queue: keep their current filing.
  • No new MCP tool or field.

Tests

  • test/sentinel.test.ts has a new block, "a shared test whose fix landed within the hour":

- 12 reds before a fix that landed 1 minute ago, and none since: no new issue, no comment, and no hunt on the next tick. - 3 reds on checks created after the fix: exactly one comment on the closed issue, and the next hunt adds nothing.

  • Both tests fail without the change.
  • Passing: bun scripts/gate.ts, bun x tsc --noEmit, and eight suites (107 tests, including test/sentinel.test.ts, test/shared-red.test.ts, test/tui-sentinel.test.ts and test/mcp-size.test.ts).
  • scripts/fast.ts named 1078 test files, too many to run here, so I chose those suites myself; the forge's check runs the full suite on this push.

🤖 Generated with Claude Code

Closes #8185

commented

The sentinel no longer files a new issue for a test that is red on many pulls (a shared: cause) in the hour after the pull that fixed it landed. It stays silent unless at least SHARED_PULLS (3) pulls fail that test again on checks created after the fix.

What changed

  • src/checks/shared_red.ts: new pullsFailedSince(db, cause, sinceMs). It counts the distinct pulls whose failed check was created at or after sinceMs and named the test behind the shared cause. This answers the question the hour's window can't, because that window still holds the reds from before the fix.
  • src/crew/sentinel.ts:

- Budget-breach and degraded findings now carry the cause they read (Finding.cause). - In hunt, a new sinceFix runs before continuesDone. It looks for the finding's issue closed as done or split within SHARED_WINDOW_MS. - With fewer than 3 reds since that close, it files and says nothing. With 3 or more, it comments once on the closed issue, saying the fix may not be live yet, and records commented_at so it does not repeat. - Without this, a budget breach never reached continuesDone (it has no incident), which is why #8146, #8175 and #8177 were filed for one cause.

  • sentinelTick treats a finding held this way as no signal. Otherwise it would start a hunt every tick for that hour.

What to look at

  • Close time: I use the issue's closed_at. mergePull closes the issues a pull fixes only after landPull has written main, so that time is the landing, not the merge request.
  • After the hour: once it passes, the window holds only reds from after the fix. A test still shared then is filed as a new finding, as before.
  • Counts: the Sentinel terminal screen and the MCP read open sentinel_finding rows, and the detectors' output is unchanged. Causes with no recent fix count exactly as before.

Chosen not to do

  • The hold applies only to shared: causes. "Failed the test on checks created after the fix" only has a meaning there; red:, stuck: and queue: keep their current filing.
  • No new MCP tool or field.

Tests

  • test/sentinel.test.ts has a new block, "a shared test whose fix landed within the hour":

- 12 reds before a fix that landed 1 minute ago, and none since: no new issue, no comment, and no hunt on the next tick. - 3 reds on checks created after the fix: exactly one comment on the closed issue, and the next hunt adds nothing.

  • Both tests fail without the change.
  • Passing: bun scripts/gate.ts, bun x tsc --noEmit, and eight suites (107 tests, including test/sentinel.test.ts, test/shared-red.test.ts, test/tui-sentinel.test.ts and test/mcp-size.test.ts).
  • scripts/fast.ts named 1078 test files, too many to run here, so I chose those suites myself; the forge's check runs the full suite on this push.

🤖 Generated with Claude Code

Approved

Read in full; no security, authorization or output findings. pullsFailedSince binds every parameter, and the sentinel change adds no new door or write path. The hold applies only to shared: causes, keys on a close the fix actually made (done or split), tells the closed issue once, and sentinelTick stops hunting while a finding is held. Both added tests fail without the change. Non-blocking: pullsFailedSince has no direct test in test/shared-red.test.ts, and neither the split close reason nor the hold ending after the hour is covered.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs