## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents can submit suggestions and complaints while they work. > - Operators currently need database access to read those messages. > - That makes it hard to find feedback from one agent or share a specific message. > - This pull request adds a standard Commentary tab in Audit. > - Operators can filter messages, browse 50 at a time, and share links to full message dialogs. ## Linked Issues or Issue Description Refs #15367, which added feedback storage and agent submission. The duplicate search found no open PR for a commentary reader. **Subsystem affected** Server, shared API contracts, and the board UI. **Problem or motivation** Agent suggestions and complaints are stored but have no board reader. Operators must query the database to inspect feedback. **Proposed solution** Add Commentary to Audit without an experimental toggle. Show previews, agent and message-type filters, text search, and 50-message pages. Opening a row updates the URL. A copied URL opens the full message with its agent, task, and run context. **Alternatives considered** Direct database queries remain useful for operators, but do not provide a normal product workflow. An experimental setting would add setup to a read-only audit page. **Roadmap alignment** This completes the operator view for the existing feedback feature. It supports human oversight and does not change agent execution or task ownership. ## What Changed - Add company-scoped, board-only list and detail endpoints with audit permission and source-task privacy checks. - Return bounded previews and counts. Fetch full bodies only when a message opens. - Add the Commentary tab, search, filters, 50-row pagination, and URL-based selection. Audit tab destinations work in both layouts, with a classic sidebar entry for Commentary. - Add production Storybook examples for populated, filtered, linked, long, paginated, empty, loading, failed, denied, mobile, and light states. - Update API documentation and the feature and agent access maps. ## Verification - Final head `abc4a251c14cfbfec007542214beec528f2b18bf`: 55 checks pass; two conditional Storybook checks are skipped. The PR workflow is successful. Greptile is 5/5 with all findings resolved. - Focused database, HTTP, submission, OpenAPI, and UI regression tests cover company isolation, task privacy, filter bounds, 50-row pagination, and copied message links. - Browser Storybook journeys cover row opening, direct links, combined filters, search, and pagination. Storybook uses synthetic API fixtures; database authorization is tested separately. - Token gates, feature maps, and Storybook catalog validation pass. - `pnpm -r typecheck`, `pnpm build`, and `pnpm build-storybook` pass on the rebased branch. All 80 focused tests and all 37 Audit tests pass, including the real App route table in both layouts, task grant/revocation through HTTP, deleted-task privacy, and URL UI regressions. The full suite passes in the parallel PR CI matrix. The local serial full-suite run was stopped before completion after checking the recorded 94-minute serial duration. Local focused tests, workspace typecheck, production build, and final server/UI checks pass. - The linked-message Storybook test initially asserted against the loading dialog. It now waits for the message body; both direct-link and row-open journeys pass. - Native and legacy deleted-task privacy regressions failed before the fix and pass afterward. The reader checks the run task binding after the task foreign key clears. - A rapid search-then-agent-filter browser regression reproduced the search overwriting the selected agent. The pending search now restarts when URL filters change. The same browser test passes with both filters applied. - CI found two existing AuditHub assertions that still expected five tabs. They now assert the six-tab model and selected-company Commentary rendering. All 37 Audit tests pass. All other test and build jobs passed before this test-only correction. - The [agent-chat attachment browser test](https://github.com/paperclipai/paperclip/actions/runs/39307881171/job/118250189664) timed out waiting for an attachment preview. The [same shard passed on the prior head](https://github.com/paperclipai/paperclip/actions/runs/39306658703/job/118245498343) with identical application code; the intervening change only updates AuditHub unit tests. The single retry passed on the same head. The precise cause of the earlier failure remains unconfirmed. ## Risks - Commentary may contain sensitive task context. The reader requires board access and audit permission, and filters source-task visibility before returning previews, counts, or full bodies. - Text search scans stored message bodies. Pages are bounded and full bodies are fetched on demand. - Offset pagination can shift if new messages arrive while paging. Ordering uses timestamp and ID for stable ties. - No database migration or agent submission behavior changes are required. ## Model Used - OpenAI Codex, GPT-6 family, with reasoning, tool use, browser interaction, and code execution. 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 (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>
8.2 KiB
Dashboards, activity, and audit trails — agent access
Product map: Dashboards, activity, and audit trails.
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.
overview
Review: baseline.
API: present — representative operation IDs:
GET /api/companies/{companyId}/dashboard.
Agent access: available — REST / native call_api / CLI dashboard.
Policy: Same company plus visibility/audit/cost/run permissions where the route requires them.
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: Dashboard data is accessible; live-work rendering and event streaming are separate surfaces.
activity
Review: baseline.
API: present — representative operation IDs:
GET /api/companies/{companyId}/activity.GET /api/issues/{id}/activity(UUID or issue identifier).
Agent access: partial — REST / native call_api / CLI activity for company
activity. Sandbox agents can use GET issue activity through the default
callback bridge.
The bridge still rejects company activity and company audit routes.
Policy: Company activity requires same-company access and company_scope:read,
with issue visibility filtering. Issue activity requires same-company resource
access and issue:read for the resolved issue. The sandbox transport does not
replace those controller checks or permit activity writes.
Evidence: source-only — activity routes,
agent authorization tests,
and bridge tests.
Issue activity transport reviewed at 89770ba707fb1ebd4cabd184eec2e7fee226e0c3;
other operations retain the baseline source review above.
Verification: not-run — no live agent-credential proof. Local route and bridge
regressions pass: permitted agent issue read, denied company/resource scope,
denied writes, extra path segments, and company audit routes. With a real
sandbox agent, read an authorized issue's activity, then verify denial for an
inaccessible issue, another company, and company-wide audit.
Gaps: Audit export and raw activity creation have extra restrictions; do not equate them with issue activity reading. Live sandbox access remains unverified.
runs
Review: baseline.
API: present — representative operation IDs:
GET /api/companies/{companyId}/heartbeat-runs.GET /api/companies/{companyId}/live-runs.GET /api/heartbeat-runs/{runId}.GET /api/heartbeat-runs/{runId}/events.GET /api/heartbeat-runs/{runId}/log.GET /api/heartbeat-runs/{runId}/workspace-operations.GET /api/heartbeat-runs/{runId}/issues.GET /api/issues/{id}/runs.GET /api/issues/{id}/recovery-actions.
Agent access: available — REST / native call_api / CLI run. Sandbox agents can
use these diagnostic GET paths through the default queue and HTTP/2
callback bridge.
Use the injected run credential; see the bounded read workflow.
Policy: Same-company and company_scope:read checks apply to company run
inventory. Run content requires run/task visibility; private run list entries
may be redacted stubs. Task run/recovery reads require issue:read. Run-linked
tasks also pass the caller's task-read SQL predicate individually, including
activity links and the original task. Existing credential redaction remains.
Bridge admission grants no cancellation, retry, recovery resolution or
provider-trace administration authority.
Evidence: source-only — scoped review of f10210990a3c9cad1a4359318388f237de3169dd:
run routes,
task links,
task filtering,
bridge regressions,
HTTP/2 transport regressions,
and private-run regressions.
Verification: not-run for a deployed sandbox agent with these new routes.
Isolated regressions cover admitted GETs, denied writes/extra segments, query
forwarding, controller denials, private run stubs, and mixed public/private task
links. They do not qualify a live run. After deployment, use a real agent run to
read an authorized failure and assert denial/redaction for another company,
private tasks and restricted key modes. Do not count a skipped database suite
as successful verification.
Gaps: Telemetry/run visibility is checked independently from seeing the source task. Company heartbeat history defaults to 200 rows and caps explicit limits at 1,000 in both the route and service. The response remains an array. Scope, visibility, and secret redaction checks apply to the bounded result set. Live updated-bridge admission and useful incident diagnosis remain unverified.
routine-audit
Review: baseline.
API: present — representative operation IDs:
GET /api/routines/{id}/runs.
Agent access: available — REST / native call_api / CLI routine runs.
Policy: Same company plus visibility/audit/cost/run permissions where the route requires them.
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: Routine execution history is distinct from configuration revisions and scheduling changes.
timeline
Review: baseline.
API: present — representative operation IDs:
GET /api/companies/{companyId}/timeline.
Agent access: available — REST / native call_api.
Policy: Same company plus visibility/audit/cost/run permissions where the route requires them.
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: API exists; no dedicated timeline tool is necessary for this requirement.
agent-commentary
Review: baseline.
API: present — GET /api/companies/{companyId}/agent-commentary and
GET /api/companies/{companyId}/agent-commentary/{id}.
Agent access: restricted — the browsing API is board-only. Agent submission
continues through the existing POST and native submit tools.
Policy: Company membership, audit:view_agent_actions, and source-task visibility. Counts and previews
use the same visibility predicate as full messages; cross-company IDs return 404.
Feedback stays hidden after source-task deletion, even when its task foreign key clears.
Evidence: source-only — routes and
reader.
Verification: not-run for a deployed instance. Test list/detail denials with
agent credentials, another company, and an unreadable task.
Gaps: Storybook simulates the API and does not qualify deployed authorization.