Skip to content

fix(config): grant the verbs this workflow calls, without the reduced reads - #974

Draft
wenzowski wants to merge 1 commit into
mainfrom
claude/cloud-1819-batten-spelling-allowance
Draft

wenzowski wants to merge 1 commit into
mainfrom
claude/cloud-1819-batten-spelling-allowance

Conversation

@wenzowski

Copy link
Copy Markdown
Contributor

Closes CLOUD-1780.

Two approval prompts per session for unsubscribe_pr_activity, which is absurd on its face: permissions.deny already blocks subscribing, so unsubscribing is the call that restores the declared posture. It prompted anyway because it was in neither list.

The board writes are the same error one layer up. AGENTS.md makes moving the row part of doing the work — "the state transition IS how others know" — so gating save_issue and save_comment behind a prompt gates the work, not a side effect. 45 calls this session, every one interactive.

What is deliberately not here

An earlier attempt added mcp__Linear__get_issue, list_issues and list_comments, and connector grant loose refused the tree for it. The gate is right and the reasoning is worth keeping: both have [[mint]] reductions, so granting the raw tool puts a cheaper-looking route to the same payload in the model's own tool list. Measured 2026-08-31 — the raw tools were registered, so that session called them 973 times for 13.2 MB and 73% of all its tool output, against 1.9 MB for Bash, Grep and Read together.

They were inert as well as harmful: issue read loose denies those tools at the mediated boundary whatever permissions.allow says. So the reads stay out and the route stays batten mcp call.

What goes in has no reduction to defeat: the two unsubscribe verbs, the recorded board writes (record = "board-writes" — captured, not reduced), the forge verbs this loop calls, and ./target/debug/batten, which Bash(batten:*) does not match because it is path-qualified.

timeout is 473 calls and stays out — it wraps an arbitrary command, so allowlisting it is a general execution grant wearing a prefix.

hooks untouched; hooks-wiring-check reports 5 harnesses, 0 unwired.

Branch name

The branch says 1819; the row is CLOUD-1780. CLOUD-1819 is the adjacent turn mint ahead tool-scope defect, still open.

🤖 Generated with Claude Code

https://claude.ai/code/session_016LP3X4mHLU6kwirAAsFT8w


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Sep 17, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

Warning

Review limit reached

Next included review available in 39 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 5b92ad4c-e5d0-4cca-bee9-02a850a9b354

📥 Commits

Reviewing files that changed from the base of the PR and between 00305c9 and 73d098e.

📒 Files selected for processing (1)
  • .claude/settings.json

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: d3a4c096-05f9-456e-b66d-00d89fe83c96

📥 Commits

Reviewing files that changed from the base of the PR and between 8fe8429 and 00305c9.

📒 Files selected for processing (1)
  • .claude/settings.json

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The permissions.allow list in .claude/settings.json adds access for the local Batten binary and several GitHub, Claude Code Remote, and Linear MCP tools. The existing mcp__github__pull_request_read entry remains at the start of the expanded permission block.

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to 00305

The requested workflow permissions are enabled without an identified functional or security regression. The change is ready to merge.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies a configuration fix that grants the permissions required by the workflow. It is concise and directly related to the changes.
Description check ✅ Passed The description explains the permission changes, the approval prompts they address, and the deliberate exclusions. It is directly related to the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

… connector

Two prompts per session for `unsubscribe_pr_activity` is the acute symptom,
and it is absurd on its face: `permissions.deny` already blocks SUBSCRIBING,
so unsubscribing is the call that restores the declared posture. It asked
for approval anyway, twice, because it was in neither list.

WHAT IS DELIBERATELY NOT HERE, and it is the half worth reading. Two
attempts at this added Linear grants and `connector grant loose` refused
the tree for both. The first added the reads (`get_issue`, `list_issues`,
`list_comments`); the second kept the WRITES (`save_issue`, `save_comment`)
on the theory that a `record = "board-writes"` row is captured rather than
reduced. Both were wrong, and the module says why in one line:

    reduced_connector := "mcp__Linear"

The predicate is a PREFIX over the whole server, not a per-tool list — "a
grant naming one tool and a grant globbing the whole server are the same
finding, because either one puts the unreduced payload back on the model's
surface". So no `mcp__Linear*` entry belongs here at all, and the route
stays `batten mcp call`.

The measurement behind it: the raw tools WERE registered once, so that
session called them 973 times for 13.2 MB and 73% of all its tool output,
against 1.9 MB for Bash, Grep and Read together.

What goes in is what has no reduction to defeat: the two unsubscribe verbs,
the forge verbs this loop actually calls, `get_session`, and
`./target/debug/batten`, which `Bash(batten:*)` does not match because it
is path-qualified.

`timeout` is 473 calls and stays out: it wraps an arbitrary command, so
allowlisting it is a general execution grant wearing a prefix.

The `hooks` block is untouched.

Refs: CLOUD-1780
@wenzowski
wenzowski force-pushed the claude/cloud-1819-batten-spelling-allowance branch from 00305c9 to 73d098e Compare September 18, 2026 02:43
@wenzowski
wenzowski marked this pull request as ready for review September 18, 2026 02:43
@wenzowski
wenzowski marked this pull request as draft September 18, 2026 04:11
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.

1 participant