diu-stop: a file citation buys silence only when it is backed - #784
Conversation
|
This pull request is part of a Mergify stack:
|
e409545 to
d01a1ea
Compare
Revision history
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d01a1ea. Configure here.
d01a1ea to
2166b85
Compare
4d9f2f3 to
1d1cad5
Compare
…e only The reminder was re-read to the user on every prompt for every outstanding claim, including claims whose proof had already been pasted. There was no way to turn it down: CATSTACK_HOOK_MODE_UNVERIFIED_TAG_LEDGER=off still printed the full list at exit 0, because this hook is not on run_hook and nothing reads the registry mode for it. CATSTACK_UNVERIFIED_TAG_REMINDER is read in-hook through _flags/flags.py, the one pattern proven to work here (wrong-check-reflect/detect.py:12-15, 191): stale default, and what unset means: only claims already 3+ turns old all the old behaviour off no injection Unset resolves to stale on purpose. A flag whose unset value is the old behaviour changes nothing for the person who asked for less. reminder() at :138 already computed that exact subset and threw it away at :145. The gate is on the injection only. Emission and recording are untouched on every setting, so `off` buys silence without emptying the ledger it is mined from. A value nobody understands, and an .env candidate that cannot be read, are both named on stderr instead of passing as "not set". hooks.toml gains an enabled_by line naming the flag. Nothing reads that field -- registry.py:15 is its only mention in the repo -- so it is documentation beside the gate, not the gate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Change-Id: I4f465761ee7f84489616ba1e83c54eb98ceefff0
1d1cad5 to
ba95eda
Compare
FILE_LINE_RE matched a path and a line number and the paragraph loop skipped
the paragraph. Nothing checked that the file existed, that anyone had read it,
or at what ref. Pasting a made-up path beside the same claim turned the gate
off just as well:
$ printf '%s' '{"last_assistant_message":"The problem was the old value at
totally-made-up-file-that-does-not-exist.ts:99999.", ...}' \
| python3 engine/hooks/diu-stop/claude_stop_check.py
exit=0
A citation now counts when it names the ref it was read at
(`path:line @ origin/main`), or when the session transcript shows a tool call
that named that path. That is the rule corpus/CLAUDE.learned.md already ships
in prose and nothing enforced.
Third outcome, pinned: when the transcript cannot be read, the citation is
unchecked rather than clear. It does not buy silence, the reason goes to
stderr, and the block names the path it could not check.
tests/test_hooks.py:412 asserted the old behaviour. Its own PR, #479, listed
the file:line exemption under Non-goals -- it carried the exemption over so
fence normalization would not regress it, and did not decide that an unread
path should silence anything. The test keeps that intent and now backs its
citation with a read.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Change-Id: I9ece412c527ac3272bf86d31d8089db65fd685f5
2166b85 to
717a1f8
Compare
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_814cd18b-a5dd-4720-bef9-d00e0421862a) |
|
Queued — the merge queue status continues in this comment ↓. |
|
@Mergifyio queue |
Merge Queue Status
This pull request spent 31 minutes 21 seconds in the queue, including 30 minutes 31 seconds running CI. Required conditions to merge
|

Summary
The gate that demands evidence for a claim goes quiet as soon as the paragraph contains anything shaped like a file and a line number.
It never checks that the file exists, that it was opened this session, or which version was read.
A made-up path silences it just as well as a real one.
A citation now only buys silence when it names the version it was read at, or the transcript shows that file being read this turn.
Review Claim
A file reference silences the evidence gate only when it is backed by a version or by a real read.
Review Lane
behavior
Review Unit
engine-runtime
Safety Invariant
When the transcript cannot be read, the gate does not go quiet: an unverifiable citation is treated as no citation, so the gate asks rather than assuming. This is the rule the repo already states in prose and enforced nowhere.
Slice Rationale
One condition in one gate, plus its fixtures. Independent of the other gate change in this stack, which is about telling a mention from a use.
Non-goals
Does not change which sentences the gate considers claims, and does not alter its message.
Test Plan
Test Plan
Run at this commit:
Pinned cases: the claim alone blocks; the claim plus a real backed citation passes; the claim plus a fabricated path must block, which is what fails on main.
Revert Plan
Revert Plan
Revert this commit. Any file-shaped string silences the gate again, as on main.
Note
Medium Risk
Changes Stop-hook enforcement behavior for agents citing files; stricter blocking when transcripts are missing, but scoped to the unverified-claim path only.
Overview
The diu-stop unverified-claim gate no longer treats a bare
path:lineas evidence. A paragraph only skips the check when the citation includes a read ref (path:line @ origin/main), or the session transcript shows a tool call that named that path (parsed fromtranscript_pathJSONLtool_useinputs).If the transcript cannot be read, citations are unchecked rather than assumed valid: the block still fires and the message names the paths and asks for an
@ <ref>citation. Block copy now states that bare file:line is not output, aligned with prove-it guidance.README documents the three citation outcomes. Tests cover backed reads, fabricated paths, ref-only silence, unreadable transcripts, and Grep-shaped tool inputs.
Reviewed by Cursor Bugbot for commit 717a1f8. Bugbot is set up for automated code reviews on this repo. Configure here.