Files
PaperClipAI/maps/feature-map/questions-and-approvals.md
T
DottaandPaperclip 7d9b93aee2 docs: establish paired feature and agent access maps (#16025)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Contributors use the feature map to understand and verify product
capabilities.
> - Agents need APIs and usable entry points within their permission
boundaries.
> - Product recipes and agent access need separate records with shared
capability IDs.
> - This pull request establishes that contract and gives maintenance
ownership of both maps.
> - The benefit is repeatable access review without changing product
behavior or permissions.

## Linked Issues or Issue Description

Refs: #15983, which added the portable verification skills and updated
the feature map. This is its contract-only follow-up. Related: #15288
added the original feature map.

**Issue type**

Missing documentation and maintenance contract.

**Where is the issue?**

The product map, its missing agent access companions, and the
verification skills.

**What's wrong?**

There is no shared convention for API presence, agent entry points,
permission boundaries, access gaps, or evidence. An API declaration does
not prove that a permitted native or remote agent can use it.

**Suggested fix**

Keep the product and agent access maps as siblings under `maps/`. Reuse
capability IDs. Record representative source inventory separately from
operation review and live proof. Keep both maps aligned through the
maintenance skill.

## What Changed

- Move the existing product map to `maps/feature-map/`. Preserve its
recipes and Poteto format. Update relative links and add companion
links.
- Add `maps/agent-access-map/` with 35 area files and 171 matching
capability IDs. Seed representative API operations, agent paths,
policies and known gaps from the reviewed source inventory. Mark entries
as `baseline`, `source-only`, and live verification `not-run`.
- Define the shared contract in `maps/README.md`. Track API presence,
agent availability, policy, evidence and review depth separately.
Require operation enumeration before marking a broad capability
operation-reviewed.
- Extend `maintain-verification-skill` to reconcile both maps and
inspect actual route policy and production tool admission. Update
creation, verification, notices and contributor references to use the
shared contract.
- Add `scripts/check-maps.mjs` and ten regression tests. Check matching
areas/IDs, indexes, references, contract fields, API method/path
examples, justified exceptions and evidence-state consistency.
- Keep the coverage inventory unchanged. Preserve skill invocation
policies and both MIT license blocks. No product API, permission, UI,
runtime helper, migration, dependency or workflow changes.

## Verification

- Passed: `node scripts/check-maps.mjs` reports 35 paired areas and 171
matching capability IDs. All local map references resolve.
- Passed: `node --test scripts/check-maps.test.mjs` runs ten tests.
Fixtures cover missing companions, renamed/orphan/duplicate IDs, broken
references, missing operation fields, empty exceptions, missing API
examples, empty policy fields, and verified evidence without passed
verification.
- Passed: metadata validation for all three verification skills. Skill
and contributor links resolve. Invocation policies and both license
blocks are unchanged.
- Compared relocated recipes with current master. Contents differ only
in relative links and companion links. `coverage.json` is byte-for-byte
unchanged. Master's updated read-only interaction test reference is
retained.
- Passed: `git diff --check`. The branch starts from current master and
contains only this contract change.
- Repository-wide typecheck, tests and build were not run locally for
this documentation and Node structural-check scope. Live agent access
was not exercised. Those gaps are explicit in the baseline entries; the
structural check does not certify behavior. CI and automated review are
pending.

## Risks

- The companions are representative source baselines. They are not
complete operation inventories or passed agent journeys.
- The checker cannot establish actual permissions, native tool
admission, operation completeness or truthful live evidence. Maintenance
must inspect source and verify with the actual permitted agent context.
- External links to the old product-map directory may need updates.
Repository references have been updated.
- Existing access gaps and board/user restrictions remain recorded. This
contract does not change authority or implement missing paths.

## Model Used

OpenAI GPT-6 through Codex assisted with this change. The session does
not expose the exact serving model ID, configured context-window size,
or reasoning setting. Capabilities used: source analysis, file edits,
shell commands, and structural regression tests.

## 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

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-12 14:52:28 -05:00

185 lines
9.1 KiB
Markdown

# 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.
Agent access: [companion](../agent-access-map/questions-and-approvals.md).
## Sub-features
- `questions`: single-choice, multiple-choice, custom, and free-text answers;
paged forms retain answers until submission and show validation failures.
- `dismiss-and-reopen`: unanswered questions remain in the feed after dismissal
or a newer message; reopening restores the form without inventing an answer.
- `confirmations`: accept, decline, or request changes; stale, expired, resolved,
and withdrawn requests cannot be acted on again.
- `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`: the current actor, company, named audience, and review policy govern
resolution. A visible request is not necessarily actionable by that viewer.
- `governance`: pending/history views, approve/reject, revision request, and
resubmission for formal board approvals.
- `tool-review`: approve once, always allow the displayed scope, or decline;
decision status and provider execution outcome remain distinct.
- `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.
### `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.
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).