# Agent Task / Message / Workflow / Watch / Reaction Route Registry → Test Map

Canonical path: `specs/task/task-channel-authority-route-registry.md`

Every registered Agent Task / message / workflow / watch / reaction entry point
must have an executable forward/reverse case against the canonical Task->board
Channel authority. Forward = active board Channel member with **zero direct Task
membership**; reverse = board Channel membership revoked with **retained direct
Task membership**. A row marked `matrix` is covered by the table-driven
`TestAgentTaskChannelAuthorityForwardReverseMatrix`; `isolated` by the isolated
fail-closed matrix; `e2e` by the real Desktop/server E2E; `contract` by a
per-entry contract test.

## Taskboard Agent service entries

| Entry | Forward/Reverse test | Notes |
|---|---|---|
| create | matrix | `runAgentMatrixCreate` |
| get | matrix | `runAgentMatrixGet` |
| list | matrix | `runAgentMatrixList` |
| create-child | matrix | `runAgentMatrixCreateChild` |
| update | matrix | `runAgentMatrixUpdate` |
| claim | matrix | `runAgentMatrixClaim` |
| status | matrix | `runAgentMatrixStatus` |
| discussion | matrix | `runAgentMatrixDiscussion` |
| assignee | matrix | `runAgentMatrixAssignee` (UpdateTask AssigneeRef) |
| checkpoint | matrix | `runAgentMatrixCheckpoint` (AddTaskCheckpoint) |
| delete | isolated | canonical delete deny covered by fail-closed matrix; user-only legacy path not an Agent entry |

## Message / reaction / attachment entries

| Entry | Forward/Reverse test | Notes |
|---|---|---|
| send/reply | app integration | `TestAgentTaskScopeMessage...` (canonical Task discussion write) |
| history/search/read-check | message suite | board-derived readable predicate in `scope_private_authority_sql.go` |
| reaction | reaction matrix | `TestTaskReactionForwardReverseChannelMatrix` (forward asserts no Task membership) |
| attachment upload/read | app integration | `TestAgentTaskAttachment...` / `authorizeAgentTaskAttachmentScopeForMember` |
| message target | contract | `TestAgentTaskScopeTargetBasisRecordsBoardChannelScope` (basis = board Channel) |

## Workflow / watch / unread / projection entries

| Entry | Forward/Reverse test | Notes |
|---|---|---|
| workflow workScope/relatedScopes | app integration | `AuthorizeWorkflowRunCallbackScopeTx` → taskboard discussion write authority |
| watch/notification policy | app integration | Task Watch/inbox surface `task_conversation_materialize.go` (state-only after authorization) |
| unread/conversation projection | message suite | direct Task membership is state-only projection |
| read-state (read cursor) | isolated | user-only `MarkTaskRead`; Agent read-state via read-cursor projection |

## Server / Desktop / API entries

| Entry | Forward/Reverse test | Notes |
|---|---|---|
| server raw task-scope resolution | oracle | `TestCanonicalAgentRawTaskScopeOracleProvesNonEnumerating403` (identical 403) |
| Desktop transport | e2e | `TestRealServerDesktopTaskRemoteE2E` (real server + real rows + canonical URLs) |
| Desktop binder classification | desktop | `TestClassifyTaskErrorHintOnlyOnInvalidChannelTargetCode` |

## Fail-closed / concurrency / migration entries

| Case | Test | Notes |
|---|---|---|
| missing/cross-workspace/orphan/deleted/archived/inactive/kind/mismatch | isolated | `TestResolveActiveTaskBoardChannelFailClosedMatrix` (fresh fixture per case) |
| Channel revoke race | concurrency | `TestConcurrencyChannelRevokeRacesAuthorization` |
| Task delete race | concurrency | `TestConcurrencyTaskDeleteRacesAuthorization` |
| Task move race | concurrency | `TestConcurrencyTaskMoveRacesAuthorization` |
| legacy null-board migration | concurrency | `TestLegacyNullBoardMigrationDeniesBeforeBackfill` |
| matching-board backfill | concurrency | `TestLegacyMigrationMatchingBoardBackfillEnablesOnlyThatChannel` |

Every registered Agent Task / message / workflow / watch / reaction route has an
executable case in this registry. The canonical SQL inventory
(`guardrails/message/task-channel-authority-inventory.gen.go`) keyed by exact
file + function + AST callsite + classification + digest guards every
`scope_memberships` production occurrence.
