diff --git a/docs/superpowers/specs/2026-07-30-wcs-p0-b1-shadow-demo-design.md b/docs/superpowers/specs/2026-07-30-wcs-p0-b1-shadow-demo-design.md new file mode 100644 index 0000000..ba17796 --- /dev/null +++ b/docs/superpowers/specs/2026-07-30-wcs-p0-b1-shadow-demo-design.md @@ -0,0 +1,216 @@ +# WCS P0-B1 离线 SHADOW Demo 增量设计 + +## 1. 背景 + +现有 `javaTest` 已实现一个 Java 8、纯内存、无外部 I/O 的 LEGACY 调度演示,覆盖任务准入、确定性选车、网格寻路、通道避让、协议失败重试和业务队列归档。 + +本增量依据仓库根目录 `docs/WCS算法优化` 的设计基线继续扩展,但不复制生产工程,也不把未签字的 PLC、提升机或 ACTIVE 能力描述为已经可用。 + +## 2. 目标 + +在保留现有 LEGACY Demo 行为和测试的前提下,旁路增加可独立测试的 P0-B1 离线 SHADOW 领域内核: + +1. 编译并校验版本化不可变交通地图。 +2. 使用节点、无向边和显式冲突资源表达空间硬路权。 +3. 建模交通区段与资源保护状态。 +4. 冻结带版本和序号的复合交通快照。 +5. 生成确定性的 `GRANT/HOLD/YIELD` 决策。 +6. 通过等待图拒绝会形成环的放行组合。 +7. 根据匹配反馈逐步释放资源;错配、重启或失联时 fail closed。 +8. 记录结构化决策事件,并能用相同输入离线回放出相同结果。 +9. 证明 SHADOW 协调器不会写 PLC、LEGACY 业务状态或权威运行时预约。 + +## 3. 明确边界 + +### 3.1 范围内 + +- Java 8 纯领域对象和内存测试替身。 +- P0-B1 的 L1 领域测试、L4 JSON 黄金场景和小规模固定种子属性测试。 +- 模拟节点、无向边、显式冲突资源及容量。 +- 区段状态和资源保护状态的契约测试。 +- 快照陈旧、序号倒退、`plcBootId` 改变和路径错配测试。 +- SHADOW 决策、差异记录、禁写保护和确定性回放。 +- 仅用于证明 fail-closed 行为的 PLC/提升机契约桩。 + +### 3.2 范围外 + +- SQL Server Schema、MyBatis Mapper、真实事务和 Outbox。 +- 真实 PLC 寄存器、CRC、网络通信或硬件在环。 +- 真实 WMS 回调或业务表更新。 +- 深位和提升机的真实执行控制。 +- `ACTIVE/LIMITED_ACTIVE/PRODUCTION` 控制模式。 +- 现场 SHADOW 样本、现场性能基线或任何生产验收声明。 + +成果状态只能描述为“离线 SHADOW 模拟验证”。所有未签字外部门禁继续保持 `BLOCKED` 或 `IN_VERIFICATION`。 + +## 4. 架构 + +现有 `com.ft546.wcs.demo` LEGACY 包保持兼容。新增 `com.ft546.wcs.shadow`,避免把交通生命周期重新塞回业务队列: + +```text +com.ft546.wcs.shadow/ +├── map/ 版本化地图、资源键和编译校验 +├── snapshot/ 不可变复合快照与新鲜度检查 +├── segment/ 候选区段、区段状态机 +├── resource/ 资源定义、保护状态和内存账本 +├── decision/ 候选排序、等待图、GRANT/HOLD/YIELD +├── feedback/ 匹配校验、逐步释放与隔离 +├── replay/ 决策事件、JSON 夹具和离线回放 +└── application/SHADOW 协调器及禁写端口 +``` + +LEGACY 继续拥有现有模拟发送和业务队列状态。SHADOW 只读取冻结输入,使用本轮临时计算视图,输出决策事件和差异,不改变 `InMemoryWcsState` 中的任务、队列或历史。 + +## 5. 地图与资源模型 + +### 5.1 版本化交通地图 + +`TrafficMapCompiler` 从内存地图定义生成 `EffectiveTrafficMap`。编译时验证: + +- `mapCode`、`versionId` 和基础地图校验和匹配。 +- 交通区域边界已确认。 +- 节点与边引用有效。 +- 容量为正数。 +- 无向边使用规范资源键。 +- 安全等待点不是唯一出口。 + +交通区域只表示统一协调和版本边界,不自动成为容量 1 的资源。 + +### 5.2 资源键 + +首个增量实现: + +```text +NODE:{siteId} +EDGE:{smallerSiteId}:{largerSiteId} +CONFLICT:{resourceCode} +``` + +提升机和深位资源只保留扩展类型及 fail-closed 占位,不模拟真实放行。 + +### 5.3 资源保护 + +预约状态为: + +```text +SOFT → COMMIT_GUARD → HARD → RELEASED + ↘ UNKNOWN_HARD +``` + +- `SOFT` 只参与本轮候选计算。 +- `COMMIT_GUARD` 排他保护提交窗口。 +- `HARD` 表示匹配提交事实。 +- `UNKNOWN_HARD` 表示 ACK 丢失、失联、重启或反馈错配,按硬资源保留。 +- 时间或 ETA 到期不能释放 `HARD/UNKNOWN_HARD`。 + +SHADOW 协调器不得把这些状态写入权威运行时账本;状态机通过独立领域测试和模拟执行夹具验证。 + +## 6. 快照和区段 + +`TrafficSnapshot` 在每轮开始时冻结: + +- `tickSeq`、决策时间、地图版本和参数版本。 +- 每车 `plcBootId/heartbeatSeq/snapshotSeq`。 +- 当前位置、下一点、剩余路径、通信和故障状态。 +- 已有硬资源、未知硬资源和资源容量。 +- 待比较的 LEGACY 实际决定。 + +快照对象及其集合不可变。以下情况将车辆隔离并阻止新 GRANT: + +- 超过新鲜度上限。 +- 心跳或快照序号倒退。 +- `plcBootId` 改变。 +- 区段版本或剩余路径不匹配。 +- 通信状态未知、失联或故障。 + +候选区段不得跨过地图决断点、安全等待点或冲突资源边界。固定最大点数只作为技术上限。 + +## 7. 决策流程 + +`ShadowTrafficCoordinator.decide()` 固定执行: + +1. 校验模式必须为 `SHADOW`,地图和快照版本必须匹配。 +2. 冻结输入并登记故障、失联、`HARD/UNKNOWN_HARD` 为不可穿越资源。 +3. 为车辆生成软路径及下一候选区段。 +4. 按业务优先级、等待老化、清区代价、任务号和车辆号稳定排序。 +5. 逐候选检查节点、无向边、显式冲突资源和容量。 +6. 构建等待图;会形成环的候选不得 GRANT。 +7. 无冲突输出 `GRANT`;可安全等待输出 `HOLD`;只有存在已发布安全让行点时输出 `YIELD`。 +8. 记录结构化原因码、冲突资源、阻挡车辆和输入哈希。 +9. 通过禁写端口记录“意图”,不得发送或改变权威状态。 + +高优先级任务不能撤销已经提交的硬区段。没有安全 YIELD 点时保持 HOLD 并记录报警原因。 + +## 8. 反馈与失效关闭 + +`FeedbackReconciler` 只有在以下字段匹配时才允许释放: + +- `plcBootId` +- `plannerEpoch` +- `planVersion` +- `segmentSeq` +- 单调 `snapshotSeq` +- 当前点及剩余路径是已提交路径的合法单调后缀 + +匹配 A→B 后释放节点 A 和无向边 A—B,节点 B 继续保留。重复快照幂等返回。 + +跳点、倒退、版本错配、PLC 重启、ACK 丢失和通信中断均不得释放;相关保护转为或保持 `UNKNOWN_HARD`,车辆进入隔离。模拟器不能借助任务、楼层或其他字段推断未知载货状态。 + +## 9. 决策事件与回放 + +每轮 `DecisionEvent` 至少包含: + +- 决策 ID、tick、地图/参数版本。 +- 输入快照哈希和车辆快照序号。 +- 稳定排序后的候选。 +- 每车 `GRANT/HOLD/YIELD`、原因码、冲突资源和阻挡车辆。 +- 资源变化模拟摘要。 +- LEGACY 实际决定及结构化差异分类。 + +回放服务从 JSON 黄金夹具重建相同输入,并断言决定、原因码和资源结果完全一致。事件记录允许作为 SHADOW 的唯一旁路输出,但不得被称为现场 SHADOW 证据。 + +## 10. 错误处理 + +- 地图校验失败:拒绝加载,不使用旧校验和继续规划。 +- 模式不是 SHADOW:协调器拒绝运行。 +- 任一外部写端口调用:抛出 `ShadowWriteForbiddenException`。 +- 资源不足或等待环:返回结构化 HOLD,不抛系统异常。 +- 无安全 YIELD 点:HOLD 并记录 `NO_SAFE_YIELD_SITE`。 +- 未知载货、提升机信号或 PLC 契约:fail closed。 +- 不可恢复的模型定义错误:构造或编译阶段抛 `IllegalArgumentException`。 + +## 11. 测试策略 + +保持现有 20 个测试通过,并新增: + +1. 地图编译:版本、校验和、边规范键、区域非互斥、唯一出口。 +2. 资源账本:同节点、对向边、容量、非冲突并行。 +3. 状态机:非法跳转、单车单硬区段、未知提交保留。 +4. 快照:冻结、陈旧、倒退、bootId 改变。 +5. 决策:确定性排序、硬区段不可撤销、等待环、HOLD/YIELD。 +6. 反馈:逐步释放、重复快照、跳点、倒退、版本错配、ETA 到期。 +7. SHADOW:零 PLC 写、零业务状态写、零权威预约写。 +8. 回放:JSON 黄金场景稳定一致。 +9. 固定种子属性测试:资源容量不超限、等待图无环、未知资源不释放;失败信息输出 seed、地图版本和输入摘要。 + +验证命令: + +```bash +cd javaTest +mvn clean test +mvn exec:java +``` + +验收必须读取 Surefire 汇总,确认测试数大于 0,失败和错误均为 0。控制台演示新增 SHADOW 决策与 LEGACY 对比摘要,同时保留现有事件。 + +## 12. 交付标准 + +1. 现有 LEGACY Demo 及测试无回归。 +2. SHADOW 内核拥有独立包和明确端口,不依赖生产模块。 +3. 文档测试矩阵中适用于 P0-B1 离线领域层的场景均有测试。 +4. 相同输入、地图和参数版本产生相同决定。 +5. 未知、错配、重启和失联均不会释放资源或产生新 GRANT。 +6. SHADOW 协调器无法写 PLC、业务状态或权威预约。 +7. README 明确能力边界、运行命令和非现场证据属性。 +8. 不修改 `ruoyi-*` 生产代码,不连接数据库、PLC 或 WMS。 +