Skip to content

feat(#6966): make the review role's repo read-only in agent new - #7915

Merged
waynesun09 merged 2 commits into
mainfrom
agent-6966-review-readonly
Oct 1, 2026
Merged

waynesun09 merged 2 commits into
mainfrom
agent-6966-review-readonly

Conversation

@waynesun09

Copy link
Copy Markdown
Member

What

fullsend agent new --role review now generates readonly_repo: true, so the checked-out repository is read-only in the sandbox and the reviewer cannot modify the code it reviews.

Why

The fleet's review harness in fullsend-ai/agents (harness/review.yaml) sets readonly_repo; a generated review agent did not.

Changes

  • Role.ReadonlyRepo is added to the role table and set for review only.
  • buildHarness carries it into the emitted harness.
  • One sentence under the role table in docs/cli/agent.md.

Tests

  • TestReviewRoleMountsTheRepositoryReadOnly pins the role table.
  • TestRoleImageReachesTheHarness now also checks that readonly_repo reaches the emitted harness.
  • Each of these mutations fails a test: dropping ReadonlyRepo: true, and dropping the render wiring.
  • The triage and validation-loop goldens are unaffected.
go test -race ./internal/agentnew/

Split out of #7243. Part of #6966.

🤖 Generated with Claude Code

The fleet's review harness sets readonly_repo, so the checked-out
repository is read-only in the sandbox and a reviewer cannot modify the
code it reviews. A review agent generated by `fullsend agent new` did not
set it.

Add ReadonlyRepo to the role table, set it for review only, and carry it
into the generated harness. Tests pin the role table and the emitted
harness YAML; docs/cli/agent.md notes it under the role table. The triage
and validation-loop goldens are unaffected.

Assisted-by: Claude (fix), Claude (review)
Signed-off-by: Wayne Sun <gsun@redhat.com>
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Generate read-only repositories for review agents

✨ Enhancement 🧪 Tests 📝 Documentation 🕐 10-20 Minutes

Grey Divider

AI Description

• Set readonly_repo for generated review agents to prevent changes to the code they review.
• Carry the role setting into harness YAML and test that only review receives it.
• Document the review role’s sandbox behavior.
Diagram

graph TD
  CLI["agent new"] --> Roles["Role table"] --> Builder["Harness builder"] --> YAML["Harness YAML"] --> Sandbox["Sandbox checkout"]
Loading
High-Level Assessment

Keep the setting in the existing role table and pass it through the harness builder. A review-specific rendering condition would duplicate role policy outside the table without improving the generated result.

Files changed (5) +29 / -3

Enhancement (2) +9 / -3
render.goPass the role’s read-only setting into the harness +1/-0

Pass the role’s read-only setting into the harness

• Copies 'Role.ReadonlyRepo' into the harness so the generated YAML reflects the selected role.

internal/agentnew/render.go

roles.goMark the review role’s repository read-only +8/-3

Mark the review role’s repository read-only

• Adds 'ReadonlyRepo' to role configuration and enables it for review only.

internal/agentnew/roles.go

Tests (2) +18 / -0
render_test.goVerify read-only policy survives harness rendering +6/-0

Verify read-only policy survives harness rendering

• Extends the per-role rendering test to load emitted YAML and check that only review has 'readonly_repo' enabled.

internal/agentnew/render_test.go

roles_test.goPin the review-only role setting +12/-0

Pin the review-only role setting

• Adds a role-table test requiring 'ReadonlyRepo' for review and forbidding it for other roles.

internal/agentnew/roles_test.go

Documentation (1) +2 / -0
agent.mdDocument the review role’s read-only checkout +2/-0

Document the review role’s read-only checkout

• Explains that generated review agents set 'readonly_repo: true', matching the fleet review harness.

docs/cli/agent.md

@qodo-code-review

qodo-code-review Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Review agents can write through repository symlinks ✗ Dismissed
Description
The review role now activates ReadonlyRepo, but the enforcement command skips symlinks with `-not
-type l` and therefore never removes write permission from their targets. A checked-out repository
containing a symlink to a writable path can still be modified by the reviewer despite the generated
harness claiming the repository is read-only.
Code

internal/agentnew/roles.go[70]

+		ReadonlyRepo: true,
Relevance

●●● Strong

Recent security precedents accept symlink-containment hardening when filesystem paths can escape
intended boundaries.

PR-#7445
PR-#7061

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new review-role flag directly activates the existing enforcement path. That path explicitly
excludes symlinks from its find operation, while the harness documentation says the repository is
made read-only; consequently, symlink targets are not protected by the newly enabled behavior.

internal/agentnew/roles.go[67-70]
internal/cli/run.go[2088-2102]
docs/cli/agent.md[149-149]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The review role now enables `ReadonlyRepo`, which invokes the repository read-only enforcement, but that enforcement skips symlinks and does not protect their targets. A repository symlink can therefore provide a writable path to the reviewer, undermining the new read-only guarantee.

## Fix Focus Areas
- internal/cli/run.go[2088-2104]
- internal/agentnew/roles.go[67-70]

## Recommended Fix
Ensure read-only enforcement cannot be bypassed through symlinks, while preserving the intentional `.git` exception. Resolve and validate symlink targets before changing permissions, or reject unsafe symlinks during enforcement, and add a regression test covering a repository symlink to a writable file or directory under the sandbox workspace.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Agent guides still omit the new behavior ✗ Dismissed
Description
The review-role behavior is documented only in docs/cli/agent.md, while the documentation guide
requires every agent touchpoint to be reviewed when CLI behavior changes. The listed operations,
bring-your-own-agent, customization, CLI internals, ADR, and other guide pages remain unchanged, so
readers may receive incomplete guidance about read-only review repositories.
Code

docs/cli/agent.md[149]

+A `review` agent also gets `readonly_repo: true`: the checked-out repository is made read-only in the sandbox, so a reviewer cannot modify the code it reviews. That matches `harness/review.yaml` in fullsend-ai/agents.
Relevance

●●● Strong

Recent precedents accept documentation-completeness findings for changed CLI behavior and missing
required touchpoints.

PR-#7445
PR-#7205

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The changed CLI behavior is documented in docs/cli/agent.md, but the repository's documentation
guide identifies additional required agent touchpoints that were not changed in this PR.

Rule 2806787: Update CLI-related docs according to docs/contributing/documentation.md when changing CLI surface
docs/cli/agent.md[149-149]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The review role now generates a read-only repository harness, but only the CLI reference was updated. `docs/contributing/documentation.md` requires all documentation touchpoints for the `agent` command group to be reviewed and updated when its behavior changes.

## Fix Focus Areas
- docs/cli/agent.md[149-149]
- docs/guides/getting-started/operations.md[1-1]
- docs/guides/user/bring-your-own-agent.md[1-1]
- docs/guides/user/customizing-agents.md[1-1]
- docs/guides/user/customizing-with-skills.md[1-1]
- docs/guides/dev/cli-internals.md[1-1]
- docs/ADRs/0058-agent-registration.md[1-1]
- internal/cli/agent.go[1-1]

## Recommended Fix
Search the listed agent documentation and source help locations for role-generation and review-agent behavior. Update each location that describes the affected behavior so it states that generated review agents use `readonly_repo: true` and cannot modify the checked-out repository, or document an explicit exemption where the location is not relevant.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 72 rules
✅ Cross-repo context — repo relationships
  Explored: repo: fullsend-ai/agents (sha: 3af27dde) — View relationship
Review mode: 🚀 Fast: This is a small, localized change that propagates one role-specific boolean through the harness with focused tests and no security-sensitive or broad behavioral scope.

Grey Divider

Tip of the day
💡 Did you know, you can keep summaries lean with Findings visible per group, which tucks the rest behind a View link

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread docs/cli/agent.md
Comment thread internal/agentnew/roles.go
@fullsend-ai-review

fullsend-ai-review Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 2:51 PM UTC · Completed 3:31 PM UTC

Commit: 3d8be54 · View workflow run →

Runtime: pi · Model: sonnet → claude-sonnet-5 · Effort: high · Cost: $2.74

@github-actions

github-actions Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Site preview

Preview: https://9d82e5c0-site.fullsend-ai.workers.dev

Commit: 6fb93c3975c6b51f7ce7d81f9beea301b7bf547c

@codecov

codecov Bot commented Oct 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@fullsend-ai-review

Copy link
Copy Markdown

Review

Findings

High

  • [sub-agent-failure] N/A — The correctness sub-agent did not return findings: it timed out after 900s on two separate dispatch attempts (a full-scope pass and a tightened small-scope retry limited to the 5 changed files). Correctness review of this PR (logic correctness of the ReadonlyRepo wiring, edge-case handling for the other roles' zero-value default, and test adequacy of TestReviewRoleMountsTheRepositoryReadOnly / TestRoleImageReachesTheHarness) was not completed in this run.

Low

  • [codebase-consistency] internal/agentnew/roles_test.go:137 — TestReviewRoleMountsTheRepositoryReadOnly iterates roleTable directly instead of RoleNames() (the pattern every other role-table test in this file and in render_test.go uses for deterministic order), and formats the role name with %s instead of the %q convention used throughout internal/agentnew.
    Remediation: iterate with for _, name := range RoleNames() { role := roleTable[name]; ... } and use %q for the role name in the error message, matching render_test.go's role %q: ... convention.
  • [sub-agent-failure] N/A — The challenger sub-agent was skipped: time budget (385s remaining, below the 600s threshold). Using the pre-challenger finding set.

Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the review comment for full details.

Comment thread internal/agentnew/roles_test.go Outdated

@ggallen ggallen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the changes and found no actionable issues.

Use RoleNames() for a deterministic order and %q for the role name, like
the other role-table tests.

Assisted-by: Claude (fix), Claude (review)
Signed-off-by: Wayne Sun <gsun@redhat.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 3:44 PM UTC · Completed 4:21 PM UTC

Commit: 6fb93c3 · View workflow run →

Runtime: pi · Model: sonnet → claude-sonnet-5 · Effort: high · Cost: $1.99

@waynesun09
waynesun09 added this pull request to the merge queue Oct 1, 2026
Merged via the queue into main with commit 615506b Oct 1, 2026
54 of 55 checks passed
@waynesun09
waynesun09 deleted the agent-6966-review-readonly branch October 1, 2026 16:15
@fullsend-ai-review

Copy link
Copy Markdown

Review skipped — this PR is already merged.

The /fs-review command only reviews open PRs/MRs.

Posted by fullsend post-review check

waynesun09 added a commit to fullsend-ai/agents that referenced this pull request Oct 1, 2026
Regenerated from fullsend main (which has fullsend-ai/fullsend#7915)
with #7914 (c057eb8f4) and #7917 (2863b89d8, which includes #7916)
merged in. Only post-link-check.sh changed: the dry-run findings preview
prints model output, and under GitHub Actions a line starting with "::"
is a workflow command, so the preview now sits inside a stop-commands
block opened and closed by a random 32-hex token.

A new test feeds a comment carrying a "::warning::" line and requires
the preview to open with ::stop-commands::<32 hex>, close with the same
token, and keep the model's line inside. The truncation-cap test now
measures the comment without that framing.

Assisted-by: Claude (fix), Claude (review)
Signed-off-by: Wayne Sun <gsun@redhat.com>
waynesun09 added a commit to fullsend-ai/agents that referenced this pull request Oct 1, 2026
Regenerated from fullsend main (which has fullsend-ai/fullsend#7915)
with #7914 (c057eb8f4) and #7917 (2863b89d8, which includes #7916)
merged in. Only post-link-check.sh changed: the dry-run findings preview
prints model output, and under GitHub Actions a line starting with "::"
is a workflow command, so the preview now sits inside a stop-commands
block opened and closed by a random 32-hex token.

A new test feeds a comment carrying a "::warning::" line and requires
the preview to open with ::stop-commands::<32 hex>, close with the same
token, and keep the model's line inside. The truncation-cap test now
measures the comment without that framing.

Assisted-by: Claude (fix), Claude (review)
Signed-off-by: Wayne Sun <gsun@redhat.com>

This branch was successfully deployed

1 active and 1 inactive deployments
site-preview — 6fb93c39 Deployed Oct 1, 2026 by github-actions[bot]
dev — 6fb93c39 Deployed Oct 1, 2026 by waynesun09 via behaviour #14827
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