## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - Tasks can have an execution policy with a review stage that names an
independent human reviewer
> - The issue route starts that stage when the assignee moves the task
to done or in_review
> - Native runs do not use that route. The native finalizer writes the
task status through the issue service, which does not run the stage
transition
> - So a native worker that reports verified work as done closes the
task without the required review. A worker that reports needs_review
moves the task to in_review without the configured stage or its reviewer
> - This pull request makes the native completion path start the
configured review stage, as the route does
> - The benefit is that a configured independent review gates Done for
native workers too
## Linked Issues or Issue Description
**What happened**
A task had an execution policy with one review stage for a human
reviewer. A native worker (OpenCode on the Paperclip runner) finished
the work and reported it. When the worker reported done with verified
evidence, the task became done and the review stage never started. When
the worker reported needs_review, the task became in_review with a
generic review card, `executionState` stayed null, and the configured
reviewer was not assigned. The chat eval `tasks.completion-with-gate`
timed out in setup because the task never reached the pending review
stage.
**Expected behavior**
Verified work on a task with a configured human review stage goes to
in_review with that stage pending, the stage reviewer assigned and the
worker kept as the return assignee. The task becomes done only after the
reviewer approves.
**Steps to reproduce**
1. Create a task assigned to a native agent with `executionPolicy.stages
= [{ type: "review", participants: [{ type: "user", userId: <reviewer>
}] }]`.
2. Let the agent finish the work and report done with verified evidence.
3. Read the task. Before this fix it is `done` and `executionState` is
null.
## What Changed
- `server/src/services/issue-execution-policy.ts`: add
`completionReviewStageEntry`. It applies the full policy transition that
the route applies for `status: "done"` and returns `starts` (with the
stage patch), `none` or `rejected`.
- `native-run-finalizer.ts`: a done decision on a task whose policy
starts a stage becomes in_review with reason
`execution_stage_review_required`. When the policy refuses the
transition, the decision is in_progress with reason
`execution_stage_transition_rejected` and a recovery note. It is never
done. Deliverable checks still run first.
- `status-decision-committer.ts`: for a stage-entry decision, apply the
stale-owner check, start the stage from the locked task in the same
status update (this also clears a monitor that the new assignee cannot
use), and wake an agent participant with `execution_review_requested` or
`execution_approval_requested`, as the route does. If the policy
changed, the saved decision is stale and finalization retries.
- `native-completion-feedback.ts`: on such a task, tell the worker to
report done so the configured stage requests the review. Reject
needs_review with no request or with any review request. Approval
requests keep their own path, because they can be governed action cards.
- New regression test `native-execution-policy-review-stage.test.ts`
(embedded Postgres, 6 tests).
## Verification
- `cd server && npx vitest run
src/services/native-runtime/native-execution-policy-review-stage.test.ts`
(6 tests): no stage (done), human stage (in_review, reviewer assigned,
monitor cleared), agent stage (in_review, reviewer woken), refused live
review cycle (in_progress, not done), and feedback including mixed and
approval requests. The stage tests fail without the finalizer change
(the task becomes done).
- Related suites pass: `historical-task-questions`,
`native-completion-feedback`, `native-run-finalizer-telemetry`,
`native-terminal-status-projection`, `status-arbiter`,
`task-monitor.integration`, `__tests__/issue-execution-policy` (247
tests).
- Server `tsc --noEmit` shows no errors in changed files. The local
worktree has unbuilt packages, so CI supplies the full typecheck.
## Risks
- The agent-reviewer wake is a system workflow wake, like the route's.
Unit tests prove the wake row. An end-to-end native agent review after
this wake is not yet exercised in a paid eval.
- A decision saved with a new reason and resumed by an older release
projects in_review or in_progress without the stage. The task does not
close, so the older release fails safe.
- Agents on tasks with a configured review stage now get a rejection
when they report needs_review with no request or with a review request.
## Model Used
- Anthropic Claude Opus 5.5 (`claude-opus-5-5`), tool use and code
execution in Claude Code.
## 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] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>