Skip to content

feat(rovodev): add the review-agent check adapter and finish the permission keys - #2481

Merged
dyoshikawa merged 2 commits into
mainfrom
resolve-scrap-issue-2422-rovodev-keys-and-check
Jul 29, 2026
Merged

feat(rovodev): add the review-agent check adapter and finish the permission keys#2481
dyoshikawa merged 2 commits into
mainfrom
resolve-scrap-issue-2422-rovodev-keys-and-check

Conversation

@dyoshikawa

Copy link
Copy Markdown
Owner

Summary

Closes the two remaining actionable gaps of #2422 (gap 1 core and gap 3 were closed by #2442).

Gap 1 residue — permission keys

Two additions, both verified against the Rovo Dev CLI settings page:

The seven planning and Atlassian tool keys (createTechnicalPlan, getJiraIssue, createJiraIssue, updateJiraIssue, getConfluencePage, createConfluencePage, updateConfluencePage) are now known to the adapter. They split the same way the file tools do, so they ride the existing read/edit categories rather than getting one of their own: get* inspects, create*/update* mutates. createTechnicalPlan is grouped with the mutating tools because it is the planning tool that produces an artifact rather than reading one.

Worth knowing when authoring, and called out in the docs: an edit: deny now reaches Jira and Confluence, not just the working tree. They had to go into both direction maps — a key in TOOL_KEY_TO_CATEGORY alone would join MANAGED_TOOL_KEYS and be deleted on generate without ever being rewritten.

toolPermissions.default — the level Rovo Dev falls back to for any tool with no more specific setting (its own default is ask). The canonical all-tools category * drives it, derived from its catch-all exactly as bash.default is derived from bash's, and round-tripped on import. It joins OWNED_TOOL_PERMISSION_KEYS, and a tool-wide allow is dropped by the permissive-strip pass for the same reason bash.default: allow is. A pattern rule inside the * category has no counterpart and is skipped with a warning. This follows the precedent the Zed adapter already set for the * category.

Gap 2 — review-agent check adapter

New RovodevCheck emitting .rovodev/.review-agent.md — plain Markdown, no frontmatter, note the leading dot. Project scope only, per the custom review instructions docs; that is the opposite of the Rovo Dev permissions surface, which is global only.

This is the same shape as Cursor Bugbot: one aggregated instruction file rather than a file per check. Rather than copying ~150 lines, the marker convention, the <!-- rulesync:literal-check:… --> escaping, the import-side split, the replace-and-warn on generate and the deletion guard are extracted into aggregated-check-file.ts and shared. cursor-check.ts now uses it, and its 24 existing tests pass unchanged — the refactor is behavior-neutral.

Deferred

Gap 4 (mcp.disabledMcpServers definition retention) and gap 5 (hooks) are not implemented and stay deferred, as recorded on the issue.

Verification

  • pnpm cicheck green.
  • npx vitest run --config vitest.e2e.config.ts src/e2e/e2e-checks.spec.ts src/e2e/e2e-permissions.spec.ts — 87 passed.

Closes #2422

🤖 Generated with Claude Code

cm-dyoshikawa and others added 2 commits July 29, 2026 07:36
…ission keys

Gap 1 residue: adds the seven planning and Atlassian tool permission keys, and
maps the canonical all-tools category onto toolPermissions.default the same way
bash's catch-all drives bash.default. The new keys ride the existing read/edit
categories rather than getting one of their own — get* inspects, create*/update*
mutates — so an edit: deny now reaches Jira and Confluence too, which the docs
call out.

Gap 2: new checks adapter emitting .rovodev/.review-agent.md, plain Markdown
with no frontmatter. It is the same aggregated-single-file surface Cursor
Bugbot has, so the marker convention, escaping, import split, replace-and-warn
and deletion guard are extracted into aggregated-check-file.ts and shared
rather than copied; cursor-check.ts now uses it and its tests are unchanged.

Gaps 4 (mcp.disabledMcpServers definition retention) and 5 (hooks) stay
deferred.

Closes #2422

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…y on import

Rovo Dev rewrites a single tool key when the user answers 'always allow' to one
prompt. Import took the strictest of the keys that carried a value and ignored
the rest, so that lone key imported as a blanket category allow — and with the
Atlassian keys now riding the same categories, the next generate would have
handed that grant to Jira and Confluence writes too.

A silent key now counts as the implicit fallback level (toolPermissions.default,
or Rovo Dev's own ask) rather than as absent. A category the file says nothing
about at all is still skipped rather than invented.

Also splits hasHandWrittenContent into hasHandWrittenPreamble (the warning) and
isOnlyGeneratedSections (the deletion guard), restoring the pre-refactor
behavior for an empty BUGBOT.md, which the extraction had made deletable; adds
the aggregated-check-file unit tests; and records the ownership migration for
the newly owned permission keys in the docs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dyoshikawa
dyoshikawa merged commit 7c0efe4 into main Jul 29, 2026
9 checks passed
@dyoshikawa
dyoshikawa deleted the resolve-scrap-issue-2422-rovodev-keys-and-check branch July 29, 2026 15:12
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.

bug(rovodev): per-tool permissions emitted at toolPermissions.<tool> instead of toolPermissions.tools.<tool>, so they never apply

2 participants