paperclip/doc/connections/TASK-REVIEWS.md

135 lines
7.5 KiB
Markdown

# Connection reviews in task history
An agent call governed by **Ask human / Ask first** creates a server-owned
`request_confirmation.payload.toolAction` interaction linked to the existing
`tool_action_requests` record. No provider call runs while this review is pending.
The default approval lifetime remains one hour.
The task feed keeps one record for each review. **Review request** opens the
composer takeover. Dismissing the takeover only hides it; the review remains
pending, ordinary comments do not supersede it, and the agent is not resumed.
Multiple reviews retain separate records and the existing takeover navigation.
The card shows the app icon and a short request description. Destructive actions
retain destructive approval styling. Audit metadata and signed arguments remain
on the underlying review record.
**Approve & run** executes the signed, stored arguments once. **Decline** executes
nothing in one click. Both the task and Connections queue use
one decision transaction; a decision removes the pending queue item while its
history remains on the task. The human decision, resolver, remembered permission,
and execution outcome remain separate. Provider failure does not turn an approved
decision into a decline. Successful results stay collapsed behind the status chevron;
expanding it shows formatted JSON (or plain text). The resumed agent processes the
recorded result in a new turn and writes the user-facing answer. Live activity
invalidation refreshes both surfaces, with existing polling/reconnect reconciliation
retained.
## Remembered permission
Choose **Always allow** from the split button beside **Approve & run**. It
atomically saves approval and an action-wide trust rule for the
same agent, connection, and action, restricted to the originating project when one
exists. Future argument values may differ. The menu item exposes the scope through
its tooltip and accessible description; the receipt records the saved permission. If saving the rule
fails, the approval transaction rolls back and no provider call runs.
The rule remains bound to the reviewed catalog definition/schema. Changed
definitions require review again. Revocation, explicit denial, connection access,
and formal approval requirements remain effective. Manage/revoke rules through the
existing Connections trust-rule controls.
The accept/approve endpoints support optional `rememberAction: true`; omission
continues to approve once. Trust-rule promotion supports `argumentMode: "action"`;
its existing omitted/`"exact"` mode continues to bind exact argument values.
## Governed waiting and recovery
The gateway returns `approval_required` with the linked request/interaction IDs
and instructions to finish unrelated work, then yield `in_review` without retrying
or claiming completion. Agent task completion is rejected while a linked action
is pending, approved, or executing. Provider execution is server-owned.
`tool_action_deliveries` is a durable, content-free outbox keyed by action request.
It refers to the authoritative request, invocation, and interaction instead of
copying provider data. Once the originating runs have ended and no other task
interactions remain pending, ready outcomes are batched into one continuation
wake. The wake includes the recorded result/decline and instructions not to repeat
the operation. Native runners materialize validated server-owned interaction
outcomes; legacy runners receive the wake context and agent message. Existing
scheduler eligibility and budget gates still apply. Closed tasks retire receipts;
reassignment does not deliver the old agent's outcome to another agent.
Startup and periodic sweeps recover committed approvals, undelivered outcomes,
expiry, and incomplete feed projections. An execution left in progress for ten
minutes is marked failed with `tool_execution_outcome_unknown`. Its external
outcome is uncertain: inspect the provider before retrying. It is never
automatically replayed. This grace period exceeds the current approved-call timeout.
Migration 0249 adds the outbox and a partial unique wake-idempotency index.
The index is built transactionally; migration can briefly block wake-table writes
while PostgreSQL scans an existing large table. No external payload is added to the
outbox.
## Verification workflows
Run the credential-free, isolated browser suite:
```sh
PAPERCLIP_E2E_PORT=3222 pnpm exec playwright test -c tests/e2e/connection-reviews.config.ts
```
This starts a dedicated embedded database/server and local MCP fixture, configures
Ask first through the UI, and verifies approve, decline, remembered permission with
changed arguments, dismissal/reopening, ordinary comments, cross-tab queue/task
updates, provider failure, and restart while waiting. Assertions include useful
agent results and provider invocation counts. Screenshots, JSON journey identifiers,
and traces are attached to the Playwright HTML report. The deterministic agent is a
scripted process adapter; these results do not prove model-runner behavior.
Run the opt-in, local model-runner matrix with the harness's normal credentials:
```sh
PAPERCLIP_RUNNER_E2E_CONNECTION_REVIEWS=1 pnpm test:e2e:runner -- --suite connection-reviews
```
The 16 cells cover approve, decline, always allow, and restart/resume for native
Codex, native ACPX Claude, legacy Codex CLI, and legacy Claude CLI. Qualified model
settings come from the existing runner catalog. This flag does not expand the
normal hosted/Daytona matrix. The fixture MCP provider is real HTTP but is not
Notion; live Notion evidence must be reported separately.
For a real Notion test, start `paperclipai test-drive` from this checkout using
valid provider credentials, verify its process checkout/port ownership, connect
Notion normally, set an available read-only search/list action to Ask human, and
perform the same approve/decline/always-allow journeys for all four profiles.
Capture request/run IDs, screenshots, traces, and actual page results. Missing
credentials or account/provider access are untested dependencies, never a pass.
## Storybook
```sh
pnpm --filter @paperclipai/ui exec storybook dev -p 6018 -c storybook/.storybook --no-open --ci
```
Open **Chat & Comments / Connection Reviews**. The production task thread/card and
Connections queue cover pending, dismissed/reopened, multiple requests, each
submitting action, recoverable errors, concurrent resolution, approved/executing,
success/failure, decline with/without a reason, expiry/cancellation, remembered
scope/receipt, approval options, narrow layout, and queue/empty states. The global
theme toolbar switches light/dark. Story actions simulate server responses; use the
browser suite for integration proof.
Provider output, execution errors, and review notes travel in the continuation's
`untrustedToolResults` field, separate from its control instructions. Both native
and legacy wake prompts render those fields as fenced JSON with an explicit
untrusted-data boundary. Embedded provider instructions cannot grant permission
or change the task's continuation policy. Wake materialization redacts secrets
and bounds each text field before rendering.
A continuation includes at most eight shortened result records and caps the
serialized wake context at 32 KB. It links to the task interaction API for all
full outcomes and instructs the agent to retrieve omitted or incomplete results
before finishing. A committed receipt cutoff preserves acknowledgement of that
referenced set across restart, without putting an unbounded ID list in the wake.
Task review queries reconcile every 20 seconds if a live event is missed.