Files
PaperClipAI/maps/feature-map/questions-and-approvals.md
T
DottaandPaperclip a61cf38106 docs: keep the feature map focused on substantial features (#18767)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The feature map describes product capabilities and user journeys.
> - Small fixes and test changes have added long notes to that map.
> - These notes make substantial features harder to find.
> - This pull request removes those additions from the last week's
changes and sets a clear rule for future additions.
> - The benefit is a smaller map with stable capability IDs and accurate
entry points.

## Linked Issues or Issue Description

**Issue type**

Unclear or confusing documentation.

**Where is the issue?**

`maps/feature-map/`, the map maintenance instructions, and repository
rules.

**What's wrong?**

Between October 27 and November 3, 2026, 115 commits changed the feature
map. Many additions describe bug fixes, performance details, small UI
changes, or new tests. They do not introduce substantial product
features. The old synchronization instructions also encouraged a map
edit for every behavior change.

**Suggested fix**

Add a rule that requires a substantial new feature before expanding the
map. Remove minor-update notes. Keep genuine feature additions and
minimal corrections to existing instructions. The review covers master
through `b22ef22d56`; it does not revert application code. Conflict
resolution preserves later map changes from master outside that audit
snapshot.

Searched open GitHub PRs and issues for related feature-map work. No
duplicate cleanup was found. Substantial feature additions retained here
include Coordinator (#17983), the agent YAML editor (#18036), document
image galleries (#18157), remote workspace storage (#18403), native Kimi
(#18391), proactive chat messages (#18374), and the Sentry receiver
added in #18714.

## What Changed

- Add `rules/feature-map-scope.mdc` and register its `maps/**` scope
with Greptile.
- Align `AGENTS.md` and the shared map contract with that rule. Routine
fixes and test changes no longer require incidental map edits.
- Remove 755 net lines from 23 feature recipes. Preserve all 35 areas
and 192 capability IDs.
- Keep substantial features and the corrections needed for current
navigation, provider availability, and access boundaries.

Examples from the reviewed changes:

| Removed or shortened addition | Why it does not need a feature-map
expansion |
| --- | --- |
| Rounded composer image thumbnails (#18689) | Small UI change within
existing task creation. |
| Connection profile reads and review-count queries (#18687, #18688) |
Performance details within existing app permissions. |
| Warm-session, Retry, export-capacity, and tool-wait cases | Regression
details for existing execution and recovery. |
| New task-search, project-context, document-persistence, and routine
test journeys | Test additions for existing capabilities. The tests
remain in place. |
| New task button placement (#18703) | Another entry to an existing task
form. |
| Local browser verification notes | Run evidence belongs in the PR or
test report. |

## Verification

- `node scripts/check-maps.mjs` passes: 35 areas, 192 capability IDs,
valid references and contract fields.
- `node scripts/storybook-catalog.mjs` passes: 328 files and 3,068
stories. Generated indexes remain ignored.
- Compared capability keys and navigation metadata in every edited
recipe with the original source. All are unchanged.
- Checked rule frontmatter, Greptile registration, representative scope
matches, and `git diff --check`.
- `pnpm -r typecheck` and `pnpm build` pass on
`9a60eef8eb8da9bc7c3a02203c79bec12e8c8b6b`. The final
`a0801e8a939494ecde3739097a80258917428e94` commit only corrects two
lines in the plugin-panel recipe; map and catalog checks pass again.
- Greptile reviewed the final `a0801e8a939494ecde3739097a80258917428e94`
head at 5/5 with no findings. The earlier review found one inaccurate
phrase about unavailable plugin panels. The hook confirms that readiness
gates automatic opening, while declared panels remain selectable. The
final documentation commit corrects that phrase and the thread is
resolved. Paperclip's refreshed review is advisory and remains queued.
- The earlier CI run failed two assertions: [server
4/12](https://github.com/paperclipai/paperclip/actions/runs/41634761842/job/125914173960)
counted three Anthropic identity calls instead of two in
`connection-management.integration.test.ts`; [chat
1/3](https://github.com/paperclipai/paperclip/actions/runs/41634761842/job/125914174257)
observed zero publications instead of one in the same-principal
endpoint-settlement case. Both exact tests pass locally on the rebased
head. This PR changes neither their source nor their expectations. These
failed results remain historical evidence.
- Final-head CI passed server 4/12 and all other suites except the first
[chat 1/3
attempt](https://github.com/paperclipai/paperclip/actions/runs/41637834618/job/125925926131),
which repeated the same zero-publication assertion. The browser gate
passed. The single failed-job retry was accepted for this unchanged head
in [workflow attempt
2](https://github.com/paperclipai/paperclip/actions/runs/41637834618/attempts/2).
[Chat 1/3 passed on that
retry](https://github.com/paperclipai/paperclip/actions/runs/41637834618/job/125933199635),
and the aggregate verification gate passed. Both required gates, `ci /
verify` and `ci / e2e`, are green on
`a0801e8a939494ecde3739097a80258917428e94`. The one retry allowance is
consumed.
- The first full local `pnpm test:run` attempt was interrupted before
completion so master could be rebased without changing source under
running tests. It is not a passing test result. Full current-head CI
remains required.
- No application code, tests, schemas, or lockfiles changed.

## Risks

- Low runtime risk. This change only edits documentation and review
guidance.
- Detailed regression instructions become less visible in the feature
map. Their tests and technical documentation remain available.
- Some additions mix a new feature with a small fix. Those blocks retain
the feature and shorten the incidental detail.

## Model Used

- OpenAI Codex, GPT-6 family, with reasoning, Git history inspection,
repository tools, and code execution. The session does not expose a more
specific model deployment ID or 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
#` / `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 — map, catalog,
capability-ID, and rule-scope checks; full Vitest limits are stated
above
- [x] I have added or updated tests where applicable — no new runtime
tests apply to this documentation change
- [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 07:16:37 -06:00

231 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
navigation: {"section":"Tasks and conversations","sectionOrder":20,"order":50}
---
# 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](../agent-access-map/questions-and-approvals.md).
## 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` — inspect the bounded server-redacted arguments and audit hash before approving once, always allowing the displayed scope, or declining;
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](./README.md#before-driving-a-journey).
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](../agent-access-map/questions-and-approvals.md). 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 with a proposal longer than its preview. Open Arguments and audit hash on task and Apps review surfaces and inspect the tail before a decision. 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](../../ui/src/components/IssueThreadInteractionCard.test.tsx),
[paged task cards](../../ui/src/components/task-chat/TaskChatInteractionCard.test.tsx),
and [task thread](../../ui/src/components/TaskChatThread.test.tsx) cover form,
receipt, and dismissal behavior. [Resolution routes](../../server/src/__tests__/issue-thread-interaction-routes.test.ts)
and [response delivery](../../server/src/__tests__/question-response-delivery.test.ts)
cover authority and durable continuation. Run a targeted set with:
```sh
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](../../ui/src/components/TaskChatThread.test.tsx)
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](../../ui/src/components/AttentionInteractionResolver.test.tsx)
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](../../server/src/__tests__/approvals-service.test.ts)
and [idempotency routes](../../server/src/__tests__/approval-routes-idempotency.test.ts)
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](../../tests/e2e/connection-reviews.spec.ts) drives
task/queue synchronization, approve, decline, remembered permission, provider
failure, and restart with a scripted process agent and local MCP provider:
```sh
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](../../doc/connections/TASK-REVIEWS.md#verification-workflows).
### `skill-test`
Automated: [read-only interaction contract](../../server/src/__tests__/issue-thread-interaction-routes.test.ts)
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](../../server/src/services/chat-question-forms.test.ts),
[Discord forms](../../server/src/services/chat-discord-question-forms.test.ts),
and [interaction publications](../../server/src/__tests__/chat-interaction-publications.test.ts)
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](../../server/src/services/chat-interaction-continuation.test.ts)
and [Slack card tests](../../server/src/services/chat-channels/slack/cards.test.ts).
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](./steering.md).
### Documentation scope: Formal governance approvals
Formal board decisions and signoff have recipes; every approval payload/type and actor/host error permutation is not enumerated.