Complete the selective V2 checkpoint with its minimal AgentBus, object-storage, replay persistence, and validated-workbench shared dependency closure.
156 lines
9.5 KiB
Markdown
156 lines
9.5 KiB
Markdown
# M012 / Layer 3 字段解析兜底 Agent Change Request v1
|
||
|
||
| 项 | 内容 |
|
||
| --- | --- |
|
||
| 状态 | Implemented and locally verified — live provider由独立后续 CR 承接 |
|
||
| 日期 | 2026-08-10 |
|
||
| 提出人 | 用户确认启动字段解析兜底 Agent;技术接口由本 Change Request 把关 |
|
||
| 共用基线 | `fixed_channel_parser_recovery_contract_v2_discussion_draft.md` |
|
||
| 基线 SHA-256 | `faedb8b78ac7f752dc4ccaaf49abf542a75818e87d9494748e58b5dff48e4c56` |
|
||
| Checkpoint | `M012-layer3-field-recovery-agent-v1` |
|
||
| 影响范围 | Backend / Layer 3 Contracts / Recovery Skill / Test / Docs |
|
||
|
||
## 1. 变更背景
|
||
|
||
QBD 确定性 Parser 已能形成 row/segment/room observation 骨架,但某些来源 token 可能真实存在、
|
||
又无法由程序唯一解释。此时不能把整行或整份附件交给 Agent 重解析,也不能让 Agent 覆盖 Parser
|
||
记录。本变更建立字段级 Recovery 链:只把 `UNRESOLVED+RECOVERABLE` 的稳定 `field_id` 任务交给
|
||
Agent;Agent 只返回 `RecoveryPatchSet`;本地组件验证后,以同一 deterministic projector 生成
|
||
`EffectiveFactView`。
|
||
|
||
本 Change Request 只承接 Layer 3。Rate Code、canonical Room Type、订单当前状态、Allotment 扣减、
|
||
CandidateDecision、用户确认及 PMS/Opera 均不在本次范围。
|
||
|
||
## 2. 权威版本与边界
|
||
|
||
- observation:`fixed-channel-observation-v1`
|
||
- semantic role:`fixed-channel-semantic-role-v1`
|
||
- field reason:`field-reason-v1`
|
||
- Recovery request/patch:`fixed-channel-recovery-v1`
|
||
- Effective facts:`fixed-channel-effective-facts-v1`
|
||
- QBD Agent profile/Skill:`fixed-channel-field-recovery-qbd-v1`
|
||
|
||
共用基线中的字段枚举、field ID/hash、reason、target refs、allowed schema/candidate namespace 和 overlay
|
||
规则是唯一格式来源。Java DTO、JSON fixture、Skill Prompt 和 Parser adapter 不得另造同义字段。
|
||
|
||
QBD F 列完全忽略:即使非空也不得进入 observation、request、prompt、patch、issue、review 或 nights。
|
||
普通LianTai在该checkpoint中deferred,不能复用QBD Prompt猜测实现。
|
||
|
||
## 3. 本次实现
|
||
|
||
1. 独立 additive Recovery DTO:request、task、allowed schema/candidate ref、patch、validation result、
|
||
field effect 和 EffectiveFactView;
|
||
2. `RecoveryRequestBuilder`:只从持久 observation 的精确 field registry 构造最小任务;
|
||
3. `FieldRecoveryAgentPort`:稳定的 provider-neutral 调用边界;仅有非空 task 时才允许调用;
|
||
4. `RecoveryPatchValidator`:验证版本/hash/attempt/idempotency/owner/evidence/schema/candidate refs;
|
||
5. `EffectiveFactAssembler`:accepted patch 先进入 effective field map,再经同版 dependency graph 与
|
||
CurrentFactProjector 重投影;不得直接 JSON path 拼接;
|
||
6. QBD 字段 Recovery Agent 的仓库内受控 Skill 源文件,并打包成可重复校验的 `.skill` archive;
|
||
7. fake/in-memory port 与 synthetic fixtures,完成不联网的 request→patch→validate→assemble 测试。
|
||
|
||
## 4. 本次明确不做
|
||
|
||
- 不让 Agent 下载、打开或重解析 XLSX;
|
||
- 不把整行、未选中行、完整邮件 history、附件 URL/bytes 交给 Agent;
|
||
- 不恢复 `MISSING/CONFLICT/NOT_APPLICABLE/LOCKED/REVIEW_ONLY`;
|
||
- 不让 Agent 新增 row/segment/room/fact、改 change role 或合并明细;
|
||
- 不输出或查询 Layer 4 的 207 行目录、Rate Code、canonical Room Type;
|
||
- 不复用 Layer 5 `booking.agent.*`、CandidateDecision 或旧 SuperAgent task-result callback;
|
||
- 本 checkpoint 不新增 HTTP/MCP endpoint,不配置真实 Provider Secret,不执行外部网络调用;
|
||
- 不建卡、不改数据库业务事实、不写 PMS/Opera/OHIP。
|
||
|
||
## 5. 调用与幂等顺序
|
||
|
||
```text
|
||
ParsedFactSet.parser_observations
|
||
-> RecoveryRequestBuilder
|
||
-> tasks 为空:不调用 Agent,按有无 active review 建立 BASELINE / BASELINE_WITH_REVIEW
|
||
-> tasks 非空:FieldRecoveryAgentPort.recover(request)
|
||
-> RecoveryPatchValidator
|
||
-> QbdEffectiveDependencyResolver
|
||
-> QbdCurrentFactProjector
|
||
-> EffectiveFactAssembler / apply-once store
|
||
-> EffectiveFactView
|
||
```
|
||
|
||
- `attempt` 只有发生一次真实 Agent port 调用时递增;Builder 或本地校验重跑不递增;
|
||
- 同一 request/attempt/observation hash/recovery version 生成同一 `idempotency_key`;
|
||
- 同一 key 最多应用一次;重放相同 PatchSet 返回既有结果,不重复 overlay;
|
||
- Agent 无唯一答案返回 `NO_CANDIDATE/AMBIGUOUS`,字段保持未解决并进入人工复核;
|
||
- Parser 结构问题(例如 `BUSINESS_MERGE_REQUIRED`)不调用字段 Agent,按稳定 issue/target 引用进入
|
||
`review_flags[]`;字段 issue 被合法 Recovery 解决后只保留原始审计记录,不再作为 active review;
|
||
- accepted patch 也只代表 Layer 3 来源语义恢复,不代表 Layer 5 业务决定或可执行动作。
|
||
|
||
## 6. 输入最小化与安全
|
||
|
||
每个 task 只包含目标 row/segment/room 的稳定 ID、semantic role、Parser reason、exact raw token、
|
||
本地冻结的 schema/有限 candidate refs、必要 sibling context 和 evidence refs。BEFORE 只可作为最小只读
|
||
上下文,不能成为目标。evidence locator 不包含签名 URL、附件 bytes、邮箱正文或 Secret。
|
||
|
||
Skill 包不得包含真实邮件、真实附件原文、sender 凭据、HMAC/API Secret、生产 URL、207 行目录或
|
||
个人信息。所有 Skill 示例使用 synthetic token 和虚构 ID。
|
||
|
||
## 7. 兼容与并行工作策略
|
||
|
||
当前 `BookingContracts.java` 和 QBD Parser 是另一任务的在途热点。本次先在独立 Recovery 包中新增
|
||
provider-neutral 契约与纯服务;Parser adapter 只在共用基线字段已经对齐后做最小接线。禁止通过复制
|
||
一份 Parser observation DTO 绕开对齐,也禁止回滚其他任务的未提交修改。
|
||
|
||
旧 `ParsedFactSet` 缺少 observations 时 fail-closed 为 `RECOVERY_NOT_APPLICABLE`,不能把旧
|
||
`unresolved_fields[]` 当第二真相源。live Agent dispatch 默认关闭;fake port 仅供测试。
|
||
|
||
## 8. 验收标准
|
||
|
||
1. 只有 `UNRESOLVED+RECOVERABLE` 且 role 允许的 field 生成 task;其他五态/权限全部排除。
|
||
2. task 的 reason 逐字复制 observation;field ID/owner/path/hash/version 任一不一致 fail-closed。
|
||
3. request 不含 attachment URL/bytes、完整 row/workbook、Layer 4 catalog 或 canonical Rate/Room。
|
||
4. Agent 输出请求外 ID/evidence、locked field、null candidate、跨 owner 值、非法 schema/ref 时拒绝。
|
||
5. `REFERENCE_ONLY` 只能选择一个允许 ref;`SCHEMA_CONSTRAINED` 必须通过本地类型和范围检查。
|
||
6. accepted patch 不改变 Parser observation/facts;Effective field 标记 `AGENT_RECOVERED`。
|
||
7. dates 恢复后 nights 由本地规则重算并保持 `PROFILE_DERIVED`;BEFORE/merge/F 永不被 Agent改变。
|
||
8. source field ID 经同一 projector 映射到 effective current fact;未被 current projection 消费的 patch 拒绝。
|
||
9. 同一 idempotency key 重放不重复应用;不同 observation hash 的 PatchSet 不可串用。
|
||
10. `.skill` archive 可重复构建、成员/哈希可验证,且扫描不到真实数据、Secret 或 Layer 4目录。
|
||
11. focused Java/Python tests、适度 server 回归、项目文档检查和 `git diff --check` 通过。
|
||
|
||
## 9. 需求追踪
|
||
|
||
| 需求项 | 后端 | 测试 | 当前状态 |
|
||
| --- | --- | --- | --- |
|
||
| Recovery DTO / schema | Done | Done | Verified |
|
||
| Request Builder | Done | Done | Verified |
|
||
| Agent Port / fake adapter | Port Done;live adapter Deferred | Fake Done | Verified boundary |
|
||
| Patch Validator | Done | Done | Verified |
|
||
| Effective Fact Assembler | Done | Done | Verified |
|
||
| QBD Recovery `.skill` | Done | Done | INTERNAL_ONLY verified |
|
||
| Parser adapter / Layer 3 E2E | Shared DTO/index/resolver/projector Done | Done | Verified |
|
||
| Persistent idempotency adapter | Interface Done;production adapter Deferred | In-memory Done | Deferred wiring |
|
||
|
||
## 10. 预计修改文件
|
||
|
||
- 独立 `workflows/reservation/.../recovery` DTO、port、service 与 tests;
|
||
- QBD Recovery Skill 源文件、专用 packager/validator、package tests 和 `.skill` artifact;
|
||
- Parser 对齐完成后的最小 adapter/assembler wiring;
|
||
- 本 Change Request、项目索引、Project State 与 `.project-docs` task memory。
|
||
|
||
不修改前端、数据库 migration、外部 callback、安全权限、RateRoom 目录、Layer 5 Booking Agent 或
|
||
PMS/OHIP 集成。
|
||
|
||
## 11. 实施证据与未启用项
|
||
|
||
- Java focused:`FixedChannelObservationCanonicalizerTest, RecoveryContractsTest,
|
||
RecoveryRequestBuilderTest, RecoveryPatchValidatorTest, EffectiveFactAssemblerTest` 通过;覆盖字段门禁、
|
||
候选 JCS identity、唯一候选、歧义/失败、dependency 重算、结构 review、Agent skip、transport
|
||
failure 与幂等 replay;
|
||
- 后端全量:`server/./mvnw -q test` 通过;
|
||
- Skill 源:`agent-skills/fixed-channel-field-recovery/`;
|
||
- `.skill`:`artifacts/fixed-channel-field-recovery-qbd-v1/fixed-channel-field-recovery.skill`,SHA-256
|
||
`75fa2c64d8155bb9f6426caee3d590351f7be1b64630e73b5ebba9fd9962c74e`;
|
||
- manifest SHA-256:`5317d5ba20a5b4cbf2acdf4c0d17f3622baa3644b5f647d34f7ccfeda55c73ad`;
|
||
- archive reproducibility check、静态安全校验、5 个 Python package tests 和 `py_compile` 均通过。
|
||
|
||
本 checkpoint 本身有意不提供生产 `FieldRecoveryAgentPort` provider adapter,也不提供数据库版
|
||
`RecoveryAssemblyIdempotencyStore`。该后置项已由
|
||
`M012-layer3-field-recovery-superagent-integration-change-request-v1.md` 独立实现;真实调用仍默认/生产
|
||
关闭,须完成专用 profile、Secret、PostgreSQL migration smoke 与部署审计后才可放行。
|