Files
th-hotel-simple/docs/project/requirements/M012-layer3-field-recovery-agent-change-request-v1.md
T
鲨鱼辣椒 694c4317a3 checkpoint: complete recoverable V2 pre-separation baseline
Complete the selective V2 checkpoint with its minimal AgentBus, object-storage, replay persistence, and validated-workbench shared dependency closure.
2026-08-20 17:09:00 +08:00

156 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 与部署审计后才可放行。