## Thinking Path > - Paperclip lets people inspect and manage their agents’ work. > - The timeline must report canonical ownership history, and OpenCode tool failures need bounded diagnostics. > - The measured candidate also had independently reproduced question-navigation and oracle defects. > - This change promotes the reviewed production fixes and pins one immutable, qualified source composition. > - Original queries, model, counts, clocks, privacy controls and qualification holds remain intact. ## Linked Issues or Issue Description Refs #18775, #18777, #18779, #18711, #18713, #18718, #18699, #18798, #18799. **What happened?** The measured candidate predates merged native-runtime fixes and contains fixture defects. The timeline omitted recorded reassignment/removal history. Finish-input errors lacked a closed correlation and shape witness. **Expected behavior:** project recorded ownership transitions without inventing facts, distinguish successful native execution from failed verification steps, and retain content-free finish diagnostics. **Steps to reproduce:** repeat an unchanged assignee while editing another field; then reassign or unassign it. Only recorded transitions should appear. Invalid OpenCode finish input should produce a correlated rejection witness without values or schema text. Related #18699 adds gated company OTLP diagnostics. This change uses the existing local callback; it adds no exporter or capture policy. ## What Changed - Promote canonical timeline creation, reassignment and removal projection from #18777. Initial child ownership requires a recorded fresh-creation receipt; delegation requires a readable recorded parent. Unknown legacy facts fail closed. User actors/owners require active company membership; agent actors/targets must exist in that company. Spans, events and edges share that admission filter. Remove the introduced all-history absence query and use guarded indexed UUID lookups. - Add the shared/OpenAPI `unassigned` event kind, preserving newer main contracts and issue-route/service code through reviewed semantic joins. Existing UI consumers remain generic; no new visual marker is claimed. - Add bounded OpenCode finish diagnostics: schema digest, hashed call identity, closed shape enums and validation category. A throwing sink does not change admission or cancellation. - Pin immutable candidate `fd5e3b1e5a379524c0d1651ed8273e75ffd86541`, composed from combined #18777 source `b734393eff0d7ef85b7ad8abd556d2a66ca3a4e6` plus the reviewed MCP diagnostic delta. It preserves actually merged #18775 `97c07d149b5670088faf15317dcf603c75e2af87` and #18779 `a352c057d475067b4fe67375f06785287dfbe0ce`, and merged runtime fixes #18711, #18713 and #18718. - Qualify narrative handling for adjacent repair/verification sentences, intervening native-failure wording, and negated repair objects. Questions, denials and hypotheticals retain their controls. Preserve Previous question beside the qualified Entity type import; separately restore the already-called `internalResultLink` goal helper binding. That import is a runtime fixture repair, not a type-only change. - Include the narrow older-baseline CI typecheck closure and causal heartbeat test observers in the candidate. All four default typecheck projects execute. Main already includes the protected upstream tooling and newer heartbeat fixture, so neither is overwritten with an older candidate file. - Preserve all 244 identities, original queries, model, native/human counts and clocks, including the explicit prior Studio accounting exception. The full catalog stays on its candidate branch; the 196/244 gate and historical SDK runtime holds remain. ## Verification The primary’s f478 retry repeated the real composer-hidden five-second assertion (1 failure,18 passes,1 skip). Investigation established a setup readiness gap: an outer route response can delay mounting the chat thread beyond the assertion. The successor adds the existing real-thread `aria-busy="false"` readiness barrier before the unchanged composer assertion. The original120-second scenario and digest, unread, source-link, history, and reply checks are unchanged. The full owning browser scenario passed naturally in10.2s and with its first real chat response held6000ms in12.0s. This synchronizes fixture setup; the underlying AWS late-mount latency remains unproved. **Current main gates passed:** exact head `823dab49fcd8470140c178771e5c0c6b78725e97` has [successful normal CI](https://github.com/paperclipai/paperclip/actions/runs/41724620555), including both required aggregates, fresh Greptile 5/5 and zero unresolved review threads. Paperclip Review is neutral with a completed substantive 5/5 and no actionable defect. The current optional Superagent Security Scan is neutral/inconclusive: Security Graph context retrieval returned HTTP503, so its assessment did not start. That result supplies no security PASS credit. The primary source PR retains its separate current-head gate before Root sequences normal protected merges. - Reviewed MCP controls: 130 on main and 129 on the older candidate. Meaningful parent comparisons failed before implementation/correlation correction. Controls cover actual offered schema identity, null/omitted admission, bounded rejection categories and throwing-sink cancellation. - Exact unchanged production postimages retain 63 Postgres/public-route controls, nine plan controls and the focused index-plan proof. Owner OpenAPI passes 32 controls; main’s newer contract passes 33. Earlier setup/sandbox failures remain recorded; unchanged database controls were not replayed. - Narrative owner controls pass 216, retaining all prior 207 controls. The independent peer passes 144 balanced cases; earlier 108 and 39-case matrices remain retained. Actual consumer parent failures reproduced the review findings before repair. - Main’s server NoEmit passed on its protected baseline; only two pin files changed afterward. The candidate’s prior full server and four-project checks passed. All server/package/script/root-lock inputs remain byte-identical; the changed Runner project’s guard passes on the current source. Compatibility driver controls pass 47 and six owning suites pass 82. The one explicitly reviewed Docker-only unit omission concerns an unimported image-build feature; all four intended project guards still execute. - Pin/adapter/contract controls pass 47. All 242 expanded declarations, the two legacy dispatch rows, and all 244 singleton private policies retain their authenticated identities. Descriptor, launcher and private-protocol bytes remain exact; declaration loading invoked zero fixture callbacks. - All 506 SDK input blobs match the meaningfully compiled `6abe5739` source vector. Prior real shared/SDK builds measured declaration/map changes and zero runtime-JavaScript changes; a compiled consumer accepts the new kind and rejects an unknown kind. The reviewed registry remains unchanged. Default source proof, 51 SDK controls, 20 custody controls and 16 UI consumer controls remain qualified; runtime/compiler/parser/Zod/canary pins and held runtime grades are unchanged. - The full Mac heartbeat run on prior observer source retained **58 passes / six failures in 802.78s**. Two nonassignee controls subsequently pass focused checks. Four late timeout causes remain unresolved locally; no flakiness/infrastructure cause or complete local pass is claimed. [Actual AWS CI](https://github.com/paperclipai/paperclip/actions/runs/41712023737/job/126182620050) ran this exact heartbeat file with **64 passes in 107.209s**. Its server/package inputs are unchanged in the current narrative-only successor. The source-identical f478 heartbeat file also passed all64 AWS tests in105.812s; source inputs remain unchanged. Current main ordinary CI passed; the primary source PR must independently close its latest-head ordinary CI gate. - Historical main [run 41713049555](https://github.com/paperclipai/paperclip/actions/runs/41713049555) recorded six synchronized runner-shutdown failures and cancellations; the shutdown cause is unknown. A separate chat passive-control assertion observed one `db.transaction` call where zero was expected. Finite local probes passed 2+2 but did not establish a cause or late stack. No external publication, cleanup cause, source fix or flakiness is inferred. The primary’s separate composer-visibility CI failure also remains an inconclusive historical result; no guessed fix is credited. No old-head retry was used. - Earlier UI/inbox fixture failures and the CLI startup timeout remain historical. UI/inbox repairs are now upstream in #18799/#18798 and main preserves those files verbatim. The CLI timeout cause remains unknown. Broader local repository/Rust qualification is not claimed; fresh hosted CI supplies broader coverage. - All four actual repair merges, an exact merged-tree/diagnostic source join, and fresh controller/source/private-policy/active-run guards precede the ten-case TestOps measurement. No paid or model eval was launched for this PR; the original three passes/seven failures remain unchanged. ## Risks The next ten-case model result is unproved. Earlier MCP timeout and continuation-shape causes remain unknown; diagnostics provide future evidence without relaxing validation or rewriting grades. Prior local/CI failures are retained, including the unresolved chat assertion and local heartbeat timeouts. Initial ownership requires canonical in-window audit facts. Missing legacy facts remain unknown. The additive `unassigned` contract is synchronized across shared/OpenAPI/server consumers, with no new UI marker. SDK runtime holds and the broader 196/244 qualification gate remain. Normal protected merges require fresh checks and resolved feedback; no CODEOWNER or branch-protection bypass is authorized here. ## Model Used OpenAI `gpt-6.1-sol` through Codex. Capabilities used: repository analysis, code changes, source validation, and local test execution. The context-window size is not exposed by this harness. ## 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 — current focused/type/pin controls pass; the prior full Mac heartbeat failures remain disclosed and receive no local PASS credit - [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 — current main normal CI and required aggregates passed; optional neutral reviews and separate primary gate are disclosed above - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups — exact current main head; full thread pagination verified - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
11 KiB
Dashboards, activity, and audit trails — agent access
Product map: Dashboards, activity, and audit trails.
Feature ID: activity.
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
Capability ID: activity/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
Capability ID: activity/activity.
Review: baseline.
API: present — representative operation IDs:
GET /api/companies/{companyId}/activity.GET /api/issues/{id}/activity(UUID or issue identifier).GET /api/companies/{companyId}/audit/agent-actions?actorScope=all&entityType=case&entityId={caseRef}(case UUID or 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.
Working-tree case history update (2026-10-20): the all-actors Audit endpoint
accepts case resource/action/date filters for ordinary company readers who can
read those cases. Agent, responsible-person and run attribution filters still
require audit:view_agent_actions; the basic tier still strips those fields and
details. case_events mutations lacking an activity-log counterpart are merged
with logged case events before the retained-source permission predicate and
cursor limit. Case snippets are enriched only after that filter. Missing,
inaccessible and other-company cases return no rows; exact identifiers are
case-insensitive. The raw company activity API remains its existing stored-log
view.
Local verification: real temporary-Postgres audit route regressions cover historical creation/fields, UUID/identifier filters, one-row cursor pagination, hidden private sources, and duplicate handoff suppression. This is local transport/database evidence, not a deployed agent run or a sandbox bridge qualification.
runs
Capability ID: activity/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.
The recovery-actions GET also accepts inspectSourceRunId and optional
inspectSourceActionId. The explicit path requires the same readable task and
exact company/task/run/action binding, including resolved retained actions.
Run-only selection lists at most 20 actions; action selection observes current
recorded-source identity with an eight-lease ceiling. This path does not run
read revalidation, mutate recovery/Retry state, call providers or inspect files.
Only closed reason/policy values supplement the existing recorded failure;
the observation is neither historical cause nor permission to execute. Local
HTTP/database regressions
cover exact selection, foreign action denial, reused allocations, redaction,
bounded lookup and unchanged persisted state. Deployed agent use is unverified.
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
Capability ID: activity/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
Capability ID: activity/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.
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
Capability ID: activity/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, commentary:view, and source-task visibility. All human company roles,
including viewers, receive the permission by default, with an upgrade grant for existing active human members.
Human invitation approval adds the default to older saved grant lists without widening existing scopes.
Agent-action audit access remains separate. 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.