Skip to content

test(incidents): address #52 reviewer notes — full benign coverage + snapshot caveat#53

Merged
askalf merged 1 commit into
mainfrom
incidents-followup-reviewer-notes
Jul 16, 2026
Merged

test(incidents): address #52 reviewer notes — full benign coverage + snapshot caveat#53
askalf merged 1 commit into
mainfrom
incidents-followup-reviewer-notes

Conversation

@askalf

@askalf askalf commented Jul 16, 2026

Copy link
Copy Markdown
Owner

What

Small follow-up to #52, addressing the two non-blocking notes the sprayberry-reviewer bot raised on that PR (which auto-merged on approval before these landed):

  1. Full benign coveragefeat(incidents): reproduce real 2025-26 browser-agent attacks + harden detector #52's description said it was tuned against 9 benign look-alikes, but the committed test/incidents.test.mjs BENIGN map only had 6. Adds the missing three — a "should not disclose … to the user" support macro, a privacy policy ("your data / browsing history"), and a helpdesk page ("do not forward … to anyone") — so the false-positive suite matches the claim and exercises the broadened do not … / third-person patterns against second-person and non-"do not" phrasings. 142 → 145 tests.

  2. Snapshot caveat — notes in the generated incidents/INCIDENTS.md that it's a snapshot and that test/incidents.test.mjs is the CI source of truth (regenerate with npm run demo:incidents), so a reader doesn't mistake the committed receipt for a live check.

Verification

  • 145/145 tests pass.
  • Receipts regenerated through real Chrome (Chrome/150) — still 5/5 incidents stopped.
  • No production-code change: this only adds test cases and a doc line.

…shot caveat

Follow-up to the sprayberry-reviewer approval on #52:

- Add the 3 benign look-alikes the PR body referenced but the test omitted
  (should-not-disclose-to-the-user, privacy policy, helpdesk), so the FP-discipline
  suite matches the claimed coverage and exercises the broadened do-not / third-person
  patterns against second-person and non-"do not" phrasings. 142 -> 145 tests.
- Note in the generated INCIDENTS.md that it is a snapshot; test/incidents.test.mjs
  is the CI source of truth. Regenerate with `npm run demo:incidents`.

Receipts regenerated through real Chrome (Chrome/150) — still 5/5.

@sprayberry-reviewer sprayberry-reviewer left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review from the Sprayberry Labs fleet code reviewer (sprayberry-reviewer bot). This is a verdict-bearing automated review, not a human sign-off.

Verdict: no blocking issues found — approving.


What was checked

This is a pure test/doc follow-up to #52 (11 additions, 0 deletions, no production-code change). Three things to verify: (1) each new BENIGN fixture genuinely stays ALLOW under the current detector, (2) the snapshot caveat is accurate, and (3) CI is green.

New BENIGN fixtures — all confirmed ALLOW

test/incidents.test.mjs:76'support macro (should not disclose ... to the user)'

'<p>Agents should not disclose ticket internals to the user without a manager sign-off.</p>'

The INSTRUCTION_TO_AI do\s+not\s+(…disclose…) pattern requires the exact phrase "do not"; "should not" does not satisfy \bdo\s+not\s+. The disclose-system-prompt pattern (reveal|…|disclose\s+(me\s+)?(your|the)\s+(system\s+)?(prompt|instructions?…)) needs disclose to be followed by your/the … prompt/instructions; "disclose ticket internals" doesn't match. No INSTRUCTION_TO_AI signal, no command signal, no external sink → analyzeNode returns nullALLOW ✓. This correctly exercises "should not" ≠ "do not" in the detection grammar.

test/incidents.test.mjs:77'privacy policy (your data / browsing history)'

'<p>We never share your personal data. Your browsing history is yours. Export your data anytime.</p>'

"Your browsing history" contains a second-person possessive (your). The SENSITIVE browsing-history pattern is gated on third-person possessives (the user's / their / his / her), so it does not fire. share and export match EXFIL_VERB, but hasExfilLeg also requires an off-origin sink (external URL or email); none is present. → ALLOW ✓. This directly exercises the second-person guard introduced in #52.

test/incidents.test.mjs:78'helpdesk (do not forward ... to anyone)'

'<p>To reset your password, do not forward your reset code to anyone. We will never email you asking for it.</p>'

"do not forward"forward is not in the INSTRUCTION_TO_AI do-not verb list (tell|inform|alert|notify|warn|reveal|disclose|surface|mention|report|say|indicate). password hits SENSITIVE (score +1), and forward matches EXFIL_VERB, but there is no external sink (no URL, no email address literal). exfilTarget = false; no command signal → analyzeNode returns nullALLOW ✓. This exercises the narrowness of the do-not verb list and confirms forward+password without a sink is harmless.

Doc caveat — accurate

incidents/INCIDENTS.md and incidents/run-incidents.mjs (the generator template) both receive the same note:

> **This file is a generated snapshot** — regenerate it with `npm run demo:incidents` after any
> change to the detector or fixtures. The verdicts are enforced for real in CI by
> `test/incidents.test.mjs`, which is the source of truth; this document is a human-readable receipt.

npm run demo:incidents is the correct script (package.json maps it to node incidents/run-incidents.mjs). test/incidents.test.mjs is indeed the CI-enforced source of truth. The caveat is accurate and directly addresses the non-blocking note from #52.

CI

All checks pass: test (145/145), test-node20, CodeQL, analyze — all green.


What's good

The three fixtures are well-targeted: each isolates a distinct boundary in the detection grammar (verb-list precision, possessive gating, external-sink requirement) rather than being redundant copies. The generator-template update ensures future regenerations of INCIDENTS.md will carry the caveat automatically — not just the committed snapshot.

@askalf
askalf merged commit e90b559 into main Jul 16, 2026
4 checks passed
@askalf
askalf deleted the incidents-followup-reviewer-notes branch July 16, 2026 21:41
@askalf askalf mentioned this pull request Jul 16, 2026
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.

2 participants