Skip to content

Latest commit

 

History

History
507 lines (389 loc) · 8.78 KB

File metadata and controls

507 lines (389 loc) · 8.78 KB

API_CONTRACT.md — TrustOps P0 API 契约

版本:v1.1
语言:中文为主,关键术语保留英文
状态:Frozen for P0 Implementation
Canonical API:/api/v1


1. 边界

Browser
→ Next.js BFF
→ FastAPI
→ Domain Services
→ AgentTeams / Skill Runtime
→ PostgreSQL / Object Storage / Adapters

本地与比赛 SSE 可由 Browser 直连 FastAPI。


2. 通用请求头

Authorization: Bearer <token>
X-Request-ID: req_...
Idempotency-Key: ...
If-Match: "<resource-version>"

关键命令必须使用 Idempotency-Key。


3. 成功响应

{
  "data": {},
  "meta": {
    "request_id": "req_001",
    "timestamp": "2026-08-02T12:00:00Z"
  }
}

异步命令:

202 Accepted
{
  "data": {
    "command_id": "cmd_001",
    "status": "ACCEPTED",
    "run_id": "run_001",
    "status_url": "/api/v1/runs/run_001",
    "events_url": "/api/v1/runs/run_001/events"
  }
}

4. 错误

{
  "error": {
    "code": "CONTROL_DRIFT_UNRESOLVED",
    "message": "Technical message.",
    "user_message": "当前仍存在未解决的控制漂移。",
    "retryable": false,
    "details": {},
    "allowed_actions": ["REQUEST_RECHECK"]
  },
  "meta": {
    "request_id": "req_001",
    "trace_id": "trace_001"
  }
}

5. Reviews

POST /api/v1/reviews
GET  /api/v1/reviews/{review_id}
GET  /api/v1/reviews
POST /api/v1/reviews/{review_id}/validate-inputs

6. Questionnaire

POST /api/v1/reviews/{review_id}/questionnaires
GET  /api/v1/questionnaires/{questionnaire_id}
POST /api/v1/questionnaires/{questionnaire_id}/reparse

上传返回 202。


7. Documents

POST /api/v1/reviews/{review_id}/documents
GET  /api/v1/documents/{document_id}
GET  /api/v1/document-versions/{document_version_id}
GET  /api/v1/reviews/{review_id}/evidence
GET  /api/v1/evidence-chunks/{evidence_chunk_id}

8. Start LIVE_AI Run

POST /api/v1/reviews/{review_id}/runs
{
  "execution_mode": "LIVE_AI",
  "agent_runtime": "AGENTTEAMS",
  "scope": {
    "type": "REVIEW",
    "question_ids": null
  },
  "model_policy": {
    "allow_manual_model_retry": true,
    "allow_silent_model_fallback": false
  }
}

若 AgentTeams 未准备,返回 503,不创建 TEST Run。


9. Run

GET  /api/v1/runs/{run_id}
POST /api/v1/runs/{run_id}/cancel
GET  /api/v1/runs/{run_id}/tasks
GET  /api/v1/runs/{run_id}/trace

10. AgentTask

GET  /api/v1/agent-tasks/{agent_task_id}
POST /api/v1/agent-tasks/{agent_task_id}/retry

Retry 创建新 TaskAttempt。


11. SSE

GET /api/v1/runs/{run_id}/events
Accept: text/event-stream
Last-Event-ID: evt_...

Event envelope:

{
  "event_id": "evt_001",
  "event_type": "agent_task.completed",
  "timestamp": "...",
  "organization_id": "org_001",
  "review_id": "review_001",
  "run_id": "run_001",
  "question_id": "q_005",
  "trace_id": "trace_001",
  "span_id": "span_001",
  "data": {}
}

Canonical events 见 ARCHITECTURE.md。


12. Questions

GET /api/v1/reviews/{review_id}/questions
GET /api/v1/questions/{question_id}/decision-context

Decision Context 必须返回:

{
  "question": {},
  "answer": {},
  "evidence": [],
  "control_snapshots": [],
  "control_evaluations": [],
  "risk_review": {},
  "findings": [],
  "statuses": {
    "question": "BLOCKED",
    "evidence": "VERIFIED",
    "control": "DRIFT",
    "approval": "LOCKED",
    "exception": "NONE",
    "export_gate": "BLOCKED"
  },
  "allowed_actions": [
    "REQUEST_RECHECK",
    "EDIT_AND_DISCLOSE_EXCEPTION",
    "REJECT"
  ]
}

13. Answer

POST /api/v1/questions/{question_id}/answer-versions
POST /api/v1/questions/{question_id}/redraft

Redraft 返回 AgentTask,不立即返回固定答案。


14. Controls

GET /api/v1/reviews/{review_id}/controls
GET /api/v1/control-snapshots/{control_snapshot_id}
GET /api/v1/control-evaluations/{control_evaluation_id}
GET /api/v1/controls/{control_definition_id}/snapshots?review_id=...

Snapshot 与 Evaluation 分离。


15. Recheck

POST /api/v1/questions/{question_id}/rechecks
GET  /api/v1/rechecks/{recheck_request_id}
{
  "control_definition_id": "IAM_MFA_COVERAGE",
  "previous_snapshot_id": "snapshot_c1",
  "reason": "Exceptions were remediated.",
  "execution_mode": "LIVE_AI"
}

必须产生真实 AgentTask 与新 Snapshot。


16. Risk Review

GET  /api/v1/risk-review-results/{risk_review_result_id}
POST /api/v1/questions/{question_id}/risk-reviews

Reviewer 失败时仍返回持久化的 Fail-closed RiskReviewResult:

{
  "status": "FAILED",
  "decision": "BLOCK",
  "source": "SYSTEM_FAIL_CLOSED",
  "findings": [
    {"finding_type": "REVIEWER_UNAVAILABLE", "severity": "BLOCKING"}
  ]
}

17. Exception Disclosure

POST /api/v1/questions/{question_id}/exception-disclosures

创建后必须重新 Review。


18. ApprovalRequest

POST /api/v1/questions/{question_id}/approval-requests
GET  /api/v1/approval-requests/{approval_request_id}
GET  /api/v1/approval-requests?status=PENDING

19. ApprovalDecision

POST /api/v1/approval-requests/{approval_request_id}/decisions
{
  "decision": "APPROVE",
  "answer_version_id": "answer_v2",
  "risk_review_result_id": "risk_review_v2",
  "evidence_document_version_ids": ["doc_v3_2"],
  "control_snapshot_ids": ["snapshot_c2"],
  "comment": "Reviewed and approved."
}

后端必须重新校验版本。


20. Export Preview

POST /api/v1/reviews/{review_id}/exports/preview

返回 counts、blocking questions、actions、version_set_hash 和 gate status。


21. Export

POST /api/v1/reviews/{review_id}/exports
GET  /api/v1/exports/{export_id}
GET  /api/v1/exports/{export_id}/manifest
GET  /api/v1/exports/{export_id}/files/{file_id}/download

创建时重新 Gate,不信任 Preview。


22. Completion Report

GET /api/v1/reviews/{review_id}/completion-report

返回:

  • evidence_backed;
  • control_verified;
  • human_approved;
  • exception_disclosed;
  • needs_confirmation;
  • excluded;
  • blocking。

23. Trace

GET /api/v1/runs/{run_id}/trace
GET /api/v1/traces/{trace_id}/spans/{span_id}
GET /api/v1/model-calls/{model_call_id}
GET /api/v1/skill-invocations/{skill_invocation_id}

默认脱敏。


24. RunRecording

POST /api/v1/runs/{run_id}/recordings
GET  /api/v1/run-recordings/{run_recording_id}
GET  /api/v1/run-recordings/{run_recording_id}/events

必须返回:

{
  "presentation_mode": "RECORDED_REAL_RUN",
  "source_run_id": "run_001",
  "source_execution_mode": "LIVE_AI",
  "is_current_live_execution": false
}

25. 核心错误码

AUTHENTICATION_REQUIRED
PERMISSION_DENIED
ORGANIZATION_SCOPE_VIOLATION
REVIEW_NOT_FOUND
REVIEW_STATE_CONFLICT
QUESTION_STATE_CONFLICT
ANSWER_VERSION_CONFLICT
RISK_REVIEW_VERSION_CONFLICT
CONTROL_SNAPSHOT_VERSION_CONFLICT
APPROVAL_VERSION_CONFLICT
CONTROL_DRIFT_UNRESOLVED
CONTROL_UNAVAILABLE
CONTROL_SNAPSHOT_STALE
EVIDENCE_MISSING
EVIDENCE_EXPIRED
INVALID_CITATION
LIVE_AI_RUNTIME_NOT_READY
AGENTTEAMS_UNAVAILABLE
AGENT_TASK_FAILED
MODEL_CALL_FAILED
MODEL_TIMEOUT
STRUCTURED_OUTPUT_INVALID
SKILL_INVOCATION_FAILED
SKILL_PERMISSION_DENIED
REVIEWER_UNAVAILABLE
BLOCKING_FINDING_OPEN
APPROVAL_LOCKED
APPROVAL_REQUIRED
APPROVAL_INVALIDATED
EXPORT_BLOCKED
EXPORT_VERSION_CONFLICT
EXPORT_GENERATION_FAILED
IDEMPOTENCY_KEY_REQUIRED
IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_PAYLOAD

26. 安全规则

  • Agent 不能调用 Human Approval Endpoint;
  • Browser 不直接调用模型;
  • Browser 不直接调用 Control Adapter;
  • 下载检查 Organization / Role / Classification;
  • Secrets 不进入 API / SSE / Trace;
  • Mock / Live / Recorded 明确返回。

25. 版本绑定与并发规则

以下 Command 必须接收客户端预期版本或版本集合 Hash:

编辑 Answer
请求 Recheck
请求 Approval
提交 ApprovalDecision
创建 Export

当服务端当前版本与客户端预期不一致时,返回:

409 Conflict

并提供:

{
  "error": {
    "code": "VERSION_SET_CHANGED",
    "user_message": "相关答案、证据、控制快照或审查结果已经变化,请刷新后重新确认。",
    "retryable": false
  }
}

26. API 真相边界

  • API 不接受前端传入的 APPROVED 或 READY 作为正式状态;
  • SSE 事件只用于通知,最终状态仍可通过 Query API 校准;
  • Agent 输出通过内部 Runtime Contract 进入 Domain Service,不能由浏览器提交;
  • 下载地址必须是短期授权地址或受鉴权端点;
  • Trace API 不返回 Secret、完整 Restricted Document 或隐藏 Chain-of-Thought。