Skip to content

ums: an untested negative capability claim is its own failure mode - #2721

Merged
d-morrison merged 4 commits into
mainfrom
claude/shigella-review-on-request-gz6u67
Aug 31, 2026
Merged

ums: an untested negative capability claim is its own failure mode#2721
d-morrison merged 4 commits into
mainfrom
claude/shigella-review-on-request-gz6u67

Conversation

@claude

@claude claude Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

What this records

UCD-SERG/shigella#46, 2026-08-31.
Across several turns I told the user that GitHub branch-protection and ruleset settings were "not readable from this session", and that confirming a required-checks list needed a human to open Settings.
That was false, and I never tested it.
It was inferred from the absence of a dedicated MCP tool for rulesets, and then restated in a merged PR body and in a filed issue as a "needs a human with branch-protection access" note.

GH_TOKEN was set in the environment the whole time.
Plain curl against the REST API answered every part of the question on the first attempt.

Three properties make this its own failure mode rather than an ordinary wrong guess:

  1. The absence of a dedicated tool is not evidence the data is unreachable. A tool listing is a menu, not a boundary.
  2. The claim was load-bearing and outward-facing, so it shipped into two deliverables rather than merely misleading the conversation.
  3. A negative capability claim is self-sealing. It produces no failed call, no error, nothing red, and the cheap test that would refute it is exactly the test the claim tells you not to bother running. A positive claim gets tested by being acted on; this one ends the inquiry.

New section, not a recurrence note

Added as a new subsection of shared/workflow/growth-mindset.md, "A limitation you never tested leaves no error to diagnose".

That file already owns "the limitation may not be real", and its three existing subsections are the closest existing coverage.
Each of them starts from a call that was made and came back wrong: a tool errored, a bounded probe returned nothing, a request was refused.
Their remedies all read the artifact that call produced.
None of those remedies is reachable when no call was made at all, so this is a gap in that file rather than a repetition of it.

shared/workflow/metacognitive-monitoring.md gets a taxonomy entry instead of the section, because its State type ("re-query, never recall") prescribes a remedy that does not apply here: there is nothing to re-query when no call was ever made.

Files changed

File Change
shared/workflow/growth-mindset.md New subsection, plus its Do/Don't pair.
shared/workflow/growth-mindset.cases.md The shigella#46 case record.
shared/workflow/metacognitive-monitoring.md New Capability claim type; back-references to the taxonomy made count-free, and the Do-and-don't checklist's enumeration extended to include it.
shared/workflow/metacognitive-monitoring.rationale.md The same back-references.
shared/workflow/challenge-the-assignment.md One back-reference made count-free.
memories/gh-cli.md The existing ruleset bullet extended in place.

The gh-cli.md edit extends the existing "gh pr checks does NOT say which checks are REQUIRED" bullet rather than adding a sibling, per ums's step 3.
It adds the effective-rules endpoint (repos/{owner}/{repo}/rules/branches/{branch}, which covers org-level rulesets in one call) and the bypass fields that make mergeable_state: "clean" mean something.
Measured live against two rulesets, both reporting current_user_can_bypass: "never" and no bypass_actors key at all rather than an empty array: Morrison-Lab/ai-config 17712474 and UCD-SERG/shigella 6339629.
The second also records how the trap is met in practice: reading the value through dict.get returns None for an absent key as readily as a null one, so it gets written down as bypass_actors: null when there is no such field in the response.

Review rounds

Round 1 returned two findings, both accepted and fixed in abd8fc8:

  • the Do-and-don't checklist still enumerated five claim types and omitted capability, so a reader following it literally would skip the type this change exists to add;
  • the rationale companion still opened with "The five" in the section mirroring the taxonomy, while its two siblings a few lines below had been made count-free.

Neither was caught by the first sweep because that sweep searched for the word "five".
The checklist carries the staleness as an enumeration rather than a count, so a count-keyed query cannot see it.
That is address-every-comment.cases.md's own round-3 case, recurring in the same file it was recorded about.

Round 2 confirmed both fixed, re-swept the two files and their siblings independently, and returned no findings.

Dupe-check

Queries run over shared/, memories/, CLAUDE.md, CLAUDE.cases.md, AGENTS.md, skills/, and hooks/:

Query Result
not readable from this session 0
menu, not a boundary 0
absence of a tool 0
no dedicated tool 0
self-sealing 0
attempted call 0
bypass_actors 0
current_user_can_bypass 0
rules/branches 0
capability claim 2, both unrelated (self-review-fallback.md, challenge-the-assignment.cases.md)
tool surface 2, both in memories/ about MCP tool inventories
ruleset present in memories/gh-cli.md, which is why that file was extended in place

Per "Never assert a corpus gap from a grep": these are the queries and their results, not a claim that the corpus lacked the idea.
The coverage judgment came from reading the four candidate fragments (research-before-asking, growth-mindset, metacognitive-monitoring, verify-the-right-artifact) plus use-mcp-servers.md's "When a rule names a mechanism this session does not have", the nearest near-miss: it covers a mechanism that is genuinely absent and prescribes finding a local equivalent, where this covers one assumed absent and never probed.

Checks run locally

  • check-links.py -- 2815 links, 0 broken. Negative control: breaking the new gh-cli.md link made it report exactly that link.
  • validate-skills.py -- all valid.
  • check-context-closure.py -- under budget; none of the six edited files is in the always-loaded pool.
  • markdownlint-cli2@0.23.0, the version Morrison-Lab/gha's lint-markdown/package.json pins at @v2 -- 692 files, 0 errors.
  • check-new-line-breaks at the SHA validate.yml pins (fdaeccc4), diff-scoped after committing -- clean, with a negative control that flagged a deliberate two-sentence line in each edited file.
  • Every scripts/test_*.py suite and scripts/check-*.py gate -- pass.
  • check-stale-records.py -- no new orphans; age bucket not read, per the fragment's own instruction under a shallow clone.
  • Added lines are ASCII-only.

Generated by Claude Code

claude added 3 commits August 31, 2026 04:19
Records the shigella#46 learning: branch-protection and ruleset settings
were reported "not readable from this session" across several turns, and in
two deliverables, on the strength of no dedicated MCP tool existing. Plain
curl against the REST API answered the whole question on the first attempt.

- shared/workflow/growth-mindset.md gains "A limitation you never tested
  leaves no error to diagnose". Its three existing subsections each start
  from a call that was made and came back wrong, so none of their remedies
  reaches a limitation that was only inferred.
- shared/workflow/metacognitive-monitoring.md gains a Capability claim type,
  whose remedy is to attempt the call rather than to re-query; four
  count-based back-references to that list are made count-free.
- memories/gh-cli.md extends the existing ruleset bullet in place with the
  effective-rules endpoint and the bypass fields, measured live.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YJnmjBt8DbqWZhAkuvj1fc
The caveat was scoped to one ruleset by its author's own self-review. A
second, UCD-SERG/shigella 6339629, reports the same shape: no
bypass_actors key rather than an empty array, and current_user_can_bypass
never.

Records how the trap is actually met: reading the value through dict.get
returns None for an absent key as well as a null one, so it gets written
down as 'bypass_actors: null' when there is no such field in the
response. That happened in the session that produced this entry.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YJnmjBt8DbqWZhAkuvj1fc
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Review found both. The Do-and-don't checklist still enumerated five types
and omitted capability, so a reader following it literally would skip the
type this change exists to add. The rationale companion still opened with
"The five" in the section mirroring the taxonomy, while its two siblings a
few lines below had been made count-free.

Neither was caught by the first sweep because that sweep searched for the
word "five". The checklist carries the staleness as an enumeration rather
than a count, so a count-keyed query cannot see it. Derived the
replacement population from the enumeration itself rather than from the
count, which is address-every-comment.cases.md's own round-3 case in this
same file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YJnmjBt8DbqWZhAkuvj1fc
@github-actions

Copy link
Copy Markdown
Contributor

👀 Claude Review Dispatchedrun reviewing PR #2721 at abd8fc8.

@github-actions

Copy link
Copy Markdown
Contributor

Claude finished reviewView run


Links are clean, no broken references.

Review: #2721

This round's diff (5d1fbf59..abd8fc80) touches only shared/workflow/metacognitive-monitoring.md and shared/workflow/metacognitive-monitoring.rationale.md, sweeping the two stale back-references flagged in the prior review round (posted 2026-08-31T04:26:57Z):

  1. metacognitive-monitoring.md:1082 — the "Do and don't" enumeration now reads state, capability, scope, cause, inference, or default, including the new Capability type. Fixed.
  2. metacognitive-monitoring.rationale.md:42 — "The five are worth keeping as a list" is now "They are worth keeping as a list", removing the stale count. Fixed.

I re-swept both files (and their siblings growth-mindset.md, growth-mindset.cases.md, challenge-the-assignment.md, gh-cli.md) for any remaining "five"/count-based back-references to the claim-type taxonomy — the only other "five" hits in these files are unrelated (a measurement-count case title, a test-run count, an unrelated "five recorded instances" in .rationale.md:859), not stale references to the claim-type list. check-links.py still reports 0 broken links (2815 checked).

No new content issues in this round's diff. The prior round's two findings are both resolved and no new ones were introduced.

Verdict

Ready for merge

Reviewed commit: abd8fc8

@github-actions

Copy link
Copy Markdown
Contributor

💰 Cost: $0.5819 (review) — run

@d-morrison
d-morrison merged commit f1eb357 into main Aug 31, 2026
19 of 20 checks passed
@d-morrison
d-morrison deleted the claude/shigella-review-on-request-gz6u67 branch August 31, 2026 04:33
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