Files
PaperClipAI/maps/agent-access-map/inbox-search.md
T
DottaandPaperclip aded4197e5 fix: make multiplayer task toasts personal (#16153)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for work.
> - A company can have several human users and shared agents.
> - Live task events currently produce toasts for any user who can read the task.
> - This makes unrelated work interrupt other users.
> - This pull request checks each user's task participation before it permits a toast.
> - Users receive relevant task notifications while company views continue to refresh.

## Linked Issues or Issue Description

**What happened?**

Company task activity and agent failures produce noisy toasts for users who have no involvement in the task.

**Expected behavior**

A task qualifies when the viewer created it, commented on it, is its assigned user, deliberately acted on it under the Mine rules, or has an explicit user mention in its description or a non-deleted comment. Viewing, agent ownership, responsible-user attribution, and parent participation alone do not qualify.

**Steps to reproduce**

1. Sign in as two users in the same company.
2. Have the second user create and update a task that does not involve the first user.
3. Observe a task toast in the first user's company view before this fix.

The duplicate PR search found no existing change for personal task-toast eligibility.

## What Changed

- Extract the existing Mine participation predicate without changing Mine behavior.
- Compute task eligibility from stored tasks, comments, and run associations after WebSocket access checks. Use an exact indexed comment-mention lookup with `LIMIT 1`.
- Add optional `toastEligible` metadata to each viewer's event copy. Keep it off the shared event bus.
- Require eligibility for live task activity and task-linked run errors. Suppress generic agent errors.
- Continue cache updates for quiet events. Refetch visible comments when authenticated events omit hydration details. Ignore stale socket callbacks after account or company changes.
- Document toast semantics and add feature-map and agent-access-map coverage.
- Add persisted-data, socket, UI, and authenticated browser regression coverage.

## Verification

- Final commit: `1dc4f9402c5883744738cfe236ad00fa0bb5ca4c`.
- All 55 current-head checks passed. Two Storybook checks were skipped because this change does not affect that coverage.
- Greptile approved this exact commit with 5/5. The security scan passed. Both review threads are resolved.
- Local `pnpm build`, `pnpm -r typecheck`, `pnpm check:token-gates`, and `node scripts/check-maps.mjs` passed.
- The focused socket/UI suite passed 123 tests. The persisted eligibility suite passed 9 tests, including long history, exact viewer matching, and regex escaping. The existing Mine service suite previously passed 140 tests.
- The named browser case `task toasts follow personal involvement in multiplayer` passed against the final commit in an isolated authenticated instance. It used two real sessions, real WebSocket delivery, and persisted tasks, edits, comments, and mentions. It verified quiet unrelated activity, viewing alone, first and historical mentions, own-action suppression, visible-task suppression, and live cache refresh.
- A prior-head server shard passed its single rerun after a fixture-cleanup deadlock. The final-head CI run passed without a rerun.
- The broad local run remained in progress when CI completed the full test suite. Local focused checks and CI provide the completed test evidence.

## Risks

- This intentionally reduces live notifications. A new client stays quiet against an older server that omits eligibility.
- Eligibility queries add work to live event delivery. A lookup failure suppresses the toast and still delivers the authorized event.
- Deleted mentions cease to qualify unless another participation rule applies. Historical comment authorship retains the existing Mine behavior.
- No database migration or notification-settings change is required.

## Model Used

OpenAI Codex with GPT-6 assisted with implementation, tests, documentation, and PR preparation. It used repository tools, shell commands, and browser automation. The runtime did not expose an exact backend revision 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
- [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-13 08:09:19 -05:00

6.1 KiB

Inbox, decisions, and search — agent access

Product map: Inbox, decisions, and search.

Review date: 2026-10-12. Source commit: f981fa3cc10cb8663a87dec60345fbff46d54d0a.

This is a source-reviewed baseline of representative operations and known gaps. Each capability needs operation-level review before its entire scope can be qualified. No live agent execution is claimed. Follow the map contract for format, permission checks, evidence and maintenance.

views

Review: baseline.

API: present — representative operation IDs:

  • GET /api/agents/me/inbox-lite.
  • GET /api/agents/me/inbox/mine.
  • GET /api/companies/{companyId}/issues.

Agent access: partial — REST / native call_api; MCP inbox/task search.

Policy: Own agent context; responsible-user inbox policy and explicit opt-in/grants for cross-user archive; decision policy separately. Automatic read cleanup does not count as user participation, including historical reader-attributed rows. Explicit user recovery decisions still count.

Evidence: source-only — implementation at the reviewed commit above. The cleanup exclusion in issue queries was reviewed at 89770ba707fb1ebd4cabd184eec2e7fee226e0c3. Issue service regressions cover membership, unread counts, timestamps, and retained audit rows.

Verification: not-run — exercise a listed permitted operation with actual agent credentials/run context; inspect its result and applicable persistence/attribution. Assert the relevant denied actor, owner, company or mode from Policy. Review the remaining operations before qualifying the whole capability. Seed a completed issue with only automatic read cleanup under a user identity: Mine and Unread must exclude it while activity history retains the row. An explicit recovery decision must still establish participation. No live user-inbox proof is claimed.

Gaps: Agent inbox and Mine support exist; board attention/unread/dismissal aggregation is a separate user-only surface.

triage

Review: baseline.

API: present — representative operation IDs:

  • POST /api/issues/{id}/inbox-archive.
  • DELETE /api/issues/{id}/inbox-archive.

Agent access: partial — REST / native call_api; existing garden-inbox workflow.

Policy: Own agent context; responsible-user inbox policy and explicit opt-in/grants for cross-user archive; decision policy separately.

Evidence: source-only — implementation at the reviewed commit above.

Verification: not-run — exercise a listed permitted operation with actual agent credentials/run context; inspect its result and applicable persistence/attribution. Assert the relevant denied actor, owner, company or mode from Policy. Review the remaining operations before qualifying the whole capability.

Gaps: Archive has an agent-aware responsible-user policy. Personal read/unread/dismissal does not have equivalent agent semantics everywhere.

decisions

Review: baseline.

API: present — representative operation IDs:

  • GET /api/companies/{companyId}/decision-queues.
  • GET /api/companies/{companyId}/decision-queues/{key}/items.

Agent access: partial — REST / native call_api under decision queue authorization.

Policy: Own agent context; responsible-user inbox policy and explicit opt-in/grants for cross-user archive; decision policy separately.

Evidence: source-only — implementation at the reviewed commit above.

Verification: not-run — exercise a listed permitted operation with actual agent credentials/run context; inspect its result and applicable persistence/attribution. Assert the relevant denied actor, owner, company or mode from Policy. Review the remaining operations before qualifying the whole capability.

Gaps: Queue browsing/managing may be allowed; governed approval decisions still have separate board/resolver boundaries.

Review: baseline.

API: present — representative operation IDs:

  • GET /api/companies/{companyId}/search.
  • GET /api/companies/{companyId}/issues.

Agent access: available — Native search_tasks for tasks; REST / native call_api for broader search.

Policy: Own agent context; responsible-user inbox policy and explicit opt-in/grants for cross-user archive; decision policy separately.

Evidence: source-only — implementation at the reviewed commit above.

Verification: not-run — exercise a listed permitted operation with actual agent credentials/run context; inspect its result and applicable persistence/attribution. Assert the relevant denied actor, owner, company or mode from Policy. Review the remaining operations before qualifying the whole capability.

Gaps: General company search and dedicated task search are different result sets; use the appropriate one.

toasts

Review: baseline.

API: present — GET /api/companies/{companyId}/events/ws (WebSocket upgrade); viewer-specific toastEligible metadata on authorized events. No notification mutation endpoint.

Agent access: not-applicable — toast presentation is a human browser concern. Agent-authenticated event subscriptions retain authorization but do not qualify for human toasts. Agent task mutations may notify participating humans.

Policy: Company membership and task/run read checks precede human participation checks. Creator, current human assignee, commenter, deliberate actor, or explicit user mention qualifies; agent ownership and responsible-user attribution alone do not. See toast semantics.

Evidence: source-only — socket projection and eligibility.

Verification: not-run — Connect two users and an agent; assert per-user eligibility without losing authorized cache updates. Deny revoked membership and private task access. Confirm relevance lookup failure yields a quiet authorized event.

Gaps: Browser recipes and regression sources are not deployment acceptance proof.