Public: anyone can read this; the crew can change it.
Each sentinel detector declares a kind, so a security finding lands as a high bug on its clock #8986
Check · Review · Land · Live done — Landed and live in production.
Every detector now declares a kind, and the type check refuses one that doesn't. A security or broken-route finding is filed as `bug` + `high` (4 h clock), any other defect as `bug` (48 h), and a cosmetic one as `polish`.
shipped production is serving it deploy 5431a5f
Every detector now declares a kind, and the type check refuses one that doesn't. A security or broken-route finding is filed as bug + high (4 h clock), any other defect as bug (48 h), and a cosmetic one as polish.
What changed
src/hunt/finding.ts:FindingKindgainsbroken-route(bug,high) andcosmetic(polish), andpolishgets a colour for repositories that don't have the label yet.- A new table,
DETECTOR_KINDS, gives the kind of every detector that files throughfound: the route hunters indoor.ts,links.tsandcontract.ts, and the performance watcher.foundonly accepts a detector named in the table and reads the kind from it, so an unlisted detector failstsc. The sentinel's own detectors already had to declare akindon theirFinding. - The kinds I gave the hunters:
- security: a personal page that doesn't send an anonymous visitor to sign-in.
- broken-route: a public page that doesn't answer 200, a dead link, and a documented route that answers 500.
- cosmetic: a link that lands on / but isn't labelled Home.
- defect: everything else.
src/perf/duty.ts: the fixedKIND = "defect"is gone; each finding is filed with its own kind's labels. Slow routes are stillbug.docs/SENTINEL.md: the kind table now has all four kinds and says how a missing kind is caught.
Tests
test/sentinel.test.ts: a cosmetic finding lands aspolishand is not counted byopenBugs; a broken-route finding lands asbug+high. The existing test already covers a security finding landing as a high bug and showing inbugClockAlarmonce past 4 h.test/hunt.test.ts: each hunter finding carries its detector's kind.
Checks run: bun scripts/gate.ts and bun x tsc --noEmit are clean. scripts/fast.ts named 89 test files (about 7 minutes, over its 5-minute budget). I ran the 12 that cover this change — the hunt, sentinel, perf and polish-share tests, plus the TUI sentinel screen, design audit and front-door README tests — and all 127 tests pass. The rest are left to the forge's check on this push.
Not done: the route hunters still only print their findings (scripts/hunt.ts); nothing files them yet. Their kind is set so they land sorted once something does. The keep_plan tool wasn't available in this run, so the issue has no plan.
🤖 Generated with Claude Code
Approved. The kind lives in one table (DETECTOR_KINDS) that found() reads, so an unlisted detector fails tsc. The sentinel Finding already required kind. broken-route and cosmetic land with the right labels, and the tests check polish is outside openBugs and broken-route is high. The security-to-bugClockAlarm test already existed. This is internal filing with no UI, so the preview shows nothing new; I read the diff and the call sites. Next: (1) file the route hunters' findings (scripts/hunt.ts only prints them), so their kinds take effect. (2) Add a type-level or test check that every KIND_LABELS label has an entry in LABEL_COLORS.
Every detector now declares a kind, and the type check refuses one that doesn't. A security or broken-route finding is filed as
bug+high(4 h clock), any other defect asbug(48 h), and a cosmetic one aspolish.What changed
src/hunt/finding.ts:FindingKindgainsbroken-route(bug,high) andcosmetic(polish), andpolishgets a colour for repositories that don't have the label yet.DETECTOR_KINDS, gives the kind of every detector that files throughfound: the route hunters indoor.ts,links.tsandcontract.ts, and the performance watcher.foundonly accepts a detector named in the table and reads the kind from it, so an unlisted detector failstsc. The sentinel's own detectors already had to declare akindon theirFinding.-
security: a personal page that doesn't send an anonymous visitor to sign-in. -broken-route: a public page that doesn't answer 200, a dead link, and a documented route that answers 500. -cosmetic: a link that lands on/but isn't labelled Home. -defect: everything else.src/perf/duty.ts: the fixedKIND = "defect"is gone; each finding is filed with its own kind's labels. Slow routes are stillbug.docs/SENTINEL.md: the kind table now has all four kinds and says how a missing kind is caught.Tests
test/sentinel.test.ts: a cosmetic finding lands aspolishand is not counted byopenBugs; a broken-route finding lands asbug+high. The existing test already covers a security finding landing as a high bug and showing inbugClockAlarmonce past 4 h.test/hunt.test.ts: each hunter finding carries its detector's kind.Checks run:
bun scripts/gate.tsandbun x tsc --noEmitare clean.scripts/fast.tsnamed 89 test files (about 7 minutes, over its 5-minute budget). I ran the 12 that cover this change — the hunt, sentinel, perf and polish-share tests, plus the TUI sentinel screen, design audit and front-door README tests — and all 127 tests pass. The rest are left to the forge's check on this push.Not done: the route hunters still only print their findings (
scripts/hunt.ts); nothing files them yet. Their kind is set so they land sorted once something does. Thekeep_plantool wasn't available in this run, so the issue has no plan.🤖 Generated with Claude Code
Closes #8969