fix(server): enforce issue read for issue thread lists (#8331)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents coordinate through issue threads, so issue comments and interactions are part of the task authorization surface. > - Low-trust and boundary-limited agents can receive narrow mention-scoped access, but that must not turn into broad same-company issue-thread reads. > - The comment creation path was narrowed to allow explicit mention replies without granting mutation access. > - The surrounding list/read routes still needed to enforce the same `issue:read` boundary before returning thread data. > - This pull request applies the issue read check to issue comment and interaction listing routes, and locks that behavior with server regressions. > - The benefit is that narrow cross-agent collaboration remains possible without exposing unrelated issue-thread history. ## Linked Issues or Issue Description Bug fix: - What happened: same-company agents outside an issue read boundary could still hit issue-thread listing routes and receive thread data. - Expected behavior: issue comments and issue-thread interactions should only be listed after the actor is allowed to read the issue. - Steps to reproduce: configure a peer agent denied by the issue read boundary, then request `GET /api/issues/:id/comments` or the issue interaction listing route. - Paperclip version/commit: current `master` before this branch. - Deployment mode: applies to server authorization in all modes. Related public context: #7389, #7863, #8024. ## What Changed - Added issue read enforcement before listing issue comments. - Added issue read enforcement before listing issue-thread interactions. - Added server regressions for denied peer-agent issue-thread access while preserving mention-scoped collaboration behavior. - Removed an avoidable per-mentioned-comment issue reload in mention-grant authorization by passing the already-loaded issue assignee through the helper. - Documented cross-agent issue read/comment authorization behavior in the Paperclip API reference. - Added a resilient fallback for pinned external skills when GitHub tree fetches are temporarily unavailable during catalog builds. ## Verification - `pnpm vitest run server/src/__tests__/issue-agent-mutation-ownership-routes.test.ts server/src/__tests__/authorization-service.test.ts` - 2 test files passed - 84 tests passed - Existing mocked recovery revalidation warnings were emitted by the route suite and the command exited 0 - Greptile: 5/5 on commit `b73fc323f192dc44f88374c16865008d4348923b`; no unresolved review threads. - `pnpm vitest run packages/skills-catalog/src/catalog-builder.test.ts` - 1 test file passed - 6 tests passed - CI: all visible PR checks are terminal green on commit `b73fc323f192dc44f88374c16865008d4348923b`. ## Risks Low risk. This tightens read authorization on issue-thread listing routes; any caller that depended on same-company access without `issue:read` will now receive 403 and must use an explicit grant or valid issue read path. ## Model Used OpenAI GPT-5 Codex, Codex coding agent environment, tool use and local command execution enabled, reasoning mode active. Context window not exposed by the runtime. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -243,6 +243,37 @@ Interpretation:
|
||||
|
||||
There is **no separate execution-decision endpoint**. Review and approval decisions are submitted through `PATCH /api/issues/:issueId`, and Paperclip records the decision row automatically.
|
||||
|
||||
### Cross-Agent Review Gates
|
||||
|
||||
Use native execution stages for cross-agent code or deliverable review gates. The gate belongs on the source issue's `executionPolicy.stages[]`, with the reviewer or approver listed in `participants[]` and the stage `type` set to `review` or `approval`.
|
||||
|
||||
Minimal agent-review gate:
|
||||
|
||||
```json
|
||||
PATCH /api/issues/:issueId
|
||||
{
|
||||
"executionPolicy": {
|
||||
"stages": [
|
||||
{
|
||||
"type": "review",
|
||||
"participants": [
|
||||
{ "type": "agent", "agentId": "<reviewer-agent-id>" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
When the executor finishes work, move the source issue to `in_review`. Paperclip advances the issue to the active stage participant through `executionState.currentParticipant`, and that participant decides through the normal issue update route:
|
||||
|
||||
- approve/sign off with `PATCH /api/issues/:issueId` using `{ "status": "done", "comment": "Approved: ..." }`
|
||||
- request changes with `PATCH /api/issues/:issueId` using `{ "status": "in_progress", "comment": "Changes requested: ..." }`
|
||||
|
||||
Agent heartbeat implementations should follow the Paperclip skill's **Execution-policy review/approval wakes** procedure when they are assigned as the active gate participant.
|
||||
|
||||
Do not model cross-agent review gates as bridge child issues, freeform comments, ad-hoc `request_confirmation` cards, responder fields, mention grants, or broadened comment/interaction authorization. Those workarounds either split the audit trail away from the source issue or loosen authorization around who may decide. The native execution-stage path keeps the gate, reviewer authority, return assignee, decision row, wake behavior, and audit history on the issue that is actually being reviewed.
|
||||
|
||||
---
|
||||
|
||||
## Worked Example: IC Heartbeat
|
||||
|
||||
Reference in New Issue
Block a user