Files
Agentswarm/docs/integration/audit-trace-schema.md
T
Songhaoz666andClaude Opus 4.8 af4ace4340 审计/链路追踪落地(可回放审计记录 FROZEN v1)(Refs #17)
issue #17 要求「每步 trace 可回放(谁/何模型/何工具/何审批)+ schema 冻结 + 测试」。
本仓已持久化事件流 + 任务谱系 + 每任务 usage(model_id) + 审批;本 PR 把它们规整为
统一、有序、可回放的审计记录并冻结 schema。

代码:
- orchestrator/audit.py(新,纯模块,无 Redis/WS/FastAPI/模型):build_audit_trace(
  events, task_facts, approvals, lineage) 逐事件产审计记录(who/when/model_id/tool_count/
  approval{id,decision}/result/lineage),audit_id 由序位确定(非随机,可字节级复现);
  replay(records) 产人读步骤行。无内容、无密钥、缺信号不伪造(model/tool 缺则 null)。
- orchestrator/main.py:build_audit_trace_for_run(装配器,从 list_events + 任务 usage +
  run.approvals 取数)+ 读接口 GET …/{id}/audit(三别名路由,复用既有鉴权)。

文档:docs/integration/audit-trace-schema.md → FROZEN v1:§3.1 回放装配、§5 冻结记录形;
诚实标注**有意排除**(prompt/代码原文、model 请求响应体刻意不留痕——无内容原则;
无 SK/MCP 工具层故无工具名谱系),按规则 #9 不伪造、不在本次扩展。

测试:scripts/test-audit-trace.py(纯模块 + 集成):逐步 who/model/tool/approval 重建、
result 归类、有序回放、**断言无 secret_ref/azkv/明文泄漏**;接入 CI。

影响范围:仅 agent_swarm(orchestrator 新增只读审计接口 + 纯模块 + 文档 + 测试 + CI)。
- Manager:新增只读 GET …/{id}/audit;不改回调/契约/计费/审批链。
- 密钥/审计:审计记录只含非内容元数据 + secret_ref 永不写入;归因按 user/channelId,不引入 tenant。

Refs #17

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 18:06:50 +08:00

7.3 KiB
Raw Blame History

审计与链路追踪 Schema(Audit / Lineage / Trace)

状态:FROZEN v1(可回放审计记录已落地) —— 回应 issue #17。每步 trace(谁/何时/何模型/何工具/何审批/结果/lineage)可由 orchestrator/audit.py 的纯装配器从已持久化的事件流 + 任务谱系 + 审批重建并按序回放;读接口 GET …/{id}/audit。契约测试 scripts/test-audit-trace.py。

诚实边界(规则 #9,本次不扩展):审计记录只含非内容元数据——prompt 原文/代码/对话刻意不留痕(与回调脱敏同源原则);model trace = model_id + token 计数(不留请求/响应体);tool trace = 文件/Git 资源动作计数(本运行时无 SK/MCP 工具层,故无工具名谱系)。这些为有意取舍/后续层,不在本次冻结内。

依据:heicode-mananger/docs/heicode.md §五/§九、docs/heicode-runtime-auth-newapi-secret-design.md §三。配套:event-schema.md、security-boundary.md。

1. 原则

  • 审计要能回答:谁、在什么时候、让哪个子 Agent、使用了什么资源、做了什么、结果如何。
  • AGENT.md / resource context 面向模型理解;permission manifest 面向系统强制执行;审计以结构化记录为准,不以 Markdown 为准。
  • 审计记录不得含明文密钥:只记 secret_ref(azkv://)、审批 approval_id、范围与 TTL。

2. 追踪域(Lineage)

2.1 部署 / 运行链路

manager_deployment_id ↔ deployment_id ↔ swarm_id(workflow_id) ↔ correlation_id(trace_id),四者贯穿一次交付,事件按 swarm_id 持久化。

2.2 任务链路(已实现)

每个任务携带:task_id、parent_task_id、root_task_id、child_task_ids、depends_on、source(runtime_bridge / planner / dynamic_handoff)、agent_role、assigned_agent_id、retry_count、时间戳。可由此重建任务 DAG 与重做/移交谱系。

2.3 执行链路(已实现,基于事件流)

按 swarm_id 顺序持久化的事件即执行轨迹:task.created/claimed/running/heartbeat/blocked/retried/failed/completed、handoff.requested/completed、artifact.created、timeline.updated、deployment.status_changed,每条含 event_id、occurred_at、agent_instance_id、correlation_id。

2.4 审批链路(已实现)

run.approvals[approval_id]:operation、risk_level、decision(approved/rejected)、credential_ref、lease_id、reason、决策时间。客户端审批,运行时仅记录与校验。

2.5 资源 / 凭证访问链路

secret_refs(azkv://,仅引用)、resource grant 的 allowed_actions/constraints/status/created_by/revoked_by/created_at/revoked_at(字段定义在 Manager 侧 heicode.md §五)。本仓只透传与引用,不落明文。

2.6 回调投递链路(已实现)

run.metadata.callback_attempts:每次回调的 event_id、event_type、url、status、attempted_at,用于回调可靠性审计(/diagnostics 暴露)。

3. 已实现(本仓)

能力 实现
事件流持久化 + 分页查询 _store_event(按 swarm_id 追加)、list_events(cursor/limit);/logs、/events 暴露
任务谱系字段 parent/root/child_task_ids、depends_on、source、retry_count
审批记录 run.approvals、record_approval_decision
回调投递审计 callback_attempts、/diagnostics
用量归因 usage + X-Agent-* 归因头(见 usage-billing)
脱敏 _redact_sensitive(保留 secret_ref,脱敏明文密钥)
可回放审计装配 + 回放 orchestrator/audit.py:build_audit_trace(events, task_facts, approvals, lineage) 纯函数把事件流 + 任务(含 usage.model_id/工具计数)+ 审批规整为有序审计记录(§5 冻结形);replay(records) 产人读步骤行。读接口 GET …/{id}/audit(build_audit_trace_for_run)。纯净、确定性、无内容/无密钥。

3.1 回放装配(issue #17)

audit.build_audit_trace 对每条事件产一条审计记录,按存储顺序排列,audit_id 由序位确定(aud_000001…,非随机,同一 run 字节级可复现)。逐步可答:

  • 谁:actor.agent_instance_id(事件携带)/ actor.agent_role(任务谱系回填)。
  • 何模型:model.model_id(取自任务 usage.model_id,缺则 null,不伪造)。
  • 何工具:tool.count(取自任务 tool_calls/tool_count;无工具层时为 null)。
  • 何审批:approval.{approval_id, decision}(取自 payload + run.approvals,绝不含 secret_ref)。
  • 结果:result 由 event_type 归类(completed→success / failed→failed / blocked|approval.rejected→blocked / stopped→stopped / 其余→info)。
  • lineage:四 ID 全量。每条 redacted: true。

4. 覆盖与边界

追踪项 状态
Task lineage / execution trace ✅ 已实现(事件流 + 任务字段)
Approval trace ✅ 已实现(审计记录 approval.{id,decision})
Model trace(model_id + token 计数) ✅ 已实现(审计记录 model.model_id;无请求/响应体——见下「有意排除」)
Tool trace(计数) ✅ 计数已实现(tool.count);工具名谱系 N/A(无 SK/MCP 工具层)
统一审计记录 schema + 回放 ✅ 已冻结(§5)+ 可回放(audit.build_audit_trace/replay,GET …/{id}/audit)
有意排除(非缺口) Prompt/代码/对话原文——刻意不留痕(无内容原则);model 请求/响应体——同上;SK/MCP 工具名谱系——无工具层。这些属取舍/后续层,按规则 #9 不伪造、不在本次冻结。
留存期 / 合规归档策略 🟡 由 Audit & Compliance Team 定(留存期、外部归档),非本仓编排器。

5. 审计记录 Schema(FROZEN v1 —— orchestrator/audit.py 产出形)

{
  "audit_id": "aud_000001",                  // 序位确定(非随机),同一 run 可复现
  "occurred_at": "2026-06-08T...Z",
  "action": "task.completed",                // = event_type
  "actor": { "agent_role": "impl", "agent_instance_id": "agent-7" },  // 谁
  "task_id": "swarm-...-t | null",
  "model": { "model_id": "gpt-x" } | null,    // 何模型(缺则 null,不伪造)
  "tool":  { "count": 2 } | null,             // 何工具(计数;无工具层为 null)
  "approval": { "approval_id": "approval_...", "decision": "approved|rejected" } | null, // 何审批(无 secret_ref)
  "result": "success | failed | blocked | stopped | info",            // 结果
  "lineage": { "manager_deployment_id": "...", "deployment_id": "...", "swarm_id": "...", "correlation_id": "..." },
  "redacted": true
}

归因主轴为 user.id/channelId(见 usage-billing),不引入 tenant;actor 在审计记录中以 agent_role/agent_instance_id 表达执行主体,用户主体由 lineage→Manager 侧关联。

6. 待对齐对象

Audit & Compliance Team:留存期与外部归档策略、合规要求;prompt/model 请求体留痕是否在他处(受隐私/安全约束,本仓默认不留);与 telemetry-architecture(benchmark 目录)数据源对齐。