Skill 版本、执行引用与归档
按业务职责归类的既有接口契约
更新时间:2026年09月08日 13时20分03秒(UTC+8)
本次仅迁移文档,不改变接口行为。原有“候选”标识保留,表示发布状态尚需逐项核验,不代表本次已上线该能力。
Skill 历史查询(开发候选)
GET /api/skills/:id?versions=1&before=N 返回 { versions: [{ revision, createdAt }], nextBefore },每页最多 50 项,按 revision 递减,before 为排他游标。不存在或非所属 Skill 返回空列表,不泄漏存在性。GET /api/skills/:id?revision=N 返回原有 { skill } 结构的指定历史快照,不存在或无权读取返回 404。revision/before 必须为正安全整数;所有成功响应为 private/no-store。已归档 Skill 历史仅所属用户可查。此接口不是 Partner API,未新增外部 API Key 权益。
POST /api/skills/:id/executions(开发候选)接收 { revision, projectId, executionId },要求当前登录用户拥有 Skill 且为画布成员;16KiB 请求上限。返回 { lock: { skillId, revision, executionId } },同一绑定重试幂等,改绑冲突 409,无权限/不存在 404,格式错误 400,超限 413。该接口只持久化版本引用,不启动生成、不扣费、不证明 Agent 接受任务。尚未接入发送流程或 Partner API。
Skill 执行引用回读(开发候选)
GET /api/skills/:id/executions?projectId=...&executionId=...&revision=... 要求网站登录,返回 { lock: { skillId, revision, executionId }, projectId, skill }。必须同时匹配当前用户拥有的 Skill、已有执行引用、指定画布/版本,并验证当前画布成员关系;缺失、错配与权限撤销均404,格式错误400,读取异常503,响应 private/no-store。skill 是该执行引用的历史快照,已归档 Skill 的被引用版本仍可读取,不替换为最新版。GET 不创建执行引用、不启动任务、不证明客户端执行内容与快照相同;此接口不是 Partner API。
网站聊天绑定 Skill 上下文(开发候选)
POST /api/opencode-spicy 可携带 canvasProjectId 与严格 skillBinding={skillId,revision,executionId}。提供绑定时,BFF 在发送上游前按当前登录用户核对执行引用及成员权限,读取历史指令并与原始 prompt 分段组装;内部绑定字段不转发上游。无效引用400、不存在/无权限404;不提供绑定的请求保持旧行为。此检查不证明引擎实际完成任务,也不接管本地 Agent 的执行。网站纯聊天与工具循环均已发送此合同;工具循环在首步、自动续步及人工确认后保持同一画布和执行引用。
Skill 归档内部读写(候选)
GET /v1/internal/skill-archives/{ownerUuid}/{skillUuid}/{revision}/{sha256}.json 仅供服务间读取,要求强度合规且匹配的 x-media-worker-token,固定 OSS 前缀 infinite-canvas/skill-archives/;OSS_VIDEO_ENDPOINT 必须是同区内网端点。成功直接返回 application/json 字节和 Cache-Control: private, no-store,不返回签名 URL、不进入公开媒体缓存。读取限制 16 MiB,核对对象键中的 SHA-256;身份、版本及完整格式仍由调用方使用归档校验模块核验。缺失对象 404、无权限 403、非法键 400、未配置/非内网端点 503、空/超限/摘要不符 502。
PUT 使用相同路径和服务鉴权,接收最大 16 MiB 的归档 JSON,校验 SHA-256、格式标识及 owner/skill/revision 身份后,以禁止覆盖方式写入。已存在对象不覆盖;写入或冲突后必须回读且字节完全一致,才返回 { ok: true, archiveKey, bytes, sha256 },响应 private/no-store。空内容、摘要或身份错误 400,超限 413,损坏对象回读 502。请求体读取限时 30 秒,不代表 OSS 调用全链路取消保证。
接口已由 Web 历史版本/执行引用读取按归档定位表调用;自动归档登记和热快照释放尚未实现。服务 token 不是终端用户授权,BFF 在归档读取前核对用户与版本归属。读写已完成隔离替身测试与 develop 同区内网真实 OSS canary:随机中性对象创建、重复提交、实际回读及精确清理通过;Web 服务/数据库/Proxy HTTP/OSS 登记与历史读取全链路已在隔离环境实测通过,生产尚未部署;返回 receipt 不触发删除历史快照。
Web 服务端 skill-archive-storage.ts 实现上述私有协议客户端:只接收 UUID/版本/摘要定位符,不接受用户提供的对象 URL;禁止重定向,流式读取不信任 Content-Length,读取时校验大小、摘要、格式与身份。PUT 收据匹配后独立 GET 验证,才返回定位符。历史版本查询已在授权查询后接入;其他服务调用方仍须先完成终端用户授权,定位符不是授权凭证。
管理员 Skill 归档策略(开发候选)
GET /api/admin/skill-archive-policy 返回 { policy: { retentionDays, revision, updatedBy, updatedAt } };未配置为 null/0/null/null。PUT 接收严格 { retentionDays: 1..36500整数|null, expectedRevision: 非负安全整数 },最大 4 KiB。现有平台 requireAdmin 鉴权先于数据读写;并发旧修订 409,非法请求 400,超限 413,存储故障 503,成功响应 private/no-store。此处是当前平台 admin 权限,不等同已完成 B 端子管理员体系。
保存只更新配置,不创建周期任务或触发归档。null 表示未设自动保留期,并不禁止操作员显式 cutoff 的维护命令。管理员设置 UI 已接入;服务端策略候选预览接口已实现,真实 PG 策略矩阵已通过,候选 UI 已接入且仅只读查询;不是 Partner API。
Skill 归档策略候选预览
GET /api/admin/skill-archive-policy/preview 仅管理员可用,响应禁止缓存。返回 policyRevision、evaluatedAt、cutoff、candidates 和 hasMore;候选最多 100 条,只含 ownerUserId、skillId、revision、createdAt。未配置保留期时 cutoff 为 null、候选为空。此接口只读且不接受执行参数;候选是采样时刻的建议,不保证稍后仍可归档。数据库故障或超时返回 503 / archive_preview_failed,不暴露数据库错误详情。