## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Questions and review decisions must work in the conversation where a task started. > - Slack omitted question context and did not publish several review kinds. > - Some answers saved in Paperclip also lost their authorized continuation or their final Slack reply. > - A settled card and a successful run did not prove that the user received the result. > - This pull request preserves complete questions and follows the existing answer and delivery receipts through continuation. > - Users can read the request, submit an authorized decision, and receive the resumed task's result in the same conversation. ## Linked Issues or Issue Description Refs #17045 and #17218. **What happened?** Slack question cards could omit instructions and editable starting text. Checkbox reviews, item verdicts, task suggestions, and connection requests had no publication path. Complex question answers submitted in Paperclip could fail continuation authorization. Several review continuations completed without delivering their result to Slack. **Expected behavior** Show the actual question and context. Use native Slack controls when they preserve the form contract. Otherwise provide an explicit Paperclip review link. Persist one authorized response, resume through the existing delivery path, settle the card, and deliver the useful result to its originating conversation. **Steps to reproduce** 1. Start a task in Slack and ask a text or choice question with instructions and help text. 2. Submit native text and choice responses, then submit a complex form through Paperclip. 3. Accept a checklist, submit item decisions, select suggested tasks, or decline a connection request. 4. Inspect the saved answer, continuation run, original Slack card, and final Slack reply independently. ## What Changed - Preserve full prompts, context, descriptions, recommendations, help, and editable starting text. Use direct buttons for short choices, inline searchable selects for longer lists, and native checkboxes with explicit submission for multiple choices. - Add native custom-answer and validated-text modals, ordinary confirmation buttons, checklist decisions, per-item verdicts with reasons, suggested-task creation/dismissal, and connection decline. Keep governed approvals, permission grants, and forms that cannot be represented faithfully in the full Paperclip review surface. - Keep Slack-specific canonical-validation feedback in its owning platform module. Shared callbacks delegate without interpreting provider presentation. - Reuse the existing canonical interaction transactions, callback receipts, publication queue, and continuation delivery. Share ordinary confirmation handling across Telegram and Slack. Recheck current authorization and commit response receipts atomically. - Settle cards with the saved answer and remove stale controls. Ignore passive Slack link callbacks so opening a task does not display a false answer error. - Validate exact multi-select receipt mappings during native continuation. Recover automation-origin connection replies from their published prompt after validating the durable connection receipt. - Keep oversized multi-select handoffs free of unused native tokens, and retain the complete Paperclip form for 101–128 choices plus Other. Make the original-conversation audience explicit before submitting a Slack modal. - Add rollback, provider serialization, callback, continuation, and negative authorization regressions. Update the connector playbook and feature/access maps. No React or application UI changes are included. - Add a durable Q01–Q11 qualification index and provider coverage matrix. Require distinct functional, good-experience, and best-available-control assessments; real unanswered/answering/settled evidence; saved results, continuation and navigation proof; and retained failures. Mark other providers unaudited rather than assuming Slack parity. ## Verification Candidate: `e0017d446b1016a38d65382366cd1408cce33039`. The eleven-core-format live Slack gallery is pinned to `c3d458b2a06b660448940fd8cf33c5906f0058d5`; subsequent boundary fixes and the sharing notice have automated verification, not new live screenshots. - Real Slack UI testing covered all 11 formats: text, closed choice, long single select, multiple choices, choices with a custom answer, pattern-validated text, confirmation, checklist, item verdicts, suggested tasks, and connection requests. Each has unanswered/answering/answered screenshots as applicable, an inspected saved result, one continuation, and an individual experience review in the local HTML gallery. - The dedicated private QA app/channel used signed callbacks to the local candidate. A separately approved password-protected, read-only preview proved connection-review, suggested-task review, and created-task navigation. Anonymous access, writes, and credential routes were denied. No OAuth grant was attempted. - Real testing exposed and repaired a multi-select continuation failure and a misleading error on link-button clicks. Failed attempts remain in the evidence. The final navigation replay opened the exact pending connection request and declined it in Slack without granting access. Suggested-task creation produced the selected child with the correct parent and description. - Final review-fix verification: **32 form tests**, **28 provider/form-rendering tests**, **30 publication tests**, and **171 native continuation/authorization tests** passed. Earlier **3 atomic-resolution rollback**, **9 targeted callback/publication/Telegram**, and **28 review-continuation** cases passed. The final Slack/Teams modal subset also passed. The automation-origin connection cases, 101/128 custom-choice cases, and oversized multi-select continuation reproduced before their fixes and passed afterward; failing logs remain retained. These counts describe relevant runs, not a reliability percentage. - CI on `b5885b85fd` exposed a test fixture that assumed every Slack modal block was an input; the new sharing notice correctly renders a non-input block. The fixture now selects input blocks safely. The exact signed-modal correction/one-continuation test passed locally, together with 14 Slack form/modal tests. The failing CI log and its specific cause remain recorded. - `pnpm -r typecheck` and `pnpm build` passed. Server typechecking was repeated after the final source changes. Map and module-boundary checks and `git diff --check` passed. - The full `pnpm test:run` was attempted and stopped after repeated embedded PostgreSQL semaphore exhaustion on this host. Its 1,395-test chat suite found two stale native-control assertions; both were corrected and re-tested in a focused run. Focused database suites used separate disposable databases on existing local PostgreSQL. The full suite is not claimed green; new-head CI must complete before merge. - Final-head CI passed on `e0017d446b1016a38d65382366cd1408cce33039`: all test/build jobs and required `ci / verify` and `ci / e2e` gates are green ([run](https://github.com/paperclipai/paperclip/actions/runs/40115430194)). Greptile and Ponytail both reviewed this exact head at 5/5, the security scan passed, and all review threads are resolved. - All three QA app callbacks were restored to staging. Both temporary tunnels and local proxies were closed. The local endpoint was archived and its local credential copies removed. The candidate app was stopped. Limits: provider execution used a deterministic Claude protocol fixture, not an LLM. This is local real-provider UX proof, not deployed staging or broader Codie/Claude qualification. The public preview intentionally blocked ancillary artifact routes, so its destination pages could show a partial-history warning. The complete permission-grant flow and every oversized/mixed-form branch were not driven manually. Earlier fixture, test, and provider failures remain recorded. ## Risks - New reply routes require durable origin proof. Incorrect receipt matching could lose a reply or route it incorrectly. Tests cover missing, forged, mismatched, and revoked authority. - Governed forms keep their Paperclip resolution checks. This change does not grant new approval authority to Slack. - Existing completed review results can become deliverable through the repaired publication path without another provider run. - No schema, lockfile, workflow, public task-status model, or runtime-instruction change is included. This branch is not deployed. ## Model Used OpenAI Codex, GPT-6 family, with code execution and tool use. The exact backend model ID and context-window size are not exposed in this session. ## 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 linked existing issues or described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket id - [x] I have run focused 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 on the new head - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups on the new head - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
15 KiB
navigation
| navigation | ||||||
|---|---|---|---|---|---|---|
|
Questions and approvals
People answer an agent's questions and decide requests without losing the task's history. A question, plan confirmation, governance approval, and app-tool review can look similar but have different authority and continuation rules. Each decision must stay attached to its original request and survive reload.
Feature ID: questions-and-approvals.
Agent access: companion.
Sub-features
questions:questions-and-approvals/questions— single-choice, multiple-choice, custom, and free-text answers; paged forms retain answers until submission and show validation failures.dismiss-and-reopen:questions-and-approvals/dismiss-and-reopen— questions and composer requests (including completion reviews) remain in the feed after dismissal or a newer message; reopening restores the form without inventing an answer.confirmations:questions-and-approvals/confirmations— accept, decline, or request changes; stale, expired, resolved, and withdrawn requests cannot be acted on again.plan-review:questions-and-approvals/plan-review— inspect the requested plan revision before accepting or asking for changes. An ordinary planning task can proceed to execution; Agent Chat hands work to linked tasks and remains a conversation.audience:questions-and-approvals/audience— the current actor, company, named audience, and review policy govern resolution. A visible request is not necessarily actionable by that viewer.governance:questions-and-approvals/governance— pending/history views, approve/reject, revision request, and resubmission for formal board approvals.tool-review:questions-and-approvals/tool-review— approve once, always allow the displayed scope, or decline; decision status and provider execution outcome remain distinct.continuation:questions-and-approvals/continuation— one recorded response leads to the eligible waiting run or continuation; repeated clicks, reloads, and competing tabs do not repeat work.
How to get to it (user POV)
task-thread
Open a task from Tasks, search, a project, or its direct /issues/:issueId link.
Answer the question near the composer, or reopen its compact unanswered entry
in the history. Open the plan preview before using the confirmation controls.
Exercise both available task presentations when a change affects shared cards.
agent-chat
With Agent Chat enabled, choose Chat and an agent (/chats/:agentRef). Answer,
dismiss, or reopen requests in this persistent conversation. A plan handoff here
creates linked work rather than turning the conversation into implementation.
attention
Open Decisions (/decisions, including a saved queue) or an Inbox attention row.
Expand an actionable interaction inline; follow its task link to inspect context.
With combined Inbox/Tasks enabled, open the corresponding Tasks view instead.
board-approval
Open Approvals → Pending or All (/approvals/pending, /approvals/all). Use the
card action or open /approvals/:approvalId for details, comments, revision
request, and resubmission. These are formal approvals, not ordinary questions.
app-review
In a task, open Review request for an Ask first app call. The same request
appears in Apps → Review (/apps/review) and the connection's Review tab.
Use Approve & run, Always allow, or Decline on the surface under test.
skill-test
Open Skill Studio, run a skill test that produces an interaction, and inspect its output card. Skill-test authority is narrower than an ordinary company run.
external-channel
In a configured chat channel, answer a published question or confirmation as a linked sender. Open the associated Paperclip task to inspect the saved outcome. Channel-specific forms and identity linking require separate provider evidence.
Driving it
Preconditions: follow the baseline. Use separate disposable requests for accept, decline, and revision paths. Record the actor and request revision. Prepare a waiting question through a test agent; a component fixture alone cannot prove live response delivery.
Operation checkpoints
Use these checks alongside the entry-point recipes below and the operation records in the access companion. Record the actual actor, surface, saved result and denial separately. Source review and linked tests do not establish a live pass.
| Capability ID | Action and persisted result | Denial, race and retry checks |
|---|---|---|
questions-and-approvals/questions |
Create fixed-ID single/multiple/custom/text questions; move between pages, submit, and reload the saved answer and responder. | Reject missing/invalid answers without resolving. Competing answers settle once. Distinguish cancel, withdraw, historical Done-task answers, and local dismissal; historical answers must not restart work. |
questions-and-approvals/dismiss-and-reopen |
Dismiss questions, completion reviews, confirmations, choices, and item requests without deciding; reload and reopen from history. | Confirm the server request remains pending and a new ordinary comment does not answer it. Resolve in another tab and refresh the old form. Saved-request dismissals persist on the server and suppress repeated agent demands; drafts and raw runtime dismissals remain browser-local. Protected actions still require authorization. |
questions-and-approvals/confirmations |
Use separate accept, decline/change-request, checkbox subset, suggested-task selection, and partial item-verdict requests. Inspect the actual selected items and created task IDs. | Test invalid selections, child-without-parent selection, expiry, supersession, withdrawal, and repeated/conflicting decisions. Partial verdicts persist; skip must not start a continuation. |
questions-and-approvals/plan-review |
Open the exact requested plan revision; reject one request and accept another. Inspect saved revision, work mode, owner, and the resulting continuation. | Edit after requesting review and reject stale acceptance. Test finalization readiness and bound completion review separately. In Agent Chat, inspect the later project/task creation and its source-plan provenance; acceptance alone is not a completed handoff. |
questions-and-approvals/audience |
Repeat a request for a named person, named agent, human-only resolver, and independent reviewer. Inspect actionability and final attribution. | Test creator exclusion, wrong audience/company, private task, missing or cancelled run, and changed responsible-user access. A human comment used by an agent remains subject to that agent’s resolver authority. |
questions-and-approvals/governance |
Create and inspect a formal request, comment, request revision, resubmit, then approve or reject distinct requests. Reload history and linked task state. | Test board decision authority separately from agent request/comment/resubmit authority. A repeated decision cannot repeat activation. Current pending status, payload revision, and governed side effects must agree. |
questions-and-approvals/tool-review |
Invoke a harmless Ask first action, compare task and Apps review surfaces, then exercise Approve once, Always allow, and Decline separately. | No provider call before approval. Repeat decisions and compare invocation count. Change the tool definition, revoke access, or set Off before a decision. Record the approval decision and provider outcome independently. |
questions-and-approvals/continuation |
After answering, inspect the saved response, delivery receipt, eligible run, and useful result in the original task/thread. | Reload, race two tabs, and interrupt delivery after saving. Require one continuation without repeated external actions. Reassignment, Stop, pause, budget, and external-thread boundaries remain effective. |
task-thread
Automated: interaction cards, paged task cards, and task thread cover form, receipt, and dismissal behavior. Resolution routes and response delivery cover authority and durable continuation. Run a targeted set with:
pnpm exec vitest run ui/src/components/TaskChatThread.test.tsx server/src/__tests__/question-response-delivery.test.ts
Manual: answer a multi-page question, go back, edit, then submit. Reload and confirm the saved answers and one agent continuation. On a fresh request, dismiss, reload, reopen, and verify the draft. Send a new comment while a question remains unanswered; it must stay reopenable in history. Try a denied actor and a request already resolved in another tab; expect an explicit error or settled receipt, never a second decision. For plans, change the plan revision before trying the old approval, then review the current revision.
agent-chat
Automated: the task thread suite parameterizes unanswered-question history for conversation mode on and off. This proves component parity, not a model's plan handoff.
Manual: repeat dismissal, reload, reopening, and answer submission in Chat. Approve a plan and inspect the linked execution task and copied plan. The chat history remains and the conversation does not close as a completed task.
attention
Automated: attention resolver covers preparing-request refresh without accepting it. The resolution-route tests above cover the API, not every Decisions or Inbox navigation path.
Manual: open the same pending request in an attention row and task tab. Resolve from the row; both surfaces must settle after refresh. Check an empty queue, loading, permission denial, and a stale request. Repeat with combined Inbox/Tasks on when that surface is part of the change. Full navigation parity remains a manual coverage gap.
board-approval
Automated: approval service and idempotency routes cover persistence and duplicate decisions. They do not drive the approval pages.
Manual: create disposable formal approval requests; approve one from the list, reject another from details, and request revision on a third. Resubmit that third request and verify Pending/All and detail history after reload. Confirm the recorded decision and its governed effect, not just a success toast.
app-review
Automated: connection reviews drives task/queue synchronization, approve, decline, remembered permission, provider failure, and restart with a scripted process agent and local MCP provider:
pnpm exec playwright test -c tests/e2e/connection-reviews.config.ts
Manual: dismiss and reopen a review, decide it from each entry point using fresh requests, and inspect the continuation's useful result. Always allow must show its scope; a future action with changed arguments should obey the saved rule. Provider failure must remain an approved decision with a failed execution. Real provider and model checks follow Task reviews.
skill-test
Automated: read-only interaction contract checks that fetching interactions does not mutate them. Shared card suites cover rendering. Neither proves the complete Skill Studio host or its permission matrix.
Manual: run a skill test with a question, answer through its visible output, and inspect the test result. Attempt a governed action outside the test's scope; expect denial. The complete Skill Studio browser journey is not covered by the referenced unit tests.
external-channel
Automated: chat question forms, Discord forms, and interaction publications cover serialization and delivery logic with fixtures.
Free-text and multi-question cards show their title, prompts, help, and context. Slack modals retain instructions and editable starting text. Closed single-choice questions use buttons for up to five options and an inline searchable selector for six to 100. Multiple choices use checkboxes (up to ten) or a multiple selector, then explicit Submit. Custom choices combine direct buttons with an Other modal; pattern errors appear beside the native input. Ordinary confirmations use buttons; checklists preserve defaults and bounds; item verdicts use radio choices and reasons; suggested tasks use Create, selection, and Dismiss. Connection requests offer Review connection and native Not now, without granting access from Slack.
Governed approvals, unsupported mixed forms, attachments, and oversized requests retain the full Paperclip review path. Link clicks navigate without attempting an answer. Terminal edits preserve the submitted response in the same authorized conversation and remove stale controls. Inspect the saved interaction, exactly one continuation, and useful reply independently. See the continuation regressions and Slack card tests. Local real-Slack proof for eleven formats, including native validation and public link navigation, is recorded with PR #17255. It uses a deterministic protocol fixture and does not establish deployed staging or model reliability.
Manual: use a disposable provider conversation, answer as the linked sender, and check the task's persisted result and one continuation. Repeat from an unlinked or wrong sender and with an expired card. A browser answer does not qualify Slack, Discord, Telegram, email, or iMessage; record each as not run unless its actual provider journey was driven.
Gotchas
- Dismissing a question does not answer it. Dismissing an app review neither grants permission nor resumes the agent. Ordinary comments cannot approve it.
- A resolved request and a successful tool execution are separate facts.
- Do not reuse an accepted request to test rejection; use another request.
- Agent Chat and skill tests have distinct lifecycle/authority rules despite sharing UI. A watchdog cannot acquire board authority by resolving a card.
- An answer to an old question can queue behind a successor run; it does not automatically steer that run. See steering.
Documentation scope: Formal governance approvals
Formal board decisions and signoff have recipes; every approval payload/type and actor/host error permutation is not enumerated.