Skip to content

Latest commit

 

History

History
2389 lines (1577 loc) · 124 KB

plan-20260911.md

File metadata and controls

2389 lines (1577 loc) · 124 KB

storage-only Agent Capture 落库计划(2026-09-11)

改名註記(2026-09-17): 本文成稿與執行時,Cargo 包名/二進制名為舊名,lib 為舊名 _core;2026-09-17 起全倉統一改名為 Mega2(mega2 / mega2_core),本文中的命令、路徑、環境變量與服務名已同步更新,歷史提交記錄本身不變。

模板版本: v2;依据 plan-template.md,核对日期 2026-09-13。

文档职责

本文解决「libra 本机两套 Agent Session(外部 hook 捕获与内部 libra code JSONL)无法以 storage-only 形态原样落入 mega2」的缺口。目标是交付:仅在 git.storage_only() 且 [agent_capture].enabled=true 时挂载 /api/v1/agent-capture——独立 ingest token、无用户/OAuth/Cedar 前置;Postgres 元数据(agent_capture_*)+ ObjectNamespace::Agent 字节;服务器事实源为 raw;查询 metadata-first,点进 transcript 返回 raw 并写 access_audit。

本文只规划任务,不宣称实现完成。落地时每个任务都必须先刷新源码锚点(GC-01),再按任务卡验收。

权威规范(唯一): ADR、下节「HTTP 契约与数据模型冻结」、任务卡字段、「实施顺序」边集。本文件不含后置覆盖附录。若历史 Review 补丁与任务卡冲突,以任务卡与冻结契约为准。

适用范围

  • src/config/:[agent_capture](enabled、tenant_id、deployment_id、配额缺省、[[agent_capture.ingest_tokens]])、known_fields、storage-only 校验门。
  • src/callisto/ + src/jupiter/migration/:agent_capture_* 表、实体、migrations() 登记。
  • src/jupiter/storage/ + src/jupiter/service/:AgentCaptureStorage + AgentCaptureService。
  • src/orbit_api/object_storage.rs:ObjectNamespace::Agent(追加,不改现有 Media)。
  • src/common/canonical_json.rs(新,AC-22):RFC 8785 fingerprint helper,供 event/receipt/HTTP 幂等共用。
  • src/api_model/(新)+ src/ceres/agent_capture/(新):DTO/错误契约与 ingest token 查找(audience 独立,禁止调用 lookup_push_token)。
  • src/api/router/agent_capture_router.rs(新)+ src/server/http_server.rs + src/api/api_doc.rs:路由、挂载、OpenAPI。
  • tests/integration_agent_capture.rs(新):进程级黑盒。
  • 文档:docs/refactoring/agent-capture.md(AC-01 创建,各实现卡按节追加,AC-14 索引收口)、docs/refactoring/README.md、docs/refactoring/integration.md、docs/plan/README.md、plan-long.md 索引。

非目标

  • 不在 review 形态挂载 /api/v1/agent-capture(不注册 → 404)。
  • 不实现 libra Mega remote 客户端(写集在 libra 仓,DEFER-AC-01)。
  • 不默认上传 FileHistory 每文件 50 版全文(DEFER-AC-02)。
  • 不实现后台 GC 清扫进程(DEFER-AC-04);本计划只保证 GC 查询不以年龄为唯一条件。
  • 不实现脱敏视图、agent_experts / runtime agent_sessions、计费镜像、Cedar、OAuth、LoginUser。
  • 不把 session 写入既有 audit_logs(target_id: i64)。
  • 不改 Git smart protocol / LFS / OCI;不复用 git.push_tokens / git.anonymous_access;不改 ObjectNamespace::Media。
  • 不重放 refs/libra/traces;不把两套事件合成一条假因果链。

成功定义

  • storage-only + enabled=true + 有效 ingest token:discovery、session upsert、blob staging/finalize、event/file-op/checkpoint ingest、metadata list、raw transcript GET 可用。
  • 无 token → 401;token 不覆盖 path → 404;review 或 enabled=false → 整棵 404;未挂载时 OpenAPI 不含 /api/v1/agent-capture。
  • 仅 redacted、无对应 raw blob → completeness=incomplete(missing_raw)。
  • tracing 不含 prompt/token/tool 原文。
  • 全部非延后任务卡 Lifecycle=done 且 Acceptance=complete;计划级 Codex 对本计划文档为 PASS。

事实基线

所有行号和源码锚点必须在开工当天刷新(GC-01)。下列锚点核对日为 2026-09-13。

类别 当前事实 证据
工作树 VCS 本 checkout 使用 Libra(.libra);无 .git。发布走 libra add / libra commit / libra push origin main test -d .libra;test ! -d .git
分支 main 跟踪 origin/main;工作树干净 libra status --short --branch → ## main...origin/main
mega2 tip 12c2f21(docs(plan): refine agent capture and storage event implementation plans) libra log -1 --oneline
包版本 Cargo.toml version = "0.10.1";单 package mega2 / lib mega2_core Cargo.toml:3
storage-only git.push_auth.is_some() src/config/model.rs:918-922
OCI 门(类比) [oci].enabled 缺省 false;非 storage-only 启用则 validate 拒绝;挂载 storage_only && oci.enabled model.rs:47-60;validate.rs:653;http_server.rs:723-786
未知字段 known_fields("") 含 oci 无 agent_capture;"oci" => ["enabled"] validate.rs:1465-1577
配置样例 review 样例注释 [oci];storage-only [oci] enabled = true config/config.toml:322-327;config/config-storage-only.toml:359-360
push token name/token/paths;lookup_push_token 常数时间 sha256;token_path_authorizes 组件边界 src/config/model.rs:931-959;src/contract/git_protocol/mod.rs:133-157
HTTP /api/v1 storage-only 用 storage_only_routers()(只读子集 + preview) src/api/api_router.rs:65-71
OpenAPI storage_only_openapi_doc(include_oci: bool) / trunk_openapi_doc(include_oci: bool) http_server.rs:791-816
对象命名空间 Git,Lfs,Log,Artifact,Attachment,Oci,Media,无 Agent;as_str 对 Media 为 media orbit_api/object_storage.rs:110-134
对象 trait put_stream/get_stream/get_range_stream/exists/delete;无 list/rename/copy orbit_api/object_storage.rs
Storage 组装 Storage 含 oci_service;mock() 使用 OciService::mock() jupiter/storage/mod.rs:150、:561、:589
迁移尾 migrations() 末项 m20260912_000100_drop_orion_build_tables jupiter/migration/mod.rs:228
audit_logs target_id: i64 callisto/audit_logs.rs:17
git_repo.id i64;monorepo 路径不必有该行 callisto/git_repo.rs:10
路径正规化 MonoServiceLogic::normalize_repo_path src/ceres/api_service/mono_api_service.rs:504
api_model 不存在 src/lib.rs:8-22;glob src/api_model/** 零命中
未来 runtime 表名 augmentcode.md 规划 agent_sessions(未建表) docs/refactoring/augmentcode.md:185-187
D 组 .github/workflows/ 无 workflow 文件 2026-09-13 现场 ls
工作区前置 .env.test 存在 .env.test
工作区脏文件 无(与 origin/main 一致) libra status --short --branch
外部参照(libra) /run/media/genedna/data/libra tip d1aafb2,核对 2026-09-13 sql/migrations/2026050303_agent_capture.sql;src/internal/ai/session/jsonl.rs;src/internal/ai/session/file_history.rs:21 MAX_VERSIONS_PER_FILE=50

当前缺口

ID 缺口 影响 证据 计划动作
GAP-AC-01 无 [agent_capture] 配置与挂载门 无法 fail-closed 声明启用 model.rs:9-52 无该段 AC-01
GAP-AC-02 无 agent_capture_* 表 无法存 session/checkpoint/event migrations() 无该名 AC-02
GAP-AC-03 无 ObjectNamespace::Agent 字节无法与 git/lfs/oci/media 隔离 object_storage.rs:110-121 AC-05
GAP-AC-04 无独立 ingest token 查找 只能误用 git.push_tokens 或匿名 git_protocol/mod.rs:146-157 AC-06
GAP-AC-05 无 /api/v1/agent-capture 无法 upsert/ingest/查询 router/mod.rs 无该模块 AC-00, AC-07, AC-16, AC-21, AC-08..AC-12, AC-17
GAP-AC-06 无进程 IT / 契约文档 无黑盒与运维事实源 tests/;无 docs/refactoring/agent-capture.md AC-13、AC-01 起增量文档、AC-14 索引

与其它计划的关系

计划/文档 关系 本计划处理
plan-20260902.md 并行先例:storage-only 挂载门、include_oci OpenAPI 增参 类比挂载;不复用 git.push_tokens / anonymous_access
plan-20260909.md 前置:storage-only LFS token 形态已交付 不触碰 LFS
plan-20260901.md 并行:ObjectNamespace::Media 已存在 只追加 Agent,不改 Media
plan-20260912.md 并行:outbound webhook;Agent 适配器等待本计划 AC-15 不实现 webhook;本计划完成是其 DEP
docs/refactoring/augmentcode.md 未来 runtime agent_sessions 不建那些表;前缀 agent_capture_*
docs/refactoring/libra.md REQ-LB-02/09 ADR-AC-02/04;不改 libra 仓
plan-long.md 无 PT 强制关联 已有索引行;AC-14 核对其仍指向本文
AGENTS.md Libra 发布 遵守;文档成稿提交 Version increment=N/A

评审结论与修订记录

计划成稿与后续可执行性折回自审:

维度 结论 修订动作
合理性 storage-only 无用户体系,捕获必须独立 token + raw 本计划承接
可行性 栈同构 OCI/LFS;无新 crate 25 张 S–M 卡(含 AC-00 / AC-04-GC / AC-08-R / AC-22)
任务卡粒度 配置/DDL/session/event/checkpoint/blob/GC/审计/对象层/认证/schema/挂载/discovery/PUT/ingest HTTP/查询/tombstone/IT/文档/收口 见粒度审计表;禁止附录覆盖正文
依赖与顺序 写集相交处全串行;无环 见实施顺序;生成器 Kahn 校验
完整性 测/文档/forward-only 迁移齐全 见各卡
安全性 独立 token;不跟随匿名 git 读;raw 有 access_audit + tombstone ADR-AC-03/04/07
功能正确性 capture_id 服务器 PK;JSONL uid=generation:offset ADR-AC-01/09
接口兼容 全新前缀;review 零变化 ADR-AC-03
数据流 staging lease → 服务器 CAS 键;blob_ref 为 GC 真相 ADR-AC-02/06
性能 同 digest 共享 CAS;list 不展开正文 性能摘要
可靠性 崩溃窗口与幂等收据 故障恢复矩阵;AC-08-R
可维护性 表前缀避开 runtime;认证不进 git_protocol GC-AC-01/02

修订历史

日期 触发 变更内容 原卡 → 新卡 受影响的引用
2026-09-11 成稿 首版:AC-01..AC-15;ADR-AC-01..09;GAP-AC-01..06 N/A 全文
2026-09-11 Codex R3 FAIL 补 G-06 边 AC-10 -> AC-12 DAG 修订 实施顺序
2026-09-13 可执行性 Review 删除 R5–R13 覆盖附录;把共享 schema / GC 查询 / CAS 恢复升为正式卡 AC-00 / AC-04-GC / AC-08-R;刷新基线(tip 12c2f21、版本 0.10.1、Media 命名空间、迁移尾 m20260912);迁移 ID 改为 m20260913_000100;blob 改为 session-scoped;repo 单 segment;跟踪配置禁用占位且无 token;PUT fingerprint 不含 completeness;list 用 {items,next_cursor};AC-20 append-only 改行为测试 保留编号;新增 AC-00, AC-04-GC, AC-08-R 实施顺序、依赖登记表、粒度审计表、测试矩阵、追溯表、里程碑、Review log
2026-09-13 Codex R14 FAIL AC-01 写集补 testing.rs;AC-07 测试迁到 http_server::tests;新增 AC-22 前置 canonical helper;按独立谓词重计 G-03;AC-21/AC-17 改为 M;HTTP 卡增量写 agent-capture.md,AC-14 改为索引收口 新增 AC-22(自 AC-00 拆出) 实施顺序、依赖、粒度审计、追溯、里程碑、Review log
2026-09-13 Codex R15 FAIL 补边 AC-05 -> AC-00(同写 agent-capture.md);AC-14 将 README / plan-long 索引验证拆成两门 AC-00 Dependencies 增 AC-05 实施顺序、粒度审计、Review log
2026-09-13 Codex R16 PASS Review log 记录 R16 PASS;P2 residual 不改任务卡 N/A Review log
2026-10-08 一致性回填 完成判据 10 项与各卡 AC/Verification 子项(共 218 处行内项 + 10 项完成判据 + 8 项文档收口)据实勾选;依据仓内实现证据、R16 Codex PASS、版本面 bump 0.10.1→0.42.25;fmt/clippy 绿,迁移 m20260913 6/6、integration_agent_capture 8/8 绿 无卡号变更 完成判据、兼容与文档收口、各卡 AC/Verification、plan-status.md

已决议设计决策

实现时若需偏离本节,必须先修改计划并说明原因,不得在代码中静默改语义。

ADR-AC-01: 服务器 PK 叫 capture_id;客户 id 只叫 client_session_id

  • Status: Accepted
  • Context: server_id 与 HTTP/主机 server 混淆。libra {provider}__{provider_session_id} 只标识本机会话。
  • Decision: agent_capture_session.id 为 BIGINT GENERATED ALWAYS AS IDENTITY。对外 JSON 与路径参数一律 capture_id。libra 复合 id 只出现在 PUT /repos/{repo}/sessions/{client_session_id}。子表 FK 列名 capture_id。UNIQUE (deployment_id, tenant_id, repo_id, producer_id, session_kind, client_session_id)。事件 UNIQUE (capture_id, event_uid)。首次 PUT 按自然键事务化:先锁/插入自然键,唯一冲突后重读,再使用已有或新建的 capture_id。receipt 不参与首次 capture_id 生成。
  • Alternatives considered: 客户端 id 当全局 PK——拒绝。UUID v7——可后补。
  • Consequences: 子资源必须先有 PUT 回包中的 capture_id。
  • Revisit when: 需要跨部署联合主键。

ADR-AC-02: 对象键由服务器派生;含 tenant;客户端不得指定 final key

  • Status: Accepted
  • Decision: ObjectNamespace::Agent → to_string()="agent"。ObjectKey path(不再重复 namespace 段):staging {deployment_id}/{tenant_id}/staging/{lease_id};committed {deployment_id}/{tenant_id}/{visibility}/sha256/{hex}。首版 visibility=raw 为事实源。deployment_id/tenant_id 来自配置。blob 表 object_key 只存服务器值。
  • Alternatives considered: 客户端提交 key / 跨租户单 CAS——拒绝。
  • Consequences: 同 digest 不同 tenant 是两行两把 key。
  • Revisit when: 多区域复制。

ADR-AC-03: 双重门 + 独立 ingest token;不跟随 anonymous_access

  • Status: Accepted
  • Decision: [agent_capture].enabled 缺省 false。挂载 git.storage_only() && enabled。enabled=true 且非 storage-only → config validate 拒绝。启用后所有 discovery/list/show/ingest 要有效 ingest token(无 token 401)。token 不覆盖正规化 path → 404。[[agent_capture.ingest_tokens]]:name、token、paths(token_path_authorizes)、可选 tenant_id(若出现必须等于段级值)。查找为独立函数、sha256 常数时间,禁止调用 lookup_push_token。producer_id = token name。enabled=true 要求至少一条 token。认证头为 Authorization: Bearer <token>。
  • Alternatives considered: 复用 push_tokens / 跟随 anonymous_access——拒绝。
  • Consequences: 运维必须配置 ingest token 才能启用;跟踪样例配置保持 disabled、无可用 token。
  • Revisit when: DEFER-AC-03。

ADR-AC-04: 必须收 raw;独立 access_audit / tombstone;不扩 audit_logs

  • Status: Accepted
  • Decision: Discovery raw_accepted=true。仅 redacted 无 raw → completeness=incomplete,partial_reason=missing_raw。GET transcript 返回 raw 并 INSERT agent_capture_access_audit。禁止写入 audit_logs。tombstone 命中后再 ingest → 409。tracing 只记 id/digest/size。
  • Alternatives considered: 拒 raw / 扩 audit_logs——拒绝。
  • Consequences: 持有 ingest token 即能读 raw。
  • Revisit when: 法律 hold 产品化。

ADR-AC-05: repo_id = 正规化 mega 路径 TEXT

  • Status: Accepted
  • Context: 两台 clone → 两个 libra.repoid。monorepo 路径常无 git_repo 行。
  • Decision: /repos/{repo} 为单一 URL segment,值为 percent-encoded 路径。服务端先解码、再 normalize_repo_path 得到 repo_id TEXT,再做 token scope。禁止 Axum 中段 catch-all。授权、UNIQUE、隔离都用 repo_id。libra_repoid 可空 metadata,不作 FK/token/object key。
  • Alternatives considered: git_repo.id FK——拒绝。{*repo} catch-all——拒绝。
  • Consequences: 同一 mega 路径共用 repo_id;用 producer_id 区分实例。
  • Revisit when: 真实多租户 org 表。

ADR-AC-06: blob_ref 是 GC 真相;lease 冻结三元组

  • Status: Accepted
  • Decision: agent_capture_blob_ref 使用明确 owner 列(session/event/checkpoint/file_op)+ CHECK 恰好一个 owner;与 owner 同行同事务。禁止单独 ref_count 当唯一真相。staging 把 lease 写成 token 的 tenant/repo/producer 与 capture_id。finalize 路径必须等于 lease;服务器重算 digest。未过期他方 409。GC 查询:NOT EXISTS blob_ref AND (lease 空或过期) AND state<>protected。lease 状态 staging -> finalizing -> committed 或 expired/aborted,条件更新必须包含 owner generation。
  • Alternatives considered: 只按年龄删——拒绝。多态 owner_pk——拒绝。
  • Consequences: 后台 sweeper 为 DEFER-AC-04。
  • Revisit when: 周期 GC。

ADR-AC-07: storage-only 可独立使用;无用户列

  • Status: Accepted
  • Decision: 表无 user_id。cl_link 可空且首版不写不查不当授权。tenant_id/deployment_id 为配置常数。
  • Alternatives considered: 等 OAuth——拒绝。
  • Consequences: review 首版不挂载。
  • Revisit when: DEFER-AC-03。

ADR-AC-08: file-op 版本化契约;不从 ToolUse JSON 推断

  • Status: Accepted
  • Decision: agent.file_op.v1。无 source_event_uid(或不存在)则拒绝。op ∈ {read,write,patch,delete,search}。路径拒 ..、NUL、绝对路径。digest 非空必须指向已 finalize raw blob。
  • Alternatives considered: 从 tool JSON 猜字段——拒绝。
  • Consequences: 客户端必须显式发 file-op 批。
  • Revisit when: 需要服务端派生。

ADR-AC-09: JSONL uid 一律 {generation}:{byte_offset};incomplete 一等

  • Status: Accepted
  • Decision: JSONL 去重禁止 UUID/tool_call_id/内容 hash。原生 id 进 native_id。lifecycle 用 lifecycle_seq。source_stream (capture_id, stream_kind, generation)。completeness ∈ {empty,incomplete,complete,truncated}。未知 kind 存 envelope。FileHistory 不默认 50 版全文。单 session file blob 缺省上限 20。
  • Alternatives considered: event_id 当 uid——拒绝。
  • Consequences: jsonl 重写必须升 generation。
  • Revisit when: 跨 generation 折叠查询。

ADR-AC-10: blob staging 以 session 为边界;tenant 固定来自配置

  • Status: Accepted
  • Decision: staging/finalize 使用 /sessions/{capture_id}/blobs/...,不得使用 repo-level staging。请求不得提交 tenant_id、deployment_id 或 final object key;有效 tenant/deployment 一律来自 [agent_capture] 配置。token 的 tenant_id 若存在,必须与配置值相同,否则配置拒绝。所有 session、blob、tombstone、audit 查询均带 effective tenant/deployment 条件。
  • Consequences: tombstone 可在 staging 前以 capture_id 检查;同 repo 下不同 session 不会共享未绑定的 lease。

ADR-AC-11: canonical JSON 与明确的状态/错误契约

  • Status: Accepted
  • Decision: 需要比较 payload 的 idempotency key、event UID 与 receipt 均使用 RFC 8785 canonical JSON fingerprint;JSON 欄位顺序不影响相同判定;拒绝 duplicate key、NaN/Infinity 与溢出数字。HTTP 认证与资源判定顺序为 401 → 404 → 409 → 400/413。固定 schema 的未知 session/stream 值拒绝;未知 event kind 存 unknown 并保留 envelope。PUT fingerprint 不含服务端 completeness/lifecycle。
  • Consequences: 所有 batch 为整批事务;同 fingerprint 重试返回既有结果,不同 fingerprint 返回 409。

HTTP 契约与数据模型冻结

router 内部 path 以 /agent-capture 开头,由外层 nest 到 /api/v1;下表 public path 为完整外部路径,实现时不得再加一层 /api/v1。

认证:Authorization: Bearer <ingest_token>。错误响应固定 { "error": { "code": string, "message": string } },不得包含 token secret、raw prompt、tool 原文或其他 tenant 是否存在的线索。分页统一 limit 与 cursor,默认 limit=50,最大 limit=200;list response { "items": [...], "next_cursor": string|null }。

配额缺省(AC-01 冻结)

字段 缺省 作用
enabled false 挂载门
max_blob_bytes 16777216 staging/finalize 413(含 chunked)
max_file_blobs_per_session 20 超限 session truncated
max_events_per_batch 500 events batch 413
max_event_bytes 1048576 单 event 413
lease_ttl_seconds 900 staging lease TTL

Public endpoints

Method Public path 卡
GET /api/v1/agent-capture/discovery AC-16
PUT /api/v1/agent-capture/repos/{repo}/sessions/{client_session_id} AC-21
POST /api/v1/agent-capture/sessions/{capture_id}/blobs/staging AC-08
POST /api/v1/agent-capture/sessions/{capture_id}/blobs/{lease_id}/finalize AC-08
POST /api/v1/agent-capture/sessions/{capture_id}/events:batch AC-09
POST /api/v1/agent-capture/sessions/{capture_id}/file-ops:batch AC-10
POST /api/v1/agent-capture/sessions/{capture_id}/checkpoints AC-11
GET /api/v1/agent-capture/repos/{repo}/sessions AC-12
GET /api/v1/agent-capture/sessions/{capture_id} AC-12
GET /api/v1/agent-capture/sessions/{capture_id}/checkpoints AC-12
GET /api/v1/agent-capture/sessions/{capture_id}/transcript AC-12
GET /api/v1/agent-capture/sessions/{capture_id}/file-ops AC-12

session 固定字段:capture_id: i64、client_session_id: string、tenant_id: string、deployment_id: string、repo_id: string、producer_id: string、session_kind: external_capture\|internal_code、started_at、ended_at、completeness: empty\|incomplete\|complete\|truncated、partial_reason: string\|null、created_at、updated_at。identity 与服务端字段不可由客户端覆写;未知 JSON 字段拒绝。

event 的 event_uid 必须是 ASCII 十进制 generation:byte_offset,两部分均为非负整数且不得溢出。source_stream watermark 只允许单调前进;新 generation 可重置 offset。

blob 首版允许 raw 与可选 redacted;checkpoint/transcript 事实源必须是 committed raw。

幂等键

Endpoint Client key Fingerprint Commit
session PUT Idempotency-Key header 自然键 + immutable metadata(不含 completeness) 自然键锁 → fingerprint compare → session commit
blob staging Idempotency-Key header capture + size + content metadata lease intent → object write
finalize Idempotency-Key header capture + lease + declared size/digest lease generation 条件 → blob/ref/receipt
event batch body batch_id capture + batch_id + canonical events receipt 同事务
file-op batch body batch_id capture + batch_id + canonical ops receipt 同事务
checkpoint body checkpoint_id capture + checkpoint_id + canonical metadata/digest unique receipt 同事务

Schema 最小集(AC-02 必须实现)

表 关键约束
agent_capture_session identity PK;无 user_id;UNIQUE 六元组;session_kind CHECK
agent_capture_event FK session ON DELETE RESTRICT;UNIQUE (capture_id, event_uid)
agent_capture_source_stream UNIQUE (capture_id, stream_kind, generation)
agent_capture_checkpoint FK session RESTRICT;session_kind=external_capture 由存储层强制
agent_capture_file_op FK session RESTRICT;source_event_uid 必须能解析到同 capture event
agent_capture_blob UNIQUE (deployment_id, tenant_id, digest, visibility);lease_state CHECK;lease_generation;upload/cleanup intent 列
agent_capture_blob_ref 明确 owner_session_id / owner_event_id / owner_checkpoint_id / owner_file_op_id 可空列;CHECK 恰好一个非空;RESTRICT
agent_capture_ingest_receipt UNIQUE (deployment_id, tenant_id, producer_id, capture_id, operation, idempotency_key)
agent_capture_stream_blob UNIQUE (capture_id, stream_kind, generation);composite FK session/blob
agent_capture_access_audit append-only;无 update/delete API
agent_capture_tombstone 按 capture 自然键 / capture_id 可点查
agent_capture_deletion_ledger 删除意图行;本计划不执行物理删

跨 deployment 读取统一 404。所有查询带 deployment_id+tenant_id。

全局工程约束

遵守模板 GC-01..GC-12。任务卡粒度 G-01..G-11 继承模板正文,本节不重复。本 checkout 发布以 AGENTS.md 的 Libra 为准。本计划附加:

  • GC-AC-01: 只允许 agent_capture_* 表名与 /api/v1/agent-capture;禁止新建 runtime agent_sessions。
  • GC-AC-02: 禁止调用 lookup_push_token;禁止用 git.anonymous_access 放行本面。
  • GC-AC-03: tracing 不得含 raw prompt/token/tool 原文。
  • GC-AC-04: 不新增 crate 级 #[allow(...)];生产路径不新增裸 unwrap/expect。
  • GC-AC-05: 客户端 object_key 必须忽略或 400。
  • GC-AC-06: 函数级测试过滤必须 --exact,且输出含该测试名与 1 passed。模块级门不加 --exact。

执行检查必备需求(强制)

全文遵守 plan-template.md ER-01..ER-12。特化:

  • VCS: libra status / libra add <paths> / libra commit -m / libra push origin main;禁止 --force。
  • ER-04 D 组: 所有卡 N/A(本 checkout 无 CI workflow 文件);C 覆盖后可 complete。
  • ER-01: 不提交 scripts/oci_smoke_storage_only.sh、secrets/。每张独立发布卡开工前确认版本面无他人未提交改动。
  • ER-08: 实现/migration/IT 卡 patch;AC-14 N/A;AC-15 patch;文档成稿提交不 bump。
  • ER-07: 本 checkout 无 .git。commit.gpgSign / gpgsig 头校验 N/A。

实施顺序

编号顺序 ≠ 执行顺序(G-09)。执行以下列边为准(与各卡 Dependencies 中的 AC-* 一一对应;DEP-* 只出现在依赖登记表与卡 Dependencies,不画成本节边):

  • AC-00 -> AC-07
  • AC-01 -> AC-00
  • AC-01 -> AC-02
  • AC-01 -> AC-06
  • AC-02 -> AC-00
  • AC-02 -> AC-03
  • AC-03 -> AC-18
  • AC-04 -> AC-04-GC
  • AC-04 -> AC-20
  • AC-04-GC -> AC-05
  • AC-05 -> AC-00
  • AC-05 -> AC-07
  • AC-06 -> AC-00
  • AC-06 -> AC-07
  • AC-07 -> AC-16
  • AC-08 -> AC-08-R
  • AC-08 -> AC-11
  • AC-08 -> AC-17
  • AC-08-R -> AC-09
  • AC-08-R -> AC-12
  • AC-08-R -> AC-13
  • AC-09 -> AC-10
  • AC-10 -> AC-11
  • AC-10 -> AC-12
  • AC-11 -> AC-12
  • AC-12 -> AC-13
  • AC-12 -> AC-17
  • AC-13 -> AC-14
  • AC-13 -> AC-15
  • AC-14 -> AC-15
  • AC-16 -> AC-13
  • AC-16 -> AC-21
  • AC-17 -> AC-13
  • AC-18 -> AC-08-R
  • AC-18 -> AC-19
  • AC-19 -> AC-04
  • AC-20 -> AC-04-GC
  • AC-20 -> AC-12
  • AC-20 -> AC-17
  • AC-21 -> AC-08
  • AC-22 -> AC-00
  • AC-22 -> AC-04
  • AC-22 -> AC-18

全串行发布顺序(ER-12;同一时刻只一张卡处于已 bump 未推送):AC-01 → AC-22 → AC-02 → AC-03 → AC-18 → AC-19 → AC-04 → AC-20 → AC-04-GC → AC-05 → AC-06 → AC-00 → AC-07 → AC-16 → AC-21 → AC-08 → AC-08-R → AC-09 → AC-10 → AC-11 → AC-12 → AC-17 → AC-13 → AC-14 → AC-15。AC-14 在 AC-15 前完成本地文档,不 bump。

依赖登记表

ID direction 类型 对象 Owner 产物与可用性判据 证据 超时与失败策略
DEP-AC-01 incoming 跨计划 plan-20260902 的 include_oci 挂载模式 本计划 storage_only_openapi_doc(include_oci: bool) 已存在;AC-07 增 include_agent_capture 平行参数 src/server/http_server.rs:791 缺失则 AC-07 按现状改签名
DEP-AC-02 incoming 上游 revision libra @ d1aafb2 本计划 event_uid 形态 / FileHistory 硬帽按该 pin 事实基线 pin 前进则开工刷新映射
DEP-AC-03 outgoing 跨仓 libra Mega remote 客户端 未来 libra 计划 DEFER-AC-01 ADR-AC-03 本仓 HTTP 先稳定

无 DEP-AC-05:HTTP schema 由 AC-00 提供;canonical helper 由 AC-22 提供;AC-14 只做索引收口。

发布分组与并发窗口

ID 成员 唯一发布点 窗口规则 失败回滚顺序 理由
N/A — — 每张实现卡独立发布。AC-14 no-release 继承 AC-15 — 无需家族

并发声明: 实现阶段 全串行(即使 AC-01/AC-06 写集不相交,本计划仍全串行以免发布窗口交错)。

发布者: 执行本计划的单一 Agent(ER-12)。

发布窗口顺序: AC-01 → AC-22 → AC-02 → AC-03 → AC-18 → AC-19 → AC-04 → AC-20 → AC-04-GC → AC-05 → AC-06 → AC-00 → AC-07 → AC-16 → AC-21 → AC-08 → AC-08-R → AC-09 → AC-10 → AC-11 → AC-12 → AC-17 → AC-13 → AC-14 → AC-15(AC-14 不 bump)。

Phase 0: 计划冻结

目标: 本文 Codex 计划审查 PASS 后入库。

进入条件: 当前 checkout 可核对锚点。

退出条件: Review log 最终 Codex 为 PASS;tip 含本文件。

Phase 1: 配置、schema、存储、对象层

目标: 无 HTTP 也可测的 catalog + CAS 键 + canonical fingerprint helper。

进入条件: Phase 0。

退出条件: AC-01、AC-22、AC-02、AC-03、AC-18、AC-19、AC-04、AC-20、AC-04-GC、AC-05、AC-06 complete。

Phase 2: HTTP、IT、文档、收口

目标: 可发布 ingest/查询面。

进入条件: AC-05 与 AC-06 完成。

退出条件: AC-00、AC-07、AC-16、AC-21、AC-08、AC-08-R、AC-09..AC-14、AC-17、AC-15 完成。

任务卡

任务 ID 使用稳定前缀 AC-。编号被引用后不重排;拆出的卡使用 AC-00、AC-04-GC、AC-08-R、AC-16..AC-22,因此编号顺序 ≠ 执行顺序。

任务卡粒度规则(G-*)

N/A(原因:全文逐字遵守 plan-template.md 的 G-01..G-11 与推荐拆分/反模式速查;不在本文件复制以免与模板漂移。本计划以各卡 Granularity 行与「任务卡粒度审计表」为机器可核对摘要。ER-03 开工前仍须逐字段核对各卡 Granularity 行。)

Verification 判定口径

N/A(原因:逐字继承 plan-template.md「Verification 判定口径」。本卡 Verification 只登记本卡特有命令。ER-04 强制门不计入 G-03。本计划所有命名测试过滤门一律加 --exact,并以输出出现目标测试名且含 1 passed 为判定依据(GC-AC-06);未匹配过滤器时 cargo 退出 0 属幽灵验收。

零命中守卫必须使用下列模板(rg 退出码 0 = 有命中失败;1 = 零命中通过;>1 = 命令失败,不得当作通过)。禁止 ! rg、if rg; then exit 1; fi、裸 rg …; rc=$?:

if rg -n "<pattern>" <paths>; then
  echo "FAIL: forbidden pattern found"; exit 1
else
  rc=$?
  if [ "$rc" -ne 1 ]; then echo "ERROR: rg failed with exit $rc"; exit "$rc"; fi
  echo "OK: zero hits"
fi

仅用于定位符号的 rg 必须注明「锚点定位用,非判据」。 )

字段全局默认与例外

  • Release boundary 默认: independent
  • Task type 默认: implementation
  • Rollback mode 默认: revert
  • Migration and rollback 默认: N/A
  • Security and privacy 默认: 继承 GC-07、GC-AC-02/03
  • Performance budget 默认: 继承 GC-10
  • Docs and compatibility impact 默认: 公开行为由拥有卡增量追加 docs/refactoring/agent-capture.md;AC-14 只做索引收口
  • D-group 默认: N/A(本 checkout 无 CI workflow 文件)
  • C/D coverage from 默认: self

默认覆盖:

任务 偏离的字段 取值与理由
AC-02 Rollback mode forward-only:本仓无运行期 down
AC-14 Task type / Release boundary / Version increment / C/D docs / no-release / N/A / AC-15
AC-15 Task type / Rollback mode release / immutable-release

规则 waiver: 无 EX-*。

任务卡粒度审计表

任务 type axis recovery complete self-contained AC VER landing / prod-files scope deps writeset release split-from exception
AC-01 implementation [agent_capture] 配置门与 ingest_tokens revert yes yes 8/8 6/8 2/4 M none no-overlap independent N/A N/A
AC-22 implementation RFC 8785 canonical JSON helper revert yes yes 6/8 5/8 1/2 S none no-overlap independent 自 AC-00 拆出 N/A
AC-02 migration capture 表 DDL forward-only yes yes 8/8 7/8 1/2 M AC-01 序列化于 AC-01 independent N/A N/A
AC-03 implementation session 实体与 upsert revert yes yes 5/8 3/8 2/4 M AC-02 序列化于 AC-02 independent N/A N/A
AC-18 implementation event 与 source_stream storage revert yes yes 6/8 4/8 2/4 M AC-03,AC-22 序列化于 AC-03,AC-22 independent 自 AC-03 拆出 N/A
AC-19 implementation checkpoint 与 file_op storage revert yes yes 6/8 4/8 2/4 M AC-18 序列化于 AC-18 independent 自 AC-03 拆出 N/A
AC-04 implementation blob/blob_ref/receipt revert yes yes 7/8 3/8 2/5 M AC-19,AC-22 序列化于 AC-19,AC-22 independent N/A N/A
AC-20 implementation access_audit/tombstone/ledger storage revert yes yes 7/8 4/8 2/5 M AC-04 序列化于 AC-04 independent 自 AC-04 拆出 N/A
AC-04-GC implementation GC candidate query revert yes yes 3/8 1/8 1/1 S AC-04,AC-20 serialized independent AC-04 N/A
AC-05 implementation Agent 命名空间与对象服务 revert yes yes 6/8 5/8 3/4 M AC-04-GC 序列化于 AC-04-GC independent N/A N/A
AC-06 implementation ingest token 查找 revert yes yes 6/8 5/8 1/3 S AC-01 no-overlap independent N/A N/A
AC-00 implementation shared HTTP schema/error/path contract revert yes yes 5/8 5/8 3/5 M AC-01,AC-06,AC-02,AC-22,AC-05 序列化于 AC-01,AC-06,AC-02,AC-22,AC-05 independent N/A N/A
AC-07 implementation HTTP挂载门与OpenAPI flag revert yes yes 7/8 7/8 3/3 M AC-05,AC-06,AC-00,DEP-AC-01 序列化于 AC-05,AC-06,AC-00 independent N/A N/A
AC-16 implementation discovery HTTP revert yes yes 4/8 4/8 2/3 M AC-07 序列化于 AC-07 independent 自 AC-07 拆出 N/A
AC-21 implementation session PUT revert yes yes 5/8 5/8 1/1 M AC-16 序列化于 AC-16 independent 自 AC-07 拆出 N/A
AC-08 implementation blob staging/finalize HTTP revert yes yes 7/8 7/8 2/2 M AC-21 序列化于 AC-21 independent N/A N/A
AC-08-R implementation CAS recovery/fencing revert yes yes 8/8 8/8 2/2 M AC-08,AC-18 serialized independent AC-08 N/A
AC-09 implementation events batch revert yes yes 6/8 6/8 2/2 M AC-08-R,DEP-AC-02 序列化于 AC-08-R independent N/A N/A
AC-10 implementation file-ops batch revert yes yes 6/8 6/8 2/2 M AC-09 序列化于 AC-09 independent N/A N/A
AC-11 implementation checkpoint POST revert yes yes 6/8 6/8 2/2 M AC-10,AC-08 序列化于 AC-10,AC-08 independent N/A N/A
AC-12 implementation metadata/transcript查询面 revert yes yes 8/8 7/8 2/2 M AC-10,AC-11,AC-20,AC-08-R 序列化于 AC-10,AC-11,AC-20,AC-08-R independent N/A N/A
AC-17 implementation tombstone拒再ingest revert yes yes 4/8 4/8 2/2 M AC-12,AC-20,AC-08 序列化于 AC-12,AC-20,AC-08 independent 自 AC-12 拆出 N/A
AC-13 implementation 进程级 IT revert yes yes 8/8 7/8 1/1 M AC-12,AC-16,AC-17,AC-08-R no-overlap independent N/A N/A
AC-14 docs 契约文档与索引 revert 文档 yes yes 8/20 6/20 0/0 M AC-13 序列化于 AC-13 no-release N/A N/A
AC-15 release 收口发布 immutable-release yes yes 5/12 2/12 0/0 S AC-13,AC-14 I–R 窗口 independent N/A N/A

Task AC-01: [agent_capture] 配置门与 ingest_tokens

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 新增 Config.agent_capture: AgentCaptureConfig。字段与 serde 缺省以「HTTP 契约与数据模型冻结」配额表为准:enabled=false、tenant_id、deployment_id、配额五元组、[[agent_capture.ingest_tokens]](name/token/paths/可选 tenant_id)。enabled=true 且非 git.storage_only() → config.validate Err。enabled=true 且 ingest_tokens 为空 → Err。token 可选 tenant_id 若出现必须等于段级 tenant_id,否则 validate Err。known_fields 登记该段及子键。未知子键拒绝。config/config.toml 只加注释块。config/config-storage-only.toml 写 [agent_capture] enabled = false 占位,禁止提交可用 ingest token。测试用内存 Config / 临时 toml 注入 token。

Out of scope:

  • HTTP 挂载(AC-07)
  • lookup 函数(AC-06)
  • schema(AC-02)

Current evidence:

事实 证据
Config 无该段 src/config/model.rs:9-52
OCI 同类门 src/config/validate.rs:653;src/config/tests.rs:97-110
known_fields 根表含 oci 无 agent_capture src/config/validate.rs:1465-1577
storage-only 样例启用 OCI config/config-storage-only.toml:359-360
Config 结构体字面量 src/config/testing.rs:156

Acceptance criteria:

  • Config 含字段 agent_capture: AgentCaptureConfig
  • AgentCaptureConfig.enabled serde 缺省为 false
  • enabled=true 且 git.push_auth 为 None 时 config.validate 返回 Err
  • enabled=true 且 ingest_tokens 为空时 config.validate 返回 Err
  • known_fields("") 含 "agent_capture"
  • 含 agent_capture.unexpected 的临时 toml reject_unknown_fields 返回 Err
  • config::tests::agent_capture_quota_defaults 测试通过
  • config/config-storage-only.toml 的 [agent_capture].enabled 等于 false

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'config::tests::agent_capture_enabled_requires_storage_only' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'config::tests::agent_capture_enabled_requires_ingest_token' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'config::tests::agent_capture_quota_defaults' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'config::validate::tests::reject_unknown_fields_rejects_unknown_agent_capture_key' -- --exact --nocapture
  • cargo run -p mega2 -- --config config/config.toml config validate 退出 0
  • cargo run -p mega2 -- --config config/config-storage-only.toml config validate 退出 0

Dependencies: 无

Deliverables: N/A

Implementation write set: src/config/model.rs;src/config/validate.rs;src/config/testing.rs;src/config/tests.rs;config/config.toml(仅注释);config/config-storage-only.toml;docs/refactoring/agent-capture.md(新,配置/配额节)

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: 创建 docs/refactoring/agent-capture.md 配置/配额节;样例注释。

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 独立 ingest_tokens;禁止把可用 token 写入跟踪配置。

Performance budget: validate 为启动路径;token 表按配置条数线性扫描,本卡不实现查找。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=[agent_capture] 配置门与 ingest_tokens; recovery=revert; complete=yes; self-contained=yes; AC=8/8; VER=6/8; landing=2; prod-files=4; scope=M; deps=none; writeset=no-overlap; release=independent; split-from=N/A; exception=N/A

Task AC-22: canonical JSON fingerprint helper

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 在 src/common/canonical_json.rs 交付 RFC 8785 canonical JSON fingerprint helper,供 event UID/payload 比较、ingest receipt 与 HTTP 幂等共用。本卡不实现 HTTP DTO。当前 src/common/mod.rs 仅有 errors 与 utils。后续 AC-18/AC-04/AC-00 必须调用本 helper,禁止再写一份等价实现。

Out of scope:

  • HTTP DTO / router fixture(AC-00)
  • event storage(AC-18)

Current evidence:

事实 证据
common 模块 src/common/mod.rs:1-2
无 canonical helper 现场 rg canonical_json src/common 预期退出码 1

Acceptance criteria:

  • src/common/mod.rs 含 pub mod canonical_json
  • 相同语义、不同键顺序的 JSON 得到同一 fingerprint
  • duplicate key 返回 Err
  • NaN 返回 Err
  • Infinity 返回 Err
  • 溢出数字返回 Err

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'common::canonical_json::tests::fingerprint_stable_under_key_reorder' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'common::canonical_json::tests::rejects_duplicate_key' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'common::canonical_json::tests::rejects_nan' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'common::canonical_json::tests::rejects_infinity' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'common::canonical_json::tests::rejects_overflow' -- --exact --nocapture

Dependencies: 无

Deliverables: N/A

Implementation write set: src/common/canonical_json.rs;src/common/mod.rs

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: N/A(内部 helper;契约叙述由消费卡追加)

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: fingerprint 不含 token secret。

Performance budget: 仅用于幂等比较,不在 list 热路径展开 blob。

Estimated scope: S

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=RFC 8785 canonical JSON helper; recovery=revert; complete=yes; self-contained=yes; AC=6/8; VER=5/8; landing=1; prod-files=2; scope=S; deps=none; writeset=no-overlap; release=independent; split-from=AC-00; exception=N/A

Task AC-02: agent_capture_* 建表迁移

Task type: migration

Lifecycle / Acceptance: done / complete

Description: 新增 m20260913_000100_add_agent_capture_tables,在 migrations() 末尾登记(当前末项为 m20260912_000100_drop_orion_build_tables)。本卡只做 DDL。表、列、UNIQUE/FK/CHECK/索引/RESTRICT 以「HTTP 契约与数据模型冻结」schema 表为准,包括:agent_capture_session(identity id,无 user_id,UNIQUE 六元组含 deployment_id)、checkpoint、event、file_op、source_stream、blob(含 lease 状态/generation、upload_intent、cleanup_intent)、blob_ref(typed owner 列 + 恰好一个 owner 的 CHECK,无多态 owner_pk)、ingest_receipt、access_audit、tombstone、deletion_ledger、stream_blob。down 空。

Out of scope:

  • sea-orm 实体与查询(AC-03 起)
  • HTTP(AC-07+)

Current evidence:

事实 证据
迁移列表末项 src/jupiter/migration/mod.rs:228 m20260912_000100_drop_orion_build_tables
无 agent_capture 表名 锚点定位用:rg -n agent_capture src/jupiter/migration src/callisto 预期 rg 退出码 1

Acceptance criteria:

  • migrations() 末项为 m20260913_000100_add_agent_capture_tables
  • apply_migrations 后存在表 agent_capture_session
  • agent_capture_session 无列 user_id
  • agent_capture_session 存在 UNIQUE (deployment_id, tenant_id, repo_id, producer_id, session_kind, client_session_id)
  • agent_capture_event 存在 UNIQUE (capture_id, event_uid)
  • agent_capture_blob 存在 UNIQUE (deployment_id, tenant_id, digest, visibility)
  • migration_constraints_and_scope 测试通过
  • 该迁移 down 函数为空实现

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::migration::m20260913_000100_add_agent_capture_tables::tests::migration_creates_session_table' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::migration::m20260913_000100_add_agent_capture_tables::tests::migration_session_has_no_user_id' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::migration::m20260913_000100_add_agent_capture_tables::tests::migration_session_unique_tuple' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::migration::m20260913_000100_add_agent_capture_tables::tests::migration_event_unique_uid' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::migration::m20260913_000100_add_agent_capture_tables::tests::migration_blob_unique_digest' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::migration::m20260913_000100_add_agent_capture_tables::tests::migration_constraints_and_scope' -- --exact --nocapture
  • 零命中守卫(判定口径模板):
if rg -n "Table::drop" src/jupiter/migration/m20260913_000100_add_agent_capture_tables.rs; then
  echo "FAIL: forbidden pattern found"; exit 1
else
  rc=$?
  if [ "$rc" -ne 1 ]; then echo "ERROR: rg failed with exit $rc"; exit "$rc"; fi
  echo "OK: zero hits"
fi

锚点定位用(非判据,不计 G-03):rg -n 'm20260913_000100_add_agent_capture_tables' src/jupiter/migration/mod.rs

Dependencies: AC-01

Deliverables: N/A

Implementation write set: src/jupiter/migration/m20260913_000100_add_agent_capture_tables.rs(新);src/jupiter/migration/mod.rs;docs/refactoring/agent-capture.md(追加 schema 节)

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: 追加 docs/refactoring/agent-capture.md schema 表。

Rollback mode: forward-only

Migration and rollback: 只能前滚;down 空实现;运行期无 migrate down。

Security and privacy: 无 user_id;tenant/deployment 进入 UNIQUE/FK。

Performance budget: 必要 UNIQUE/查询索引在冻结 schema 表列出;禁止无索引的 tenant 全表扫描作为唯一查询路径。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=migration; axis=capture 表 DDL; recovery=forward-only; complete=yes; self-contained=yes; AC=8/8; VER=7/8; landing=1; prod-files=2; scope=M; deps=AC-01; writeset=序列化于 AC-01; release=independent; split-from=N/A; exception=N/A

Task AC-03: session 实体与 upsert_session

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 新增 callisto 实体 agent_capture_session 并在 callisto/mod.rs 注册。新增 AgentCaptureStorage 与 upsert_session:按冻结六元组自然键事务化(先锁/插入自然键,唯一冲突后重读),返回服务器 capture_id: i64。无 HTTP。首次 PUT 的 capture_id 分配在本存储方法完成;receipt 不参与首次 capture_id 生成。R1 拆出 AC-18、AC-19。

Out of scope:

  • event / source_stream(AC-18)
  • checkpoint / file_op(AC-19)
  • blob/audit/tombstone(AC-04 / AC-20)
  • 对象存储(AC-05)

Current evidence:

事实 证据
OCI 分层先例 src/callisto/oci_repository.rs;src/jupiter/storage/oci_db_storage.rs
test_db_connection src/jupiter/tests.rs:64
AC-02 迁移产物 src/jupiter/migration/m20260913_000100_add_agent_capture_tables.rs

Acceptance criteria:

  • src/callisto/mod.rs 含 pub mod agent_capture_session
  • upsert_session 同六元组同内容第二次调用不新增行
  • upsert_session 返回的 capture_id 为大于 0 的 i64
  • session 实体源码无字段 user_id
  • src/jupiter/storage/mod.rs 含 pub mod agent_capture_storage

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::upsert_session_idempotent' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::upsert_session_returns_capture_id' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'callisto::agent_capture_session::tests::session_model_has_no_user_id' -- --exact --nocapture 锚点定位用(非判据,不计 G-03):rg -n 'pub mod agent_capture_session' src/callisto/mod.rs

Dependencies: AC-02

Deliverables: N/A

Implementation write set: src/callisto/agent_capture_session.rs;src/callisto/mod.rs;src/jupiter/storage/agent_capture_storage.rs;src/jupiter/storage/mod.rs(pub mod 行)

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: N/A

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 查询必带 deployment/tenant 条件。

Performance budget: 自然键 UNIQUE 查找为 O(1) 索引点查。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=session 实体与 upsert; recovery=revert; complete=yes; self-contained=yes; AC=5/8; VER=3/8; landing=2; prod-files=4; scope=M; deps=AC-02; writeset=序列化于 AC-02; release=independent; split-from=N/A; exception=N/A

Task AC-18: event 与 source_stream storage

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 新增实体 agent_capture_event、agent_capture_source_stream。insert_event 按 (capture_id, event_uid) 幂等,payload 比较调用 AC-22 canonical_json helper。source_stream watermark 以 (generation, byte_offset) 比较,只允许单调前进;新 generation 可重置 offset。complete/truncated 不得被普通 insert 降级。自 AC-03 拆出。

Out of scope:

  • session upsert(AC-03)
  • checkpoint / file_op(AC-19)
  • HTTP events batch(AC-09)

Current evidence:

事实 证据
消费 AC-03 src/jupiter/storage/agent_capture_storage.rs 已有 upsert_session
ADR-AC-09 本文冻结契约

Acceptance criteria:

  • src/callisto/mod.rs 含 pub mod agent_capture_event
  • src/callisto/mod.rs 含 pub mod agent_capture_source_stream
  • 重复 (capture_id, event_uid) 同内容不新增 event 行
  • 同 uid 不同 payload 的 insert 返回 Err
  • source_stream watermark 回退被拒绝
  • 不存在的 capture_id 上 insert_event 返回 Err

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::event_uid_idempotent' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::event_uid_conflict_different_payload' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::source_stream_watermark_monotonic' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::event_requires_session' -- --exact --nocapture

Dependencies: AC-03;AC-22

Deliverables: N/A

Implementation write set: src/callisto/agent_capture_event.rs;src/callisto/agent_capture_source_stream.rs;src/callisto/mod.rs;src/jupiter/storage/agent_capture_storage.rs

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: N/A

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: payload 比较用 canonical JSON;tracing 不写 event 原文。

Performance budget: uid UNIQUE 点查;禁止按 payload 全文扫描去重。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=event 与 source_stream storage; recovery=revert; complete=yes; self-contained=yes; AC=6/8; VER=4/8; landing=2; prod-files=4; scope=M; deps=AC-03,AC-22; writeset=序列化于 AC-03,AC-22; release=independent; split-from=AC-03; exception=N/A

Task AC-19: checkpoint 与 file_op storage

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 新增实体 agent_capture_checkpoint、agent_capture_file_op。插入 checkpoint 要求父 session session_kind=external_capture。file_op 要求 source_event_uid 已存在于同一 capture。自 AC-03 拆出。

Out of scope:

  • HTTP checkpoint / file-ops(AC-10 / AC-11)
  • blob 实体(AC-04)

Current evidence:

事实 证据
消费 AC-18 insert_event 已可创建 event_uid
ADR-AC-08 本文

Acceptance criteria:

  • src/callisto/mod.rs 含 pub mod agent_capture_checkpoint
  • src/callisto/mod.rs 含 pub mod agent_capture_file_op
  • 对 session_kind=internal_code 的父行插入 checkpoint 返回 Err
  • 对 session_kind=external_capture 的父行插入 checkpoint 成功
  • 缺少对应 event 的 file_op 插入返回 Err
  • 存在 source event 的 file_op 插入成功

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::checkpoint_rejects_internal_code_parent' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::checkpoint_accepts_external_capture_parent' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::file_op_requires_source_event' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::file_op_inserts_when_source_exists' -- --exact --nocapture

Dependencies: AC-18

Deliverables: N/A

Implementation write set: src/callisto/agent_capture_checkpoint.rs;src/callisto/agent_capture_file_op.rs;src/callisto/mod.rs;src/jupiter/storage/agent_capture_storage.rs

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: N/A

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 路径合法性在 HTTP 卡拒绝;本卡只保证 FK 式 source_event。

Performance budget: checkpoint 插入 O(1);不在本卡展开 transcript 字节。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=checkpoint 与 file_op storage; recovery=revert; complete=yes; self-contained=yes; AC=6/8; VER=4/8; landing=2; prod-files=4; scope=M; deps=AC-18; writeset=序列化于 AC-18; release=independent; split-from=AC-03; exception=N/A

Task AC-04: blob / blob_ref / receipt

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 补实体与 AgentCaptureStorage 方法:blob staging 行、finalize 写 committed 行、blob_ref 与 owner 同事务、ingest receipt 幂等(fingerprint 调用 AC-22 helper)。GC 候选查询由 AC-04-GC 承接。access_audit / tombstone / ledger 由 AC-20 承接。本卡不写对象存储字节。

Out of scope:

  • GC 候选查询(AC-04-GC)
  • access_audit / tombstone / deletion_ledger(AC-20)
  • HTTP(AC-08)
  • ObjectNamespace(AC-05)
  • 后台 sweeper(DEFER-AC-04)

Current evidence:

事实 证据
消费 AC-19 catalog src/jupiter/storage/agent_capture_storage.rs
无 ref_count 列 表由 AC-02 创建;实体本卡新建

Acceptance criteria:

  • src/callisto/mod.rs 含 pub mod agent_capture_blob
  • src/callisto/mod.rs 含 pub mod agent_capture_blob_ref
  • src/callisto/mod.rs 含 pub mod agent_capture_ingest_receipt
  • finalize 写入 committed blob 行
  • 上述 finalize 与至少一条 blob_ref 在同一事务提交
  • 同 receipt scope 同内容返回既有 receipt
  • src/callisto/agent_capture_blob.rs 源码无标识符 ref_count

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::finalize_writes_blob_ref_same_txn' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::ingest_receipt_idempotent' -- --exact --nocapture
  • 零命中守卫(判定口径模板):
if rg -n "ref_count" src/callisto/agent_capture_blob.rs; then
  echo "FAIL: forbidden pattern found"; exit 1
else
  rc=$?
  if [ "$rc" -ne 1 ]; then echo "ERROR: rg failed with exit $rc"; exit "$rc"; fi
  echo "OK: zero hits"
fi

Dependencies: AC-19;AC-22

Deliverables: N/A

Implementation write set: src/callisto/agent_capture_blob.rs;src/callisto/agent_capture_blob_ref.rs;src/callisto/agent_capture_ingest_receipt.rs;src/callisto/mod.rs;src/jupiter/storage/agent_capture_storage.rs

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: N/A

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: object_key 只存服务器派生值。

Performance budget: 同 digest 共享 committed 行(UNIQUE digest/visibility/tenant/deployment)。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=blob/blob_ref/receipt; recovery=revert; complete=yes; self-contained=yes; AC=7/8; VER=3/8; landing=2; prod-files=5; scope=M; deps=AC-19,AC-22; writeset=序列化于 AC-19,AC-22; release=independent; split-from=N/A; exception=N/A

Task AC-20: access_audit / tombstone / ledger storage

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 补实体 agent_capture_access_audit、agent_capture_tombstone、agent_capture_deletion_ledger。access_audit 只 insert。is_tombstoned 供 HTTP 409。ledger 只作为删除意图行(本卡不删对象)。自 AC-04 拆出。append-only 用行为测试证明,禁止对共享 agent_capture_storage.rs 做 .update( 零命中(该文件含 session/watermark/lease 合法更新)。

Out of scope:

  • GET transcript 写 audit(AC-12)
  • tombstone HTTP 409(AC-17)
  • 后台 sweeper(DEFER-AC-04)

Current evidence:

事实 证据
消费 AC-04 AgentCaptureStorage blob 方法
ADR-AC-04 不扩 audit_logs;src/callisto/audit_logs.rs:17 target_id: i64

Acceptance criteria:

  • src/callisto/mod.rs 含 pub mod agent_capture_access_audit
  • src/callisto/mod.rs 含 pub mod agent_capture_tombstone
  • src/callisto/mod.rs 含 pub mod agent_capture_deletion_ledger
  • is_tombstoned 对已插入 tombstone 返回 true
  • insert_access_audit 成功插入一行
  • access_audit_rejects_update 对已插入 audit 行的 update 失败
  • access_audit_rejects_delete 对已插入 audit 行的 delete 失败

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::tombstone_is_detected' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::access_audit_inserts_row' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::access_audit_rejects_update' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::access_audit_rejects_delete' -- --exact --nocapture

Dependencies: AC-04

Deliverables: N/A

Implementation write set: src/callisto/agent_capture_access_audit.rs;src/callisto/agent_capture_tombstone.rs;src/callisto/agent_capture_deletion_ledger.rs;src/callisto/mod.rs;src/jupiter/storage/agent_capture_storage.rs

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: N/A

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 禁止写入 audit_logs。

Performance budget: tombstone 按 capture_id/自然键点查。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=access_audit/tombstone/ledger storage; recovery=revert; complete=yes; self-contained=yes; AC=7/8; VER=4/8; landing=2; prod-files=5; scope=M; deps=AC-04; writeset=序列化于 AC-04; release=independent; split-from=AC-04; exception=N/A

Task AC-04-GC: GC 候选查询

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 在 AgentCaptureStorage 提供 GC 候选查询:NOT EXISTS blob_ref 且(lease 空或过期)且 state<>protected。不实现后台 sweeper(DEFER-AC-04)。自 AC-04 拆出,避免与 blob_ref/receipt 轴复合。

Out of scope:

  • 后台删除对象(DEFER-AC-04)
  • HTTP finalize 恢复(AC-08-R)

Current evidence:

事实 证据
消费 AC-04/AC-20 catalog src/jupiter/storage/agent_capture_storage.rs
ADR-AC-06 本文

Acceptance criteria:

  • 仍有 blob_ref 的 blob 不进入 candidates
  • 有效 lease 的 blob 不进入 candidates
  • protected blob 不进入 candidates

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::gc_candidates_skip_live_lease_ref_protected' -- --exact --nocapture

Dependencies: AC-04;AC-20

Deliverables: N/A

Implementation write set: src/jupiter/storage/agent_capture_storage.rs

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: N/A

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 查询带 tenant/deployment。

Performance budget: 候选查询必须使用 blob_ref/lease 索引,禁止无界全表扫描作为唯一实现。

Estimated scope: S

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=GC candidate query; recovery=revert; complete=yes; self-contained=yes; AC=3/8; VER=1/8; landing=1; prod-files=1; scope=S; deps=AC-04,AC-20; writeset=serialized; release=independent; split-from=AC-04; exception=N/A

Task AC-05: ObjectNamespace::Agent 与 AgentCaptureService 对象层

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 附录式新增 ObjectNamespace::Agent(Display/to_string() 为 agent)。AgentCaptureService 组合 storage + MegaObjectStorageWrapper:staging put_stream 到服务器 key;finalize 重算 sha256 后写入 committed key;忽略任何客户端 final key。接入 Storage 字段与 mock()。当前 enum 已有 Media,本卡只追加 Agent,不改 Media。

Out of scope:

  • HTTP(AC-08)
  • 认证(AC-06)

Current evidence:

事实 证据
enum 现为 Git..Media,无 Agent src/orbit_api/object_storage.rs:110-134
OCI 先例 src/jupiter/service/oci_service.rs;src/jupiter/storage/mod.rs:150 / :589

Acceptance criteria:

  • ObjectNamespace::Agent.to_string() 等于 "agent"
  • staging ObjectKey path 含 {tenant_id}/staging/
  • committed ObjectKey path 含 {tenant_id}/raw/sha256/
  • finalize 使用服务器计算的 digest 而非请求体声明的 final key
  • Storage 含 agent_capture_service 字段
  • Storage::mock 可构造(含 agent_capture_service)

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'orbit_api::object_storage::tests::agent_namespace_as_str' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::service::agent_capture_service::tests::staging_key_includes_tenant' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::service::agent_capture_service::tests::committed_key_includes_tenant_and_raw' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::service::agent_capture_service::tests::finalize_uses_server_digest' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::tests::mock_storage_includes_agent_capture_service' -- --exact --nocapture

Dependencies: AC-04-GC

Deliverables: N/A

Implementation write set: src/orbit_api/object_storage.rs;src/jupiter/service/agent_capture_service.rs;src/jupiter/service/mod.rs;src/jupiter/storage/mod.rs;docs/refactoring/agent-capture.md(追加 ObjectNamespace/object key 节)

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: 追加 docs/refactoring/agent-capture.md ObjectNamespace/object key 节。

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 客户端 object_key 忽略;key 含 deployment/tenant。

Performance budget: 流式 put/get;finalize 一次 sha256。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=Agent 命名空间与对象服务; recovery=revert; complete=yes; self-contained=yes; AC=6/8; VER=5/8; landing=3; prod-files=4; scope=M; deps=AC-04-GC; writeset=序列化于 AC-04-GC; release=independent; split-from=N/A; exception=N/A

Task AC-06: ingest token 查找(独立于 git push token)

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 在 src/ceres/agent_capture/auth.rs 实现 lookup_ingest_token:只扫描 config.agent_capture.ingest_tokens,sha256 常数时间,命中后用 token_path_authorizes 判断 path。本卡不注册 HTTP。禁止调用 lookup_push_token。producer_id = token name。

Out of scope:

  • 路由挂载(AC-07)
  • 改 lookup_push_token 签名

Current evidence:

事实 证据
git 查找 src/contract/git_protocol/mod.rs:146-157
路径前缀 src/config/model.rs:955-959
ceres 现无 agent_capture src/ceres/mod.rs:1-9

Acceptance criteria:

  • lookup_ingest_token 对正确明文返回对应 name
  • 错误明文返回 None
  • 不覆盖 path 时 token_covers_capture_repo 为 false
  • src/ceres/agent_capture 源码不出现标识符 lookup_push_token
  • 该查找不读取 config.git.push_tokens
  • 存在 src/ceres/agent_capture/mod.rs

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'ceres::agent_capture::auth::tests::lookup_matches_name' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'ceres::agent_capture::auth::tests::lookup_rejects_wrong_secret' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'ceres::agent_capture::auth::tests::path_prefix_does_not_cover_sibling' -- --exact --nocapture
  • 零命中守卫(判定口径模板):
if rg -n "lookup_push_token" src/ceres/agent_capture; then
  echo "FAIL: forbidden pattern found"; exit 1
else
  rc=$?
  if [ "$rc" -ne 1 ]; then echo "ERROR: rg failed with exit $rc"; exit "$rc"; fi
  echo "OK: zero hits"
fi
  • 零命中守卫(判定口径模板):
if rg -n "push_tokens" src/ceres/agent_capture; then
  echo "FAIL: forbidden pattern found"; exit 1
else
  rc=$?
  if [ "$rc" -ne 1 ]; then echo "ERROR: rg failed with exit $rc"; exit "$rc"; fi
  echo "OK: zero hits"
fi

Dependencies: AC-01

Deliverables: N/A

Implementation write set: src/ceres/agent_capture/mod.rs;src/ceres/agent_capture/auth.rs;src/ceres/mod.rs(pub mod agent_capture)

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: N/A

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 常数时间比较;失败不区分「无此 token」与「错密」以外的租户存在性。

Performance budget: 按 token 表线性扫描,与 lookup_push_token 同量级。

Estimated scope: S

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=ingest token 查找; recovery=revert; complete=yes; self-contained=yes; AC=6/8; VER=5/8; landing=1; prod-files=3; scope=S; deps=AC-01; writeset=no-overlap; release=independent; split-from=N/A; exception=N/A

Task AC-00: 共享 HTTP schema 与错误契约

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 新增 src/api_model/(lib.rs 登记 mod api_model)与 DTO/错误信封/分页 envelope、repo 单 segment percent-encoding helper。canonical fingerprint 调用 AC-22 helper,本卡不得复制实现(G-09:本卡拆出 AC-22)。新建 src/api/router/agent_capture_router.rs,本卡只提供无业务 handler 的 route-construction fixture:router 只接受单一 {repo} segment,禁止 Axum 中段 catch-all。后续 HTTP 卡只追加 handler,不改 path。当前 checkout 没有 api_model 模块。unauthorized 错误码与 Authorization: Bearer 方案对齐 AC-06 查找失败语义。追加 docs/refactoring/agent-capture.md HTTP path/error/pagination 节。

Out of scope:

  • 业务 handler 与 storage
  • http_server 挂载(AC-07)

Current evidence:

事实 证据
src/lib.rs 无 api_model src/lib.rs:8-22
无 src/api_model/ 现场 glob 零命中
router 模块列表无 agent_capture src/api/router/mod.rs

Acceptance criteria:

  • all_public_paths_construct 测试通过
  • repo_path_is_single_segment 测试通过
  • error_envelope 测试通过
  • pagination_envelope 测试通过
  • agent_capture_schema 测试通过

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'api_model::agent_capture::tests::agent_capture_schema' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::repo_path_is_single_segment' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::all_public_paths_construct' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api_model::agent_capture::tests::error_envelope' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api_model::agent_capture::tests::pagination_envelope' -- --exact --nocapture

Dependencies: AC-01;AC-06;AC-02;AC-22;AC-05

Deliverables: N/A

Implementation write set: src/api_model/mod.rs;src/api_model/agent_capture.rs;src/lib.rs;src/api/router/agent_capture_router.rs;src/api/router/mod.rs;docs/refactoring/agent-capture.md(追加 HTTP path/error/pagination)

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: 追加 docs/refactoring/agent-capture.md HTTP path/error/pagination 节。

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 错误 envelope 不含 token secret、raw prompt、其它 tenant 是否存在。

Performance budget: canonical JSON 仅用于 fingerprint,不在 list 热路径展开 blob。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=shared HTTP schema/error/path contract; recovery=revert; complete=yes; self-contained=yes; AC=5/8; VER=5/8; landing=3; prod-files=5; scope=M; deps=AC-01,AC-06,AC-02,AC-22,AC-05; writeset=序列化于 AC-01,AC-06,AC-02,AC-22,AC-05; release=independent; split-from=N/A; exception=N/A

Task AC-07: HTTP 挂载门与 OpenAPI include_agent_capture

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: http_server 仅当 storage_only && agent_capture.enabled 把 AC-00 的 agent_capture_router nest 进已有 /api/v1。storage_only_openapi_doc 与 trunk_openapi_doc 各增加 include_agent_capture: bool(平行 include_oci,见 DEP-AC-01)。review 形态不 merge 该 router。本卡不向 router 追加业务 handler。review / disabled 404 测试写在 http_server::tests,不改 agent_capture_router.rs。现有 include_oci 调用点改为显式传入 include_agent_capture=false。追加文档挂载节。

Out of scope:

  • discovery JSON(AC-16)
  • session PUT(AC-21)
  • blob/events HTTP(AC-08 / AC-09)

Current evidence:

事实 证据
OCI 挂载/OpenAPI src/server/http_server.rs:723-816
storage_only routers src/api/api_router.rs:65-71
消费 AC-00/AC-05/AC-06 router fixture;Storage.agent_capture_service;lookup_ingest_token

Acceptance criteria:

  • include_agent_capture=false 的 OpenAPI 路径字符串均不含 /api/v1/agent-capture
  • include_agent_capture=true 时 http_server 将 agent_capture_router 并入 /api/v1
  • review 形态(push_auth 缺省)对 /api/v1/agent-capture/discovery 返回 404
  • enabled=false 的 storage-only 对 /api/v1/agent-capture/discovery 返回 404
  • storage_only_openapi_doc 接受 include_agent_capture: bool
  • trunk_openapi_doc 接受 include_agent_capture: bool
  • 既有 storage_only_openapi_include_oci_dual_state 在新签名下仍通过

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'server::http_server::tests::storage_only_openapi_omits_agent_capture_when_flag_false' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'server::http_server::tests::storage_only_nests_agent_capture_when_enabled' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'server::http_server::tests::review_morphology_does_not_register_agent_capture' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'server::http_server::tests::disabled_storage_only_does_not_register_agent_capture' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'server::http_server::tests::storage_only_openapi_doc_takes_include_agent_capture' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'server::http_server::tests::trunk_openapi_doc_takes_include_agent_capture' -- --exact --nocapture
  • source .env.test && cargo test -p mega2 --lib 'server::http_server::tests::storage_only_openapi_include_oci_dual_state' -- --exact --nocapture

Dependencies: AC-05;AC-06;AC-00;DEP-AC-01

Deliverables: N/A

Implementation write set: src/server/http_server.rs;src/api/api_router.rs;src/api/api_doc.rs;docs/refactoring/agent-capture.md(追加挂载节)

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: 追加 docs/refactoring/agent-capture.md 挂载节。

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 非 storage-only 或 disabled 不注册路由(fail-closed)。

Performance budget: 挂载为启动期一次 nest。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=HTTP挂载门与OpenAPI flag; recovery=revert; complete=yes; self-contained=yes; AC=7/8; VER=7/8; landing=3; prod-files=3; scope=M; deps=AC-05,AC-06,AC-00,DEP-AC-01; writeset=序列化于 AC-05,AC-06,AC-00; release=independent; split-from=N/A; exception=N/A

Task AC-16: discovery HTTP

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 在已挂载的 router 上增加内部 path /agent-capture/discovery(public GET /api/v1/agent-capture/discovery)。有效 ingest token(Authorization: Bearer)返回 JSON,字段 raw_accepted 为 true。无 token 或错 token → 401。自 AC-07 拆出。

Out of scope:

  • 挂载门(AC-07)
  • session PUT(AC-21)
  • 查询 GET(AC-12)

Current evidence:

事实 证据
消费 AC-07 挂载 src/server/http_server.rs nest;AC-00 router 文件
消费 AC-06 lookup_ingest_token;ADR-AC-03;ADR-AC-04

Acceptance criteria:

  • 无 Authorization 的 discovery 返回 401
  • 有效 token 的 discovery JSON 字段 raw_accepted 等于 true
  • 错误 token 的 discovery 返回 401
  • include_agent_capture=true 的 OpenAPI 路径列表含字符串 /api/v1/agent-capture/discovery

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::discovery_unauthorized' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::discovery_raw_accepted' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::discovery_wrong_token' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'server::http_server::tests::storage_only_openapi_includes_agent_capture_when_flag_true' -- --exact --nocapture

Dependencies: AC-07

Deliverables: N/A

Implementation write set: src/api/router/agent_capture_router.rs;src/api/api_doc.rs;src/server/http_server.rs(OpenAPI 含 discovery 的测试);docs/refactoring/agent-capture.md(追加 discovery 节)

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: 追加 docs/refactoring/agent-capture.md discovery 节。

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 401 不泄露 token 表是否为空以外的租户线索。

Performance budget: discovery 无 DB。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=discovery HTTP; recovery=revert; complete=yes; self-contained=yes; AC=4/8; VER=4/8; landing=2; prod-files=3; scope=M; deps=AC-07; writeset=序列化于 AC-07; release=independent; split-from=AC-07; exception=N/A

Task AC-21: session PUT

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: PUT /api/v1/agent-capture/repos/{repo}/sessions/{client_session_id}:{repo} 为单一 percent-encoded segment;解码后 normalize_repo_path 得到 repo_id TEXT;写 session 行;响应含 capture_id。token 不覆盖该 path → 404。无 token → 401。PUT fingerprint 不含服务端 completeness/lifecycle;同自然键同 immutable fingerprint 重试成功(即使 completeness 已变);不同 immutable fingerprint → 409。自 AC-07 拆出。

Out of scope:

  • discovery(AC-16)
  • blob HTTP(AC-08)
  • tombstone 409(AC-17)

Current evidence:

事实 证据
ADR-AC-01 / ADR-AC-05 本文
消费 AC-16 / AC-03 token 中间件;upsert_session
normalize src/ceres/api_service/mono_api_service.rs:504

Acceptance criteria:

  • 合法 PUT 响应 JSON 字段 capture_id 为大于 0 的整数
  • token 不覆盖该 repo 时 PUT 返回 404
  • 同自然键不同 immutable fingerprint 的第二次 PUT 返回 409
  • 无 token 的 PUT 返回 401
  • completeness 变化后同一 PUT 重试仍返回同一 capture_id

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::put_session_returns_capture_id' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::put_session_unknown_path_is_404' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::put_session_conflict' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::put_session_unauthorized' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::session_put_retry_after_completeness_change' -- --exact --nocapture

Dependencies: AC-16

Deliverables: N/A

Implementation write set: src/api/router/agent_capture_router.rs;docs/refactoring/agent-capture.md(追加 session PUT 节)

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: 追加 docs/refactoring/agent-capture.md session PUT 节。

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 404 用于 scope miss,避免探测其它 tenant 的 403 差异。

Performance budget: 自然键点查。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=session PUT; recovery=revert; complete=yes; self-contained=yes; AC=5/8; VER=5/8; landing=1; prod-files=1; scope=M; deps=AC-16; writeset=序列化于 AC-16; release=independent; split-from=AC-07; exception=N/A

Task AC-08: blob staging 与 finalize HTTP

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: session-scoped:内部 POST /agent-capture/sessions/{capture_id}/blobs/staging 与 POST /agent-capture/sessions/{capture_id}/blobs/{lease_id}/finalize。超限 413(含 chunked,限额 max_blob_bytes)。finalize 校验 lease、重算 digest;声明 digest 必须等于服务器 digest,否则 400。客户端 object_key 不成为 final key。CAS 崩溃窗与 fencing 由 AC-08-R 承接。无公开 repo-level staging。

Out of scope:

  • events(AC-09)
  • CAS recovery/fencing(AC-08-R)
  • 后台 GC(DEFER-AC-04)

Current evidence:

事实 证据
消费 AC-05 / AC-21 AgentCaptureService;PUT 已返回 capture_id
ADR-AC-02 / ADR-AC-10 本文

Acceptance criteria:

  • 无 token 的 staging 返回 401
  • 超配额 body 的 staging 返回 413
  • 合法 staging 的 JSON 字段 lease_id 为非空字符串
  • finalize 成功响应 JSON 字段 digest 为非空字符串
  • 他人未过期 lease 的 finalize 返回 409
  • 请求体携带客户端 object_key 时响应 object_key 等于服务器 committed key
  • 声明 digest 与服务器 sha256 不一致时 finalize 返回 400

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::staging_unauthorized' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::staging_too_large' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::staging_returns_lease' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::finalize_returns_digest' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::finalize_lease_conflict' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::finalize_ignores_client_object_key' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::finalize_digest_mismatch' -- --exact --nocapture

Dependencies: AC-21

Deliverables: N/A

Implementation write set: src/api/router/agent_capture_router.rs;src/jupiter/service/agent_capture_service.rs;docs/refactoring/agent-capture.md(追加 blob staging/finalize 节)

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: 追加 docs/refactoring/agent-capture.md blob staging/finalize 节。

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 401→404→409→400/413;忽略客户端 key。

Performance budget: 流式上传;单 blob ≤ 16 MiB。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=blob staging/finalize HTTP; recovery=revert; complete=yes; self-contained=yes; AC=7/8; VER=7/8; landing=2; prod-files=2; scope=M; deps=AC-21; writeset=序列化于 AC-21; release=independent; split-from=N/A; exception=N/A

Task AC-08-R: blob CAS 恢复与 fencing

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 承接 AC-08 的恢复轴:lease staging -> finalizing -> committed 或 expired/aborted;owner generation fencing;upload intent 先于 object 写入;cleanup intent 持续到 staging 删除确认。(capture_id, stream_kind, generation) 持久绑定 raw_blob_id;同水位同 digest 重试成功,同水位不同 digest 409。旧 owner 延迟提交影响 0 行并 409。GC 排除规则不在本卡(AC-04-GC)。自 AC-08 拆出。

Out of scope:

  • HTTP happy/auth/413 门(AC-08)
  • GC 查询(AC-04-GC)
  • events HTTP(AC-09)

Current evidence:

事实 证据
消费 AC-08 HTTP 与 AC-18 stream catalog router/service;source_stream 实体
ADR-AC-06 / ADR-AC-11 本文

Acceptance criteria:

  • 同 lease 与 digest 重试返回既有 committed receipt
  • 旧 owner generation 条件提交返回 409
  • snapshot binding 与 blob_ref 同事务提交
  • object write 失败留下 upload intent
  • object write 失败不报告成功
  • cleanup 删除失败保留 cleanup intent
  • 同 snapshot watermark 与 digest 重试幂等
  • 同 watermark 不同 digest 返回 409

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::finalize_retry_and_old_owner_fenced' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::stream_snapshot_binding_atomic' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::intent_recovery_after_object_write_failure' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::object_write_failure_does_not_report_success' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::cleanup_intent_survives_delete_failure' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::stream_snapshot_replacement_fenced' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::snapshot_same_watermark_digest_idempotent' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'jupiter::storage::agent_capture_storage::tests::snapshot_same_watermark_digest_conflict' -- --exact --nocapture

Dependencies: AC-08;AC-18

Deliverables: N/A

Implementation write set: src/jupiter/storage/agent_capture_storage.rs;src/jupiter/service/agent_capture_service.rs;docs/refactoring/agent-capture.md(追加 CAS/fencing 节)

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: 追加 docs/refactoring/agent-capture.md CAS/fencing 节。

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 未提交不得报成功;他方未过期 lease 不可覆盖。

Performance budget: 条件更新 0 行即 409,不重写他人对象。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=CAS recovery/fencing; recovery=revert; complete=yes; self-contained=yes; AC=8/8; VER=8/8; landing=2; prod-files=2; scope=M; deps=AC-08,AC-18; writeset=serialized; release=independent; split-from=AC-08; exception=N/A

Task AC-09: events batch 与 watermark

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: POST /api/v1/agent-capture/sessions/{capture_id}/events:batch。event_uid 必须匹配 ASCII {generation}:{byte_offset}。未知 event_kind 存 unknown 并保留 envelope。整批事务。同 uid 同 canonical fingerprint 200 既有;不同内容 409。body batch_id 为幂等键。

Out of scope:

  • file-ops(AC-10)
  • 从 tool JSON 派 file-op

Current evidence:

事实 证据
ADR-AC-09 本文
libra pin DEP-AC-02

Acceptance criteria:

  • 合法 batch 返回 200
  • 非法 event_uid(非 数字:数字)返回 400
  • 未知 kind 仍插入一行 event_kind=unknown
  • 同 uid 不同 payload 返回 409
  • batch 后 source_stream completeness 可更新为 incomplete 或 complete
  • 无 token 返回 401

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::events_batch_ok' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::events_rejects_bad_uid' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::events_unknown_kind_kept' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::events_conflict_different_payload' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::events_updates_completeness' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::events_unauthorized' -- --exact --nocapture

Dependencies: AC-08-R;DEP-AC-02

Deliverables: N/A

Implementation write set: src/api/router/agent_capture_router.rs;src/jupiter/storage/agent_capture_storage.rs;docs/refactoring/agent-capture.md(追加 events 节)

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: 追加 docs/refactoring/agent-capture.md events 节。

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 401 优先;payload 不上 tracing。

Performance budget: 单请求 ≤ max_events_per_batch;超限 413。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=events batch; recovery=revert; complete=yes; self-contained=yes; AC=6/8; VER=6/8; landing=2; prod-files=2; scope=M; deps=AC-08-R,DEP-AC-02; writeset=序列化于 AC-08-R; release=independent; split-from=N/A; exception=N/A

Task AC-10: file-ops batch

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: POST /api/v1/agent-capture/sessions/{capture_id}/file-ops:batch 校验 agent.file_op.v1。无 source_event_uid 拒绝。绝对路径 / .. / NUL 拒绝。op=search 接受。超 max_file_blobs_per_session 将 session completeness 标 truncated。body batch_id 为幂等键;不同 canonical fingerprint → 409。

Out of scope:

  • 默认上传 50 版 FileHistory(DEFER-AC-02)
  • checkpoint(AC-11)

Current evidence:

事实 证据
ADR-AC-08 本文
FileHistory 硬帽 DEP-AC-02;libra file_history.rs:21

Acceptance criteria:

  • 合法 write file-op 返回 200
  • 缺 source_event_uid 返回 400
  • path 含 .. 返回 400
  • op=search 返回 200
  • 无 token 返回 401
  • 超过配置 max_file_blobs_per_session 后 session completeness 为 truncated

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::file_op_ok' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::file_op_requires_source' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::file_op_rejects_dotdot' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::file_op_search_ok' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::file_op_truncated_over_cap' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::file_op_batch_idempotency_conflict' -- --exact --nocapture

Dependencies: AC-09

Deliverables: N/A

Implementation write set: src/api/router/agent_capture_router.rs;src/jupiter/storage/agent_capture_storage.rs;docs/refactoring/agent-capture.md(追加 file-ops 节)

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: 追加 docs/refactoring/agent-capture.md file-ops 节。

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 路径穿越拒绝;digest 非空必须指向已 finalize raw。

Performance budget: 每 session file blob 缺省 ≤ 20。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=file-ops batch; recovery=revert; complete=yes; self-contained=yes; AC=6/8; VER=6/8; landing=2; prod-files=2; scope=M; deps=AC-09; writeset=序列化于 AC-09; release=independent; split-from=N/A; exception=N/A

Task AC-11: checkpoint POST(仅 external_capture)

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: POST /api/v1/agent-capture/sessions/{capture_id}/checkpoints。父 session 必须 external_capture。事实源必须是已 committed raw;redacted 可选。仅 redacted → completeness=incomplete 且 partial_reason=missing_raw。同 transcript_digest 共享 CAS。body checkpoint_id 为幂等键;不同 fingerprint → 409。

Out of scope:

  • 查询 GET(AC-12)
  • 内部 JSONL 伪 checkpoint

Current evidence:

事实 证据
libra checkpoint 是完整快照 DEP-AC-02
消费 AC-08 committed raw AC-08/AC-08-R

Acceptance criteria:

  • external session + committed raw blob 的 POST 返回 200
  • internal_code session 的 POST 返回 400
  • transcript 仍为 staging 时返回 400
  • 仅 redacted digest 时响应 completeness 为 incomplete
  • 两个 checkpoint 相同 transcript_digest 只对应一个 committed blob 行
  • 无 token 返回 401

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::checkpoint_ok' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::checkpoint_rejects_internal_code' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::checkpoint_requires_committed_raw' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::checkpoint_redacted_only_incomplete' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::checkpoint_shares_cas_blob' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::checkpoint_idempotency_conflict' -- --exact --nocapture

Dependencies: AC-10;AC-08

Deliverables: N/A

Implementation write set: src/api/router/agent_capture_router.rs;src/jupiter/storage/agent_capture_storage.rs;docs/refactoring/agent-capture.md(追加 checkpoint 节)

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: 追加 docs/refactoring/agent-capture.md checkpoint 节。

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 不得把仅 redacted 当 raw transcript。

Performance budget: 同 digest 不复制对象字节。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=checkpoint POST; recovery=revert; complete=yes; self-contained=yes; AC=6/8; VER=6/8; landing=2; prod-files=2; scope=M; deps=AC-10,AC-08; writeset=序列化于 AC-10,AC-08; release=independent; split-from=N/A; exception=N/A

Task AC-12: metadata / transcript 查询面

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: GET list/show/file-ops/checkpoints 为 metadata-first,list JSON 使用 {items,next_cursor},不含 transcript 正文。GET .../transcript 返回 committed raw(application/octet-stream)并 INSERT agent_capture_access_audit。external 缺省最新 committed raw checkpoint;internal_code 以 source_stream generation/watermark 读绑定 raw。缺 raw → 409 missing_raw。tombstone 后再 ingest 由 AC-17 承接。

Out of scope:

  • tombstone 后再 ingest 的 409(AC-17)
  • 后台删除字节(DEFER-AC-04)
  • 公开 DELETE API

Current evidence:

事实 证据
ADR-AC-04 GET transcript = raw + access_audit
消费 AC-11/AC-10/AC-20/AC-08-R checkpoint、file-ops、audit、stream binding

Acceptance criteria:

  • list sessions 的 item 对象无键 transcript
  • GET session JSON 含键 capture_id
  • GET transcript 正文等于 finalize 的 raw 字节
  • GET transcript 后 agent_capture_access_audit 增加一行
  • 无 token 的 GET transcript 返回 401
  • 缺 committed raw 时 GET transcript 返回 409
  • GET file-ops 在无 op 时返回 200
  • GET file-ops JSON 含键 items

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::list_sessions_metadata_only' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::get_session_ids' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::get_transcript_raw_and_audit' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::get_transcript_unauthorized' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::list_file_ops_ok' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::list_file_ops_has_items_key' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::missing_raw_returns_409' -- --exact --nocapture

Dependencies: AC-10;AC-11;AC-20;AC-08-R

Deliverables: N/A

Implementation write set: src/api/router/agent_capture_router.rs;src/jupiter/storage/agent_capture_storage.rs;docs/refactoring/agent-capture.md(追加 query/transcript 节)

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: 追加 docs/refactoring/agent-capture.md query/transcript 节。

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 持有 ingest token 即可读 raw;必写 access_audit。

Performance budget: list 不展开正文。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=metadata/transcript查询面; recovery=revert; complete=yes; self-contained=yes; AC=8/8; VER=7/8; landing=2; prod-files=2; scope=M; deps=AC-10,AC-11,AC-20,AC-08-R; writeset=序列化于 AC-10,AC-11,AC-20,AC-08-R; release=independent; split-from=N/A; exception=N/A

Task AC-17: tombstone 拒再 ingest

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 已 tombstone 的 capture 再 PUT / staging / finalize / events / file-ops / checkpoint 返回 409。测试可直接 insert tombstone 行(无公开 DELETE API)。未授权仍优先 401。自 AC-12 拆出。

Out of scope:

  • 查询 GET(AC-12)
  • 后台删除对象字节(DEFER-AC-04)
  • 公开 DELETE API

Current evidence:

事实 证据
ADR-AC-04 本文
消费 AC-20 / AC-08 / AC-21 is_tombstoned;staging/PUT 路由

Acceptance criteria:

  • 已 tombstone 的 client_session_id 再 PUT 返回 409
  • 已 tombstone 的 capture 再 staging 返回 409
  • 未 tombstone 的 PUT 仍返回 200
  • 无 token 的 tombstone 后再 PUT 仍返回 401

Verification:

  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::tombstone_rejects_reingest_put' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::tombstone_rejects_staging' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::tombstone_put_unauthorized_is_401' -- --exact --nocapture
  • (new) source .env.test && cargo test -p mega2 --lib 'api::router::agent_capture_router::tests::tombstone_blocks_all_ingest_writes' -- --exact --nocapture

Dependencies: AC-12;AC-20;AC-08

Deliverables: N/A

Implementation write set: src/api/router/agent_capture_router.rs;src/jupiter/storage/agent_capture_storage.rs;docs/refactoring/agent-capture.md(追加 tombstone 节)

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: 追加 docs/refactoring/agent-capture.md tombstone 节。

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 401 优先于 409。

Performance budget: tombstone 检查点查,与 ingest 同事务/锁序。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=tombstone拒再ingest; recovery=revert; complete=yes; self-contained=yes; AC=4/8; VER=4/8; landing=2; prod-files=2; scope=M; deps=AC-12,AC-20,AC-08; writeset=序列化于 AC-12,AC-20,AC-08; release=independent; split-from=AC-12; exception=N/A

Task AC-13: 进程级 integration_agent_capture

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 新增 tests/integration_agent_capture.rs,使用隔离 local/mock object backend。覆盖:enabled happy path(discovery 200 与 GET transcript 200)、review 配置 404、无 token 401、tracing 无 raw sentinel、跨 deployment 隔离、tombstone 与 ingest 竞态。畸形 JSON / 超长字段 / chunked 超限由 AC-08/AC-09 单测承担,不在本卡重复扩轴。同步 docs/refactoring/integration.md 覆盖矩阵一行。

Out of scope:

  • docker/libra 客户端 live(DEFER-AC-01)
  • 契约长文(AC-14)
  • AC-08/AC-09 输入边界单测

Current evidence:

事实 证据
OCI IT 先例 tests/integration_oci.rs;docs/refactoring/integration.md
消费 AC-12/AC-16/AC-17/AC-08-R 查询、discovery、tombstone、CAS 恢复已发布

Acceptance criteria:

  • docs/refactoring/integration.md 表含 integration_agent_capture 行
  • enabled 路径用例断言 discovery 200
  • enabled 路径用例断言 GET transcript 200
  • review 配置用例断言 discovery 404
  • 无 token 用例断言 401
  • tracing 输出不含 raw sentinel 字符串
  • 跨 deployment 读取返回 404
  • tombstone 与 ingest 竞态下失败者不得 200 提交

Verification:

  • (new) source .env.test && cargo test -p mega2 --test integration_agent_capture -- --test-threads=1 --exact integration_agent_capture_happy_path --nocapture
  • (new) source .env.test && cargo test -p mega2 --test integration_agent_capture -- --test-threads=1 --exact integration_agent_capture_review_404 --nocapture
  • (new) source .env.test && cargo test -p mega2 --test integration_agent_capture -- --test-threads=1 --exact integration_agent_capture_unauthorized --nocapture
  • (new) source .env.test && cargo test -p mega2 --test integration_agent_capture -- --test-threads=1 --exact integration_agent_capture_tracing_has_no_raw_sentinel --nocapture
  • (new) source .env.test && cargo test -p mega2 --test integration_agent_capture -- --test-threads=1 --exact integration_agent_capture_cross_deployment_isolated --nocapture
  • (new) source .env.test && cargo test -p mega2 --test integration_agent_capture -- --test-threads=1 --exact integration_agent_capture_tombstone_race --nocapture
  • rg -n 'integration_agent_capture' docs/refactoring/integration.md 退出 0

Dependencies: AC-12;AC-16;AC-17;AC-08-R

Deliverables: N/A

Implementation write set: tests/integration_agent_capture.rs;docs/refactoring/integration.md

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: integration.md 覆盖矩阵一行(随附同步集)

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: IT 使用一次性 token,证据脱敏(ER-11)。

Performance budget: 进程级不测吞吐;只断言功能与隔离。

Estimated scope: M

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=implementation; axis=进程级 IT; recovery=revert; complete=yes; self-contained=yes; AC=8/8; VER=7/8; landing=1; prod-files=1; scope=M; deps=AC-12,AC-16,AC-17,AC-08-R; writeset=no-overlap; release=independent; split-from=N/A; exception=N/A

Task AC-14: 契约文档与索引

Task type: docs

Lifecycle / Acceptance: done / complete

Description: 索引与契约收口,不新建 docs/refactoring/agent-capture.md(该文件由 AC-01 创建,后续实现卡按节追加)。本卡核对该文件已含挂载门、token、ID、raw、object key、配额、error envelope、pagination、非目标;更新 docs/refactoring/README.md、docs/plan/README.md、plan-long.md、docs/errors.md(无新 MegaError 变体则 N/A 段)。不改 src/。产物随 AC-15 提交进入仓库。

Out of scope:

  • 任何 src/ 改动(须先 ER-03 重分类)
  • libra 客户端文档
  • 从零撰写契约正文(由 AC-01 及各 HTTP 卡追加)

Current evidence:

事实 证据
agent-capture.md 已由前置卡写入 AC-01 创建;AC-02/AC-00 及 HTTP 卡追加;开工时 test -f docs/refactoring/agent-capture.md
索引已有本计划行 docs/plan/README.md;docs/plan/plan-long.md:775

Acceptance criteria:

  • docs/refactoring/agent-capture.md 文件存在
  • 该文件含标题「挂载」
  • 该文件含字符串 capture_id
  • 该文件含字符串 raw_accepted
  • docs/refactoring/README.md 含 agent-capture.md
  • docs/plan/README.md 含 plan-20260911.md
  • docs/plan/plan-long.md 日期计划索引含 plan-20260911.md
  • docs/errors.md 含 agent-capture 或显式 N/A 段落标题

Verification:

  • test -f docs/refactoring/agent-capture.md
  • rg -n '挂载' docs/refactoring/agent-capture.md
  • rg -n 'capture_id' docs/refactoring/agent-capture.md
  • rg -n 'plan-20260911.md' docs/plan/README.md
  • rg -n 'plan-20260911.md' docs/plan/plan-long.md
  • 暂存 allowlist(全部 libra status --short 路径,不筛选状态字母):
staged=$(libra status --short | awk '{print $NF}')
if printf '%s\n' "$staged" | rg -n '^(src/|config/|Cargo\.toml|Cargo\.lock|tests/)'; then
  echo "FAIL: forbidden pattern found"; exit 1
else
  rc=$?
  if [ "$rc" -ne 1 ]; then echo "ERROR: rg failed with exit $rc"; exit "$rc"; fi
  echo "OK: zero hits"
fi

Dependencies: AC-13

Deliverables: docs/refactoring/agent-capture.md;docs/refactoring/README.md;docs/errors.md;docs/plan/README.md;docs/plan/plan-long.md

Implementation write set: docs/refactoring/agent-capture.md;docs/refactoring/README.md;docs/errors.md;docs/plan/README.md;docs/plan/plan-long.md

Release write set: N/A

Files likely touched: 同 Implementation write set

Docs and compatibility impact: 本卡即为文档轴

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 文档不得粘贴真实 token。

Performance budget: N/A

Estimated scope: M

Version increment: N/A

Release boundary: no-release

C/D coverage from: AC-15

Granularity: type=docs; axis=契约文档与索引; recovery=revert 文档; complete=yes; self-contained=yes; AC=8/20; VER=6/20; landing=0; prod-files=0; scope=M; deps=AC-13; writeset=序列化于 AC-13; release=no-release; split-from=N/A; exception=N/A

Task AC-15: 收口发布

Task type: release

Lifecycle / Acceptance: done / complete

Description: 不引入新行为。ER-08 parity 预检后 patch bump Cargo.toml,刷新 Cargo.lock,在已 bump 树上跑 AGENTS 三门(ER-04 C 组,不计入本卡 G-03)与 cargo build / cargo build --tests,提交并 libra push origin main,确认远端 ref。无 tag/artifact。

Out of scope:

  • 新 HTTP/表
  • tag / GitHub release artifact

Current evidence:

事实 证据
版本面一处 Cargo.toml:3 当前 0.10.1(开工日再核)
无 workflow .github/workflows/ 现场为空

Acceptance criteria:

  • 开工时 Cargo.toml 的 version 与 Cargo.lock 中 name = "mega2" 的 version 一致
  • bump 后 Cargo.toml patch 段比开工值大 1
  • Cargo.lock 中 package mega2 的 version 等于新 Cargo.toml version
  • libra push origin main 退出 0
  • remote_ref 经 libra ls-remote --heads origin main 的 awk 首字段赋值后与 libra rev-parse HEAD 相等

Verification:

  • rg -n '^version' Cargo.toml
  • local=$(libra rev-parse HEAD) && remote_ref=$(libra ls-remote --heads origin main | awk 'NR==1{print $1}') && test -n "$remote_ref" && test "$local" = "$remote_ref"

Dependencies: AC-13;AC-14

Deliverables: N/A

Implementation write set: Cargo.toml;Cargo.lock(仅 version 刷新)

Release write set: Inherited

Files likely touched: 同 Implementation write set

Docs and compatibility impact: N/A

Rollback mode: immutable-release

Migration and rollback: N/A:已推送只能前滚。

Security and privacy: 不提交 secrets/。

Performance budget: N/A

Estimated scope: S

Version increment: patch

Release boundary: independent

C/D coverage from: self

Granularity: type=release; axis=收口发布; recovery=immutable-release; complete=yes; self-contained=yes; AC=5/12; VER=2/12; landing=0; prod-files=0; scope=S; deps=AC-13,AC-14; writeset=I–R 窗口; release=independent; split-from=N/A; exception=N/A

测试矩阵

类别 必须覆盖 Target / command
单元 token 查找、canonical JSON、object key、OpenAPI 开关、DTO --lib 'ceres::agent_capture';--lib 'common::canonical_json';--lib 'orbit_api::object_storage';--lib 'server::http_server';--lib 'api_model::agent_capture'
集成(DB) 迁移、upsert、blob_ref、tombstone、watermark、GC、CAS --lib 'jupiter::storage::agent_capture_storage';--lib 'jupiter::migration::m20260913_000100_add_agent_capture_tables'
集成(进程) happy / review 404 / 401 / tracing / 跨 deployment / tombstone race --test integration_agent_capture -- --test-threads=1 --exact <name>
CLI N/A(无新子命令) N/A
HTTP API 各 router 测试函数 --lib 'api::router::agent_capture_router'
迁移 表/UNIQUE/无 user_id/约束 AC-02
配置 enabled 门、配额、未知字段、样例 validate --lib 'config::';config validate
Git 协议 N/A N/A
安全 401/404/不调用 push_tokens;tracing 无原文 各卡守卫
性能 CAS 共享;list 无正文 AC-11/AC-12
live/gated N/A(无 libra 客户端) DEFER-AC-01

追溯表

任务 来源/证据 mega2 落点 文档/兼容动作 指定测试

| AC-01 | GAP-AC-01 / ADR-AC-10 | src/config/**;两份 toml | 创建 agent-capture.md 配置/配额节 | config::tests::agent_capture_* | | AC-22 | ADR-AC-11 | src/common/canonical_json.rs | N/A(内部 helper) | common::canonical_json::tests::* | | AC-02 | GAP-AC-02 / ADR-AC-10 | jupiter/migration | 追加 schema 节 | m20260913_*::tests::* | | AC-03 | ADR-AC-01 | callisto/agent_capture_session + storage upsert | N/A | upsert_session_* | | AC-18 | ADR-AC-09 | event / source_stream | N/A | event_uid_* / watermark | | AC-19 | ADR-AC-08 | checkpoint / file_op | N/A | checkpoint/file_op storage | | AC-04 | ADR-AC-06 | blob / blob_ref / receipt | N/A | finalize / receipt | | AC-20 | ADR-AC-04 | access_audit / tombstone / ledger | N/A | tombstone / audit / rejects_update / rejects_delete | | AC-04-GC | ADR-AC-06 | GC candidate query | N/A | gc_candidates_skip_live_lease_ref_protected | | AC-05 | GAP-AC-03 | orbit_api;agent_capture_service | 追加 ObjectNamespace/object key 节 | namespace/service | | AC-06 | GAP-AC-04 | ceres/agent_capture | N/A | auth | | AC-00 | ADR-AC-11 | api_model + router fixture | 追加 HTTP path/error/pagination | schema/path | | AC-07 | GAP-AC-05 | http_server 挂载 + OpenAPI flag | 追加挂载节 | 挂载/review 404 | | AC-16 | ADR-AC-03/04 | discovery 路由 | 追加 discovery 节 | discovery_* | | AC-21 | ADR-AC-01/05 | session PUT | 追加 session PUT 节 | put_session_* | | AC-08 | ADR-AC-02/06/10 | router + service HTTP | 追加 blob 节 | staging/finalize | | AC-08-R | ADR-AC-06/11 | CAS recovery/fencing | 追加 CAS/fencing 节 | retry/intent/snapshot | | AC-09 | ADR-AC-09 | router + storage | 追加 events 节 | events | | AC-10 | ADR-AC-08 | router + storage | 追加 file-op 节 | file-op | | AC-11 | libra checkpoint 快照 | router + storage | 追加 checkpoint 节 | checkpoint | | AC-12 | ADR-AC-04 | GET metadata/transcript | 追加 query/transcript 节 | query/audit/missing_raw | | AC-17 | ADR-AC-04 | tombstone 409 | 追加 tombstone 节 | tombstone_* | | AC-13 | GAP-AC-06 | tests/integration_agent_capture.rs | integration.md | --test integration_agent_capture | | AC-14 | GAP-AC-06 | docs index only | 索引 + errors.md | 链接门 + 全状态 allowlist | | AC-15 | ER-08 | Cargo.toml/Cargo.lock | N/A | 版本 + push(三门为 ER-04 C 组) |

里程碑验收与回滚

里程碑 完成条件 发布/证据 回滚或前滚
M0 计划 Codex PASS;Phase 0 Review log;tip 含本文 revert 计划文档
M1 AC-01, AC-22, AC-02, AC-03, AC-18, AC-19, AC-04, AC-20, AC-04-GC, AC-05, AC-06 各 patch AC-02 只能前滚;其余 revert
M2 AC-00, AC-07, AC-16, AC-21, AC-08, AC-08-R, AC-09..AC-12, AC-17 各 patch;storage-only 可 ingest revert 各卡
M3 AC-13..AC-15 IT + 文档 + 收口 push AC-15 前滚

故障恢复矩阵

故障点 可接受残留 恢复动作 禁止结果
staging 已写、DB 无行 租约对象 lease 过期后可 GC 查询命中 当成功收据
finalize 中途 lease owner 持有 过期抢租约重传 他方覆盖未过期 lease
CAS 已写、无 blob_ref 不可见对象 GC 候选;重试 finalize 当已提交 transcript
object write 失败 upload intent 不报告成功;重试 无 intent 的幽灵对象当成功
staging 删除失败 cleanup intent 可回收残留 已提交结果被回滚
DB 已提交、客户丢回覆 完整行 同幂等键返回既有收据 409 同内容
AC-02 已推 空表 前滚后续卡 手写 down DROP 有数据

风险登记

风险 影响 缓解 任务
误用 git.push_tokens 高:audience 混乱 GC-AC-02;AC-06 零命中 AC-06
误用 git_repo.id 当 repo 高:monorepo 路径无法 ingest ADR-AC-05 TEXT 路径 AC-03/AC-21
raw 进 tracing 高:日志泄漏 GC-AC-03;IT 抽检 AC-12/AC-13
FileHistory 50 版打满配额 中 默认不上传;上限 20 AC-10;DEFER-AC-02
与 runtime agent_sessions 撞名 中 GC-AC-01 前缀 全卡
include_oci 签名再增参回归 中 保留既有 OCI OpenAPI 测试 AC-07
并行发布占用版本面 中 ER-01 等待干净 Cargo.toml AC-15
计划附录覆盖正文 高:不可执行 本轮删除附录;单一权威 全文

性能与容量摘要

操作 单次成本 累积成本 预算/上限 验证
transcript blob O(size) 流式 每 unique digest 一份 16 MiB/blob AC-08 413
checkpoint 行 O(1) DB O(turns) 行;CAS 去重 同 digest 共享 AC-11
list sessions O(页大小) 头 不含正文 metadata-first AC-12
events batch O(n) watermark 单调 单请求条数上限 AC-09
file blobs / session O(1) 每 op ≤ 20(缺省) truncated AC-10

兼容与文档收口

  • docs/errors.md 已同步或 N/A 段(AC-14)。
  • docs/refactoring/agent-capture.md 由 AC-01 创建,各公开行为卡追加,AC-14 索引收口(非悬空)。
  • config/config.toml 注释与 config-storage-only.toml 已同步(AC-01)。
  • 运行时 OpenAPI 证据:enabled 含 /api/v1/agent-capture,review 不含(AC-07/AC-16/AC-13)。
  • README.md / AGENTS.md:N/A(无 CLI 新子命令)。
  • src/callisto/、src/jupiter/storage/、src/jupiter/migration/(含 migrations())已同步。
  • 新 docs/*.md 引用在 AC-01 创建后可解析。
  • plan-long.md 日期计划索引已登记。

Review log

Round Scope Result P0/P1 P2 处置 Evidence
R1 本计划成稿(Claude) PASS 无 P0/P1;P2:ER-07 GPG 在 Libra checkout N/A、基线版本/脏清单、零命中 rg 模板、完整 src/ 路径 R1 修订已吸收 target/tmp/plan-20260911-claude-r1.txt
R1 本计划成稿(Codex) FAIL P1×5:缺 G-* / 判定口径节;G-03 计数不诚实;AC-03/04/07/12 多轴;Dependencies 隐式;裸 rg 零命中 R2 修订关闭 target/tmp/plan-20260911-codex-r1.txt
R2 R1 修订后(Codex) FAIL P1×3:agent_capture_storage.rs 未串行;AC-12 未声明 AC-20 audit;AC-13/14 误把 discovery/raw_accepted 记到 AC-12;AC-04 复合谓词 当时修订关闭 target/tmp/plan-20260911-codex-r2.txt
R3 R2 修订后(Codex) FAIL P1×1:G-06 缺边 AC-10 -> AC-12 当时修订关闭 target/tmp/plan-20260911-codex-r3.txt
R4 R3 修订后(Claude) PASS 无 P0/P1。P2:AC-02 VER 计数、AC-15 writeset 措辞 残留,不覆盖 2026-09-13 折回稿 target/tmp/plan-20260911-claude-r4.txt
R4 R3 修订后(Codex) PASS 无 P0/P1/P2 该 PASS 只覆盖当时无附录的正文,不覆盖其后同文件补丁,也不覆盖本折回稿 target/tmp/plan-20260911-codex-r4.txt
R5–R13 同文件非正式补丁(附录覆盖任务卡) 非 Codex CLI 结论 造成双权威、DAG 分叉、基线过期、AC-00/AC-04-GC/AC-08-R 字段不完整 2026-09-13 删除附录并折回正式卡 无 target/tmp/plan-20260911-codex-r5.txt 及后续 CLI 日志;不得当作 PASS/FAIL
R14 2026-09-13 可执行性折回后全文 FAIL P1×6:AC-01 缺 testing.rs;AC-07 测试写集与落点不符;canonical helper 晚于消费者;G-03 复合谓词;AC-21/AC-17 误标 S;HTTP 卡 Docs N/A 违反 G-02/ER-06 本轮关闭 target/tmp/plan-20260911-codex-r14.txt
R15 R14 修订后全文 FAIL P1×1:G-10 AC-05 与 AC-00 同写 agent-capture.md 无依赖路径 本轮补 AC-05 -> AC-00;AC-14 索引 rg 拆成两门 target/tmp/plan-20260911-codex-r15.txt
R16 R15 修订后全文 PASS 无 P0/P1。P2:AC-14 libra status awk 管道会掩盖 status 失败 接受为 residual;不改任务卡以免推翻本轮 PASS target/tmp/plan-20260911-codex-r16.txt

非目标与延后项

ID 延后内容 原因 重启条件 承接位置
DEFER-AC-01 libra agent push Mega remote 客户端 写集在 libra 仓 HTTP 契约稳定且 libra 日期计划立项 未来 libra plan-YYYYMMDD
DEFER-AC-02 默认上传 FileHistory 50 版全文 体积与 secret 面;本机 undo 非远端口径 明确取证/远程 undo 产品需求 新日期计划
DEFER-AC-03 review 形态挂载 + OAuth 读 首版必达 storage-only 用户体系作为读面需求成立 新日期计划
DEFER-AC-04 后台 GC sweeper 本计划只交付查询不变量 对象增长需要周期回收 新日期计划
DEFER-AC-05 redacted 派生视图 raw 已是事实源 需要对非 ingest 角色展示 新日期计划

完成判据

本节于 2026-10-08 据实回填勾选。所有 25 张卡 Lifecycle=done 且 Acceptance=complete;plan-status.md 建档前核对:实现证据(src/、tests/integration_agent_capture.rs、迁移 m20260913_000100_add_agent_capture_tables.rs、docs/refactoring/agent-capture.md)均在仓内,Review log 末尾为 R16 Codex PASS,版本面已从基线 0.10.1 bump 至当前 0.42.25。

  • 所有任务卡满足 G-*;粒度审计表已填齐。
  • 所有非延后任务 Lifecycle=done 且 Acceptance=complete。
  • 所有 Verification 已运行并记录。
  • 计划完成门:cargo +nightly fmt --all --check、cargo clippy --all-targets --all-features -- -D warnings、source .env.test && cargo test --all 全绿;cargo build 与 cargo build --tests 0 错误 0 警告。
  • 文档/配置/错误契约/测试矩阵已更新。
  • migration/故障恢复已验证或记录不可验证原因(AC-02 forward-only)。
  • 实现卡代码 review 最终 PASS;计划文档 Codex 为 PASS。
  • 实现卡版本已 bump;无 release artifact(N/A:无 tag 流水线)。
  • 修订历史已记录成稿后规范性变更。
  • plan-long.md 已登记或 N/A。