make the read tool refuse a pull that does not exist

A Tangled 404 renders 200 and carries no pull record, so tangled_comments.py's
"0 comment(s)" was indistinguishable from "no such pull". On 2026-08-22 that
produced a false report that a pull was filed and unreviewed, a retracted claim
that the queue tool was broken, and a reviewer's time spent disproving it.

tangled_comment_post.py never had the defect, because it MUST resolve a
subject-uri to function. So the read tool now requires the same identifier and
exits non-zero when the page does not yield one. Proven: #99999 and a
non-existent #428 exit 1 naming the cause, while a real pull still serves its
comments.

This is the structural fix over the vigilance fix, and the argument for it is
that both of us knew the countermeasure and neither applied it — the trap was
already written in one set of notes and in three of the reviewer's own reviews.

And the post tool's error named only the cookie, so anyone hitting it on a
phantom pull would re-auth, succeed, and still fail. It now names both causes in
likelihood order, the pull first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V3LdmEL7CvCYTNpoBq1kce
This commit is contained in:
2026-08-22 08:00:16 +00:00
co-authored by Claude Opus 5
parent fe9d98fad3
commit 31839b6236
2 changed files with 22 additions and 1 deletions
+8 -1
View File
@@ -41,7 +41,14 @@ def scrape_form(doc):
uris = re.findall(r'name="subject-uri"[^>]*value="([^"]+)"', doc)
idxs = re.findall(r'name="pull-round-idx"[^>]*value="([^"]+)"', doc)
if not uris or not idxs:
sys.exit("could not find the comment form (is the cookie still valid?)")
# Two causes, and naming only one sends the reader in the wrong direction: a
# reviewer hitting this on a phantom pull will re-auth, succeed, and still fail.
sys.exit(
"could not find the comment form. Two causes, in likelihood order:\n"
" 1. THE PULL DOES NOT EXIST — a 404 page renders 200 and carries no form.\n"
" Check the branch on the remote, not the pull number.\n"
" 2. the cookie has expired."
)
return uris[-1], idxs[-1]
+14
View File
@@ -86,6 +86,20 @@ def main():
if a.round is not None:
url += f"/round/{a.round}"
doc = fetch(url, cookie)
# A 404 page renders 200 and carries no pull record, so "0 comments" used to be
# indistinguishable from "no such pull". On 2026-08-22 that cost a false report that
# #428 was filed and unreviewed, and a reviewer's time chasing it. The post tool never
# had the defect because it MUST resolve a subject-uri to work at all — so require the
# same identifier here, and refuse rather than print a header for a phantom.
if not re.search(r'name="subject-uri"[^>]*value="(at://[^"]+)"', doc):
sys.exit(
f"pull #{a.pull} does not exist in {a.owner}/{a.repo} "
f"(no pull record on {url}).\n"
" This is NOT an auth failure: the page rendered, it simply carries no pull.\n"
" A pull that exists always yields a subject-uri."
)
comments = parse_comments(doc)
if a.json: