diff --git a/maps/agent-access-map/activity.md b/maps/agent-access-map/activity.md index b5d2041289c..40d61378fdd 100644 --- a/maps/agent-access-map/activity.md +++ b/maps/agent-access-map/activity.md @@ -40,22 +40,32 @@ Review: `baseline`. API: `present` — representative operation IDs: - `GET /api/companies/{companyId}/activity`. +- `GET /api/issues/{id}/activity` (UUID or issue identifier). -Agent access: `available` — REST / native call_api / CLI activity. +Agent access: `partial` — REST / native call_api / CLI activity for company +activity. Sandbox agents can use GET issue activity through the default +[callback bridge](../../packages/adapter-utils/src/sandbox-callback-bridge.ts). +The bridge still rejects company activity and company audit routes. -Policy: Same company plus visibility/audit/cost/run permissions where the route requires -them. +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` — [implementation](../../server/src/routes/activity.ts#L224) at -the reviewed commit above. +Evidence: `source-only` — [activity routes](../../server/src/routes/activity.ts), +[agent authorization tests](../../server/src/__tests__/activity-routes.test.ts), +and [bridge tests](../../packages/adapter-utils/src/sandbox-callback-bridge.test.ts). +Issue activity transport reviewed at `89770ba707fb1ebd4cabd184eec2e7fee226e0c3`; +other operations retain the baseline source review 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. +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 activity reading. +Gaps: Audit export and raw activity creation have extra restrictions; do not +equate them with issue activity reading. Live sandbox access remains unverified. ## `runs` diff --git a/maps/agent-access-map/inbox-search.md b/maps/agent-access-map/inbox-search.md index 2c079231dd9..84ada459d12 100644 --- a/maps/agent-access-map/inbox-search.md +++ b/maps/agent-access-map/inbox-search.md @@ -22,15 +22,24 @@ API: `present` — representative operation IDs: 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. +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](../../server/src/routes/agents.ts#L3952) at -the reviewed commit above. +the reviewed commit above. The cleanup exclusion in +[issue queries](../../server/src/services/issues.ts) was reviewed at +`89770ba707fb1ebd4cabd184eec2e7fee226e0c3`. +[Issue service regressions](../../server/src/__tests__/issues-service.test.ts) +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. +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. diff --git a/maps/agent-access-map/recovery.md b/maps/agent-access-map/recovery.md index a6a12a3f1c0..db98fb8ef76 100644 --- a/maps/agent-access-map/recovery.md +++ b/maps/agent-access-map/recovery.md @@ -64,20 +64,30 @@ Review: `baseline`. API: `present` — representative operation IDs: +- `GET /api/issues/{id}/recovery-actions`. - `POST /api/issues/{id}/recovery-actions/resolve`. Agent access: `partial` — Eligible agent REST / CLI; source-bound recovery state. Policy: Task/run visibility, run ownership and source/action policy; workspace export -retry and some operator controls require board. +retry and some operator controls require board. Completion or cancellation of a +task does not clear its exact unresolved native workspace owner hold. Physical +owner release still requires the [operator stop-verification procedure](../../doc/native-workspace-finalization-recovery.md). Evidence: `source-only` — [implementation](../../server/src/routes/issues.ts#L9478) at -the reviewed commit above. +the reviewed commit above. Exact owner hold retention in the +[recovery state helper](../../server/src/services/native-runtime/native-workspace-finalization-recovery-state.ts) +was reviewed at `89770ba707fb1ebd4cabd184eec2e7fee226e0c3`. 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. +remaining operations before qualifying the whole capability. Local +[recovery route regressions](../../server/src/__tests__/issue-recovery-actions.test.ts) +verify one unchanged hold across reads and sweeps on done/cancelled tasks, no +physical copyback, and cleanup after the receipt is cleared. Exercise this +sequence in a disposable instance; automatic cleanup must use the system actor +and must not create reader participation. No live recovery proof is claimed. Gaps: Need operation-level eligibility and a real native binding for permitted recovery actions; do not route around lifecycle authority. diff --git a/maps/feature-map/activity.md b/maps/feature-map/activity.md index 0a80901ddfa..49f9489906f 100644 --- a/maps/feature-map/activity.md +++ b/maps/feature-map/activity.md @@ -40,6 +40,12 @@ Automated: [activity service](../../server/src/__tests__/activity-service.test.t Manual: Find a known mutation by actor/resource and a known run by status. Change filters, load more, and follow the source links. Reload the chosen view and verify no company leakage or duplicate events. Inspect a routine run from its audit entry. +Issue activity is also available through `GET /api/issues/{id}/activity`. +[Agent authorization](../../server/src/__tests__/activity-routes.test.ts) and +[sandbox bridge](../../packages/adapter-utils/src/sandbox-callback-bridge.test.ts) +regressions cover this route separately from company-wide audit. Live sandbox +agent access remains unverified; use the companion recipe. + Audit-event Load more and run listings differ: Runs currently loads at most 200 entries without pagination. The tested RoutineAuditActivity component has no registered activity-route host; inspect execution links actually offered by diff --git a/maps/feature-map/inbox-search.md b/maps/feature-map/inbox-search.md index ac3570b5c38..14df9295962 100644 --- a/maps/feature-map/inbox-search.md +++ b/maps/feature-map/inbox-search.md @@ -35,8 +35,19 @@ Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Seed Automated: [archive routes](../../server/src/__tests__/inbox-archive-routes.test.ts) cover server mutations. [Task-list helpers](../../ui/src/pages/Issues.test.tsx) cover search URLs, pagination, and presentation constants; they do not render the combined Inbox/Tasks page. Reading, archiving, and navigating that page remain manual checks. +Automated: [Issue service regressions](../../server/src/__tests__/issues-service.test.ts) +cover exclusion of historical automatic read cleanup from user participation, +unread counts, and activity timestamps while retaining explicit user decisions +and audit history. + Manual: Read an unread task, return to Unread, archive a handled item, and reload. Verify personal triage state changes while task status stays correct. Switch users and companies to check isolation. +Seed a completed task whose only activity under the viewing user is automatic +read cleanup. Refresh Mine and Unread: the task must not appear through that +participation, while the cleanup remains in activity history. Record an explicit +user recovery decision on a separate task and verify it still counts. This +browser journey remains manual. + ### `decisions` Automated: [decision queues](../../server/src/__tests__/decision-queues-routes.test.ts) covers route behavior. End-to-end queue-to-source navigation is manual. diff --git a/maps/feature-map/recovery.md b/maps/feature-map/recovery.md index 0236b1e4dec..3cd71abaffc 100644 --- a/maps/feature-map/recovery.md +++ b/maps/feature-map/recovery.md @@ -90,6 +90,14 @@ the supported recovery until the source task produces a useful result or a specific escalation. Reload and verify that resolved notices retire and attempt history remains. A fixture pass does not qualify every live harness/provider. +For a native workspace owner hold, repeat issue reads and recovery checks after +the task becomes done or cancelled. Verify one unchanged action ID, attempt +count, and timestamps; task completion must not authorize copyback. Clear only +the exact receipt after operator stop verification, then confirm stale action +cleanup. The [route regressions](../../server/src/__tests__/issue-recovery-actions.test.ts) +and [heartbeat regression](../../server/src/__tests__/heartbeat-process-recovery.test.ts) +cover this sequence without a live operator recovery claim. + ### `run-detail` Automated: [run workspace recovery](../../ui/src/components/RunWorkspaceRecoverySurface.test.tsx)