fix(docs): a 200 is not the page you asked for, and an absence has a scope - #2191
Conversation
…scope upstream-drift 1.2.0 shipped the fetch route yesterday; #2187 applied it across 327 stamps today and surfaced two holes in it. Both are the route's own failure mode — a false absence wearing the signs of a good read — one scope up from where 1.2.0 drew the line. A retired slug is silently aliased to its successor. slash-commands.md returns 200, text/markdown, 82,668 bytes titled "Extend Claude with skills", byte-identical to skills.md (both a833dd5c...), with zero redirects and no Location header. An invented slug still 404s, so this is specific to slugs that once existed. Rung 1 guarded truncation and a 404ing channel but not a channel that succeeds with the wrong page — and this is the worse failure, because a search for a term the requested page owns returns empty against a complete, healthy body. Identity joins rung 1: check the slug against llms.txt (nine live slugs appear as docs/en/<slug>.md, the aliased one does not), and read the body's first heading before quoting it. Separately, 1.2.0 bounded absence claims against truncation but never against scope. Searching one page and asserting the product is the same false negative one level up, and searching a literal phrase rather than the capability is another: "verbose hooks" appears zero times on hooks.md, which nonetheless documents Ctrl+O, --verbose, and CLAUDE_CODE_DEBUG_LOG_LEVEL=verbose. A phrase search there licenses a false nonexistence claim from a complete read of the right page. An absence claim now states its corpus and the terms tried. Both verified here directly rather than taken on report, per the rule the section states. Also records why the correction matters even when the conclusion survives: a sound conclusion on a false premise is fragile, because the next reader to check the premise discards the conclusion with it.
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9928c5e8fe
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Claude finished @kyle-sexton's task in 3m 4s —— View job Review complete
Findings1 inline comment posted: docs/conventions/upstream-drift/README.md:130 — the new third bullet under "Reading the basis — the fetch route" leaves the intro sentence at line 123 ("Two rules bind every read...") stale — it's now three. Given the doc's own precision elsewhere ("Two checks", "Two moves" — both still accurate), this reads as an oversight rather than a rounding. What checked out
Not independently verified
|
|
Claude has reviewed this PR 2 times. The lane skips further automatic reviews after 5; deleting this comment resets the count. |
Review round 1, both reviewers independently. Adding the absence-scope rule to the binding list left the intro reading 'Two rules bind every read'. On a normative versioned convention a stale count is not cosmetic: it leaves a reader unable to tell whether the third bullet binds or merely explains. Audited every count phrase in the section rather than patching the reported one, since this is the defect class the PR itself is about. 'Two checks, both cheap' (2 bullets) and 'Two moves break it' (2 bullets) are both accurate; only the intro was stale. The CHANGELOG's 1.2.0 entry keeps 'Two rules' -- it was true of 1.2.0 and history is never rewritten -- and the 1.3.0 entry now records the count change so the transition is legible from the changelog alone. The irony is noted and earned: a PR adding 'state the corpus and the terms tried' shipped an unverified count in its own normative text. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FdBsorqGjCU4Mg5nrmgz4m
|
Claude finished @kyle-sexton's task in 1m 55s —— View job Review complete
FindingsNone. The follow-up commit What I checked this pass
Not independently verified
|
No linked issue
Summary
upstream-drift1.2.0 shipped the fetch route yesterday (#2185).#2187 applied it across 327
stamps today and surfaced two holes in it. Both are the route's own failure mode — a false
absence carrying every outward sign of a good read — one scope up from where 1.2.0 drew the line.
This is the convention's recheck discipline finding gaps in the convention, one release after it
shipped.
upstream-drift1.2.0 → 1.3.0, additive; no required part, canonical name, orenforceability verdict changed. Pure
docs/, so no plugin bump.Fix
Hole 1 — a
200does not mean you got the page you asked for1.2.0's rung 1 guarded against truncation and against a channel that 404s. It did not guard against
a channel that succeeds with the wrong page. A retired slug is silently aliased to its
successor — no redirect, no
Location, no notice in the body:slash-commands.md200,text/markdown, 82,668 bytes, first heading# Extend Claude with skillsskills.md200,text/markdown, 82,668 bytes, same headinga833dd5c96b9b111de0daec5fc6436e210c8cdc009e51306d32438746db0b5a5— byte-identicalslash-commands200,num_redirects: 0nonexistent-page-xyz.md404— so this is not a catch-all; aliasing is specific to slugs that once existedThis outranks truncation as a failure. Truncation at least yields text you can see is short.
Here a search for a term the requested page owns comes back empty against a full, healthy-looking
body. Identity is therefore now part of rung 1, with two cheap checks:
llms.txt. Verified across ten slugs: the nine live ones eachappear as
docs/en/<slug>.md;slash-commandsappears in no such entry (only an unrelatedagent-sdk/slash-commands) — exactly the one that aliased. A mechanical detector, not a judgmentcall.
asked for ends the read. A title merely worded differently from the slug does not —
sub-agents.mdis titled "Create custom subagents",costs.md"Manage costs effectively"; bothare correct pages.
A missing slug is not a dead end — it is a prompt to find the successor in the index and cite
that slug. Left unchecked, a citation of a retired slug keeps working indefinitely while
pointing somewhere its author never read, then becomes a
404on a claim nobody re-derived the daythe alias is dropped.
Hole 2 — an absence claim now carries its scope
1.2.0 said a truncated read supports no absence claim. It never said a complete read of one page
supports no claim about the product. Two moves break it:
Widening the subject. Searching
hooksand concluding "Claude Code has no X" assertssomething about every page not searched. The honest form names the corpus: "not documented on
hooks" — or, if the sweep genuinely covered the index, "not documented on any page listed inllms.txtas of<date>", a far larger and more expensive claim.Searching the phrase instead of the capability. Verified on
hooks.md: the phrase"verbose hooks" appears zero times, while the same page documents
and separately
A phrase search returns nothing here and licenses "no verbose hooks toggle exists" — false, from a
complete, untruncated read of the right page.
Stated as its own rule because it is the reason to care: a sound conclusion resting on a false
premise is fragile, not safe. The instance above kept its conclusion on a corrected premise
(#2190); the next reader who
checks a false premise discards the conclusion with it. Fix the premise and keep the conclusion —
never keep a premise because the conclusion it props up is convenient.
Verification
Every claim above was re-derived here directly rather than taken on report, per the rule this
section states — a report of an absence is exactly the thing the convention says not to accept
second-hand:
.mdbodies fetched and hashed locally;slash-commands/skillsidentity confirmed bymatching SHA-256, byte count, and first heading
curl -L -w '%{num_redirects}'on the rendered URL404control run against an invented slug, establishing the alias is not a catch-allllms.txtfetched (187docs/en/entries) and checked slug-by-slug across all tenhooks.mdfetched in full;grep -ic "verbose hooks"→0, and all fourverbosementions readverbatim
Gates (committed tree, CI form):
check-contract-slice-prune.sh --check-diff origin/main,check-changelog-parity.sh --check-bump origin/main,check-skill-portability.sh,check-shell-portability.sh— all pass;markdownlint-cli2over both changed files — 0 errors.Remaining gates: CI is the authority.
Related
route this patches
and found both holes
over-scoped nonexistence claim that hole 2 generalizes