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

The guard records a cap once per issue per window, and the sentinel's parks signal names the capped issues #2319

Merged opened this

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

Merged

The guard now records a cap once per issue per window, and the sentinel's parks signal counts distinct capped issues and names five of them. The sentinel, guard and crew-guard tests pass (49) and the type check is clean. I ran only those three test files, not the whole suite.

shipped production is serving it deploy 28f939d

opened this

The guard now records a cap once per issue per window, and the sentinel's parks signal counts distinct capped issues and names five of them. The sentinel, guard and crew-guard tests pass (49) and the type check is clean. I ran only those three test files, not the whole suite.

  • recordCap (src/crew/guard.ts): it first looks for a capped decision on the same issue inside the current cap window, which starts a day back or at a director's last word. If one exists it writes nothing and returns false; otherwise it records and returns true. A director's word starts a new window, so the issue can be capped and recorded again. It takes an optional now so a test can move the clock.
  • Parks signal (src/crew/sentinel.ts): it counts distinct issues per repository instead of raw decisions. The 20-a-day threshold stays. The evidence gains a line, capped issues: #12, #15, …, listing up to five by number, lowest first.
  • Decisions with no issue: a guard decision without an issue id still counts once each, since there is nothing to merge it with.
  • Tests (test/sentinel.test.ts):

- Asking the same issue twice in one window records one decision, and a later window records a second. - Twenty issues, each with a duplicate capped decision, give a count of 20 and an evidence line naming five issues.

I did not clean up duplicate capped decisions already in the ledger. The signal now collapses them when it counts, so they only age out of its one-day look-back.

To try it, run bun test test/sentinel.test.ts.

🤖 Generated with Claude Code

Closes #2286

commented

The guard now records a cap once per issue per window, and the sentinel's parks signal counts distinct capped issues and names five of them. The sentinel, guard and crew-guard tests pass (49) and the type check is clean. I ran only those three test files, not the whole suite.

  • recordCap (src/crew/guard.ts): it first looks for a capped decision on the same issue inside the current cap window, which starts a day back or at a director's last word. If one exists it writes nothing and returns false; otherwise it records and returns true. A director's word starts a new window, so the issue can be capped and recorded again. It takes an optional now so a test can move the clock.
  • Parks signal (src/crew/sentinel.ts): it counts distinct issues per repository instead of raw decisions. The 20-a-day threshold stays. The evidence gains a line, capped issues: #12, #15, …, listing up to five by number, lowest first.
  • Decisions with no issue: a guard decision without an issue id still counts once each, since there is nothing to merge it with.
  • Tests (test/sentinel.test.ts):

- Asking the same issue twice in one window records one decision, and a later window records a second. - Twenty issues, each with a duplicate capped decision, give a count of 20 and an evidence line naming five issues.

I did not clean up duplicate capped decisions already in the ledger. The signal now collapses them when it counts, so they only age out of its one-day look-back.

To try it, run bun test test/sentinel.test.ts.

🤖 Generated with Claude Code

Approved

Does what the issue asked: recordCap is idempotent within the cap window (same capFrom boundary as capNoted, so a director's word reopens it), and the parks signal counts distinct issues and names up to five. Tests cover both and would fail without the change. No page, tty or input surface changes, so the security, both-doors and README items do not apply. Next two things I would do: (1) the SQL-built IN list in sentinel.ts is bound parameters, but a repo with thousands of capped issues would exceed SQLite variable limits — cap the ids or use a subquery before the LIMIT 5; (2) the dispatch caller already guards with capNoted, so say in the pull whether the new check is the only guard for other callers.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs