Skip to content

Implement WorkSuggestion API and UI enhancements with Inbox features - #165

Merged
harshlocham merged 4 commits into
mainfrom
feat/v2-p2-execution-approve-separate
Aug 10, 2026
Merged

Implement WorkSuggestion API and UI enhancements with Inbox features#165
harshlocham merged 4 commits into
mainfrom
feat/v2-p2-execution-approve-separate

Conversation

@harshlocham

@harshlocham harshlocham commented Aug 9, 2026

Copy link
Copy Markdown
Owner

This pull request implements Phase 2.4 of the "suggest_only" execution mode, introducing explicit manager approval and human-approved re-entry paths for task execution, and enhances the Work Inbox and approvals product UI. It adds new API and UI surfaces for managing approvals, enforces granular authorization checks, and introduces robust backend logic and tests for handling suggest_only mode exceptions. The changes also improve the flexibility and security of the approvals workflow.

Suggest_only execution mode exceptions and backend logic:

  • Added shouldSkipSuggestOnlyIngressFailClosed and resolveSuggestOnlyPolicyOverride helpers to handle explicit manager requests and human-approved re-entry as exceptions to the suggest_only fail-closed path, with comprehensive unit tests (apps/task-worker/services/suggest-only-execution-gate.ts, apps/task-worker/tests/suggest-only-execution-gate.test.ts). [1] [2]
  • Updated the task execution worker to respect these exceptions, passing new payload flags (explicitManagerRequest, humanApprovedExecution) and adjusting the approval and blocking logic accordingly (apps/task-worker/index.ts). [1] [2] [3] [4] [5] [6]

Approvals API and authorization:

  • Refactored the approvals API to support organization- and conversation-scoped queries, enforce fine-grained authorization (including organization admin checks), and support human approval flags on approval actions (apps/web/app/api/task-approvals/route.ts). [1] [2] [3] [4] [5]

Work Inbox and approvals UI improvements:

  • Introduced feature-flagged /inbox and /inbox/approvals surfaces in the product UI, reusing existing APIs and enabling actionable WorkSuggestion triage (accept/assign/dismiss) from the inbox (.changeset/v2-p2-inbox-ui.md, .changeset/v2-p2-approvals-product-ui.md, .changeset/v2-p2-suggestion-triage.md).
  • Improved the admin approvals page to use useCallback for loading data and support new API parameters (apps/web/app/admin/task-approvals/page.tsx). [1] [2] [3]

WorkSuggestion mutation and coordination task linkage:

  • Accept/dismiss/assign mutations now create coordination tasks with linkage to the originating suggestion, without immediately enqueueing execution (.changeset/v2-p2-suggestion-mutations.md).

Explicit manager approval and execution path:

  • Added a new explicit manager "Allow AI tools" request-execution path, distinct from WorkSuggestion accept, reusing TaskAction approvals (.changeset/v2-p2-execution-approve-separate.md).

Summary by CodeRabbit

  • New Features

    • Added a separate “Allow AI tools” action for requesting execution of converted tasks.
    • Added organization- and conversation-scoped approval access for authorized users.
    • Added approval status, pending-state handling, and clear feedback throughout the inbox and task views.
    • Added safeguards to prevent unauthorized or duplicate execution requests.
  • Bug Fixes

    • Improved suggest-only policy handling so approved requests can proceed while unapproved requests remain blocked.
  • Tests

    • Added coverage for authorization, execution requests, approval flows, policy safeguards, and inbox interactions.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@harshlocham, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 23 minutes

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

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4eb5fe07-0ee6-4c10-b7d0-2beb9b149a7a

📥 Commits

Reviewing files that changed from the base of the PR and between 4420304 and b1bed59.

📒 Files selected for processing (11)
  • apps/task-worker/index.ts
  • apps/task-worker/services/suggest-only-execution-gate.ts
  • apps/task-worker/tests/suggest-only-execution-gate.test.ts
  • apps/web/app/api/task-approvals/route.ts
  • apps/web/app/api/tasks/[id]/request-execution/route.ts
  • apps/web/components/work-suggestions/inbox-approvals.tsx
  • apps/web/components/work-suggestions/work-inbox.tsx
  • apps/web/test/task-approvals.route.test.ts
  • packages/services/repositories/task.repo.ts
  • packages/services/task-execution-enqueue.service.ts
  • packages/services/task-execution-request.service.ts
📝 Walkthrough

Walkthrough

The PR adds a separate manager request path for AI tool execution. It introduces scoped approval authorization, explicit approval state propagation, suggest-only policy exceptions, new APIs, and “Allow AI tools” actions in work-suggestion interfaces.

Changes

Execution request and authorization

Layer / File(s) Summary
Task execution request service and authorization
packages/services/..., .changeset/...
Adds task execution request orchestration, pending-approval queries, authorization helpers, enqueue exemptions, package exports, and release metadata.
Scoped approval APIs and client transport
apps/web/app/api/..., apps/web/lib/utils/api.ts, apps/web/test/..., apps/web/jest.config.cjs
Adds the task execution request endpoint, scoped approval access, organization filtering, human-approval event flags, client API helpers, and route tests.
Suggest-only worker policy flow
apps/task-worker/...
Propagates manager-request and human-approval flags. Explicit manager requests require approval, while human-approved re-entry bypasses suggest-only denial.
Work suggestion and approval controls
apps/web/app/work-suggestions/..., apps/web/components/..., apps/web/test/...
Adds “Allow AI tools” actions, organization-scoped approval loading, approval navigation, request state handling, and UI tests.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Manager
  participant WorkSuggestionUI
  participant RequestRoute
  participant RequestService
  participant TaskWorker
  Manager->>WorkSuggestionUI: Select “Allow AI tools”
  WorkSuggestionUI->>RequestRoute: POST task execution request
  RequestRoute->>RequestService: Validate and authorize request
  RequestService->>TaskWorker: Enqueue explicit manager request
  TaskWorker-->>RequestService: Create approval-required execution
  RequestService-->>WorkSuggestionUI: Return task action and status
Loading

Possibly related PRs

Suggested labels: enhancement

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the API, UI, WorkSuggestion, and Inbox changes, although it does not mention the explicit execution approval path.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/v2-p2-execution-approve-separate

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.

@harshlocham
harshlocham changed the base branch from main to feat/v2-p2-suggestion-triage August 9, 2026 11:16
Repository owner deleted a comment from coderabbitai Bot Aug 9, 2026
@harshlocham

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/web/app/api/task-approvals/route.ts (1)

154-227: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Make approval decisions atomic with the pending state.

updateTaskActionExecutionState performs a normal findByIdAndUpdate without an executionState: "approval_pending" match, so concurrent decide requests can write conflicting states and enqueue misleading task.execution.approved events. Include the pending state in the update filter, then reject null/409 when another request already decided.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/app/api/task-approvals/route.ts` around lines 154 - 227, Make the
approval update in the decision handler atomic by requiring executionState
"approval_pending" in the update filter used by updateTaskActionExecutionState.
Handle a null update result for both reject and approve decisions by returning a
409 conflict response, and only enqueue task.execution.approved after a
successful approval update.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/task-worker/index.ts`:
- Around line 884-901: Update the blocked/unsafe condition in the policy flow
around resolveSuggestOnlyPolicyOverride so bypassSuggestOnlyAfterHumanApproval
can suppress blocking only when the suggest-only mode denial is the sole
blocking reason. Keep unsafe outcomes and independent denials such as outside
allowed domains blocked, and add a regression test covering combined
suggest-only and unsafe reasons.

In `@apps/web/app/api/tasks/`[id]/request-execution/route.ts:
- Around line 67-70: Update the request body parsing in the request-execution
route around bodySchema.parse and JSON.parse so malformed JSON is caught and
returns the existing invalid-payload HTTP 400 response. Preserve schema
validation behavior for valid JSON and avoid routing SyntaxError failures to the
generic 500 handler.

In `@packages/services/task-execution-enqueue.service.ts`:
- Around line 40-41: Update the enqueue flow using explicitManagerRequest so the
resolved flag from input.explicitManagerRequest or
input.payload.explicitManagerRequest is written into the payload published to
the outbox, rather than publishing input.payload unchanged. Preserve existing
payload fields and add a test covering only input.explicitManagerRequest set to
true.

In `@packages/services/task-execution-request.service.ts`:
- Around line 76-83: Update the duplicate-handling flow around
getPendingApprovalTaskActionForTask and the request creation logic to look up
the existing action using this request’s idempotency key, including actions in
the requested state. When found, safely retry the deduplicated outbox enqueue if
needed or return the existing request state, instead of rethrowing the
duplicate-key error; preserve the current behavior for genuinely new requests.

---

Outside diff comments:
In `@apps/web/app/api/task-approvals/route.ts`:
- Around line 154-227: Make the approval update in the decision handler atomic
by requiring executionState "approval_pending" in the update filter used by
updateTaskActionExecutionState. Handle a null update result for both reject and
approve decisions by returning a 409 conflict response, and only enqueue
task.execution.approved after a successful approval update.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3949a8b0-65c3-46cb-adf4-c97a1cdf8314

📥 Commits

Reviewing files that changed from the base of the PR and between 082b342 and 4420304.

📒 Files selected for processing (27)
  • .changeset/v2-p2-execution-approve-separate.md
  • apps/task-worker/index.ts
  • apps/task-worker/services/suggest-only-execution-gate.ts
  • apps/task-worker/tests/suggest-only-execution-gate.test.ts
  • apps/web/app/admin/task-approvals/page.tsx
  • apps/web/app/api/task-approvals/route.ts
  • apps/web/app/api/tasks/[id]/request-execution/route.ts
  • apps/web/app/work-suggestions/[id]/page.tsx
  • apps/web/components/chat/task-panel.tsx
  • apps/web/components/work-suggestions/inbox-approvals.tsx
  • apps/web/components/work-suggestions/work-inbox-triage.tsx
  • apps/web/components/work-suggestions/work-inbox.tsx
  • apps/web/components/work-suggestions/work-suggestion-detail.tsx
  • apps/web/jest.config.cjs
  • apps/web/lib/utils/api.ts
  • apps/web/test/inbox-approvals.test.tsx
  • apps/web/test/task-approvals.route.test.ts
  • apps/web/test/task-request-execution.route.test.ts
  • apps/web/test/work-inbox.test.tsx
  • apps/web/test/work-suggestion-detail.test.tsx
  • packages/services/__tests__/authorization.service.test.ts
  • packages/services/__tests__/task-execution-enqueue.service.test.ts
  • packages/services/authorization.service.ts
  • packages/services/package.json
  • packages/services/repositories/task.repo.ts
  • packages/services/task-execution-enqueue.service.ts
  • packages/services/task-execution-request.service.ts

Comment thread apps/task-worker/index.ts
Comment thread apps/web/app/api/tasks/[id]/request-execution/route.ts
Comment thread packages/services/task-execution-enqueue.service.ts
Comment on lines +76 to +83
const existingPending = await getPendingApprovalTaskActionForTask(input.taskId);
if (existingPending) {
return {
taskAction: existingPending,
enqueued: false,
alreadyPending: true,
};
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Recover retries from the requested action state.

This service creates an action with executionState: "requested", but duplicate handling searches only for approval_pending. If a second request arrives before the worker creates the approval action, Lines 138-145 return no action and rethrow the duplicate-key error.

The same state mismatch makes a request unrecoverable after a transient outbox enqueue failure. Find the existing action by this request's idempotency key, then safely repeat the deduplicated enqueue or return the existing request state.

Also applies to: 104-147

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/services/task-execution-request.service.ts` around lines 76 - 83,
Update the duplicate-handling flow around getPendingApprovalTaskActionForTask
and the request creation logic to look up the existing action using this
request’s idempotency key, including actions in the requested state. When found,
safely retry the deduplicated outbox enqueue if needed or return the existing
request state, instead of rethrowing the duplicate-key error; preserve the
current behavior for genuinely new requests.

@harshlocham
harshlocham force-pushed the feat/v2-p2-execution-approve-separate branch from 4420304 to 3b4f3a4 Compare August 10, 2026 09:52
@harshlocham
harshlocham force-pushed the feat/v2-p2-execution-approve-separate branch from 6bdcc4b to 98f7823 Compare August 10, 2026 12:14
@harshlocham
harshlocham force-pushed the feat/v2-p2-execution-approve-separate branch from 98f7823 to 02bc181 Compare August 10, 2026 12:23
@harshlocham
harshlocham force-pushed the feat/v2-p2-execution-approve-separate branch from 02bc181 to 9918a05 Compare August 10, 2026 12:31
@harshlocham
harshlocham force-pushed the feat/v2-p2-execution-approve-separate branch from 9918a05 to d093fff Compare August 10, 2026 12:40
Base automatically changed from feat/v2-p2-suggestion-triage to main August 10, 2026 12:50
harshlocham and others added 4 commits August 10, 2026 18:20
- Introduced explicit manager request handling for allowing AI tools in the task execution process.
- Updated TaskExecutionRequested and TaskExecutionApproved payloads to include flags for explicit manager requests and human-approved executions.
- Added new service functions to manage suggest-only execution gate logic, allowing for exceptions based on explicit approvals.
- Enhanced the WorkSuggestion components to support requesting task execution approvals separately from accepting suggestions.
- Updated API endpoints and utility functions to accommodate new approval workflows and improved error handling.
- Added comprehensive tests for new functionalities, ensuring robust coverage for the approval process and suggest-only logic.
Only the Allow AI tools path may skip ingress fail-closed and bypass
mode denial after human approval; generic approvals stay blocked.

Co-authored-by: Cursor <cursoragent@cursor.com>
Generic approvals must not set humanApprovedExecution; only the explicit
manager Allow AI tools path may.

Co-authored-by: Cursor <cursoragent@cursor.com>
…very

Keep human-approved suggest_only from skipping unrelated unsafe denials,
copy explicitManagerRequest into the outbox payload, and recover duplicate
request-execution while the action is still requested.

Co-authored-by: Cursor <cursoragent@cursor.com>
@harshlocham
harshlocham force-pushed the feat/v2-p2-execution-approve-separate branch from d093fff to b1bed59 Compare August 10, 2026 12:50
@harshlocham
harshlocham merged commit 24955f9 into main Aug 10, 2026
8 checks passed
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