AIDAWORK / WORKFLOW

Local File V4 与条件产物终态门:从本机三层权威复核到 Carrier 终态封口

独立图页 ↗
机制说明(SoT)图是辅读 · 结论以说明与证据为准

Local File 的模块族与源码目录仍叫 V4(local-files-v4 / local-file-v4);主题 id local-file-v5 沿用旧名。钉点 Agent e2adc9a3c325 / Desktop 8eecd12081db 起(Agent ADR-0090、Desktop ADR-0087),LOCAL_FILES_V4_PROTOCOL_VERSION = 5、capability local-files-v5、schema identity local-file-v5 与全部 Local File feature token 都已删除:两端只剩 `DESKTO…

本页可直接往下读完整机制说明,不需要「演示 / 播放故事」。术语不熟先看 术语表。

先读机制说明,结论以说明与证据为准 · 基于固定代码版本核验 · 部署状态另行确认

机制说明(全文)

Local File V4 path-free(原 wire v5,现归 Desktop 协议 v3)

族名仍是 V4,独立的 Local File 协议版本已删除

Local File 的模块族与源码目录仍叫 V4(local-files-v4 / local-file-v4);主题 id local-file-v5 沿用旧名。钉点 Agent e2adc9a3c325 / Desktop 8eecd12081db 起(Agent ADR-0090、Desktop ADR-0087),LOCAL_FILES_V4_PROTOCOL_VERSION = 5、capability local-files-v5、schema identity local-file-v5 与全部 Local File feature token 都已删除:两端只剩 DESKTOP_PROTOCOL_VERSION = 3(Desktop 侧为生成副本),版本 3 蕴含旧 feature。Agent 是否给模型 V4 工具只看会话载荷里有没有合法的 localFileCapability(localFileV4Admitted);Desktop 端只有 win32 缺 native 后端时才把能力置为不可用(native_backend_unavailable),V4 读不再受托管 Python 探针影响。Local File V4 也是唯一模型可见的文件能力:readFile / writeFile / listDirectory、FileGrant、Transient grant 等旧路径已删除。绝对路径只留在 Electron Main 的 AuthorizedFolder / SelectedFileHandle / Save Destination 底座;出 Main 的 wire 使用 relativePath / attachmentId / saveDestinationId 等 path-free 字段。

对话级附件由 Main 的 assembleSubmittedLocalFileAttachments 组装:Renderer 只提交 path-free Draft intents(attachmentId + displayName + kind),Main 填入 authority id 与 localProjection,组装结果不含绝对路径。Agent 侧 listForConversation(ADR-0079)按对话、installation、identity scope 取每个 attachmentId 的最新 relation。请求与回执账本在 Agent(local_file_operations),Desktop 执行与本机权威底座分离。Local Executor 的本机原语现只剩 readSkillFile / runSkillScript / Skill 管理(见 local-executor),不是本模块。

历史清仓:migration 114(对话级附件列)再 115(在途 v4 ledger cutover);当时仅广告 v4 的桌面端收到 426 LOCAL_FILE_PROTOCOL_UPGRADE_REQUIRED。该码与 localFileProtocolUpgradeRequired 判定已在本钉点删除:不是 v3 的 Desktop 现在统一收到 426 DESKTOP_UPGRADE_REQUIRED(见 trust-boundaries / desktop-runtime;ADR-0093 起 chat POST 没带协议头时,只有携带 localFilesV4 / assembleSubmittedLocalFileAttachments 等本机执行载荷才 426)。Desktop write-state-v4.json(文件版本 3)钉点 8eecd12081db 起存于账号作用域加密信封 LocalSecureEnvelope,旧明文只作迁移来源(见 storage-planes);解析 legacy v1/v2 条目时丢弃不可迁移项并诊断 LOCAL_FILE_WRITE_STATE_LEGACY_DROPPED;protocol-4 回执分支已删除,记录里带 protocolFeatures 字段现在判为 corrupt(升级风险见 storage-planes,未核实)。

文件目标收窄:restrictFileTargets 不再过滤本 Run 内经 request_file_access 拿到的授权(附件查询把这类关系标为 run_request_grant)。Desktop 授权附件改用权威 id 作 attachmentId(文件夹 authorizedFolderId、文件 selectedFileHandleId),同一文件夹不再积累多条关系。

  • aida-agent · packages/agent/src/routing/local-file-targets.ts L77–88 · runRequestGrant · e2adc9a3c325
  • aida-agent · packages/agent/src/session/local-file-message-attachment.ts L191–193 · run_request_grant · e2adc9a3c325
  • aida-desktop · apps/desktop/electron/local-files-v4/file-access.ts L228–230 · attachmentId: folder.authorizedFolderId · 4346d79eb364
  • aida-desktop · apps/desktop/electron/local-files-v4/native-file-backend.ts L159–161 · nativeFileBackendRequiredForPlatform · 4346d79eb364

原件上传(2026-10-12 钉点)

原件上传能力原由 capability local-files-v5-original-content-v1 广告,本钉点该 capability 已删除(v3 蕴含);保留路由 POST /api/local-file/operations/:operationId/original-content:上限 20MB(LOCAL_FILE_ORIGINAL_CONTENT_MAX_BYTES,Gateway bodyLimit 超限 413 LOCAL_FILE_ORIGINAL_CONTENT_OVERSIZE),恢复路径上限 15MB(LOCAL_FILE_ORIGINAL_RESUME_MAX_BYTES);请求须 X-AIDA-Protocol: 3(原 X-Local-File-Protocol-Version: 5)、X-Local-File-Request-Digest、X-Local-File-Content-Sha256 等元数据头与 application/octet-stream,否则 400 LOCAL_FILE_ORIGINAL_CONTENT_METADATA_INVALID。原件落 local_file_operations.original_content(迁移 166);Desktop Main 由 LocalFileOriginalUplink 上传。chat POST 的 Runtime 提交门分别处理 work-v1、skill-v2 与 skillExecutionPolicy 的匹配,原 Work 身份仍是 work-v1;非支持的 wire 或 policy 不匹配返回不同的 426。RUNTIME_WORK_PROFILE_UNSUPPORTED 的 HTTP 状态依具体路径而定(connectorRead 组合限制为 409),不能一律写为 426;见 跨仓协议地图。

  • aida-agent · packages/tool-client/src/types/local-files-v4.ts L5–17 · X-AIDA-Protocol · e2adc9a3c325
  • aida-agent · packages/agent/src/gateway/api-local-file-v4.ts L347–376 · original-content · e2adc9a3c325
  • aida-agent · packages/agent/src/gateway/http.ts L1683–1684 · LOCAL_FILE_ORIGINAL_CONTENT_MAX_BYTES · e2adc9a3c325
  • aida-desktop · apps/desktop/shared/generated/local-files-v4.ts L6–18 · X-AIDA-Protocol · 4346d79eb364
  • aida-desktop · apps/desktop/electron/main.ts L1315 · LocalFileOriginalUplink · 4346d79eb364

跨仓协议对齐与清仓(视图 wire-drift)

视图 wire-drift 是 v4→v5 对齐 + 清仓的历史快照,不是「仍有开放 drift」的告警图,也不再描述现行协议:本钉点下表中三个常量都已删除,由 DESKTOP_PROTOCOL_VERSION = 3 取代。它留在 local-file-v5 主题下作追溯,不单独拆成 topic。

字段 Desktop a96b7a4 Agent b8d4167
源文件 apps/desktop/shared/generated/local-files-v4.ts L5–23 packages/tool-client/src/types/local-files-v4.ts L4–21
LOCAL_FILES_V4_PROTOCOL_VERSION 5 5
LOCAL_FILES_V4_CAPABILITY local-files-v5 local-files-v5
LOCAL_FILE_V4_SCHEMA_IDENTITY local-file-v5 local-file-v5

(表中为当时的钉点 Desktop a96b7a4 / Agent b8d4167。)图:local-file-wire-drift.architecture.json。

426 / cutover 部署序(视图 cutover-deploy,历史)

以下是 v4→v5 清仓时的顺序(ADR-0079 Consequences),已执行完毕,仅作追溯;LOCAL_FILE_PROTOCOL_UPGRADE_REQUIRED 现只存在于历史迁移 115 中。

  1. Agent:migration 114(前置 schema identity = interaction-protocol-v2 / mig 113)→ 115(前置 = conversation-attachments)。
  2. 窗口期:仅广告 localFileProtocolVersions ∋ 4 且不含 5 的 Desktop,在 chat POST、/validate-local-executor(及 preview 同源门)收到 426 LOCAL_FILE_PROTOCOL_UPGRADE_REQUIRED,文案「请更新桌面端后重试」——整轮对话硬门,不是「仅本地文件工具不可用」。
  3. mig 115:将在途 requested 且 request.protocolVersion = 4 的 Operation 标为 expired;等待该 Operation 的 suspended Run 记为 failed(error_code = LOCAL_FILE_PROTOCOL_UPGRADE_REQUIRED),不依赖 TTL drain;并剥离历史绝对路径键。
  4. Desktop:Velopack 启动更新到 V5;之后 path-free wire + 对话级附件可用。

图:local-file-cutover-deploy.sequence.json(catalog 视图 cutover-deploy)。

现行 Gateway 426 协议硬门(Desktop 协议 v3 的 DESKTOP_UPGRADE_REQUIRED、Runtime Execution、Interaction Protocol)见 desktop-runtime NOTES「Gateway 协议硬门族」。

谁是材料权威:Agent 账本 ≠ 本机事实(步进图 A 补记)

  • Agent 侧 localProjection 不是能力判定:local_file_message_attachments 行是有作用域的材料引用;localProjection(available | unavailable | revoked)是 Desktop 附加时的历史快照,Agent 源码注释明确「不得作为当前能力判定;Desktop Main 每次操作前复核 live authority」。
  • Main 复核三件事(每次 Operation 投递都做):
    1. 授权文件夹:requireFolder → V4AuthorizedFolderStore.requireActive,不存在 / 已撤销(AUTHORIZED_FOLDER_REVOKED)/ 根身份(dev+ino)变化即拒绝;
    2. 路径解析:resolveWithinRoot 只接受 folder-relative POSIX 路径,越界(path outside root)拒绝;出 Main 的结果再经 toWireRelativePath 转回相对路径;
    3. 版本 / 绑定:capabilityFingerprint 与本机不符 → capability_unavailable(冻结 protocol features 的检查随 feature token 删除);desktopExecutorInstanceId 代际变化 → capability_unsupported;同一 operationId 不同 requestDigest → conflict;写操作另校验 expected sha256(文件版本)。
  • 回执落账是 CAS:Agent terminalizeRequested 只在 status='requested' AND request_digest=期望值 AND desktop_executor_instance_id 一致 时更新,迟到或错绑定回执不改账本。
  • 读法:Agent 拥有「请求与回执」账本(谁要了什么、结果是什么);Main 拥有「此刻能否碰这块磁盘」的事实。两者不可互相替代。

目录身份摘要、参数纠错窗口与工作台澄清(钉点 Agent e2adc9a3c325 / Desktop 8eecd12081db)

  • directoryIdentityDigest(28a6ec920 / 9fdc200c):列目录回执可带被列目录本身(含空目录)的身份摘要,只能与原列目录的精确路径、actor、Root 和文件夹绑定一起用作改动版本;子项不能代表空父目录,缺失时不猜。发布顺序:先 Agent 后 Desktop(旧的严格 Agent 会拒绝该字段),不需要数据库迁移。
  • 参数纠错窗口(3b4efa961 / ee4a516be):change_files 的参数纠错在用户正式拒绝或 fs/change Operation 已准入后结束,之后由真实效应回执决定;部分 / 未知效应仍被执行阻断,不获得重放额度。
  • 工作台正式澄清(d1ef96997):modify / create 任务经正式澄清后,一次语义复核判断剩余交付是否只在聊天中回答;证据须逐字来自用户输入,判为只聊天时必需工具收窄为 list / search / read 之一,不能换任务、扩大材料或产生新授权;判不清返回可重试的 FILE_DELIVERY_REVIEW_UNRESOLVED。
  • 发布顺序核对:Desktop 列目录无条件带上 directoryIdentityDigest,不按 Agent 版本协商;Agent 28a6ec920 之前的列目录 schema 是 .strict() 且无此字段,旧 Agent 会拒绝。git 上 Agent 先合入(2026-10-21 04:34:48 EDT,3a52e997d),Desktop 12 秒后合入(a45a26e5),Desktop v0.1.62(2026-10-21 05:39 EDT 打 tag)起带该字段、v0.1.61 不带;Agent 仓库没有对应发布 tag,部署先后未核。证据:aida-desktop · apps/desktop/electron/local-files-v4/query-executor.ts L104–144 · directoryIdentityDigest · 4346d79eb364;aida-agent · packages/agent/src/runtime/README.md L149–151 · older strict Agent · e2adc9a3c325
  • 工作台澄清判例:单元测试用桩 LLM 固定返回值,覆盖只聊天收窄为单一读工具、仍要另存不放宽、各类无据或格式错返回 FILE_DELIVERY_REVIEW_UNRESOLVED、旧回答不能证明最新限制、模型失败原样抛出;2026-10-21 在钉点副本中 12 / 12 通过。真实模型判例未跑。证据:aida-agent · packages/agent/tests/unit/gateway/workbench-file-clarification.test.ts L123–155 · FILE_DELIVERY_REVIEW_UNRESOLVED · e2adc9a3c325
  • 证据:aida-agent · packages/tool-client/src/types/local-files-v4.ts L1247–1251 · directoryIdentityDigest · e2adc9a3c325;aida-agent · packages/agent/src/runtime/README.md L144–151 · directoryIdentityDigest · e2adc9a3c325;aida-agent · packages/agent/src/session/local-file-receipt-facts.ts L346–349 · directoryIdentityDigest · e2adc9a3c325;aida-desktop · apps/desktop/electron/local-files-v4/query-executor.ts L104–144 · directoryIdentityDigest · 4346d79eb364;aida-agent · packages/agent/src/orchestrator/drive-react-loop.ts L699–715 · An admitted Operation ends parameter correction · e2adc9a3c325;aida-agent · packages/agent/src/gateway/workbench-file-clarification.ts L31–64 · reviewWorkbenchFileDelivery · e2adc9a3c325;aida-agent · packages/agent/src/gateway/workbench-file-clarification.ts L74–96 · resolveWorkbenchFileClarification · e2adc9a3c325

证据与范围

  • aida-desktop · apps/desktop/shared/generated/protocol-version.ts L1–8 · DESKTOP_PROTOCOL_VERSION · 4346d79eb364

  • aida-desktop · docs/adr/0087-local-capability-convergence-and-protocol-v3.md L22–32 · Protocol v3 · 4346d79eb364

  • aida-desktop · apps/desktop/electron/local-files-v4/assemble-submitted-attachments.ts L49–79 · assembleSubmittedLocalFileAttachments · 4346d79eb364

  • aida-desktop · apps/desktop/shared/ipc-contract.ts L483–506 · localFilesV4 / assembleSubmittedLocalFileAttachments · 4346d79eb364

  • aida-desktop · apps/desktop/electron/local-files-v4/capability.ts L9–11 · assembleLocalFileV4Capability · 4346d79eb364

  • aida-desktop · apps/desktop/electron/local-files-v4/write-state-persistence.ts L730–746 · LOCAL_FILE_WRITE_STATE_LEGACY_DROPPED · 4346d79eb364

  • aida-desktop · apps/desktop/electron/update/velopack-updater.ts L35–65 · installVelopackStartup · 4346d79eb364

  • aida-agent · packages/tool-client/src/types/protocol-version.ts L1–7 · DESKTOP_PROTOCOL_VERSION · e2adc9a3c325

  • aida-agent · packages/agent/src/session/local-file-message-attachment.ts L126–158 · listForConversation · e2adc9a3c325

  • aida-agent · docs/adr/0079-local-file-v5-conversation-attachments.md L1–49 · ADR-0079 · e2adc9a3c325

  • aida-agent · packages/agent/migrations/114_local_file_v5_conversation_attachments.sql L1–40 · 114 · e2adc9a3c325

  • aida-agent · packages/agent/migrations/115_local_file_v5_ledger_cutover.sql L1–120 · 115 · e2adc9a3c325

  • aida-agent · packages/agent/src/runtime/local/local-file-v4-negotiation.ts L26–52 · localFileV4Admitted · e2adc9a3c325

  • aida-agent · packages/agent/src/gateway/chat-routes.ts L520–524 · desktopPayloadVersionUnsupported · e2adc9a3c325

  • aida-agent · packages/agent/src/session/local-file-operation-store.ts L214–245 · LocalFileOperationStore · e2adc9a3c325

  • aida-agent · packages/agent/src/session/local-file-message-attachment.ts L99–102 · historical client snapshot · e2adc9a3c325

  • aida-agent · packages/agent/src/session/local-file-operation-store.ts L369–503 · terminalizeRequested · e2adc9a3c325

  • aida-desktop · apps/desktop/electron/local-files-v4/executor.ts L85–165 · executeDelivery · 4346d79eb364

  • aida-desktop · apps/desktop/electron/local-files-v4/executor.ts L220–243 · executeFresh · 4346d79eb364

  • aida-desktop · apps/desktop/electron/local-files-v4/authorized-folder-authority.ts L437–477 · requireActive · 4346d79eb364

  • aida-desktop · apps/desktop/electron/local-files-v4/relative-wire.ts L23–58 · resolveWithinRoot · 4346d79eb364

结论来自固定版本的静态源码与合同阅读;实现存在、默认开关和生产启用分别判断。本站代码证据面板列出声明状态与具体限制。

Runtime 提交 wire 与原 Work identity

chat POST 的 Runtime 提交门接受缺省/空值(无 policy)、runtime-work-v1(无 policy),以及 runtime-work-skill-v2 且携带合法 skillExecutionPolicy;其他非空头为 RUNTIME_EXECUTION_PROTOCOL_UNSUPPORTED,头与 policy 不匹配为 RUNTIME_WORK_SKILL_POLICY_MISMATCH,均返回 426。原 Work binding 仍是 runtime-work-v1;取消提交、补充材料等路由单独判定,见协议地图。

证据:提交门 与 实际 chat POST 调用。

条件产物不可变重建与 Carrier 终态封口门(视图 conditional-artifact-gate)

当路由决策包含 conditionalArtifactRead 时,模型不能仅凭输出一段文字声称「已处理完文件」就把 Run 置为 completed。finishRuntimeWorkCarrierInTx(run-work-carrier-terminal.ts L11–91)在 outcome === 'completed' 时强制调用 readConditionalArtifactCompletionInTx(run-work-conditional-artifact.ts L49–157),在原 Root/claim fence 下从底层不可变事实表重建完成证明(见视图 conditional-artifact-gate):

  1. 前置门禁与能力快照核验(L52–84):
    • 校验 root.cancel_intent === null、无 hasRuntimeWorkEvidenceConflict、无 hasPendingWorkMaterialAdmission;
    • 通过 PgDesktopSkillSnapshotRegistry.resolveExact 核对 target.producer.skillSource.identity 处于 active,且 admittedSkillPluginTools 中存在唯一匹配的 conditionalArtifactOutput 声明;
    • 查 LocalFileMessageAttachmentStore.listForConversation 核对 target.scope 引用的每一个 attachmentId 与 selectedFileId 都真实绑定在当前会话与 frozenLocalExecutionScope 下。
  2. 6 表关联重建插件回执与消息链(L86–143):
    • 执行 continuation_requests c ⋈ pending_interactions p ⋈ agent_runs r ⋈ runtime_invocations i ⋈ interaction_receipts receipt ⋈ messages m (role='tool') 六表联合查询;
    • 按 work_step_ref(model:<round>:tool:0)严格排序,逐条核对:assertWorkPluginSource 签名一致、m.metadata.receiptId === receipt.id、m.metadata.responseDigest === canonicalJsonSha256(p.response)、以及 assertSettlementFact 领域事实已登记;
    • 收集所有 reply.artifacts 的 { artifactRef, sha256 }(若同一 artifactId 出现不同 sha256 直接抛 RUNTIME_WORK_CONDITIONAL_ARTIFACT_INVALID)。
  3. 完成度双分支判定(L144–156):
    • 确认该 rootRunId 下已没有任何 status = 'pending' 的 continuation_requests;
    • 加载完整运行消息历史并调 projectWorkFileMessagesInTx 投影文件消息;
    • 独立原件读取要求:sourceReadSatisfied = !target.independentSourceRead || attachmentReadsComplete(messages, target.sourceReadAttachmentIds);
    • 条件产物满足判定:
      • 分支 A(conditionNotMet):最新状态为 not_applicable 且 artifacts.size === 0;
      • 分支 B(已产出产物):artifacts.size > 0 且最新状态为 produced | not_applicable,同时每一个产出的 artifact 都通过了 artifactReadsComplete(messages, [...artifacts.values()]) 读取核验;
    • 若 !completion?.satisfied,finishRuntimeWorkCarrierInTx 直接抛 RUNTIME_WORK_CONDITIONAL_ARTIFACT_UNSATISFIED 阻断虚假结案。

机制说明

Local File V4 path-free(原 wire v5,现归 Desktop 协议 v3)

族名仍是 V4,独立的 Local File 协议版本已删除

Local File 的模块族与源码目录仍叫 V4(local-files-v4 / local-file-v4);主题 id local-file-v5 沿用旧名。钉点 Agent e2adc9a3c325 / Desktop 8eecd12081db 起(Agent ADR-0090、Desktop ADR-0087),LOCAL_FILES_V4_PROTOCOL_VERSION = 5、capability local-files-v5、schema identity local-file-v5 与全部 Local File feature token 都已删除:两端只剩 DESKTOP_PROTOCOL_VERSION = 3(Desktop 侧为生成副本),版本 3 蕴含旧 feature。Agent 是否给模型 V4 工具只看会话载荷里有没有合法的 localFileCapability(localFileV4Admitted);Desktop 端只有 win32 缺 native 后端时才把能力置为不可用(native_backend_unavailable),V4 读不再受托管 Python 探针影响。Local File V4 也是唯一模型可见的文件能力:readFile / writeFile / listDirectory、FileGrant、Transient grant 等旧路径已删除。绝对路径只留在 Electron Main 的 AuthorizedFolder / SelectedFileHandle / Save Destination 底座;出 Main 的 wire 使用 relativePath / attachmentId / saveDestinationId 等 path-free 字段。

对话级附件由 Main 的 assembleSubmittedLocalFileAttachments 组装:Renderer 只提交 path-free Draft intents(attachmentId + displayName + kind),Main 填入 authority id 与 localProjection,组装结果不含绝对路径。Agent 侧 listForConversation(ADR-0079)按对话、installation、identity scope 取每个 attachmentId 的最新 relation。请求与回执账本在 Agent(local_file_operations),Desktop 执行与本机权威底座分离。Local Executor 的本机原语现只剩 readSkillFile / runSkillScript / Skill 管理(见 local-executor),不是本模块。

历史清仓:migration 114(对话级附件列)再 115(在途 v4 ledger cutover);当时仅广告 v4 的桌面端收到 426 LOCAL_FILE_PROTOCOL_UPGRADE_REQUIRED。该码与 localFileProtocolUpgradeRequired 判定已在本钉点删除:不是 v3 的 Desktop 现在统一收到 426 DESKTOP_UPGRADE_REQUIRED(见 trust-boundaries / desktop-runtime;ADR-0093 起 chat POST 没带协议头时,只有携带 localFilesV4 / assembleSubmittedLocalFileAttachments 等本机执行载荷才 426)。Desktop write-state-v4.json(文件版本 3)钉点 8eecd12081db 起存于账号作用域加密信封 LocalSecureEnvelope,旧明文只作迁移来源(见 storage-planes);解析 legacy v1/v2 条目时丢弃不可迁移项并诊断 LOCAL_FILE_WRITE_STATE_LEGACY_DROPPED;protocol-4 回执分支已删除,记录里带 protocolFeatures 字段现在判为 corrupt(升级风险见 storage-planes,未核实)。

文件目标收窄:restrictFileTargets 不再过滤本 Run 内经 request_file_access 拿到的授权(附件查询把这类关系标为 run_request_grant)。Desktop 授权附件改用权威 id 作 attachmentId(文件夹 authorizedFolderId、文件 selectedFileHandleId),同一文件夹不再积累多条关系。

  • aida-agent · packages/agent/src/routing/local-file-targets.ts L77–88 · runRequestGrant · e2adc9a3c325
  • aida-agent · packages/agent/src/session/local-file-message-attachment.ts L191–193 · run_request_grant · e2adc9a3c325
  • aida-desktop · apps/desktop/electron/local-files-v4/file-access.ts L228–230 · attachmentId: folder.authorizedFolderId · 4346d79eb364
  • aida-desktop · apps/desktop/electron/local-files-v4/native-file-backend.ts L159–161 · nativeFileBackendRequiredForPlatform · 4346d79eb364

原件上传(2026-10-12 钉点)

原件上传能力原由 capability local-files-v5-original-content-v1 广告,本钉点该 capability 已删除(v3 蕴含);保留路由 POST /api/local-file/operations/:operationId/original-content:上限 20MB(LOCAL_FILE_ORIGINAL_CONTENT_MAX_BYTES,Gateway bodyLimit 超限 413 LOCAL_FILE_ORIGINAL_CONTENT_OVERSIZE),恢复路径上限 15MB(LOCAL_FILE_ORIGINAL_RESUME_MAX_BYTES);请求须 X-AIDA-Protocol: 3(原 X-Local-File-Protocol-Version: 5)、X-Local-File-Request-Digest、X-Local-File-Content-Sha256 等元数据头与 application/octet-stream,否则 400 LOCAL_FILE_ORIGINAL_CONTENT_METADATA_INVALID。原件落 local_file_operations.original_content(迁移 166);Desktop Main 由 LocalFileOriginalUplink 上传。chat POST 的 Runtime 提交门分别处理 work-v1、skill-v2 与 skillExecutionPolicy 的匹配,原 Work 身份仍是 work-v1;非支持的 wire 或 policy 不匹配返回不同的 426。RUNTIME_WORK_PROFILE_UNSUPPORTED 的 HTTP 状态依具体路径而定(connectorRead 组合限制为 409),不能一律写为 426;见 跨仓协议地图。

  • aida-agent · packages/tool-client/src/types/local-files-v4.ts L5–17 · X-AIDA-Protocol · e2adc9a3c325
  • aida-agent · packages/agent/src/gateway/api-local-file-v4.ts L347–376 · original-content · e2adc9a3c325
  • aida-agent · packages/agent/src/gateway/http.ts L1683–1684 · LOCAL_FILE_ORIGINAL_CONTENT_MAX_BYTES · e2adc9a3c325
  • aida-desktop · apps/desktop/shared/generated/local-files-v4.ts L6–18 · X-AIDA-Protocol · 4346d79eb364
  • aida-desktop · apps/desktop/electron/main.ts L1315 · LocalFileOriginalUplink · 4346d79eb364

跨仓协议对齐与清仓(视图 wire-drift)

视图 wire-drift 是 v4→v5 对齐 + 清仓的历史快照,不是「仍有开放 drift」的告警图,也不再描述现行协议:本钉点下表中三个常量都已删除,由 DESKTOP_PROTOCOL_VERSION = 3 取代。它留在 local-file-v5 主题下作追溯,不单独拆成 topic。

字段 Desktop a96b7a4 Agent b8d4167
源文件 apps/desktop/shared/generated/local-files-v4.ts L5–23 packages/tool-client/src/types/local-files-v4.ts L4–21
LOCAL_FILES_V4_PROTOCOL_VERSION 5 5
LOCAL_FILES_V4_CAPABILITY local-files-v5 local-files-v5
LOCAL_FILE_V4_SCHEMA_IDENTITY local-file-v5 local-file-v5

(表中为当时的钉点 Desktop a96b7a4 / Agent b8d4167。)图:local-file-wire-drift.architecture.json。

426 / cutover 部署序(视图 cutover-deploy,历史)

以下是 v4→v5 清仓时的顺序(ADR-0079 Consequences),已执行完毕,仅作追溯;LOCAL_FILE_PROTOCOL_UPGRADE_REQUIRED 现只存在于历史迁移 115 中。

  1. Agent:migration 114(前置 schema identity = interaction-protocol-v2 / mig 113)→ 115(前置 = conversation-attachments)。
  2. 窗口期:仅广告 localFileProtocolVersions ∋ 4 且不含 5 的 Desktop,在 chat POST、/validate-local-executor(及 preview 同源门)收到 426 LOCAL_FILE_PROTOCOL_UPGRADE_REQUIRED,文案「请更新桌面端后重试」——整轮对话硬门,不是「仅本地文件工具不可用」。
  3. mig 115:将在途 requested 且 request.protocolVersion = 4 的 Operation 标为 expired;等待该 Operation 的 suspended Run 记为 failed(error_code = LOCAL_FILE_PROTOCOL_UPGRADE_REQUIRED),不依赖 TTL drain;并剥离历史绝对路径键。
  4. Desktop:Velopack 启动更新到 V5;之后 path-free wire + 对话级附件可用。

图:local-file-cutover-deploy.sequence.json(catalog 视图 cutover-deploy)。

现行 Gateway 426 协议硬门(Desktop 协议 v3 的 DESKTOP_UPGRADE_REQUIRED、Runtime Execution、Interaction Protocol)见 desktop-runtime NOTES「Gateway 协议硬门族」。

谁是材料权威:Agent 账本 ≠ 本机事实(步进图 A 补记)

  • Agent 侧 localProjection 不是能力判定:local_file_message_attachments 行是有作用域的材料引用;localProjection(available | unavailable | revoked)是 Desktop 附加时的历史快照,Agent 源码注释明确「不得作为当前能力判定;Desktop Main 每次操作前复核 live authority」。
  • Main 复核三件事(每次 Operation 投递都做):
    1. 授权文件夹:requireFolder → V4AuthorizedFolderStore.requireActive,不存在 / 已撤销(AUTHORIZED_FOLDER_REVOKED)/ 根身份(dev+ino)变化即拒绝;
    2. 路径解析:resolveWithinRoot 只接受 folder-relative POSIX 路径,越界(path outside root)拒绝;出 Main 的结果再经 toWireRelativePath 转回相对路径;
    3. 版本 / 绑定:capabilityFingerprint 与本机不符 → capability_unavailable(冻结 protocol features 的检查随 feature token 删除);desktopExecutorInstanceId 代际变化 → capability_unsupported;同一 operationId 不同 requestDigest → conflict;写操作另校验 expected sha256(文件版本)。
  • 回执落账是 CAS:Agent terminalizeRequested 只在 status='requested' AND request_digest=期望值 AND desktop_executor_instance_id 一致 时更新,迟到或错绑定回执不改账本。
  • 读法:Agent 拥有「请求与回执」账本(谁要了什么、结果是什么);Main 拥有「此刻能否碰这块磁盘」的事实。两者不可互相替代。

目录身份摘要、参数纠错窗口与工作台澄清(钉点 Agent e2adc9a3c325 / Desktop 8eecd12081db)

  • directoryIdentityDigest(28a6ec920 / 9fdc200c):列目录回执可带被列目录本身(含空目录)的身份摘要,只能与原列目录的精确路径、actor、Root 和文件夹绑定一起用作改动版本;子项不能代表空父目录,缺失时不猜。发布顺序:先 Agent 后 Desktop(旧的严格 Agent 会拒绝该字段),不需要数据库迁移。
  • 参数纠错窗口(3b4efa961 / ee4a516be):change_files 的参数纠错在用户正式拒绝或 fs/change Operation 已准入后结束,之后由真实效应回执决定;部分 / 未知效应仍被执行阻断,不获得重放额度。
  • 工作台正式澄清(d1ef96997):modify / create 任务经正式澄清后,一次语义复核判断剩余交付是否只在聊天中回答;证据须逐字来自用户输入,判为只聊天时必需工具收窄为 list / search / read 之一,不能换任务、扩大材料或产生新授权;判不清返回可重试的 FILE_DELIVERY_REVIEW_UNRESOLVED。
  • 发布顺序核对:Desktop 列目录无条件带上 directoryIdentityDigest,不按 Agent 版本协商;Agent 28a6ec920 之前的列目录 schema 是 .strict() 且无此字段,旧 Agent 会拒绝。git 上 Agent 先合入(2026-10-21 04:34:48 EDT,3a52e997d),Desktop 12 秒后合入(a45a26e5),Desktop v0.1.62(2026-10-21 05:39 EDT 打 tag)起带该字段、v0.1.61 不带;Agent 仓库没有对应发布 tag,部署先后未核。证据:aida-desktop · apps/desktop/electron/local-files-v4/query-executor.ts L104–144 · directoryIdentityDigest · 4346d79eb364;aida-agent · packages/agent/src/runtime/README.md L149–151 · older strict Agent · e2adc9a3c325
  • 工作台澄清判例:单元测试用桩 LLM 固定返回值,覆盖只聊天收窄为单一读工具、仍要另存不放宽、各类无据或格式错返回 FILE_DELIVERY_REVIEW_UNRESOLVED、旧回答不能证明最新限制、模型失败原样抛出;2026-10-21 在钉点副本中 12 / 12 通过。真实模型判例未跑。证据:aida-agent · packages/agent/tests/unit/gateway/workbench-file-clarification.test.ts L123–155 · FILE_DELIVERY_REVIEW_UNRESOLVED · e2adc9a3c325
  • 证据:aida-agent · packages/tool-client/src/types/local-files-v4.ts L1247–1251 · directoryIdentityDigest · e2adc9a3c325;aida-agent · packages/agent/src/runtime/README.md L144–151 · directoryIdentityDigest · e2adc9a3c325;aida-agent · packages/agent/src/session/local-file-receipt-facts.ts L346–349 · directoryIdentityDigest · e2adc9a3c325;aida-desktop · apps/desktop/electron/local-files-v4/query-executor.ts L104–144 · directoryIdentityDigest · 4346d79eb364;aida-agent · packages/agent/src/orchestrator/drive-react-loop.ts L699–715 · An admitted Operation ends parameter correction · e2adc9a3c325;aida-agent · packages/agent/src/gateway/workbench-file-clarification.ts L31–64 · reviewWorkbenchFileDelivery · e2adc9a3c325;aida-agent · packages/agent/src/gateway/workbench-file-clarification.ts L74–96 · resolveWorkbenchFileClarification · e2adc9a3c325

证据与范围

  • aida-desktop · apps/desktop/shared/generated/protocol-version.ts L1–8 · DESKTOP_PROTOCOL_VERSION · 4346d79eb364

  • aida-desktop · docs/adr/0087-local-capability-convergence-and-protocol-v3.md L22–32 · Protocol v3 · 4346d79eb364

  • aida-desktop · apps/desktop/electron/local-files-v4/assemble-submitted-attachments.ts L49–79 · assembleSubmittedLocalFileAttachments · 4346d79eb364

  • aida-desktop · apps/desktop/shared/ipc-contract.ts L483–506 · localFilesV4 / assembleSubmittedLocalFileAttachments · 4346d79eb364

  • aida-desktop · apps/desktop/electron/local-files-v4/capability.ts L9–11 · assembleLocalFileV4Capability · 4346d79eb364

  • aida-desktop · apps/desktop/electron/local-files-v4/write-state-persistence.ts L730–746 · LOCAL_FILE_WRITE_STATE_LEGACY_DROPPED · 4346d79eb364

  • aida-desktop · apps/desktop/electron/update/velopack-updater.ts L35–65 · installVelopackStartup · 4346d79eb364

  • aida-agent · packages/tool-client/src/types/protocol-version.ts L1–7 · DESKTOP_PROTOCOL_VERSION · e2adc9a3c325

  • aida-agent · packages/agent/src/session/local-file-message-attachment.ts L126–158 · listForConversation · e2adc9a3c325

  • aida-agent · docs/adr/0079-local-file-v5-conversation-attachments.md L1–49 · ADR-0079 · e2adc9a3c325

  • aida-agent · packages/agent/migrations/114_local_file_v5_conversation_attachments.sql L1–40 · 114 · e2adc9a3c325

  • aida-agent · packages/agent/migrations/115_local_file_v5_ledger_cutover.sql L1–120 · 115 · e2adc9a3c325

  • aida-agent · packages/agent/src/runtime/local/local-file-v4-negotiation.ts L26–52 · localFileV4Admitted · e2adc9a3c325

  • aida-agent · packages/agent/src/gateway/chat-routes.ts L520–524 · desktopPayloadVersionUnsupported · e2adc9a3c325

  • aida-agent · packages/agent/src/session/local-file-operation-store.ts L214–245 · LocalFileOperationStore · e2adc9a3c325

  • aida-agent · packages/agent/src/session/local-file-message-attachment.ts L99–102 · historical client snapshot · e2adc9a3c325

  • aida-agent · packages/agent/src/session/local-file-operation-store.ts L369–503 · terminalizeRequested · e2adc9a3c325

  • aida-desktop · apps/desktop/electron/local-files-v4/executor.ts L85–165 · executeDelivery · 4346d79eb364

  • aida-desktop · apps/desktop/electron/local-files-v4/executor.ts L220–243 · executeFresh · 4346d79eb364

  • aida-desktop · apps/desktop/electron/local-files-v4/authorized-folder-authority.ts L437–477 · requireActive · 4346d79eb364

  • aida-desktop · apps/desktop/electron/local-files-v4/relative-wire.ts L23–58 · resolveWithinRoot · 4346d79eb364

结论来自固定版本的静态源码与合同阅读;实现存在、默认开关和生产启用分别判断。本站代码证据面板列出声明状态与具体限制。

Runtime 提交 wire 与原 Work identity

chat POST 的 Runtime 提交门接受缺省/空值(无 policy)、runtime-work-v1(无 policy),以及 runtime-work-skill-v2 且携带合法 skillExecutionPolicy;其他非空头为 RUNTIME_EXECUTION_PROTOCOL_UNSUPPORTED,头与 policy 不匹配为 RUNTIME_WORK_SKILL_POLICY_MISMATCH,均返回 426。原 Work binding 仍是 runtime-work-v1;取消提交、补充材料等路由单独判定,见协议地图。

证据:提交门 与 实际 chat POST 调用。

条件产物不可变重建与 Carrier 终态封口门(视图 conditional-artifact-gate)

当路由决策包含 conditionalArtifactRead 时,模型不能仅凭输出一段文字声称「已处理完文件」就把 Run 置为 completed。finishRuntimeWorkCarrierInTx(run-work-carrier-terminal.ts L11–91)在 outcome === 'completed' 时强制调用 readConditionalArtifactCompletionInTx(run-work-conditional-artifact.ts L49–157),在原 Root/claim fence 下从底层不可变事实表重建完成证明(见视图 conditional-artifact-gate):

  1. 前置门禁与能力快照核验(L52–84):
    • 校验 root.cancel_intent === null、无 hasRuntimeWorkEvidenceConflict、无 hasPendingWorkMaterialAdmission;
    • 通过 PgDesktopSkillSnapshotRegistry.resolveExact 核对 target.producer.skillSource.identity 处于 active,且 admittedSkillPluginTools 中存在唯一匹配的 conditionalArtifactOutput 声明;
    • 查 LocalFileMessageAttachmentStore.listForConversation 核对 target.scope 引用的每一个 attachmentId 与 selectedFileId 都真实绑定在当前会话与 frozenLocalExecutionScope 下。
  2. 6 表关联重建插件回执与消息链(L86–143):
    • 执行 continuation_requests c ⋈ pending_interactions p ⋈ agent_runs r ⋈ runtime_invocations i ⋈ interaction_receipts receipt ⋈ messages m (role='tool') 六表联合查询;
    • 按 work_step_ref(model:<round>:tool:0)严格排序,逐条核对:assertWorkPluginSource 签名一致、m.metadata.receiptId === receipt.id、m.metadata.responseDigest === canonicalJsonSha256(p.response)、以及 assertSettlementFact 领域事实已登记;
    • 收集所有 reply.artifacts 的 { artifactRef, sha256 }(若同一 artifactId 出现不同 sha256 直接抛 RUNTIME_WORK_CONDITIONAL_ARTIFACT_INVALID)。
  3. 完成度双分支判定(L144–156):
    • 确认该 rootRunId 下已没有任何 status = 'pending' 的 continuation_requests;
    • 加载完整运行消息历史并调 projectWorkFileMessagesInTx 投影文件消息;
    • 独立原件读取要求:sourceReadSatisfied = !target.independentSourceRead || attachmentReadsComplete(messages, target.sourceReadAttachmentIds);
    • 条件产物满足判定:
      • 分支 A(conditionNotMet):最新状态为 not_applicable 且 artifacts.size === 0;
      • 分支 B(已产出产物):artifacts.size > 0 且最新状态为 produced | not_applicable,同时每一个产出的 artifact 都通过了 artifactReadsComplete(messages, [...artifacts.values()]) 读取核验;
    • 若 !completion?.satisfied,finishRuntimeWorkCarrierInTx 直接抛 RUNTIME_WORK_CONDITIONAL_ARTIFACT_UNSATISFIED 阻断虚假结案。

代码证据

引用核验检查固定 commit 的文件与范围;实现结论来自代码阅读。自动检查不证明生产环境已启用。

已核验实现

Local File 架构族 / 源码目录仍称 V4;Protocol v3(Agent ADR-0090 / Desktop ADR-0087)删除了 LOCAL_FILES_V4_PROTOCOL_VERSION=5、local-files-v5 capability、local-file-v5 schema identity 与全部 Local File feature token:两端只剩 DESKTOP_PROTOCOL_VERSION=3(Desktop 侧为生成副本),V4 准入看载荷里有没有合法的 localFileCapability。

aida-desktopapps/desktop/shared/generated/protocol-version.ts:1–84346d79eb36402355e51118df0edf1f98586880c符号:DESKTOP_PROTOCOL_VERSION = 3
aida-agentpackages/tool-client/src/types/protocol-version.ts:1–77f2e519936b57902d4907ed8026fe1ecdd146e82符号:DESKTOP_PROTOCOL_VERSION = 3
aida-agentpackages/agent/src/runtime/local/local-file-v4-negotiation.ts:30–567f2e519936b57902d4907ed8026fe1ecdd146e82符号:localFileV4Admitted
已核验实现

对话附件由 Electron Main assembleSubmittedLocalFileAttachments 组装;Renderer 只提交 path-free intents(attachmentId/displayName/kind),IPC 合同标明 Main-assembled、绝对路径不出 Renderer。

aida-desktopapps/desktop/electron/local-files-v4/assemble-submitted-attachments.ts:63–934346d79eb36402355e51118df0edf1f98586880c符号:assembleSubmittedLocalFileAttachments
aida-desktopapps/desktop/electron/local-files-v4/assemble-submitted-attachments.ts:58–1034346d79eb36402355e51118df0edf1f98586880c符号:assembleSubmittedLocalFileAttachments
aida-desktopapps/desktop/shared/ipc-contract.ts:1670–16754346d79eb36402355e51118df0edf1f98586880c符号:localFilesV4
aida-desktopapps/desktop/electron/local-files-v4/capability.ts:12–194346d79eb36402355e51118df0edf1f98586880c符号:assembleLocalFileV4Capability
已核验实现

Agent listForConversation(ADR-0079)按对话级 attachmentId 取最新 relation;migrations 114(附件列 path-free)→ 115(在途 v4 ledger cutover);部署先 Agent 后 Desktop。

aida-agentpackages/agent/src/session/local-file-message-attachment.ts:127–1597f2e519936b57902d4907ed8026fe1ecdd146e82符号:listForConversation
aida-agentdocs/adr/0079-local-file-v5-conversation-attachments.md:26–507f2e519936b57902d4907ed8026fe1ecdd146e82符号:listForConversation
aida-agentpackages/agent/migrations/114_local_file_v5_conversation_attachments.sql:26–447f2e519936b57902d4907ed8026fe1ecdd146e82符号:local_file_message_attachments
aida-agentpackages/agent/migrations/115_local_file_v5_ledger_cutover.sql:3–337f2e519936b57902d4907ed8026fe1ecdd146e82符号:ledger-cutover
已核验实现

旧的 426 LOCAL_FILE_PROTOCOL_UPGRADE_REQUIRED 与 localFileProtocolUpgradeRequired 判定已删除;不是 v3 的 Desktop 在 chat POST / validate-local-executor 统一收到 426 DESKTOP_UPGRADE_REQUIRED(ADR-0093 起 chat POST 没带协议头时,只有携带 localFileAttachments 等本机执行载荷才 426)。载荷缺 localFileCapability 只是本轮不注册 V4 工具。

aida-agentpackages/agent/src/runtime/local/local-file-v4-negotiation.ts:30–567f2e519936b57902d4907ed8026fe1ecdd146e82符号:localFileV4Admitted
aida-agentpackages/agent/src/gateway/chat-routes.ts:608–6127f2e519936b57902d4907ed8026fe1ecdd146e82符号:desktopPayloadVersionUnsupported
aida-agentpackages/agent/src/gateway/chat-routes.ts:325–3387f2e519936b57902d4907ed8026fe1ecdd146e82符号:desktopPayloadVersionUnsupported
aida-agentpackages/agent/src/gateway/request-schemas.ts:95–1127f2e519936b57902d4907ed8026fe1ecdd146e82符号:localFileAttachments
已核验实现

Desktop 权威底座在 Main:assembleLocalFileV4Capability 产出基线能力,只有在需要 native 后端的平台(win32)缺后端时才清空 methods 并标 native_backend_unavailable,V4 读不再受托管 Python 探针影响;Agent LocalFileOperationStore 拥有 local_file_operations 账本;write-state 现存于账号作用域的加密信封,解析时丢弃不可迁移的 legacy 条目并诊断 LOCAL_FILE_WRITE_STATE_LEGACY_DROPPED。

aida-desktopapps/desktop/electron/local-files-v4/capability.ts:12–194346d79eb36402355e51118df0edf1f98586880c符号:assembleLocalFileV4Capability
aida-desktopapps/desktop/electron/local-files-v4/native-file-backend.ts:233–2354346d79eb36402355e51118df0edf1f98586880c符号:nativeFileBackendRequiredForPlatform
aida-agentpackages/agent/src/session/local-file-operation-store.ts:225–2567f2e519936b57902d4907ed8026fe1ecdd146e82符号:LocalFileOperationStore
aida-desktopapps/desktop/electron/local-files-v4/write-state-persistence.ts:860–8764346d79eb36402355e51118df0edf1f98586880c符号:LOCAL_FILE_WRITE_STATE_LEGACY_DROPPED
已核验实现

历史部署顺序(v4→v5 清仓,已过去):Agent 迁移 114 再 115(ADR-0079),然后 Desktop Velopack;迁移 115 让在途 protocolVersion=4 操作过期,并以 LOCAL_FILE_PROTOCOL_UPGRADE_REQUIRED 结束等待中的 suspended Run。该错误码现已只存在于历史迁移里。

aida-agentdocs/adr/0079-local-file-v5-conversation-attachments.md:48–507f2e519936b57902d4907ed8026fe1ecdd146e82符号:114
aida-agentpackages/agent/migrations/115_local_file_v5_ledger_cutover.sql:88–1187f2e519936b57902d4907ed8026fe1ecdd146e82符号:LOCAL_FILE_PROTOCOL_UPGRADE_REQUIRED
aida-desktopapps/desktop/electron/update/velopack-updater.ts:35–654346d79eb36402355e51118df0edf1f98586880c符号:installVelopackStartup
已核验实现

视图 wire-drift 与 cutover-deploy 是 v4→v5 清仓(迁移 114/115)的历史快照:Protocol v3 之后 Local File 不再有独立的 wire 版本,两张图只作追溯,不描述现行协议门(现行门见 trust-boundaries)。

aida-agentpackages/agent/migrations/114_local_file_v5_conversation_attachments.sql:2–327f2e519936b57902d4907ed8026fe1ecdd146e82符号:113
aida-agentpackages/agent/src/runtime/local/local-file-v4-negotiation.ts:30–567f2e519936b57902d4907ed8026fe1ecdd146e82符号:localFileV4Admitted
aida-agentpackages/agent/src/gateway/chat-routes.ts:608–6127f2e519936b57902d4907ed8026fe1ecdd146e82符号:desktopPayloadVersionUnsupported
已核验实现

Agent 附件行的 localProjection 是历史客户端快照,不作为当前能力判定;Desktop Main 每次投递都复核授权文件夹(requireActive:撤销/根身份)、相对路径(resolveWithinRoot 越界拒绝)与执行绑定(executor 代际变化回 capability_unsupported、requestDigest 冲突回 conflict、capabilityFingerprint 不符回 capability_unavailable;冻结 protocol features 的检查已随 feature token 删除);Agent 回执落账 terminalizeRequested 以 status=requested + request_digest + executor 实例为条件更新。

aida-agentpackages/agent/src/session/local-file-message-attachment.ts:108–1117f2e519936b57902d4907ed8026fe1ecdd146e82符号:historical client snapshot
aida-agentpackages/agent/src/session/local-file-operation-store.ts:537–6717f2e519936b57902d4907ed8026fe1ecdd146e82符号:request_digest = ${input.expectedRequestDigest}
aida-desktopapps/desktop/electron/local-files-v4/executor.ts:245–3244346d79eb36402355e51118df0edf1f98586880c符号:requireFolder
aida-desktopapps/desktop/electron/local-files-v4/executor.ts:435–4594346d79eb36402355e51118df0edf1f98586880c符号:different request digest
aida-desktopapps/desktop/electron/local-files-v4/executor.ts:540–5534346d79eb36402355e51118df0edf1f98586880c符号:capabilityFingerprint
aida-desktopapps/desktop/electron/local-files-v4/authorized-folder-authority.ts:462–4834346d79eb36402355e51118df0edf1f98586880c符号:AUTHORIZED_FOLDER_REVOKED
aida-desktopapps/desktop/electron/local-files-v4/relative-wire.ts:75–1104346d79eb36402355e51118df0edf1f98586880c符号:path outside root
已核验实现

原件上传:路由 /api/local-file/operations/:operationId/original-content 保留(上限 20MB,LOCAL_FILE_ORIGINAL_CONTENT_MAX_BYTES,Gateway bodyLimit 超限 413;恢复上限 15MB),capability local-files-v5-original-content-v1 已删除(v3 蕴含);元数据头里的协议字段改为 X-AIDA-Protocol,Gateway 要求其等于 3,并仍要求 X-Local-File-Request-Digest / Content-Sha256 等头与 application/octet-stream;Desktop Main 由 LocalFileOriginalUplink 上传,原件入 local_file_operations.original_content。

aida-agentpackages/tool-client/src/types/local-file-original.ts:1–407f2e519936b57902d4907ed8026fe1ecdd146e82符号:LOCAL_FILE_ORIGINAL_CONTENT_MAX_BYTES
aida-agentpackages/tool-client/src/types/protocol-version.ts:1–77f2e519936b57902d4907ed8026fe1ecdd146e82符号:DESKTOP_PROTOCOL_VERSION
aida-desktopapps/desktop/shared/generated/local-file-original.ts:1–404346d79eb36402355e51118df0edf1f98586880c符号:LOCAL_FILE_ORIGINAL_CONTENT_MAX_BYTES
aida-desktopapps/desktop/shared/generated/protocol-version.ts:1–84346d79eb36402355e51118df0edf1f98586880c符号:DESKTOP_PROTOCOL_VERSION
aida-agentpackages/agent/src/gateway/api-local-file-v4.ts:368–3977f2e519936b57902d4907ed8026fe1ecdd146e82符号:original-content
aida-agentpackages/agent/src/gateway/api-body-limit-middleware.ts:75–797f2e519936b57902d4907ed8026fe1ecdd146e82符号:LOCAL_FILE_ORIGINAL_CONTENT_MAX_BYTES
aida-desktopapps/desktop/electron/main.ts:1581–15814346d79eb36402355e51118df0edf1f98586880c符号:LocalFileOriginalUplink
aida-desktopapps/desktop/electron/local-files-v4/original-file-read.ts:1–54346d79eb36402355e51118df0edf1f98586880c符号:LOCAL_FILE_ORIGINAL_CONTENT_ROUTE
已核验实现

chat POST 的 Runtime 提交门接受缺省/空值(无 policy)、runtime-work-v1(无 policy),以及 runtime-work-skill-v2 且携带合法 skillExecutionPolicy;其他非空头为 RUNTIME_EXECUTION_PROTOCOL_UNSUPPORTED,头与 policy 不匹配为 RUNTIME_WORK_SKILL_POLICY_MISMATCH,均返回 426。原 Work binding 仍是 runtime-work-v1;取消提交、补充材料等路由单独判定,见协议地图。

aida-agentpackages/agent/src/gateway/chat-routes.ts:555–5617f2e519936b57902d4907ed8026fe1ecdd146e82符号:RUNTIME_WORK_PROFILE_UNSUPPORTED
aida-agentpackages/agent/src/gateway/chat-work-admission.ts:15–247f2e519936b57902d4907ed8026fe1ecdd146e82符号:runtimeWorkSubmissionProtocol
aida-agentpackages/agent/src/gateway/chat-routes.ts:531–5357f2e519936b57902d4907ed8026fe1ecdd146e82符号:submissionProtocol
已核验实现

文件目标收窄 restrictFileTargets 不再过滤本 Run 内经 request_file_access 拿到的授权:附件查询把同一 Run 的 request_file_access 工具消息所带关系标为 run_request_grant,restrictFileTargets 对 runRequestGrant=true 一律保留。Desktop 侧授权附件改用权威 id 作 attachmentId(文件夹为 authorizedFolderId,文件为 selectedFileHandleId),同一文件夹不再积累多个关系。

静态读码;未运行 E2E。

aida-agentpackages/agent/src/routing/local-file-targets.ts:140–1517f2e519936b57902d4907ed8026fe1ecdd146e82符号:runRequestGrant
aida-agentpackages/agent/src/session/local-file-message-attachment.ts:209–2117f2e519936b57902d4907ed8026fe1ecdd146e82符号:run_request_grant
aida-desktopapps/desktop/electron/local-files-v4/file-access.ts:497–4994346d79eb36402355e51118df0edf1f98586880c符号:attachmentId: folder.authorizedFolderId
已核验实现

LF 列目录回执可带 directoryIdentityDigest(28a6ec920 / 9fdc200c):表示被列目录本身(含空目录)的身份,只能与原列目录的精确路径、actor、Root 与文件夹绑定一起作为改动版本使用,子项不能提供空父目录的身份,缺失时不得猜;回执事实投影保留原摘要并比对。发布顺序:先发支持该字段的 Agent,再发会发送该可选字段的 Desktop(旧的严格 Agent 会拒绝);不需要数据库迁移。

aida-agentpackages/tool-client/src/types/local-files-v4.ts:1473–14777f2e519936b57902d4907ed8026fe1ecdd146e82符号:directoryIdentityDigest
aida-agentpackages/agent/src/runtime/README.md:193–2007f2e519936b57902d4907ed8026fe1ecdd146e82符号:directoryIdentityDigest
aida-agentpackages/agent/src/session/local-file-receipt-facts.ts:794–7977f2e519936b57902d4907ed8026fe1ecdd146e82符号:directoryIdentityDigest
aida-desktopapps/desktop/electron/local-files-v4/query-executor.ts:104–1444346d79eb36402355e51118df0edf1f98586880c符号:directoryIdentityDigest
已核验实现

LF 参数纠错窗口(3b4efa961 / ee4a516be):change_files 的参数纠错在两种情况下结束——被纠正的提案以用户正式拒绝(authorization_declined)收尾,或已准入 fs/change Operation(有 operationId);此后由真实效应回执决定下一次失败,部分 / 未知效应仍走执行阻断,不获得重放额度。

aida-agentpackages/agent/src/orchestrator/local-file-failure-history.ts:124–1387f2e519936b57902d4907ed8026fe1ecdd146e82符号:An admitted Operation ends parameter correction
已核验实现

Workbench 正式澄清后的交付范围复核(d1ef96997):本机工作台 modify/create 任务在正式澄清后,用一次严格 JSON 的语义复核判断剩余交付是否只在聊天中呈现;证据必须逐字来自原请求或用户答复、chat_only 至少一段来自最新答复,否则 FILE_DELIVERY_REVIEW_UNRESOLVED 可重试错误;判为 chat_only 时把必需工具收窄为 list/search/read 之一并标记只读文件效应;不能换任务、扩大材料范围或产生新授权。

语义复核由 LLM 完成;只读了合同与校验,未跑实际判例。

aida-agentpackages/agent/src/gateway/workbench-file-clarification.ts:59–927f2e519936b57902d4907ed8026fe1ecdd146e82符号:reviewWorkbenchFileDelivery
aida-agentpackages/agent/src/gateway/workbench-file-clarification.ts:176–1987f2e519936b57902d4907ed8026fe1ecdd146e82符号:resolveWorkbenchFileClarification
条件路径

directoryIdentityDigest 发布顺序核对:Desktop 列目录无条件写入该字段,没有按 Agent 版本协商或降级;Agent 28a6ec920 之前的 localFileListResultSchema 是 .strict() 且没有该字段,所以旧 Agent 会拒绝。合入顺序:Agent(3a52e997d)2026-10-21 04:34:48 EDT 合入 master,Desktop(a45a26e5)04:35:00 EDT 合入;Desktop v0.1.62(1dcf4686,2026-10-21 05:39 EDT 打 tag)起带该字段,v0.1.61 不带。Agent 仓库没有对应的发布 tag。

只核了 git 合入与 tag 时间;Agent 何时部署到哪个环境、用户何时装上 v0.1.62 都没有记录可读,所以「先发 Agent」在部署层面仍未核实。

aida-desktopapps/desktop/electron/local-files-v4/query-executor.ts:104–1444346d79eb36402355e51118df0edf1f98586880c符号:directoryIdentityDigest
aida-agentpackages/agent/src/runtime/README.md:198–2007f2e519936b57902d4907ed8026fe1ecdd146e82符号:older strict Agent
已核验实现

工作台澄清的确定性判例(单元测试,LLM 用桩返回固定 JSON,不调真实模型):只聊天且证据逐字来自最新回答时,必需工具收窄为 list_files / search_files / read_files 之一;仍要另存副本时不放宽;readIntent=modify、编造 attachmentId、证据不在回答里、证据取自问题、scope=unclear 或非 JSON 都返回 FILE_DELIVERY_REVIEW_UNRESOLVED;更早的回答不能证明最新的交付限制;模型调用失败原样抛出、不当作放行。2026-10-21 在钉点副本里运行该文件 12 / 12 通过。

只证明解析与校验合同;真实模型对各种说法会怎么判,没有跑判例(不调付费模型)。依赖 PG 的集成测试 runtime-v2-work-local-file-query 未跑。

aida-agentpackages/agent/tests/unit/gateway/workbench-file-clarification.test.ts:251–2887f2e519936b57902d4907ed8026fe1ecdd146e82符号:FILE_DELIVERY_REVIEW_UNRESOLVED
已核验实现

迁移 190:guard_local_file_original_content 增加 document_conversion / convert_pdf_to_xlsx 原件消费者(maxBytes 20MB)。

aida-agentpackages/agent/migrations/190_document_conversion_original_consumer.sql:1–457f2e519936b57902d4907ed8026fe1ecdd146e82符号:document_conversion
已核验实现

STA-213:Desktop 投影并保存 make_docx 生成的 Word 产物(runtime-work-artifact-projection);与条件产物完成门衔接,不扩大插件授权。

aida-desktopapps/desktop/electron/agent-loop/runtime-work-artifact-projection.ts:64–894346d79eb36402355e51118df0edf1f98586880c符号:make_docx