Files
FabledScribe/tests
bvandeusenandClaude Opus 5 0bf7406f42
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Successful in 10s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / integration (push) Successful in 55s
CI & Build / Python tests (push) Successful in 1m40s
CI & Build / Build & push image (push) Successful in 25s
fix(mcp): two rule reads reach a read-only key, and every tool must now be classified (#3191)
rules_due_for_verification (the rule staleness sweep) and rule_history (what a
rule used to say) are pure reads, and a read-scoped API key was refused both:
neither is in _READ_ONLY_TOOLS, and the completeness test that should have
caught it only looked at tools whose NAMES start like a read (get_, list_,
search…). Neither does.

- Both join _READ_ONLY_TOOLS; the comment that pointed at this issue now says
  why they sat unlisted.
- _WRITE_TOOLS declares every writing tool by name. Nothing reads it at
  runtime — default-deny already refuses an unlisted tool — it exists so the
  classification is total.
- test_every_registered_tool_is_classified_exactly_once takes its candidates
  from what build_mcp_server() actually mounts, requires each in exactly one
  of the three sets, and still flags a classified name that is no tool. The
  decision stays explicit; only the candidate set widened.
- test_the_completeness_check_can_fail drops a real tool from its set and
  asserts it is noticed (rule 167).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01821k5B3Ysecp9fNYs92Kuy
2026-09-15 12:31:04 -04:00
..