Files
PaperClipAI/maps/agent-access-map
DottaandPaperclip 2cbca4ceb0 fix: retain channel tools across task continuations (#16806)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Chat channels give an agent tools for its assigned task.
> - Each later run must resolve the task and its accepted requester
again.
> - Some native runs store the task in a database column without the
older JSON fields.
> - Tool discovery read only the JSON fields. GitHub calls also required
a new inbound comment.
> - This pull request uses the durable task binding and accepted request
history.
> - Later runs retain their channel tools while current access checks
still apply.

## Linked Issues or Issue Description

**What happened?**

A GitHub task can find `begin_review` on its first run, then receive an
empty tool list on a later native run. If discovery is repaired alone, a
call can still fail because the later run has no new inbound comment.
Slack and voice tool access also read the older JSON task fields.

**Expected behavior**

A later run for the same task can find and call its assigned channel
tools. The current requester, task, company, agent, endpoint, and access
rules must still allow the call. Revoked access must fail.

**Steps to reproduce**

1. Start a GitHub task and accept its linked requester.
2. Confirm that the runtime can find `begin_review`.
3. Start a later native run with `nativeIssueId`, accepted parent
identity, and no JSON task ID or new wake comment.
4. Search for `begin_review` again. Before this change, the search
returns an empty list.
5. Repair discovery alone and call `read_pull_request`. Before the
request-history fix, the call fails with no active conversation
capability.

**Paperclip version or commit**

Reproduced in source tests before this patch. The branch includes master
at `fa50cab5685b9cdbb26ad9c610cc5b6c373d3ff4`.

**Additional context**

This is a core run-binding bug. The tests use PostgreSQL and synthetic
provider responses. They do not send live reviews, Slack messages, or
phone calls.

## What Changed

- Resolve run task IDs from durable columns, with legacy JSON fields as
a fallback.
- Use the same binding in the gateway, access policy, identity service,
and channel runtime preparation.
- Recover accepted channel request history across later runs. Keep
company, task, agent, and requester boundaries.
- Recover older wake sources through verified parent runs, including
after same-user board follow-ups. Clear the board message’s own legacy
wake fallback. Keep cycle checks without a fixed limit on valid task
history.
- Retain the GitHub origin after a board comment from the same accepted
user. Skip GitHub origin lookup results from other providers.
- Keep ordinary board tools available when the requester changes. Accept
legacy user comments without an author-type field. Still reject explicit
malformed task IDs.
- Prevent a later failure reply from replacing an earlier final GitHub
answer. Recheck this rule under the publication lease.
- Rotate the native tool contract to replace retained sessions with an
older tool list.
- Add continuation, publication, revocation, and boundary tests. Update
the access and feature maps.

## Verification

- Red: the later GitHub assigned-tool search returned an empty list
before the binding fix.
- Red: the later GitHub read failed with no active conversation
capability before the request-history fix.
- Green: runtime MCP discovery, GitHub read/begin/submit review, and
response publication pass for monitor and same-user board continuations.
- Green: Slack history, retained access controls, revocation, and voice
gateway continuation pass.
- Green: 35 channel, failure-publication, legacy-origin, long-history,
and provenance tests pass. Both review findings had failing tests before
their fixes.
- Green: 107 gateway, operation-credential, identity, and provenance
tests pass. These cover both first-run CI failures without changing
their tests.
- Green: 122 runtime, discovery-policy, and native-session tests pass; 2
unrelated tests are skipped.
- Map checks and whitespace checks pass.
- Updated to master in `cfcaba22628772d7fe1fb32b57ff7031c7072781`. The
sole conflict was two tests added at the same location. Both the
continuation test and the publication 403/401 test are retained.
- Current local verification: all 179 gateway, credential,
requester-identity, access-policy, runtime-context, and session-resume
tests passed. Repository typecheck and build passed. Map and whitespace
checks passed.
- The new review regression first returned no source for a same-user
board follow-up over legacy wake metadata. After the repair, all 27
provenance and channel cases passed. The combined GitHub
discovery/read/begin/submit path and revoked access are covered.
- The broader local channel run passed 176 cases and failed four
timing/setup cases: a 15-second Slack authorization timeout,
webhook-verification polling, a Slack acknowledgement deadline, and
Discord setup polling. All four passed in isolation without source,
assertion, or deadline changes. The earlier failure record is retained;
the exact load/order cause is not established. Full CI must pass on the
latest commit.
- Current head: `7b9a08dcbc7b8140b589742f136944270b0496bb`. Repository
typecheck and build pass on this commit. Greptile completed on this
exact commit with 5/5; all four review threads are resolved. The
final-head [CI
run](https://github.com/paperclipai/paperclip/actions/runs/39278921653)
passed: 55 checks passed and 2 intentionally skipped, with no failures
or pending checks. This includes the full sharded test matrix, browser
tests, typecheck, build, and Runner verification. Results were delayed
during the [GitHub Actions
incident](https://www.githubstatus.com/incidents/8tzbpcnl75jp). An
additional unsharded local full test run has not completed; the
completed full-suite evidence is CI.
- Earlier verification: the first PR commit failed two server suites.
Those failures were fixed and verified before this update. The original
4 GiB sandbox could not complete full local typechecking or tests; the
current checkout completed typechecking and build. The full test suite
runs through the CI shards. No full local test-suite pass or live
provider delivery is claimed.

## Risks

- Request history can restore the wrong authority if its scope is too
broad. The resolver checks each accepted parent against the task,
company, agent, and requester. Tests cover invalid and cyclic history.
- The native contract change starts a new provider session for older
contracts.
- No database migration or public API schema changes are required. Each
tool call still checks live access.

## Model Used

- OpenAI Codex, GPT-6 family. The runtime does not expose the exact
deployment model ID or context-window size. The agent used reasoning,
repository tools, code edits, and local test 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
- [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-10-19 11:20:39 -05:00
..

Paperclip agent access map

This map accompanies the feature map. It records APIs, agent entry points, permission boundaries and verification for the same capability IDs. The shared contract defines the format and maintenance rules.

Browse access contracts

The same-named feature recipes define navigation and capability IDs. Run node scripts/storybook-catalog.mjs for the generated maps/generated/agent-access-map.md index, or browse the published feature guide. Add or update the affected companion; there is no central registration or count.

Existing baseline source references describe the original inspection, not current verification. Record new executed evidence in the PR, issue, or CI artifact with its revision and scope. Do not refresh unrelated headers as bookkeeping.

Using an entry

Read its Policy and Gaps before selecting an agent path. Native fallback, legacy REST/CLI, stdio MCP and a personal assistant connection can have different authority and availability. Use a real admitted production binding; a scenario declaration is not an installed tool. A restricted entry records current enforcement and leaves any unresolved delegation decision visible.

For API catalog disagreements, follow the route/service authorization and record discovery drift. For not-applicable, retain the concrete exception and local path. Split shared business operations from client-only presentation.

Use maintain-verification-skill to reconcile changed source and both maps. Use verify-paperclip and existing API/runner/MCP fixtures to collect the permitted-agent and denial evidence; report blocked/not-run coverage honestly. Run node scripts/check-maps.mjs after editing. The structural check does not certify permissions, API catalog coverage, tool admission or live behavior.

Native REST transport

The call_api parity change reconciles affected baselines against 58e16dbddfc9c8d0cf60867f9d9847f0feda055b and the changes in this PR. Ordinary REST operations use the same route authorization as legacy agent REST. Dedicated tools remain optional for those operations; protocol endpoints still need their existing clients. Board-only routes remain restricted for agent identity.

Native search_api / call_api requires operator rollout admission, a running authorized native run, current task assignment and execution-run binding, company and budget authority, task privacy, and a permitted work mode. Ask and Plan retain mutation restrictions, and runs retain their admitted JWT scope during restart recovery even when task mode changes. A waiting agent does not gain independent native control just because a REST route exists.

Credential-bearing replies, including company exports and their legacy alias, stay inline under a 10 MiB limit and use encrypted mutation receipts. Other saved API snapshots are limited to the issuing actor and responsible user, plus authorized administrators. Artifact uploads enforce the same access checks as downloads; private snapshots are excluded from company exports and public company logos. Explicit deliverables use the existing sharing path. Native event history, checkpoints and completion records omit API bodies while preserving receipt metadata and replay digests. Restored webhook secrets use the same encrypted receipt and inline response policy as newly created webhook secrets. Task image access requires the company boundary and the task permission; skill-test and low-trust agents do not need company-wide browsing authority. Completion replay applies the same idempotent projection to stored and expected payloads; the run-log guide describes its fields.

Sources: API client, catalog, native authority, credential storage classification, snapshot access, and history redaction. The affected entries remain baseline and source-only; this reconciliation does not certify every operation. Targeted real-route proof lives in the API integration suite, including owned routines, skill tests, scoped secrets, proposals and private export replay.