Skip to content

chore(hooks): catch inverted 'is /precheck the right next step?' phrasings #545

@bakeb7j0

Description

@bakeb7j0

Summary

The Stop-hook regex from #542 (PR #544, scripts/precheck-asking-detector.sh) catches the dominant asking phrasings — but only when the trigger word appears before the literal precheck within ~40 chars. Inverted phrasings escape both the interrogative and deferral alternations. Reviewer flagged this at confidence-83 during #542 review; not an AC violation of #542, but a real gap.

This issue captures the gap and the decision space before broadening the regex (broadening risks false-positives — needs deliberate calls).

Concrete examples that escape the current regex

  • "Is /precheck something I should run?"
  • "Is precheck the right next step?"
  • "Would /precheck be appropriate here?" (no trigger word from the existing list near precheck)
  • "Precheck — should I do that now?" (trigger word after precheck, separated by punctuation)

Implementation Steps

Pick exactly one of the three options below. Recommend Option A unless real-world data argues for B or C.

Option A — Add a third regex alternation, broadening the trigger set + allowing trigger after precheck.

(?i)/?precheck.{0,40}\b(should|shall|need|ready|appropriate)\b.{0,40}\?

Catches "Is /precheck something I should run?" and "Precheck — should I do that now?". Risk: false-positive on past-tense + question phrasings ("/precheck completed. Should I commit now?") — would need to refine. Recommended starting point.

Option B — Replace regex with a small structured classifier (jq + word-set).

Tokenize the message, compute distance between precheck and any of {shall, should, can, may, ready, appropriate, ...}, fire if distance ≤ N AND the message contains a ?. More precise but heavier (~3-5x slower; still well under budget) and harder to reason about. Defer unless Option A's false-positive rate is unacceptable.

Option C — Accept the gap.

If real-world session data shows inverted phrasings are <1% of asking events, the engineering cost of closing the gap exceeds the value. Document the limitation in docs/operations/precheck-asking-hook.md and move on. Defensible if observed prevalence is low.

Test Procedures

Regression test additions — to be appended to tests/regression/test_precheck_asking_detector.sh:

Test Name Input Expected
inverted_is_precheck "Is /precheck something I should run?" block JSON
inverted_appropriate "Would /precheck be appropriate here?" block JSON
inverted_precheck_first "Precheck — should I do that now?" block JSON
negative_past_tense_with_question "/precheck completed. Should I commit now?" exit 0, no JSON

The last one is critical — it's the false-positive guard for Option A.

Acceptance Criteria

  • Decision recorded (Option A / B / C) with reasoning in the PR description
  • If A or B: regex/classifier handles the four positive examples above
  • If A or B: false-positive guard negative_past_tense_with_question passes (no block)
  • If A or B: existing 14 test cases still pass (no regression)
  • If C: docs/operations/precheck-asking-hook.md documents the limitation explicitly
  • Hook performance budget still met (<50ms target on 200-event transcript)

Dependencies

Metadata

Priority: priority::low — gap is real but low-frequency; the dominant phrasings are caught
Urgency: urgency::eventual — no SLA, can sit until the prose+hook combo proves insufficient
Size: size::S — three lines of regex or ~30 lines of jq classifier
Wave: N/A
Plan: N/A — standalone hygiene chore

rules-lawyer 📜 (cc-workflow)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions