mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-09 16:02:36 +01:00
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - New users start with an onboarding first task. It has an opening question card and, after "Interview me", an interview question card. > - With the coordinator chat enabled, the agent's chat with the user mirrors pending questions from that agent's direct tasks. The onboarding task is a direct task. > - A tester moved onboarding from the task into the chat. The agent asked its interview in the chat. The chat then showed the chat card and the mirrored onboarding-task card. Both were answerable. > - This pull request expires the agent's pending onboarding-task questions when the agent asks a question in its chat with that user. > - The benefit is one interview card, answerable once, wherever onboarding runs. ## Linked Issues or Issue Description **What happened?** Onboarding testing on Paperclip Cloud staging (Codex API path). The steps were: enable the experimental chat and coordinator features, start the "Interview me" onboarding task, switch to the agent chat, and ask the chat to run the onboarding there. The chat agent started the interview, and a duplicate question card appeared. **Root cause** `conversationDecisionReceiptsService.listPendingQuestions` projects pending questions from direct tasks (created by the chat user, assigned to the chat agent) into the chat. The onboarding first task matches. The PAP-437 sibling-supersede rule in `issueThreadInteractionService.create` only works on the same issue, and it is off for chat questions. So the task's pending interview card and the new chat card both stayed pending and visible in the chat. **Expected behavior** One interview question card in the chat, answerable once. **Steps to reproduce** 1. Enable the experimental Agent Chat and coordinator features. 2. Create the onboarding first task and choose "Interview me" on its opening card. 3. Open the chat with the same agent and ask it to run the onboarding there instead of in the task. 4. The agent asks its interview in the chat. The chat shows two pending question cards: its own card and the mirrored onboarding-task card. **Paperclip version or commit** `master` at819420a60a(Paperclip Cloud staging build at the time of the test). **Deployment mode** Paperclip Cloud (staging). The same logic runs in self-hosted mode. ## What Changed - `server/src/services/issue-thread-interactions.ts`: when the chat agent creates an `ask_user_questions` card in its chat with a user, the server expires that agent's pending `ask_user_questions` cards on the onboarding first task that the same user created and assigned to the agent. The result is the existing `superseded_by_newer_interaction` shape and points at the chat card. Pending chat publications for those cards are cancelled and terminal publications are queued, the same as the existing sibling supersede. - The rule does not change questions on other direct tasks, handoff tasks, or other chats. Confirmations and plan approvals on the onboarding task are not changed. - `server/src/__tests__/coordinator-handoff.test.ts`: a new red/green test for the reported flow, and a control test that an ordinary direct-task question stays pending when the agent asks something else in chat. - `server/src/onboarding-assets/first-task/README.md`: one paragraph that documents the behavior. ## Verification Red on `master` (819420a60a) with only the new tests added: ``` $ cd server && npx vitest run src/__tests__/coordinator-handoff.test.ts -t "onboarding interview|ordinary direct task" × moves a pending onboarding interview into the agent chat instead of showing two question cards AssertionError: expected [ …(2) ] to deeply equal [ Array(1) ] [ "26b1e6ae-e1e5-4c26-8475-ad7ad93a7754", + "2364fd68-a40f-42be-854d-89210bfc5811", ] ❯ src/__tests__/coordinator-handoff.test.ts:231:53 Tests 1 failed | 1 passed | 23 skipped (25) ``` The chat showed its own interview card and the mirrored onboarding-task interview card. Green after the fix: ``` $ cd server && npx vitest run src/__tests__/coordinator-handoff.test.ts Test Files 1 passed (1) Tests 25 passed (25) ``` Neighbouring suites: ``` $ npx vitest run src/__tests__/issue-thread-interactions-service.test.ts src/__tests__/issue-onboarding-first-task-routes.test.ts src/__tests__/chat-interaction-publications.test.ts src/__tests__/coordinator-handoff.test.ts Test Files 4 passed (4) Tests 183 passed (183) ``` `tsc --noEmit -p server` shows no errors in the changed files. Other errors in that local run come from the unbuilt `@paperclipai/paperclip-runner` package. CI typecheck covers the full build. Not done: a live browser repro. Staging has no Codex company and no agent chat with this flow. The evidence is the tester's notes and the service-level test. ## Risks - If a user ignores the onboarding card and the agent asks an unrelated question in its chat, the onboarding task's pending question card expires. The onboarding task stays open, and a message on the task still wakes the agent. The chat already showed both cards to that user, so this keeps one live ask from the agent. - Race: if the onboarding task run posts its interview card after the chat card, both stay pending. Agent Chat questions are intentionally not expired by other cards, so this PR does not reverse the rule. - No schema, API, or UI change. ## Model Used - Claude Opus 5.5 (`claude-opus-5-5`), Anthropic, via Claude Code with tool use and code execution. ## 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>