Files
PaperClipAI/server/src
DottaandClaude Opus 5.5 ba75b44c3c fix(chat): name the addressee on human-only card denials and list team requirements (#20245)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agent Chat answers a person's requests with a chat agent that reads
API results and the chat guidance
> - A decision card can be human-only and addressed to one person, and
the teams catalog lists ready-made teams with their requirements
> - When an agent tried to accept another person's card, the denial said
only "human-only", so the agent told the asker to accept the card
themselves
> - When an agent recommended a catalog team, the guidance asked only
for roles, so the agent left out the required skills
> - This pull request makes the denial name the addressee as the only
resolver, and asks agents to list a team's roles, required skills and
configuration inputs
> - The benefit is that chat answers send people to the right person and
show what a team needs before install

## Linked Issues or Issue Description

Refs #20206, #20220, #20239

**What happened**
Alex wrote "I approve Riley's request." in Agent Chat. The pending card
is human-only and addressed to Riley. The agent tried to record the
decision and got `403 interaction_human_only` with only "This
issue-thread interaction is human-only". The reply correctly said the
card stays pending, but it then told Alex to "accept or decline that
request" on the task. Alex cannot do that; only Riley can.
In a second chat, a person asked "Do we have a ready-made team for
building a website?". The agent recommended Product Engineering and its
roles. It did not name the four required skills that the catalog
returned in `requiredSkills`.

**Expected behavior**
When an agent cannot resolve a card that is addressed to another person,
the reply names that person as the only one who can resolve it. The
reply does not tell the asker to act on the card.
When an agent recommends a catalog team, the reply names the team's
roles, every required skill and every configuration input. It says that
a catalog listing does not mean the accounts are configured.

**Steps to reproduce**
1. As user Alex, create a `request_confirmation` card with
`resolverPolicy: "human_only"` and `addresseeUserId` set to user Riley
on Alex's chat task.
2. In that chat, write "I approve Riley's request."
3. Read the agent run. `resolve-from-comment` returns 403
`interaction_human_only` without the addressee. The reply tells Alex to
accept or decline the card.
4. In a new chat, ask "Do we have a ready-made team for building a
website?".
5. Read the reply. It names Product Engineering and its roles, but not
its required skills.

## What Changed

- `server/src/services/issue-thread-interaction-resolution.ts`: when an
agent is denied on a human-only card that is addressed to a person other
than the verified replying user, the denial says the card is addressed
to that person, that only they can accept or decline it, that the denial
is final, and that the agent must not ask the asker to act on the card.
The details include `addresseeUserId`. Cards without an addressee keep
the old message.
- `server/src/routes/issues.ts`: the route adds the addressee's display
name to that denial (`details.addresseeName` and the message). If the
name lookup fails, the generic addressee text stays.
- `server/src/services/agent-conversations.ts`: the teams catalog
paragraph asks agents to name a recommended team's roles (`agentSlugs`),
every required skill (`requiredSkills`, by ref) and every configuration
input (`envInputs`), and to say that a listing does not mean accounts
are configured.
- Tests: evaluator unit tests, a route-level test for the named denial,
and a directive assertion.

## Verification

- `cd server && npx vitest run
src/services/issue-thread-interaction-resolution.test.ts
src/__tests__/agent-conversations.test.ts
src/__tests__/issue-thread-interaction-routes.test.ts
src/__tests__/confirmation-comment-resolution.test.ts`: 4 files, all
pass.
- `tsc --noEmit -p server/tsconfig.json`: passes.
- The change is cherry-picked onto the eval branch
`chat-eval/case-reply-completeness`. The live Runner E2E cells
`questions-and-approvals.wrong-reviewer` and `teams.find-team` run
there.

## Risks

- Low risk. The resolver decision does not change: the same requests are
allowed and denied. Only the denial text and details change for agents
on addressed human-only cards.
- The denial reads one user row for the display name. A failed read
falls back to the generic text.
- The chat directive is slightly longer, so each chat prompt uses a few
more tokens.

## Model Used

- Anthropic Claude Opus 5.5 (`claude-opus-5-5`), with 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>
2026-11-09 06:48:54 -06:00
..
…
…
…
…
…