# 如何将代理证据与调查员笔记分开

代理调查一旦让分析员把证据文件当成笔记本使用，就会出问题。这种冲动完全可以理解。你手里有一份加密审计记录、一个异常的出站请求，还有截止时间。你解密或导出记录，在可疑调用旁边添加评论，为了让时间线更易读而重新排列几个字段，然后把结果保存为案件记录。几个月后，没有人能分清代理做了什么，以及调查员认为这意味着什么。

保持原始加密记录不变。把每一项结论、问题、假设和更正放入独立的案件文件，并通过稳定的会话和调用标识符指回源记录。这样的划分听起来有些讲究，直到有人质疑调查结果、第二位分析员接手工作，或者法务询问调查开始前究竟有哪些字节已经存在。那时，它决定了你拥有的是可审计的事实记录，还是一份看起来很有说服力、却无人知道来历的文件。

## 证据和分析回答的是不同问题

证据回答的是：「系统保存了哪条记录？」调查员笔记回答的是：「我认为这条记录说明了什么？」这两个问题彼此相关，但处理方式必须不同。前者需要保持稳定，后者则会随着案件进展不断变化。

加密审计记录可能包含令人不安的事实：代理进程调用了带凭据的 HTTP 操作，某条 SSH 命令返回了异常结果，或者用户批准了一次运行，但之后的行为与预期不同。记录不是草稿。不要润色其中的措辞，不要删除看起来无关的条目，也不要把时间戳改写成更易读的格式。即使是看似无害的编辑，也会破坏一个基本审查问题的清晰答案：这还是系统生成的那条记录吗？

笔记必须保持可编辑，因为严谨的调查会不断修正自身。早期笔记可能写着：「调用 c-204 似乎发送了客户数据。」读过请求和响应上下文后，分析员可能会改成：「调用 c-204 在请求标头中发送了一个内部标识符；记录无法证明客户数据离开了该环境。」这样的更正是健康的。它属于案件文件，因为这体现的是推理过程发生了变化，而不是证据被修改了。

人们经常混淆的是保存与可读性。解密、导出、搜索、解析和渲染会让证据更容易使用，但它们不会把输出变回原件。JSON 导出文件、电子表格、PDF 打印件或粘贴的文字记录都属于衍生物。它们可能准确且有用，但必须标明生成方式，以及它们来自哪个被保存的对象。

把这当作一条工作规则：源记录只读，所有解释性句子都放在别处。这条规则也让协作更稳妥。第二位分析员可以不同意你的结论，却不必触碰源记录；审查员也可以检查你的引用，而不必重建你曾经编辑过什么。

## 稳定标识符让结论可以验证

一项结论应该引用能够支持它的最小稳定单位。在代理活动中，这通常意味着代理运行的会话标识符，以及具体操作的调用标识符。如果两者之间的关系很重要，就同时使用。

会话标识符回答：「我们讨论的是哪次代理进程运行？」调用标识符回答：「这次运行中的哪项具体 HTTP 或 SSH 操作支持该结论？」单独来看，任何一个标识符都不能证明什么。它们是持久的地址。证据来自该地址处保存的记录，以及你对记录内容的解释。

如果系统已经分配了标识符，就不要另造一套易读的编号方案。分析员有时会写「审批后的第三个请求」或「14:00 左右的请求」。这些说法可能方便读者理解，但不适合作为引用。视图筛选后，时间线可能发生变化；不同设备的时钟可能不一致；后续记录也可能让「第三个」变得含义不明。系统分配的会话和调用 ID 比这些文字捷径更能经受排序、导出和交接。

在独立的案件文件中使用结论表。你不需要案件管理产品。只要结构清晰的普通文档能够保留结论与引用之间的区别，就足够了。

| 结论 ID | 调查员结论 | 证据引用 | 状态 |
| --- | --- | --- | --- |
| C-01 | 代理运行在首次授权后访问了支付 API。 | 会话 `s-7f31`；调用 `c-204`、`c-205` | 已支持 |
| C-02 | 该请求修改了一条支付记录。 | 会话 `s-7f31`；调用 `c-205`；响应记录 | 未解决 |
| C-03 | 人类有意进行这项修改。 | 审批记录；没有调用证据能证明意图 | 不支持 |

这张表有两个作用。第一，它能防止读者把引用误认为解释。第二，它让分析员可以把一个看似合理的故事标记为不支持，而不必删除它。案件压力变大时，这一点很重要。人们经常删除没有成立的理论，之后却无法解释团队为什么排除了这些可能性。

准确使用源记录公开的标识符。不要自行假定它们的格式、长度，或超出系统文档所述范围的全局唯一性。如果一个标识符只有在某份收集到的日志中才有意义，就在旁边记录日志或证据包的标识符。稳定并不意味着它无所不能，而是意味着另一位调查员可以根据同一份保存下来的源记录解析出该引用。

## 可读导出文件是衍生物，不是记录本身

大多数调查都需要可读视图。你不可能靠眯着眼睛检查加密字节，也不该假装可以。可以创建用于审查的衍生物，但在开始标注前，必须明确它与源记录的关系。

先建立一条证据登记项。记录案件引用、原始文件或软件包名称、采集时间和来源、采集人员、已知的会话范围，以及验证结果。补充验证时使用的命令，并将完整的终端输出与案件材料一起保存。不要用假设填补空白。如果不知道采集人员或采集时间，就写「未知」，并提出一个待解决问题。

Sallyport 从一份只写不可变、加密且由哈希链保护的审计日志中生成 Sessions 和 Activity 日志。它的离线验证器不需要保险库密钥，因此调查员可以先验证保存下来的加密材料，再请相关人员开放可读内容：

```
sp audit verify <preserved-audit-record>
```

在证据登记表中记录实际使用的命令、参数、退出状态和完整输出。不要因为某个命令「应该」能运行，就在报告中写一行虚构的成功信息。输出本身就是验证事件的一部分。如果验证失败，就不要再把后续解读当作已经确定的证据。保留失败结果；如果可能，重新收集完整源记录，并解释中断原因，不要悄悄换成之后导出的文件。

然后创建一个名称能够说明其性质的审查副本。例如：

```
case-2026-041/
  original/
    audit-record.enc
  verification/
    verify-command.txt
    verify-output.txt
  derivatives/
    activity-readable-2026-07-24.json
  notes/
    findings.md
    claim-table.md
```

这些文件夹名称本身并不能构成保管链，但它们会促成一个有用的习惯：原始记录、验证材料、可读副本和分析内容不属于同一个概念类别。限制原始目录的写入权限。如果存储控制无法做到这一点，就在证据流程允许的地方计算并记录摘要，然后创建一份新的工作副本用于分析。目标是让意外编辑一目了然，并且能够恢复。

不要因为自己没有手动编辑文字，就把转换后的文件称为「原始文件」。解密、解析、筛选、美化打印、标准化时区或删除字段的工具，都改变了记录的表示形式。这种转换完全可能合理，但要明确标注。

## 重新序列化记录会制造无法自证的争议

重新序列化，是指解码结构化内容后再次写出。调查员在重新格式化 JSON、保存电子表格、重新生成报告，或让数据经过会自行决定字段顺序和转义方式的解析器时，都会这样做。它看起来没有问题，因为语义内容可能完全相同。但在受到质疑的调查中，「看起来相同」是一个糟糕的标准。

假设分析员把活动导出为 JSON，按本地显示时间对调用排序，添加一个 `reviewed: true` 字段，然后将文件保存为 `audit-final.json`。之后，审查员发现两个事件显示的秒数相同，但它们在源记录中的顺序很重要。此时，导出文件已经无法告诉审查员排序是否保留了源记录顺序。如果解析过程中发生错误，修改后的文件还可能掩盖问题。分析员现在必须为工具链和工作流程辩护，而不能直接指向一份保存下来的记录。

另一个常见问题是用替换方式脱敏。有人把看起来像凭据的值改成 `REDACTED`，然后把编辑后的记录作为证据传阅。这会带来两个问题。那个值可能根本不是凭据，而且如果团队没有记录每一处变化，审查副本与原始记录之间的差异位置也无法确定。请对副本进行脱敏，将其标记为脱敏衍生物，并在适当的访问控制下保留源记录。

人的笔记也可能不小心重新序列化证据。粘贴到工单中的请求正文可能丢失转义、空格、顺序或不可打印字符。截图可能隐藏可见区域之外的内容。报告中的引文可能省略改变请求含义的响应。先引用调用 ID。只引用解释结论所必需的最少文字，并说明引文来自可读副本。

一份好的案件文件会用其他人能够验证的文字记录转换过程。例如：「D-03 来自原始对象 O-01，且 O-01 已成功通过离线验证。导出过程为审查解密了记录，将视图限制在会话 s-7f31 内，并未覆盖 O-01。」如果你进行了筛选，就写明。如果你标准化了时区，就写明。如果工具丢弃了字段，也要写明。意外的证据漂白往往藏在沉默之中。

## 审批记录会缩小结论范围，但不会决定其含义

审批记录能证明的事情，比人们希望它证明的更有限。它可以显示某人批准了某次特定的代理进程运行，或者在需要逐次调用控制时，批准了某次凭据使用。但它不能证明这个人阅读了每项拟执行的操作、理解了每个后果，或有意造成最终的业务变化。

当调查触及一个令人不安的问题时，这个限制很重要：「用户授权了吗？」不要用一个词回答。把这句话拆开来看。用户可能授权了进程在该会话中运行。进程之后可能使用了某项凭据。请求可能成功了。最终操作仍可能超出这个人以为自己允许的范围。证据可以支持其中一些命题，同时让其他命题保持开放。

Sallyport 的决策阶梯把这些区别具体化了。保险库锁定时会拒绝所有操作。默认启用的按会话授权，会批准一个新发现的代理进程运行，直到它退出。按调用密钥设置要求每次使用该凭据都获得审批。调查应先确定适用的是哪项控制，再只陈述该控制能够证明的内容。

撰写结论时，要让这条边界清晰可见。「证据显示，用户批准了会话 s-7f31 中经过签名的进程」是关于会话授权的结论。「证据显示，用户批准了调用 c-205」则需要该调用对应的逐次审批记录。「用户有意修改了一条支付记录」需要有关意图的证据，而这些证据可能完全不在操作日志中。不要因为前一句方便，就把它升级成第三句。

这是分析员经常提出、而我不赞成的一种建议：把所有审批都视为知情同意的等价证据。这个建议很受欢迎，因为它能给出简单的结论。但它是错误的，因为不同控制的范围不同。运行级审批与操作级审批回答的是不同问题，任何一种审批都不能读懂人的想法。

## 编写可以修改而不会污染案件的笔记

笔记应该方便修正，同时让作者和时间清晰可见。一条好的调查结论应包含主张、理由、引用、限制和处置结果，不需要使用戏剧化的叙事口吻。

可以采用这样的格式：

```markdown
Finding: The agent called the payment API after session approval.

Claim: Session s-7f31 included a credentialed HTTP call to the payment API.
Evidence: Session s-7f31; call c-205; derivative D-03.
Reasoning: The call record identifies the configured HTTP channel and the destination represented in the record.
Limits: This record does not establish the human's business intent or the full downstream effect.
Analyst: initials
Recorded: 2026-07-24T18:32:00Z
Status: supported
```

「推理」这个字段很有价值。只有一串 ID 不能构成调查结论。说明你推断出的联系，也说明记录无法证明什么。当结论的边界被清楚写出时，读者反而更容易信任它。

不要把会变化的个人注释放进证据文件名或对象元数据中。像 `bad-call-confirmed.enc` 这样的文件名，会把观点伪装成源记录的事实。应使用 `O-01-audit-record.enc` 这样的中性证据名称，并把观点放在 `F-04-findings.md` 中。当「已确认」在第二次审查后变成「不支持」时，这样做能避免很多麻烦。

在笔记中，把观察与结论分开。观察可以写成：「c-205 的活动记录报告了成功响应。」结论可以写成：「代理很可能完成了请求的操作。」前者取决于记录的内容。后者取决于成功响应对该 API 意味着什么，可能还需要 API 文档或独立的系统记录。标明这条边界，可以防止分析员把解读偷偷塞进所谓的事实中。

如果有多人参与案件，就让他们在笔记中保留分歧。为每个相互竞争的结论分配结论 ID 和证据引用。不要把分歧合并成一句毫无信息的共识。之后的审查员应该能看出证据是否解决了争议，还是团队只是停止了讨论。

## 失败的时间线通常始于一次看似无害的编辑

设想这样一个事件：一个编程代理访问了内部部署 API。操作员发现一项陌生变更，于是把活动日志导出到电子表格。为了让表格更易读，操作员按本地时间排序，删除看起来重复的字段，并给认为可能是原因的那一行上色。随后，他们添加评论：「代理部署了未经批准的配置」，然后把工作簿发给响应团队。

第一个问题出现了：另一位分析员询问是哪一个进程发起了调用。电子表格中虽然保留了调用 ID，但会话 ID 列已经被当作「重复」字段删除。团队无法快速区分不同的运行。操作员记得所有行都来自同一次运行，但记忆不是引用。

第二个问题出现在团队将该操作与审批记录进行比较时。工作簿显示了一个相近的审批时间，但没有保留足够的上下文，无法证明这次审批适用于整个运行，还是只适用于某一次凭据使用。评论已经影响了讨论，因此人们开始争论这项操作是否未经批准，而不是先确认记录中的审批属于哪种类型。

第三个问题出现在部署团队说明 API 响应的含义是「已接受处理」，而不是「配置已部署」时。被标色的那一行是真实的，但结论范围过大。由于操作员把结论放进了看似证据的文件中，读者把它当成记录本身的属性，而不是可能出错的解读。

更清晰的重建方式会是这样。将加密审计记录作为 O-01 保存。针对 O-01 运行 `sp audit verify`，并保存命令结果。创建 D-01 作为可读视图。在案件文件中分别写出三个结论：哪个会话发起了哪个调用、审批范围是什么，以及响应能够证明什么。第三个结论可能需要部署系统的记录。如果仍无法确定，就保持未解决。这并不是调查不完整，而是一份诚实的调查。

挽救这起案件的细节很不起眼：调用 c-205 不等于写在调用 c-205 上的那句话。前者是指向保存下来的活动记录，后者是带有作者、日期且可能出错的结论。

## 必须先验证，再让解读固化

在团队围绕证据建立故事之前，先验证保存下来的审计材料。一旦某种理论在聊天、工单和会议中流传，人们就会开始按照它来阅读记录。此时，验证很容易变成在结论已经获得群体认可之后才进行的仪式。

流程应该很简单。收集源记录时不要修改它。记录来源和经手人员。使用受支持的离线命令验证加密材料。保存验证结果。完成这些步骤后，再创建带有明确标记的可读副本。最后开始填写结论表和调查笔记。

哈希链验证尤其有用，因为它可以在不需要保险库密钥的情况下检查保存下来的加密记录。这样就能把两个经常被混为一谈的问题分开：「记录是否保持了链的完整性？」以及「谁有权读取敏感内容？」调查员可以回答第一个问题，而不必仅仅为了执行基本的完整性检查就扩大秘密信息的访问范围。

验证成功并不能确定源记录的身份、所收集范围之外的完整性，或对记录的解读。它只能说明验证器接受了提交给它的链。请记录实际收集的范围。如果案件涉及首次保留会话之前可能存在的缺口，除非你确定收集内容包含相关的更早历史，否则不要写「审计显示之前没有操作」。更稳妥的说法是：「收集到的记录中没有更早的此类操作。」

撤销也适用同样的原则。日志中可能记录了会话撤销，但那条记录描述的是控制事件及其记录的范围。它不会自动解释撤销前已经完成的操作、外部服务已经接受的工作，或响应通道之外的副作用。每个命题都应关联到能够支持它的记录。

## 审查案件文件，不要修改源记录

证据应该保持稳定，调查结论应该接受审查。让审查员质疑每项结论与所引用会话或调用之间的联系，而不是让他们比较多个无法解释的修改版导出文件。

一次有用的审查可以直接提出四个问题：

1. 我能否在保存下来的记录或有文档说明的副本中找到每个被引用的会话和调用？
2. 这项结论是否区分了记录中的事件与分析员的推断？
3. 所述审批范围是否与得出的结论相符？
4. 作者是否说明了会影响该结论的转换、筛选、脱敏或缺失上下文？

如果审查员无法回答其中任何一个问题，除非源记录本身收集错误，否则修复工作就应放在案件文件中。不要为了让副本符合期望的叙事而直接修改它。修正副本生成流程，重新生成带有明确标记的新副本；如果早期副本影响了重要结论，就保留它。

对于使用 Sallyport 的团队，Sessions 日志和 Activity 日志提供了两个自然的引用层级，而即时会话撤销则提供了一个需要单独检查的控制事件。把这些记录作为锚点，而不是分析的替代品。日志可以告诉你它记录了什么；案件文件必须解释团队根据这些记录能够负责任地得出什么结论。

收集完成后的第一步应该平淡而准确：保留原始记录，完成验证，并在旁边创建一个空的结论文件。只有在能够引用支持结论的会话和调用后，才写下第一项结论。这个小小的纪律，可以避免数月后围绕调查发生变化时证据是否也发生变化的争论。
