<a id="api-tasks"></a>
# 태스크·탐색 API 전수 참조

task, goal, constraint, scope, archive, activity와 worker 제어 영역의 등록 operation을 전수 색인한다. 이 페이지는 route/address/auth/handler 요약이고 field-level 계약은 [API 의미 schema](schema-reference.md#api-schema-reference)가 소유한다.

> **분모** · 이 페이지 62개 / 전체 261개. route 등록·auth·직접 handler는 C다. 요청/응답 semantic은 operation별 C/P/U를 분리하며 route 수를 semantic 완료율로 쓰지 않는다.

## Operation 색인

| operation | handler | auth | 입력 | status | schema |
|---|---|---|---|---|---|
| [`GET /api/tasks`](#op-get-api-tasks) | `listTasks` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | none | `200/401` | [P](schema-reference.md#schema-get-api-tasks) |
| [`POST /api/tasks`](#op-post-api-tasks) | `createTask` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | JSON | `201/400/401/500` | [P](schema-reference.md#schema-post-api-tasks) |
| [`GET /api/task-categories`](#op-get-api-task-categories) | `pgListTaskCategories` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | none | `200/401/500/503` | [P](schema-reference.md#schema-get-api-task-categories) |
| [`POST /api/task-categories`](#op-post-api-task-categories) | `pgCreateTaskCategory` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | JSON | `201/400/401/404/409/413/500/503` | [P](schema-reference.md#schema-post-api-task-categories) |
| [`PATCH /api/task-categories/{id}`](#op-patch-api-task-categories-id) | `pgRenameTaskCategory` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id; JSON | `200/400/401/404/409/413/500` | [P](schema-reference.md#schema-patch-api-task-categories-id) |
| [`DELETE /api/task-categories/{id}`](#op-delete-api-task-categories-id) | `pgDeleteTaskCategory` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `200/400/401/404/409/500` | [P](schema-reference.md#schema-delete-api-task-categories-id) |
| [`POST /api/tasks/category/batch`](#op-post-api-tasks-category-batch) | `updateTasksCategoryBatch` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | JSON | `200/400/401/404/409/413/500` | [P](schema-reference.md#schema-post-api-tasks-category-batch) |
| [`GET /api/task-templates`](#op-get-api-task-templates) | `pgListTaskTemplates` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | none | `200/401/500/503` | [P](schema-reference.md#schema-get-api-task-templates) |
| [`POST /api/task-templates`](#op-post-api-task-templates) | `pgCreateTaskTemplate` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | JSON | `201/400/401/404/409/413/500/503` | [P](schema-reference.md#schema-post-api-task-templates) |
| [`PATCH /api/task-templates/{id}`](#op-patch-api-task-templates-id) | `pgUpdateTaskTemplate` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id; JSON | `200/400/401/404/409/413/500/503` | [P](schema-reference.md#schema-patch-api-task-templates-id) |
| [`DELETE /api/task-templates/{id}`](#op-delete-api-task-templates-id) | `pgDeleteTaskTemplate` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `200/400/401/404/500/503` | [P](schema-reference.md#schema-delete-api-task-templates-id) |
| [`GET /api/tasks/{id}`](#op-get-api-tasks-id) | `getTask` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `200/401/404` | [P](schema-reference.md#schema-get-api-tasks-id) |
| [`PATCH /api/tasks/{id}`](#op-patch-api-tasks-id) | `updateTaskMetadata` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id; JSON | `200/400/401/404/413/500` | [P](schema-reference.md#schema-patch-api-tasks-id) |
| [`PATCH /api/tasks/{id}/category`](#op-patch-api-tasks-id-category) | `updateTaskCategory` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id; JSON | `200/400/401/404/409/500` | [P](schema-reference.md#schema-patch-api-tasks-id-category) |
| [`GET /api/tasks/{id}/intercept-rules`](#op-get-api-tasks-id-intercept-rules) | `taskInterceptListRules` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `200/400/401/500/503` | [P](schema-reference.md#schema-get-api-tasks-id-intercept-rules) |
| [`POST /api/tasks/{id}/intercept-rules`](#op-post-api-tasks-id-intercept-rules) | `taskInterceptCreateRule` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id; JSON | `200/400/401/500/503` | [P](schema-reference.md#schema-post-api-tasks-id-intercept-rules) |
| [`PUT /api/tasks/{id}/intercept-rules/{rid}`](#op-put-api-tasks-id-intercept-rules-rid) | `taskInterceptUpdateRule` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id,rid; JSON | `200/400/401/500/503` | [P](schema-reference.md#schema-put-api-tasks-id-intercept-rules-rid) |
| [`DELETE /api/tasks/{id}/intercept-rules/{rid}`](#op-delete-api-tasks-id-intercept-rules-rid) | `taskInterceptDeleteRule` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id,rid | `200/400/401/500/503` | [P](schema-reference.md#schema-delete-api-tasks-id-intercept-rules-rid) |
| [`POST /api/tasks/{id}/intercept-rules/{rid}/toggle`](#op-post-api-tasks-id-intercept-rules-rid-toggle) | `taskInterceptToggleRule` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id,rid; JSON | `200/400/401/500/503` | [P](schema-reference.md#schema-post-api-tasks-id-intercept-rules-rid-toggle) |
| [`POST /api/tasks/control/batch`](#op-post-api-tasks-control-batch) | `controlTasksBatch` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | JSON | `200/400/401` | [P](schema-reference.md#schema-post-api-tasks-control-batch) |
| [`GET /api/task-archives`](#op-get-api-task-archives) | `listTaskArchives` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | query page,q,size,state | `200/401/500` | [P](schema-reference.md#schema-get-api-task-archives) |
| [`GET /api/task-archives/{id}`](#op-get-api-task-archives-id) | `getTaskArchive` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `200/400/401/404/500` | [P](schema-reference.md#schema-get-api-task-archives-id) |
| [`POST /api/tasks/{id}/archive`](#op-post-api-tasks-id-archive) | `queueTaskArchive` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `202/400/401/404/409/500` | [P](schema-reference.md#schema-post-api-tasks-id-archive) |
| [`POST /api/tasks/archive/batch`](#op-post-api-tasks-archive-batch) | `queueTaskArchivesBatch` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | JSON | `202/400/401` | [P](schema-reference.md#schema-post-api-tasks-archive-batch) |
| [`POST /api/task-archives/{id}/restore`](#op-post-api-task-archives-id-restore) | `queueTaskArchiveRestore` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `202/400/401/404/409/500` | [P](schema-reference.md#schema-post-api-task-archives-id-restore) |
| [`POST /api/task-archives/restore/batch`](#op-post-api-task-archives-restore-batch) | `restoreTaskArchivesBatch` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | JSON | `202/400/401` | [P](schema-reference.md#schema-post-api-task-archives-restore-batch) |
| [`DELETE /api/task-archives/{id}`](#op-delete-api-task-archives-id) | `queueTaskArchiveDelete` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `202/400/401/404/409/500` | [P](schema-reference.md#schema-delete-api-task-archives-id) |
| [`POST /api/task-archives/delete/batch`](#op-post-api-task-archives-delete-batch) | `deleteTaskArchivesBatch` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | JSON | `202/400/401` | [P](schema-reference.md#schema-post-api-task-archives-delete-batch) |
| [`GET /api/tasks/{id}/coverage`](#op-get-api-tasks-id-coverage) | `taskCoverage` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `200/401/404/500/503` | [P](schema-reference.md#schema-get-api-tasks-id-coverage) |
| [`GET /api/tasks/{id}/coverage-graph`](#op-get-api-tasks-id-coverage-graph) | `taskCoverageGraph` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `200/401/404/500/503` | [P](schema-reference.md#schema-get-api-tasks-id-coverage-graph) |
| [`GET /api/tasks/{id}/asset-refs`](#op-get-api-tasks-id-asset-refs) | `taskAssetRefs` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id; query asset_id | `200/400/401/404/500` | [P](schema-reference.md#schema-get-api-tasks-id-asset-refs) |
| [`POST /api/tasks/{id}/assets`](#op-post-api-tasks-id-assets) | `attachTaskAssets` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id; JSON | `200/400/401/404/413/500` | [P](schema-reference.md#schema-post-api-tasks-id-assets) |
| [`DELETE /api/tasks/{id}/assets/{assetID}`](#op-delete-api-tasks-id-assets-assetid) | `detachTaskAsset` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id,assetID | `200/400/401/404/500` | [P](schema-reference.md#schema-delete-api-tasks-id-assets-assetid) |
| [`GET /api/tasks/{id}/intent-assets`](#op-get-api-tasks-id-intent-assets) | `taskIntentAssets` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `200/400/401/404/500` | [P](schema-reference.md#schema-get-api-tasks-id-intent-assets) |
| [`GET /api/tasks/{id}/scope`](#op-get-api-tasks-id-scope) | `taskScopeList` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `200/401/404/500/503` | [P](schema-reference.md#schema-get-api-tasks-id-scope) |
| [`POST /api/tasks/{id}/scope`](#op-post-api-tasks-id-scope) | `taskScopeAdd` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id; JSON | `200/400/401/404/503` | [P](schema-reference.md#schema-post-api-tasks-id-scope) |
| [`DELETE /api/tasks/{id}/scope/{sid}`](#op-delete-api-tasks-id-scope-sid) | `taskScopeDelete` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id,sid | `200/400/401/404/500/503` | [C](schema-reference.md#schema-delete-api-tasks-id-scope-sid) |
| [`GET /api/tasks/{id}/goals`](#op-get-api-tasks-id-goals) | `listGoals` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `200/401/404/500` | [P](schema-reference.md#schema-get-api-tasks-id-goals) |
| [`POST /api/tasks/{id}/goals`](#op-post-api-tasks-id-goals) | `addGoal` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id; JSON | `200/400/401/404/409/500` | [P](schema-reference.md#schema-post-api-tasks-id-goals) |
| [`PATCH /api/tasks/{id}/goals/{gid}`](#op-patch-api-tasks-id-goals-gid) | `editGoal` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id,gid; JSON | `200/400/401/404/409/500` | [P](schema-reference.md#schema-patch-api-tasks-id-goals-gid) |
| [`DELETE /api/tasks/{id}/goals/{gid}`](#op-delete-api-tasks-id-goals-gid) | `deleteGoal` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id,gid | `200/400/401/404/409/500` | [C](schema-reference.md#schema-delete-api-tasks-id-goals-gid) |
| [`GET /api/tasks/{id}/constraints`](#op-get-api-tasks-id-constraints) | `listConstraints` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `200/401/404/500` | [P](schema-reference.md#schema-get-api-tasks-id-constraints) |
| [`POST /api/tasks/{id}/constraints`](#op-post-api-tasks-id-constraints) | `addConstraint` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id; JSON | `200/400/401/404/409/500` | [C](schema-reference.md#schema-post-api-tasks-id-constraints) |
| [`PATCH /api/tasks/{id}/constraints/{cid}`](#op-patch-api-tasks-id-constraints-cid) | `editConstraint` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id,cid; JSON | `200/400/401/404/409/500` | [C](schema-reference.md#schema-patch-api-tasks-id-constraints-cid) |
| [`DELETE /api/tasks/{id}/constraints/{cid}`](#op-delete-api-tasks-id-constraints-cid) | `deleteConstraint` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id,cid | `200/400/401/404/409/500` | [C](schema-reference.md#schema-delete-api-tasks-id-constraints-cid) |
| [`POST /api/tasks/{id}/control`](#op-post-api-tasks-id-control) | `control` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id; JSON | `200/400/401/404/409` | [P](schema-reference.md#schema-post-api-tasks-id-control) |
| [`PUT /api/tasks/{id}/llm`](#op-put-api-tasks-id-llm) | `updateTaskLLMProfiles` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id; JSON | `200/400/401/404` | [P](schema-reference.md#schema-put-api-tasks-id-llm) |
| [`GET /api/tasks/{id}/llm/resolution`](#op-get-api-tasks-id-llm-resolution) | `taskLLMResolutionHandler` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `200/401/404/500` | [P](schema-reference.md#schema-get-api-tasks-id-llm-resolution) |
| [`POST /api/tasks/{id}/intents/{iid}/control`](#op-post-api-tasks-id-intents-iid-control) | `controlIntent` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id,iid; JSON | `200/400/401/404/409` | [P](schema-reference.md#schema-post-api-tasks-id-intents-iid-control) |
| [`POST /api/tasks/{id}/intents/{iid}/messages`](#op-post-api-tasks-id-intents-iid-messages) | `sendWorkerMessage` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id,iid; JSON | `200/400/401/404/409/413/500` | [P](schema-reference.md#schema-post-api-tasks-id-intents-iid-messages) |
| [`POST /api/tasks/{id}/intents/{iid}/rerun`](#op-post-api-tasks-id-intents-iid-rerun) | `rerunIntent` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id,iid | `200/400/401/404/409/500` | [P](schema-reference.md#schema-post-api-tasks-id-intents-iid-rerun) |
| [`POST /api/tasks/{id}/intents/rerun-blocked`](#op-post-api-tasks-id-intents-rerun-blocked) | `rerunBlocked` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `200/401/404/409/500` | [P](schema-reference.md#schema-post-api-tasks-id-intents-rerun-blocked) |
| [`POST /api/active`](#op-post-api-active) | `setActive` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | JSON | `200/400/401/404` | [P](schema-reference.md#schema-post-api-active) |
| [`GET /api/tasks/{id}/chat/status`](#op-get-api-tasks-id-chat-status) | `taskChatStatus` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `200/401/404` | [P](schema-reference.md#schema-get-api-tasks-id-chat-status) |
| [`POST /api/tasks/{id}/chat/stop`](#op-post-api-tasks-id-chat-stop) | `stopChat` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `200/401/404` | [C](schema-reference.md#schema-post-api-tasks-id-chat-stop) |
| [`DELETE /api/tasks/{id}`](#op-delete-api-tasks-id) | `pgDeleteTask` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id; JSON | `200/400/401/409/500` | [P](schema-reference.md#schema-delete-api-tasks-id) |
| [`GET /api/tasks/{id}/chat/side-questions`](#op-get-api-tasks-id-chat-side-questions) | `handleSideQuestions` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id; query before | `200/400/401/404/409/500/503` | [P](schema-reference.md#schema-get-api-tasks-id-chat-side-questions) |
| [`POST /api/tasks/{id}/chat/side-questions`](#op-post-api-tasks-id-chat-side-questions) | `handleSideQuestions` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id; JSON | `200/202/400/401/404/409/429/500/503` | [P](schema-reference.md#schema-post-api-tasks-id-chat-side-questions) |
| [`DELETE /api/tasks/{id}/chat/side-questions`](#op-delete-api-tasks-id-chat-side-questions) | `handleSideQuestions` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id | `200/400/401/404/409/500/503` | [C](schema-reference.md#schema-delete-api-tasks-id-chat-side-questions) |
| [`GET /api/tasks/{id}/intents/{iid}/side-questions`](#op-get-api-tasks-id-intents-iid-side-questions) | `handleSideQuestions` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id,iid; query before | `200/400/401/404/409/500/503` | [P](schema-reference.md#schema-get-api-tasks-id-intents-iid-side-questions) |
| [`POST /api/tasks/{id}/intents/{iid}/side-questions`](#op-post-api-tasks-id-intents-iid-side-questions) | `handleSideQuestions` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id,iid; JSON | `200/202/400/401/404/409/429/500/503` | [P](schema-reference.md#schema-post-api-tasks-id-intents-iid-side-questions) |
| [`DELETE /api/tasks/{id}/intents/{iid}/side-questions`](#op-delete-api-tasks-id-intents-iid-side-questions) | `handleSideQuestions` | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 | path id,iid | `200/400/401/404/409/500/503` | [C](schema-reference.md#schema-delete-api-tasks-id-intents-iid-side-questions) |

<a id="op-get-api-tasks"></a>
## `GET /api/tasks`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `listTasks` · `server/server.go` · [handler 근거](evidence:handler-get-api-tasks) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `-` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 401` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-get-api-tasks) |
| 반복·완료 | read/stream 요청; stream 재연결은 cursor 계약에 따름 · 직접 조회/파일 전송 완료; 외부 조회가 있으면 응답 전 handler 결과만 보장 |

<a id="op-post-api-tasks"></a>
## `POST /api/tasks`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `createTask` · `server/server.go` · [handler 근거](evidence:handler-post-api-tasks) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `-` · query `-` · body `JSON` |
| status/error | 직접 관찰 `201, 400, 401, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-tasks) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · task/exploration 저장 후 engine launch; `201`은 탐색 완료가 아님 |

<a id="op-get-api-task-categories"></a>
## `GET /api/task-categories`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `pgListTaskCategories` · `server/task_categories.go` · [handler 근거](evidence:handler-get-api-task-categories) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `-` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 401, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-get-api-task-categories) |
| 반복·완료 | read/stream 요청; stream 재연결은 cursor 계약에 따름 · 직접 조회/파일 전송 완료; 외부 조회가 있으면 응답 전 handler 결과만 보장 |

<a id="op-post-api-task-categories"></a>
## `POST /api/task-categories`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `pgCreateTaskCategory` · `server/task_categories.go` · [handler 근거](evidence:handler-post-api-task-categories) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `-` · query `-` · body `JSON` |
| status/error | 직접 관찰 `201, 400, 401, 404, 409, 413, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-task-categories) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-patch-api-task-categories-id"></a>
## `PATCH /api/task-categories/{id}`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `pgRenameTaskCategory` · `server/task_categories.go` · [handler 근거](evidence:handler-patch-api-task-categories-id) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409, 413, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-patch-api-task-categories-id) |
| 반복·완료 | Idempotency-Key/If-Match 없음; DB upsert/trigger/side effect 때문에 반복 의미를 handler별 확인(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-delete-api-task-categories-id"></a>
## `DELETE /api/task-categories/{id}`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `pgDeleteTaskCategory` · `server/task_categories.go` · [handler 근거](evidence:handler-delete-api-task-categories-id) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-delete-api-task-categories-id) |
| 반복·완료 | Idempotency-Key/If-Match 없음; 반복 시 응답/존재 검사가 달라질 수 있음 · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-post-api-tasks-category-batch"></a>
## `POST /api/tasks/category/batch`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `updateTasksCategoryBatch` · `server/task_categories.go` · [handler 근거](evidence:handler-post-api-tasks-category-batch) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `-` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409, 413, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-tasks-category-batch) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-get-api-task-templates"></a>
## `GET /api/task-templates`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `pgListTaskTemplates` · `server/task_templates.go` · [handler 근거](evidence:handler-get-api-task-templates) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `-` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 401, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-get-api-task-templates) |
| 반복·완료 | read/stream 요청; stream 재연결은 cursor 계약에 따름 · 직접 조회/파일 전송 완료; 외부 조회가 있으면 응답 전 handler 결과만 보장 |

<a id="op-post-api-task-templates"></a>
## `POST /api/task-templates`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `pgCreateTaskTemplate` · `server/task_templates.go` · [handler 근거](evidence:handler-post-api-task-templates) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `-` · query `-` · body `JSON` |
| status/error | 직접 관찰 `201, 400, 401, 404, 409, 413, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-task-templates) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-patch-api-task-templates-id"></a>
## `PATCH /api/task-templates/{id}`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `pgUpdateTaskTemplate` · `server/task_templates.go` · [handler 근거](evidence:handler-patch-api-task-templates-id) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409, 413, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-patch-api-task-templates-id) |
| 반복·완료 | Idempotency-Key/If-Match 없음; DB upsert/trigger/side effect 때문에 반복 의미를 handler별 확인(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-delete-api-task-templates-id"></a>
## `DELETE /api/task-templates/{id}`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `pgDeleteTaskTemplate` · `server/task_templates.go` · [handler 근거](evidence:handler-delete-api-task-templates-id) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 400, 401, 404, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-delete-api-task-templates-id) |
| 반복·완료 | Idempotency-Key/If-Match 없음; 반복 시 응답/존재 검사가 달라질 수 있음 · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-get-api-tasks-id"></a>
## `GET /api/tasks/{id}`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `getTask` · `server/server.go` · [handler 근거](evidence:handler-get-api-tasks-id) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 401, 404` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-get-api-tasks-id) |
| 반복·완료 | read/stream 요청; stream 재연결은 cursor 계약에 따름 · 직접 조회/파일 전송 완료; 외부 조회가 있으면 응답 전 handler 결과만 보장 |

<a id="op-patch-api-tasks-id"></a>
## `PATCH /api/tasks/{id}`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `updateTaskMetadata` · `server/task_metadata.go` · [handler 근거](evidence:handler-patch-api-tasks-id) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 404, 413, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-patch-api-tasks-id) |
| 반복·완료 | Idempotency-Key/If-Match 없음; DB upsert/trigger/side effect 때문에 반복 의미를 handler별 확인(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-patch-api-tasks-id-category"></a>
## `PATCH /api/tasks/{id}/category`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `updateTaskCategory` · `server/task_categories.go` · [handler 근거](evidence:handler-patch-api-tasks-id-category) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-patch-api-tasks-id-category) |
| 반복·완료 | Idempotency-Key/If-Match 없음; DB upsert/trigger/side effect 때문에 반복 의미를 handler별 확인(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-get-api-tasks-id-intercept-rules"></a>
## `GET /api/tasks/{id}/intercept-rules`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `taskInterceptListRules` · `server/task_intercept.go` · [handler 근거](evidence:handler-get-api-tasks-id-intercept-rules) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 400, 401, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-get-api-tasks-id-intercept-rules) |
| 반복·완료 | read/stream 요청; stream 재연결은 cursor 계약에 따름 · 직접 조회/파일 전송 완료; 외부 조회가 있으면 응답 전 handler 결과만 보장 |

<a id="op-post-api-tasks-id-intercept-rules"></a>
## `POST /api/tasks/{id}/intercept-rules`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `taskInterceptCreateRule` · `server/task_intercept.go` · [handler 근거](evidence:handler-post-api-tasks-id-intercept-rules) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-tasks-id-intercept-rules) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-put-api-tasks-id-intercept-rules-rid"></a>
## `PUT /api/tasks/{id}/intercept-rules/{rid}`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `taskInterceptUpdateRule` · `server/task_intercept.go` · [handler 근거](evidence:handler-put-api-tasks-id-intercept-rules-rid) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id, rid` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-put-api-tasks-id-intercept-rules-rid) |
| 반복·완료 | Idempotency-Key/If-Match 없음; DB upsert/trigger/side effect 때문에 반복 의미를 handler별 확인(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-delete-api-tasks-id-intercept-rules-rid"></a>
## `DELETE /api/tasks/{id}/intercept-rules/{rid}`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `taskInterceptDeleteRule` · `server/task_intercept.go` · [handler 근거](evidence:handler-delete-api-tasks-id-intercept-rules-rid) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id, rid` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 400, 401, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-delete-api-tasks-id-intercept-rules-rid) |
| 반복·완료 | Idempotency-Key/If-Match 없음; 반복 시 응답/존재 검사가 달라질 수 있음 · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-post-api-tasks-id-intercept-rules-rid-toggle"></a>
## `POST /api/tasks/{id}/intercept-rules/{rid}/toggle`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `taskInterceptToggleRule` · `server/task_intercept.go` · [handler 근거](evidence:handler-post-api-tasks-id-intercept-rules-rid-toggle) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id, rid` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-tasks-id-intercept-rules-rid-toggle) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-post-api-tasks-control-batch"></a>
## `POST /api/tasks/control/batch`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `controlTasksBatch` · `server/task_control.go` · [handler 근거](evidence:handler-post-api-tasks-control-batch) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `-` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-tasks-control-batch) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-get-api-task-archives"></a>
## `GET /api/task-archives`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `listTaskArchives` · `server/task_archives.go` · [handler 근거](evidence:handler-get-api-task-archives) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `-` · query `page, q, size, state` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 401, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-get-api-task-archives) |
| 반복·완료 | read/stream 요청; stream 재연결은 cursor 계약에 따름 · 직접 조회/파일 전송 완료; 외부 조회가 있으면 응답 전 handler 결과만 보장 |

<a id="op-get-api-task-archives-id"></a>
## `GET /api/task-archives/{id}`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `getTaskArchive` · `server/task_archives.go` · [handler 근거](evidence:handler-get-api-task-archives-id) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 400, 401, 404, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-get-api-task-archives-id) |
| 반복·완료 | read/stream 요청; stream 재연결은 cursor 계약에 따름 · 직접 조회/파일 전송 완료; 외부 조회가 있으면 응답 전 handler 결과만 보장 |

<a id="op-post-api-tasks-id-archive"></a>
## `POST /api/tasks/{id}/archive`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `queueTaskArchive` · `server/task_archives.go` · [handler 근거](evidence:handler-post-api-tasks-id-archive) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `202, 400, 401, 404, 409, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-tasks-id-archive) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · persistent archive/restore/delete queue 접수; archive row의 state/phase가 완료 기준 |

<a id="op-post-api-tasks-archive-batch"></a>
## `POST /api/tasks/archive/batch`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `queueTaskArchivesBatch` · `server/task_archives.go` · [handler 근거](evidence:handler-post-api-tasks-archive-batch) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `-` · query `-` · body `JSON` |
| status/error | 직접 관찰 `202, 400, 401` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-tasks-archive-batch) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · persistent archive/restore/delete queue 접수; archive row의 state/phase가 완료 기준 |

<a id="op-post-api-task-archives-id-restore"></a>
## `POST /api/task-archives/{id}/restore`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `queueTaskArchiveRestore` · `server/task_archives.go` · [handler 근거](evidence:handler-post-api-task-archives-id-restore) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `202, 400, 401, 404, 409, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-task-archives-id-restore) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · persistent archive/restore/delete queue 접수; archive row의 state/phase가 완료 기준 |

<a id="op-post-api-task-archives-restore-batch"></a>
## `POST /api/task-archives/restore/batch`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `restoreTaskArchivesBatch` · `server/task_archives.go` · [handler 근거](evidence:handler-post-api-task-archives-restore-batch) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `-` · query `-` · body `JSON` |
| status/error | 직접 관찰 `202, 400, 401` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-task-archives-restore-batch) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · persistent archive/restore/delete queue 접수; archive row의 state/phase가 완료 기준 |

<a id="op-delete-api-task-archives-id"></a>
## `DELETE /api/task-archives/{id}`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `queueTaskArchiveDelete` · `server/task_archives.go` · [handler 근거](evidence:handler-delete-api-task-archives-id) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `202, 400, 401, 404, 409, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-delete-api-task-archives-id) |
| 반복·완료 | Idempotency-Key/If-Match 없음; 반복 시 응답/존재 검사가 달라질 수 있음 · `202` 접수; 후속 state/API를 확인 |

<a id="op-post-api-task-archives-delete-batch"></a>
## `POST /api/task-archives/delete/batch`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `deleteTaskArchivesBatch` · `server/task_archives.go` · [handler 근거](evidence:handler-post-api-task-archives-delete-batch) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `-` · query `-` · body `JSON` |
| status/error | 직접 관찰 `202, 400, 401` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-task-archives-delete-batch) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · persistent archive/restore/delete queue 접수; archive row의 state/phase가 완료 기준 |

<a id="op-get-api-tasks-id-coverage"></a>
## `GET /api/tasks/{id}/coverage`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `taskCoverage` · `server/server.go` · [handler 근거](evidence:handler-get-api-tasks-id-coverage) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 401, 404, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-get-api-tasks-id-coverage) |
| 반복·완료 | read/stream 요청; stream 재연결은 cursor 계약에 따름 · 직접 조회/파일 전송 완료; 외부 조회가 있으면 응답 전 handler 결과만 보장 |

<a id="op-get-api-tasks-id-coverage-graph"></a>
## `GET /api/tasks/{id}/coverage-graph`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `taskCoverageGraph` · `server/server.go` · [handler 근거](evidence:handler-get-api-tasks-id-coverage-graph) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 401, 404, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-get-api-tasks-id-coverage-graph) |
| 반복·완료 | read/stream 요청; stream 재연결은 cursor 계약에 따름 · 직접 조회/파일 전송 완료; 외부 조회가 있으면 응답 전 handler 결과만 보장 |

<a id="op-get-api-tasks-id-asset-refs"></a>
## `GET /api/tasks/{id}/asset-refs`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `taskAssetRefs` · `server/server.go` · [handler 근거](evidence:handler-get-api-tasks-id-asset-refs) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `asset_id` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 400, 401, 404, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-get-api-tasks-id-asset-refs) |
| 반복·완료 | read/stream 요청; stream 재연결은 cursor 계약에 따름 · 직접 조회/파일 전송 완료; 외부 조회가 있으면 응답 전 handler 결과만 보장 |

<a id="op-post-api-tasks-id-assets"></a>
## `POST /api/tasks/{id}/assets`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `attachTaskAssets` · `server/task_assets.go` · [handler 근거](evidence:handler-post-api-tasks-id-assets) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 404, 413, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-tasks-id-assets) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-delete-api-tasks-id-assets-assetid"></a>
## `DELETE /api/tasks/{id}/assets/{assetID}`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `detachTaskAsset` · `server/task_assets.go` · [handler 근거](evidence:handler-delete-api-tasks-id-assets-assetid) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id, assetID` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 400, 401, 404, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-delete-api-tasks-id-assets-assetid) |
| 반복·완료 | Idempotency-Key/If-Match 없음; 반복 시 응답/존재 검사가 달라질 수 있음 · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-get-api-tasks-id-intent-assets"></a>
## `GET /api/tasks/{id}/intent-assets`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `taskIntentAssets` · `server/task_assets.go` · [handler 근거](evidence:handler-get-api-tasks-id-intent-assets) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 400, 401, 404, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-get-api-tasks-id-intent-assets) |
| 반복·완료 | read/stream 요청; stream 재연결은 cursor 계약에 따름 · 직접 조회/파일 전송 완료; 외부 조회가 있으면 응답 전 handler 결과만 보장 |

<a id="op-get-api-tasks-id-scope"></a>
## `GET /api/tasks/{id}/scope`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `taskScopeList` · `server/server.go` · [handler 근거](evidence:handler-get-api-tasks-id-scope) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 401, 404, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-get-api-tasks-id-scope) |
| 반복·완료 | read/stream 요청; stream 재연결은 cursor 계약에 따름 · 직접 조회/파일 전송 완료; 외부 조회가 있으면 응답 전 handler 결과만 보장 |

<a id="op-post-api-tasks-id-scope"></a>
## `POST /api/tasks/{id}/scope`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `taskScopeAdd` · `server/server.go` · [handler 근거](evidence:handler-post-api-tasks-id-scope) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 404, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-tasks-id-scope) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-delete-api-tasks-id-scope-sid"></a>
## `DELETE /api/tasks/{id}/scope/{sid}`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `taskScopeDelete` · `server/server.go` · [handler 근거](evidence:handler-delete-api-tasks-id-scope-sid) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id, sid` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 400, 401, 404, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [C: 직접 scalar/static top-level key와 field type을 추출; nested 내부 schema는 별도 type 참조가 없으면 P](schema-reference.md#schema-delete-api-tasks-id-scope-sid) |
| 반복·완료 | Idempotency-Key/If-Match 없음; 반복 시 응답/존재 검사가 달라질 수 있음 · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-get-api-tasks-id-goals"></a>
## `GET /api/tasks/{id}/goals`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `listGoals` · `server/goals_api.go` · [handler 근거](evidence:handler-get-api-tasks-id-goals) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 401, 404, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-get-api-tasks-id-goals) |
| 반복·완료 | read/stream 요청; stream 재연결은 cursor 계약에 따름 · 직접 조회/파일 전송 완료; 외부 조회가 있으면 응답 전 handler 결과만 보장 |

<a id="op-post-api-tasks-id-goals"></a>
## `POST /api/tasks/{id}/goals`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `addGoal` · `server/goals_api.go` · [handler 근거](evidence:handler-post-api-tasks-id-goals) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-tasks-id-goals) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-patch-api-tasks-id-goals-gid"></a>
## `PATCH /api/tasks/{id}/goals/{gid}`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `editGoal` · `server/goals_api.go` · [handler 근거](evidence:handler-patch-api-tasks-id-goals-gid) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id, gid` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-patch-api-tasks-id-goals-gid) |
| 반복·완료 | Idempotency-Key/If-Match 없음; DB upsert/trigger/side effect 때문에 반복 의미를 handler별 확인(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-delete-api-tasks-id-goals-gid"></a>
## `DELETE /api/tasks/{id}/goals/{gid}`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `deleteGoal` · `server/goals_api.go` · [handler 근거](evidence:handler-delete-api-tasks-id-goals-gid) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id, gid` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [C: 직접 scalar/static top-level key와 field type을 추출; nested 내부 schema는 별도 type 참조가 없으면 P](schema-reference.md#schema-delete-api-tasks-id-goals-gid) |
| 반복·완료 | Idempotency-Key/If-Match 없음; 반복 시 응답/존재 검사가 달라질 수 있음 · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-get-api-tasks-id-constraints"></a>
## `GET /api/tasks/{id}/constraints`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `listConstraints` · `server/constraints_api.go` · [handler 근거](evidence:handler-get-api-tasks-id-constraints) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 401, 404, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-get-api-tasks-id-constraints) |
| 반복·완료 | read/stream 요청; stream 재연결은 cursor 계약에 따름 · 직접 조회/파일 전송 완료; 외부 조회가 있으면 응답 전 handler 결과만 보장 |

<a id="op-post-api-tasks-id-constraints"></a>
## `POST /api/tasks/{id}/constraints`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `addConstraint` · `server/constraints_api.go` · [handler 근거](evidence:handler-post-api-tasks-id-constraints) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [C: 직접 scalar/static top-level key와 field type을 추출; nested 내부 schema는 별도 type 참조가 없으면 P](schema-reference.md#schema-post-api-tasks-id-constraints) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-patch-api-tasks-id-constraints-cid"></a>
## `PATCH /api/tasks/{id}/constraints/{cid}`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `editConstraint` · `server/constraints_api.go` · [handler 근거](evidence:handler-patch-api-tasks-id-constraints-cid) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id, cid` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [C: 직접 scalar/static top-level key와 field type을 추출; nested 내부 schema는 별도 type 참조가 없으면 P](schema-reference.md#schema-patch-api-tasks-id-constraints-cid) |
| 반복·완료 | Idempotency-Key/If-Match 없음; DB upsert/trigger/side effect 때문에 반복 의미를 handler별 확인(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-delete-api-tasks-id-constraints-cid"></a>
## `DELETE /api/tasks/{id}/constraints/{cid}`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `deleteConstraint` · `server/constraints_api.go` · [handler 근거](evidence:handler-delete-api-tasks-id-constraints-cid) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id, cid` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [C: 직접 scalar/static top-level key와 field type을 추출; nested 내부 schema는 별도 type 참조가 없으면 P](schema-reference.md#schema-delete-api-tasks-id-constraints-cid) |
| 반복·완료 | Idempotency-Key/If-Match 없음; 반복 시 응답/존재 검사가 달라질 수 있음 · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-post-api-tasks-id-control"></a>
## `POST /api/tasks/{id}/control`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `control` · `server/server.go` · [handler 근거](evidence:handler-post-api-tasks-id-control) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-tasks-id-control) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-put-api-tasks-id-llm"></a>
## `PUT /api/tasks/{id}/llm`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `updateTaskLLMProfiles` · `server/server.go` · [handler 근거](evidence:handler-put-api-tasks-id-llm) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 404` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-put-api-tasks-id-llm) |
| 반복·완료 | Idempotency-Key/If-Match 없음; DB upsert/trigger/side effect 때문에 반복 의미를 handler별 확인(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-get-api-tasks-id-llm-resolution"></a>
## `GET /api/tasks/{id}/llm/resolution`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `taskLLMResolutionHandler` · `server/task_resolution.go` · [handler 근거](evidence:handler-get-api-tasks-id-llm-resolution) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 401, 404, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-get-api-tasks-id-llm-resolution) |
| 반복·완료 | read/stream 요청; stream 재연결은 cursor 계약에 따름 · 직접 조회/파일 전송 완료; 외부 조회가 있으면 응답 전 handler 결과만 보장 |

<a id="op-post-api-tasks-id-intents-iid-control"></a>
## `POST /api/tasks/{id}/intents/{iid}/control`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `controlIntent` · `server/server.go` · [handler 근거](evidence:handler-post-api-tasks-id-intents-iid-control) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id, iid` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-tasks-id-intents-iid-control) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-post-api-tasks-id-intents-iid-messages"></a>
## `POST /api/tasks/{id}/intents/{iid}/messages`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `sendWorkerMessage` · `server/intent_intervention.go` · [handler 근거](evidence:handler-post-api-tasks-id-intents-iid-messages) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id, iid` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409, 413, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-tasks-id-intents-iid-messages) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · agent turn을 background context에서 실행할 수 있음; activity/stop/terminal event를 확인 |

<a id="op-post-api-tasks-id-intents-iid-rerun"></a>
## `POST /api/tasks/{id}/intents/{iid}/rerun`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `rerunIntent` · `server/server.go` · [handler 근거](evidence:handler-post-api-tasks-id-intents-iid-rerun) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id, iid` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-tasks-id-intents-iid-rerun) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-post-api-tasks-id-intents-rerun-blocked"></a>
## `POST /api/tasks/{id}/intents/rerun-blocked`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `rerunBlocked` · `server/server.go` · [handler 근거](evidence:handler-post-api-tasks-id-intents-rerun-blocked) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 401, 404, 409, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-tasks-id-intents-rerun-blocked) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-post-api-active"></a>
## `POST /api/active`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `setActive` · `server/server.go` · [handler 근거](evidence:handler-post-api-active) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `-` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 404` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-active) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-get-api-tasks-id-chat-status"></a>
## `GET /api/tasks/{id}/chat/status`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `taskChatStatus` · `server/server.go` · [handler 근거](evidence:handler-get-api-tasks-id-chat-status) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 401, 404` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-get-api-tasks-id-chat-status) |
| 반복·완료 | read/stream 요청; stream 재연결은 cursor 계약에 따름 · 직접 조회/파일 전송 완료; 외부 조회가 있으면 응답 전 handler 결과만 보장 |

<a id="op-post-api-tasks-id-chat-stop"></a>
## `POST /api/tasks/{id}/chat/stop`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `stopChat` · `server/server.go` · [handler 근거](evidence:handler-post-api-tasks-id-chat-stop) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 401, 404` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [C: 직접 scalar/static top-level key와 field type을 추출; nested 내부 schema는 별도 type 참조가 없으면 P](schema-reference.md#schema-post-api-tasks-id-chat-stop) |
| 반복·완료 | Idempotency-Key 없음; unique constraint 또는 상태 check가 있는 경우만 중복을 제한(P) · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-delete-api-tasks-id"></a>
## `DELETE /api/tasks/{id}`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `pgDeleteTask` · `server/server_mgmt.go` · [handler 근거](evidence:handler-delete-api-tasks-id) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 400, 401, 409, 500` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-delete-api-tasks-id) |
| 반복·완료 | Idempotency-Key/If-Match 없음; 반복 시 응답/존재 검사가 달라질 수 있음 · handler의 직접 mutation/호출 후 응답; 외부 전달·agent 실행이 파생되면 별도 상태 확인(P) |

<a id="op-get-api-tasks-id-chat-side-questions"></a>
## `GET /api/tasks/{id}/chat/side-questions`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `handleSideQuestions` · `server/side_questions.go` · [handler 근거](evidence:handler-get-api-tasks-id-chat-side-questions) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `before` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-get-api-tasks-id-chat-side-questions) |
| 반복·완료 | read/stream 요청; stream 재연결은 cursor 계약에 따름 · history/current snapshot 조회가 응답 전에 끝남; `before`는 invalid/missing이면 0으로 처리 |

<a id="op-post-api-tasks-id-chat-side-questions"></a>
## `POST /api/tasks/{id}/chat/side-questions`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `handleSideQuestions` · `server/side_questions.go` · [handler 근거](evidence:handler-post-api-tasks-id-chat-side-questions) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 202, 400, 401, 404, 409, 429, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-tasks-id-chat-side-questions) |
| 반복·완료 | 같은 client_request_id+question은 기존 request를 200으로 반환; 같은 ID의 다른 question은 409 · side-question session/request 시작; events/terminal request state가 완료 기준 |

<a id="op-delete-api-tasks-id-chat-side-questions"></a>
## `DELETE /api/tasks/{id}/chat/side-questions`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `handleSideQuestions` · `server/side_questions.go` · [handler 근거](evidence:handler-delete-api-tasks-id-chat-side-questions) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [C: 직접 scalar/static top-level key와 field type을 추출; nested 내부 schema는 별도 type 참조가 없으면 P](schema-reference.md#schema-delete-api-tasks-id-chat-side-questions) |
| 반복·완료 | Idempotency-Key/If-Match 없음; 반복 시 응답/존재 검사가 달라질 수 있음 · active run에 cancel을 요청하고 DB history clear 후 응답; run goroutine 종료까지 기다리지는 않음 |

<a id="op-get-api-tasks-id-intents-iid-side-questions"></a>
## `GET /api/tasks/{id}/intents/{iid}/side-questions`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `handleSideQuestions` · `server/side_questions.go` · [handler 근거](evidence:handler-get-api-tasks-id-intents-iid-side-questions) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id, iid` · query `before` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-get-api-tasks-id-intents-iid-side-questions) |
| 반복·완료 | read/stream 요청; stream 재연결은 cursor 계약에 따름 · history/current snapshot 조회가 응답 전에 끝남; `before`는 invalid/missing이면 0으로 처리 |

<a id="op-post-api-tasks-id-intents-iid-side-questions"></a>
## `POST /api/tasks/{id}/intents/{iid}/side-questions`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `handleSideQuestions` · `server/side_questions.go` · [handler 근거](evidence:handler-post-api-tasks-id-intents-iid-side-questions) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id, iid` · query `-` · body `JSON` |
| status/error | 직접 관찰 `200, 202, 400, 401, 404, 409, 429, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [P: top-level key는 직접 추출했지만 derived/helper/opaque 또는 nested type이 남음](schema-reference.md#schema-post-api-tasks-id-intents-iid-side-questions) |
| 반복·완료 | 같은 client_request_id+question은 기존 request를 200으로 반환; 같은 ID의 다른 question은 409 · side-question session/request 시작; events/terminal request state가 완료 기준 |

<a id="op-delete-api-tasks-id-intents-iid-side-questions"></a>
## `DELETE /api/tasks/{id}/intents/{iid}/side-questions`

| 계약 | 확인 결과 |
|---|---|
| 등록·handler | `handleSideQuestions` · `server/side_questions.go` · [handler 근거](evidence:handler-delete-api-tasks-id-intents-iid-side-questions) |
| 인증 | JWT 필요; `extractToken`이 Bearer→cookie→query `token` 순으로 선택 |
| wire 입력 | path `id, iid` · query `-` · body `없음(직접 body decode 미발견)` |
| status/error | 직접 관찰 `200, 400, 401, 404, 409, 500, 503` · 일반 error body `{error:string}`; helper status는 schema에서 P/U |
| 응답·validation | [C: 직접 scalar/static top-level key와 field type을 추출; nested 내부 schema는 별도 type 참조가 없으면 P](schema-reference.md#schema-delete-api-tasks-id-intents-iid-side-questions) |
| 반복·완료 | Idempotency-Key/If-Match 없음; 반복 시 응답/존재 검사가 달라질 수 있음 · active run에 cancel을 요청하고 DB history clear 후 응답; run goroutine 종료까지 기다리지는 않음 |

<a id="api-page-limit"></a>
## 이 페이지의 확인 한계

- route registration/auth/handler 직접 목적지는 전수 확인했다.
- field/schema/error/side-effect 의미는 별도 schema page의 C/P/U가 권위다.
- OpenAPI가 없고 실제 HTTP server는 실행하지 않았다. helper 내부·외부 서비스·DB 운영 상태는 정적 소스 이상으로 보장하지 않는다.
