Files
PaperClipAI/server
DottaandPaperclip a2a6129ed5 Allow a new human intent to request tool review after a decline (#18742)
## Thinking Path

> - Paperclip manages work for companies of AI agents.
> - App writes can require a human review for each invocation.
> - Decline and Always allow are separate controls.
> - The gateway currently reuses a declined action across later human
requests with the same arguments.
> - A new request can therefore receive the old decline instead of a new
review.
> - This change uses the saved run and human comment to distinguish a
new intent.
> - The new intent still follows the current policy and approval gates.

## Linked Issues or Issue Description

**What happened?**

After a person declines an Ask first app write, a later request from
that person for the same write receives `action_declined`. The gateway
matches company, task, agent, tool and arguments across runs. It does
not distinguish the later human request.

**Expected behavior**

A distinct later request from the same responsible person can open a new
Ask first review. It must not execute the write or reuse approval. A
retry of the declined intent, including its rejection continuation, must
remain declined.

**Steps to reproduce**

1. Ask an agent to perform an app write that requires approval.
2. Decline the proposed action.
3. Send a new request for the same action.
4. Observe that the gateway reuses the old rejection and creates no new
pending review.

**Paperclip version or commit**

The behavior is present on master `7b8aa60b6d` and in a retained native
journey. The focused parent control reproduces the matching error. No
related open fix was found in the scoped PR search.

## What Changed

- Only a rejected match can be released for a later human intent.
- Require the active run, company, task, agent and responsible person to
match the saved direct-human comment. Reject derived, deleted, untrusted
or system-authored input and invalid chronology.
- Preserve all other replay states, signed argument checks, current
policy, unresolved-effect guards, approval and execution owners.
- Document the distinction between decline and a standing policy change.

## Verification

- Actual matching-function control: parent fails; this change passes.
The control uses the unchanged owner body with synthetic database rows.
It does not claim real PostgreSQL or provider verification.
- 52 focused pure controls pass. These cover same-intent retries,
rejection continuations, foreign scope and actor, invalid authorship,
chronology and other action states.
- TypeScript 7.0.2 checks pass for the new helper and its owning tests.
- `node scripts/check-maps.mjs` and `git diff --check` pass.
- The existing gateway service suite has a new signed-action integration
test. It covers ordinary and reopened human requests. It requires the
old rejection plus one new pending request, a stable retry, and no
completed call. Each leaf prints one fixed success label after its
assertions so CI can distinguish execution from a platform skip. No
local PostgreSQL, app, model or provider execution was run. Current-head
normal CI41594912212 completed with48 successful jobs and1 expected
skip. Both real PostgreSQL leaves executed and emitted their
post-assertion markers; the owning job passed. Full typecheck/build
checks passed in CI.

## Risks

This adds one indexed run/comment read only after a rejected matching
action. Missing identity or ambiguous provenance keeps the old
rejection. Legacy and external comments without direct-human provenance
do not reset it. A new human intent is not consent to execute. This core
PR remains unmerged. Candidate native journey qualification is separate;
the original failed journey is retained.

## Model Used

OpenAI `gpt-6.1-sol` with reasoning, source inspection and tool use. The
host did not expose the context-window size.

## 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
#123` / `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
- [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>
2026-11-03 06:28:36 -06:00
..