docs: plan wcs dispatch traffic demo
This commit is contained in:
428
docs/superpowers/plans/2026-07-30-wcs-dispatch-traffic-demo.md
Normal file
428
docs/superpowers/plans/2026-07-30-wcs-dispatch-traffic-demo.md
Normal file
@@ -0,0 +1,428 @@
|
||||
# WCS Dispatch and Traffic Demo Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 在工作树根目录创建独立的 Java 8 Maven Demo,用真实 JUnit 5 测试模拟 LEGACY WCS 的中心调度、确定性选车、路径交通管制、避让和队列生命周期。
|
||||
|
||||
**Architecture:** `LegacyDispatchCenter` 是单周期入口,只调用一次任务准入,再稳定处理车辆和活动队列。`VehicleAssignmentService`、`TrafficController`、`GridPathPlanner`、`SimulatedProtocolAdapter` 均为纯 Java 边界;`InMemoryWcsState` 保存模拟任务、队列、车辆和历史,不连接生产数据库或 PLC。
|
||||
|
||||
**Tech Stack:** Java 8、Maven 3.6、JUnit Jupiter 5.10.2、Maven Surefire 3.2.5、Exec Maven Plugin 3.1.0。
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- 生产控制模式保持 LEGACY;Demo 不修改生产 WCS 源码。
|
||||
- 不连接 SQL Server、PLC、WMS 或 Spring,不产生真实设备写入。
|
||||
- 不建立生产中央路权服务,不写交通运行表,不启用 SHADOW/ACTIVE。
|
||||
- 不使用 `default02` 至 `default08` 保存新增交通状态。
|
||||
- 所有源码使用 Java 8 可用语法与 API。
|
||||
- `mvn test` 的真实测试数必须大于 0,failures 和 errors 必须为 0。
|
||||
- 车辆资格固定为 connected、`workMode=5`、`status=1`、`allowSend=true`、`battery>30`。
|
||||
- 选择顺序固定为同层、绝对楼层差、Y 距离、X 距离、vehicleId。
|
||||
- 队列状态保持旧语义:新建 `issued=0/executionStatus=1`,下发 `1/3`,完成 `1/4` 后归档删除。
|
||||
|
||||
---
|
||||
|
||||
## File Map
|
||||
|
||||
### Build and documentation
|
||||
|
||||
- `javaTest/pom.xml`:独立 Maven 构建、JUnit 5、Surefire、Exec 插件。
|
||||
- `javaTest/README.md`:运行方式、场景、LEGACY 安全边界。
|
||||
|
||||
### Domain
|
||||
|
||||
- `javaTest/src/main/java/com/ft546/wcs/demo/model/Site.java`:站点、楼层和坐标值对象。
|
||||
- `javaTest/src/main/java/com/ft546/wcs/demo/model/VehicleSnapshot.java`:不可变车辆执行快照。
|
||||
- `javaTest/src/main/java/com/ft546/wcs/demo/model/DispatchTask.java`:业务任务及准入状态。
|
||||
- `javaTest/src/main/java/com/ft546/wcs/demo/model/DispatchQueueEntry.java`:活动队列及旧状态码流转。
|
||||
- `javaTest/src/main/java/com/ft546/wcs/demo/model/DecisionCode.java`:调度和交通决策码。
|
||||
|
||||
### State and scheduling
|
||||
|
||||
- `javaTest/src/main/java/com/ft546/wcs/demo/repository/InMemoryWcsState.java`:车辆、任务、队列、历史和每周期事件。
|
||||
- `javaTest/src/main/java/com/ft546/wcs/demo/center/VehicleAssignmentDecision.java`:确定性选车结果和理由。
|
||||
- `javaTest/src/main/java/com/ft546/wcs/demo/center/VehicleAssignmentService.java`:车辆资格过滤和稳定比较器。
|
||||
- `javaTest/src/main/java/com/ft546/wcs/demo/center/QueueAdmissionService.java`:每周期把一个待处理任务转为活动队列。
|
||||
- `javaTest/src/main/java/com/ft546/wcs/demo/center/CycleResult.java`:单周期已处理车辆和事件快照。
|
||||
- `javaTest/src/main/java/com/ft546/wcs/demo/center/LegacyDispatchCenter.java`:单周期中心调度入口。
|
||||
|
||||
### Traffic and protocol
|
||||
|
||||
- `javaTest/src/main/java/com/ft546/wcs/demo/traffic/GridMap.java`:站点、边和静态障碍。
|
||||
- `javaTest/src/main/java/com/ft546/wcs/demo/traffic/GridPathPlanner.java`:确定性广度优先最短路。
|
||||
- `javaTest/src/main/java/com/ft546/wcs/demo/traffic/TrafficDecision.java`:路径、HOLD 或避让结果。
|
||||
- `javaTest/src/main/java/com/ft546/wcs/demo/traffic/TrafficController.java`:剩余路径锁、离线点、通道冲突和避让去重。
|
||||
- `javaTest/src/main/java/com/ft546/wcs/demo/simulation/SimulatedProtocolAdapter.java`:可注入失败的无 I/O 下发适配器。
|
||||
- `javaTest/src/main/java/com/ft546/wcs/demo/DemoApplication.java`:构造场景、推进周期和打印结果。
|
||||
|
||||
### Tests
|
||||
|
||||
- `javaTest/src/test/java/com/ft546/wcs/demo/VehicleAssignmentServiceTest.java`
|
||||
- `javaTest/src/test/java/com/ft546/wcs/demo/TrafficControllerTest.java`
|
||||
- `javaTest/src/test/java/com/ft546/wcs/demo/LegacyDispatchCenterTest.java`
|
||||
- `javaTest/src/test/java/com/ft546/wcs/demo/QueueLifecycleTest.java`
|
||||
- `javaTest/src/test/java/com/ft546/wcs/demo/DemoScenarioTest.java`
|
||||
|
||||
---
|
||||
|
||||
## Task 1: Bootstrap Real JUnit 5 and Domain Models
|
||||
|
||||
**Files:**
|
||||
- Create: `javaTest/pom.xml`
|
||||
- Create: `javaTest/src/main/java/com/ft546/wcs/demo/model/Site.java`
|
||||
- Create: `javaTest/src/main/java/com/ft546/wcs/demo/model/VehicleSnapshot.java`
|
||||
- Create: `javaTest/src/main/java/com/ft546/wcs/demo/model/DispatchTask.java`
|
||||
- Create: `javaTest/src/main/java/com/ft546/wcs/demo/model/DispatchQueueEntry.java`
|
||||
- Create: `javaTest/src/main/java/com/ft546/wcs/demo/model/DecisionCode.java`
|
||||
- Test: `javaTest/src/test/java/com/ft546/wcs/demo/QueueLifecycleTest.java`
|
||||
|
||||
**Interfaces:**
|
||||
- Produces: `Site(String id, int floor, int x, int y, String channel)`
|
||||
- Produces: `VehicleSnapshot(String vehicleId, int floor, String currentSite, int workMode, int status, int battery, boolean connected, boolean allowSend, boolean cargo)`
|
||||
- Produces: `DispatchTask(String taskId, TaskType type, String sourceSite, String targetSite, int floor, int priority)`
|
||||
- Produces: `DispatchQueueEntry.business(DispatchTask task, String vehicleId)`
|
||||
- Produces: `markIssued(List<String> path)`, `markCompleted()`, `isIssued()`, `getExecutionStatus()`
|
||||
|
||||
- [ ] **Step 1: Add Maven build and write the failing lifecycle test**
|
||||
|
||||
`pom.xml` must set `maven.compiler.source` and `target` to `1.8`, add `org.junit.jupiter:junit-jupiter:5.10.2`, configure `maven-surefire-plugin:3.2.5`, and configure `exec-maven-plugin:3.1.0` with main class `com.ft546.wcs.demo.DemoApplication`.
|
||||
|
||||
The first test:
|
||||
|
||||
```java
|
||||
@Test
|
||||
void queueUsesLegacyLifecycleCodes() {
|
||||
DispatchTask task = new DispatchTask("T-1", TaskType.OUTBOUND, "A", "B", 1, 2);
|
||||
DispatchQueueEntry queue = DispatchQueueEntry.business(task, "1");
|
||||
assertEquals(0, queue.getIssued());
|
||||
assertEquals(1, queue.getExecutionStatus());
|
||||
queue.markIssued(Arrays.asList("A", "B"));
|
||||
assertEquals(1, queue.getIssued());
|
||||
assertEquals(3, queue.getExecutionStatus());
|
||||
queue.markCompleted();
|
||||
assertEquals(4, queue.getExecutionStatus());
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run the focused test and verify RED**
|
||||
|
||||
Run: `cd javaTest && mvn -Dtest=QueueLifecycleTest test`
|
||||
|
||||
Expected: FAIL during test compilation because domain classes do not exist.
|
||||
|
||||
- [ ] **Step 3: Implement immutable inputs and guarded queue transitions**
|
||||
|
||||
Implement nested enum `DispatchTask.TaskType { INBOUND, OUTBOUND, RELOCATION }`. Reject blank IDs, battery outside 0–100, non-positive floors and `markCompleted()` before issue with `IllegalStateException`. Copy path input into an unmodifiable list.
|
||||
|
||||
- [ ] **Step 4: Run the focused test and verify GREEN**
|
||||
|
||||
Run: `cd javaTest && mvn -Dtest=QueueLifecycleTest test`
|
||||
|
||||
Expected: tests=1, failures=0, errors=0.
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add javaTest/pom.xml javaTest/src/main/java/com/ft546/wcs/demo/model javaTest/src/test/java/com/ft546/wcs/demo/QueueLifecycleTest.java
|
||||
git commit -m "test: bootstrap wcs demo domain"
|
||||
```
|
||||
|
||||
## Task 2: Deterministic Vehicle Assignment
|
||||
|
||||
**Files:**
|
||||
- Create: `javaTest/src/main/java/com/ft546/wcs/demo/center/VehicleAssignmentDecision.java`
|
||||
- Create: `javaTest/src/main/java/com/ft546/wcs/demo/center/VehicleAssignmentService.java`
|
||||
- Test: `javaTest/src/test/java/com/ft546/wcs/demo/VehicleAssignmentServiceTest.java`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: `DispatchTask`, `VehicleSnapshot`, `Map<String, Site>`
|
||||
- Produces: `VehicleAssignmentDecision select(DispatchTask task, List<VehicleSnapshot> vehicles, Map<String, Site> sites)`
|
||||
- Produces: `DecisionCode.ASSIGNED`, `HOLD_NO_ELIGIBLE_VEHICLE`, `REJECT_INVALID_SITE`
|
||||
- Produces: `Optional<VehicleSnapshot> getVehicle()`, `DecisionCode getCode()`, `String getReason()`
|
||||
|
||||
- [ ] **Step 1: Write failing assignment tests**
|
||||
|
||||
Tests must assert:
|
||||
|
||||
```java
|
||||
assertEquals("2", service.select(task, Arrays.asList(crossFloor, sameFloor), sites)
|
||||
.getVehicle().get().getVehicleId());
|
||||
```
|
||||
|
||||
```java
|
||||
assertEquals("1", service.select(task, Arrays.asList(vehicle2, vehicle1), sites)
|
||||
.getVehicle().get().getVehicleId());
|
||||
```
|
||||
|
||||
Also assert ineligible vehicles are excluded and a missing source site returns `REJECT_INVALID_SITE`.
|
||||
|
||||
- [ ] **Step 2: Run and verify RED**
|
||||
|
||||
Run: `cd javaTest && mvn -Dtest=VehicleAssignmentServiceTest test`
|
||||
|
||||
Expected: FAIL because assignment types do not exist.
|
||||
|
||||
- [ ] **Step 3: Implement stable assignment**
|
||||
|
||||
Eligibility is exactly `connected && workMode == 5 && status == 1 && allowSend && battery > 30`. Sort by:
|
||||
|
||||
```java
|
||||
Comparator.comparingInt(candidate -> candidate.sameFloorPenalty)
|
||||
.thenComparingInt(candidate -> candidate.floorDistance)
|
||||
.thenComparingInt(candidate -> candidate.yDistance)
|
||||
.thenComparingInt(candidate -> candidate.xDistance)
|
||||
.thenComparing(candidate -> candidate.vehicle.getVehicleId());
|
||||
```
|
||||
|
||||
Distances use `Site` coordinates; never parse malformed numeric substrings from site IDs. Return a reason string containing the chosen comparison values.
|
||||
|
||||
- [ ] **Step 4: Run and verify GREEN**
|
||||
|
||||
Run: `cd javaTest && mvn -Dtest=VehicleAssignmentServiceTest test`
|
||||
|
||||
Expected: all assignment tests pass.
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add javaTest/src/main/java/com/ft546/wcs/demo/center javaTest/src/test/java/com/ft546/wcs/demo/VehicleAssignmentServiceTest.java
|
||||
git commit -m "feat: add deterministic vehicle assignment demo"
|
||||
```
|
||||
|
||||
## Task 3: Grid Path Planning and Traffic Control
|
||||
|
||||
**Files:**
|
||||
- Create: `javaTest/src/main/java/com/ft546/wcs/demo/traffic/GridMap.java`
|
||||
- Create: `javaTest/src/main/java/com/ft546/wcs/demo/traffic/GridPathPlanner.java`
|
||||
- Create: `javaTest/src/main/java/com/ft546/wcs/demo/traffic/TrafficDecision.java`
|
||||
- Create: `javaTest/src/main/java/com/ft546/wcs/demo/traffic/TrafficController.java`
|
||||
- Test: `javaTest/src/test/java/com/ft546/wcs/demo/TrafficControllerTest.java`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: sites, adjacency, static blocks, vehicles and active queues
|
||||
- Produces: `List<String> shortestPath(GridMap map, String start, String end, Set<String> blocked)`
|
||||
- Produces: `TrafficDecision plan(VehicleSnapshot vehicle, DispatchQueueEntry queue, Collection<VehicleSnapshot> vehicles, Collection<DispatchQueueEntry> queues)`
|
||||
- Produces: `PATH_READY`, `HOLD_NO_PATH`, `HOLD_CHANNEL_BLOCKED`, `AVOIDANCE_CREATED`
|
||||
|
||||
- [ ] **Step 1: Write failing path and traffic tests**
|
||||
|
||||
Cover:
|
||||
|
||||
```java
|
||||
assertEquals(Arrays.asList("A", "D", "C"), planner.shortestPath(map, "A", "C",
|
||||
Collections.singleton("B")));
|
||||
```
|
||||
|
||||
```java
|
||||
TrafficDecision decision = controller.plan(car1, car1Queue, vehicles, queues);
|
||||
assertEquals(DecisionCode.AVOIDANCE_CREATED, decision.getCode());
|
||||
assertEquals(9, decision.getAvoidanceQueue().get().getPriority());
|
||||
```
|
||||
|
||||
Also test offline current-site locking, no route, avoidance de-duplication, and successful re-plan after avoidance queue deletion.
|
||||
|
||||
- [ ] **Step 2: Run and verify RED**
|
||||
|
||||
Run: `cd javaTest && mvn -Dtest=TrafficControllerTest test`
|
||||
|
||||
Expected: FAIL because traffic types do not exist.
|
||||
|
||||
- [ ] **Step 3: Implement deterministic BFS and occupancy view**
|
||||
|
||||
`GridPathPlanner` visits neighbors sorted by site ID. `TrafficController` blocks:
|
||||
|
||||
1. static map obstacles,
|
||||
2. disconnected vehicle current sites,
|
||||
3. every other active queue path from that vehicle's current-site index onward.
|
||||
|
||||
Before planning a business queue, detect a same-floor vehicle at a different site with the same target channel. If it has no active queue, create `DispatchQueueEntry.avoidance(...)` to a configured cache site, priority 9. If it already has an avoidance queue, return `HOLD_CHANNEL_BLOCKED` without creating another.
|
||||
|
||||
- [ ] **Step 4: Run and verify GREEN**
|
||||
|
||||
Run: `cd javaTest && mvn -Dtest=TrafficControllerTest test`
|
||||
|
||||
Expected: all traffic tests pass.
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add javaTest/src/main/java/com/ft546/wcs/demo/traffic javaTest/src/test/java/com/ft546/wcs/demo/TrafficControllerTest.java
|
||||
git commit -m "feat: simulate wcs traffic control"
|
||||
```
|
||||
|
||||
## Task 4: In-Memory State, Admission, and Cycle Coordinator
|
||||
|
||||
**Files:**
|
||||
- Create: `javaTest/src/main/java/com/ft546/wcs/demo/repository/InMemoryWcsState.java`
|
||||
- Create: `javaTest/src/main/java/com/ft546/wcs/demo/center/QueueAdmissionService.java`
|
||||
- Create: `javaTest/src/main/java/com/ft546/wcs/demo/center/CycleResult.java`
|
||||
- Create: `javaTest/src/main/java/com/ft546/wcs/demo/center/LegacyDispatchCenter.java`
|
||||
- Create: `javaTest/src/main/java/com/ft546/wcs/demo/simulation/SimulatedProtocolAdapter.java`
|
||||
- Test: `javaTest/src/test/java/com/ft546/wcs/demo/LegacyDispatchCenterTest.java`
|
||||
|
||||
**Interfaces:**
|
||||
- Produces: `CycleResult runCycle()`
|
||||
- Produces: `int getAdmissionInvocationCount()`
|
||||
- Produces: `Optional<DispatchQueueEntry> createPendingQueue(InMemoryWcsState state)`
|
||||
- Produces: state methods to add/update vehicles and tasks, query active queues/history/events
|
||||
- Produces: `SimulatedProtocolAdapter.ProtocolResult send(DispatchQueueEntry queue, List<String> path)`
|
||||
|
||||
- [ ] **Step 1: Write failing coordinator tests**
|
||||
|
||||
The first test:
|
||||
|
||||
```java
|
||||
CycleResult result = center.runCycle();
|
||||
assertEquals(1, admission.getInvocationCount());
|
||||
assertEquals(Arrays.asList("1", "2", "3"), result.getProcessedVehicleIds());
|
||||
assertEquals(1, state.getActiveQueues().size());
|
||||
```
|
||||
|
||||
Also test protocol failure leaves `issued=0/executionStatus=1`, the next cycle retries successfully, and reaching the destination archives and deletes the queue exactly once.
|
||||
|
||||
- [ ] **Step 2: Run and verify RED**
|
||||
|
||||
Run: `cd javaTest && mvn -Dtest=LegacyDispatchCenterTest test`
|
||||
|
||||
Expected: FAIL because coordinator types do not exist.
|
||||
|
||||
- [ ] **Step 3: Implement one-admission-per-cycle coordinator**
|
||||
|
||||
`runCycle()` must:
|
||||
|
||||
1. call admission exactly once,
|
||||
2. freeze and sort vehicle IDs,
|
||||
3. add any avoidance queue returned by traffic control,
|
||||
4. only send a queue when `PATH_READY`,
|
||||
5. leave HOLD queues unchanged,
|
||||
6. call protocol once per unissued ready queue,
|
||||
7. complete and archive an issued queue only when vehicle current site equals queue end site.
|
||||
|
||||
`SimulatedProtocolAdapter.failNextSend()` injects one failure and records every attempted queue ID without I/O.
|
||||
|
||||
- [ ] **Step 4: Run and verify GREEN**
|
||||
|
||||
Run: `cd javaTest && mvn -Dtest=LegacyDispatchCenterTest,QueueLifecycleTest test`
|
||||
|
||||
Expected: coordinator and lifecycle tests pass.
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add javaTest/src/main/java/com/ft546/wcs/demo/repository javaTest/src/main/java/com/ft546/wcs/demo/center javaTest/src/main/java/com/ft546/wcs/demo/simulation javaTest/src/test/java/com/ft546/wcs/demo/LegacyDispatchCenterTest.java
|
||||
git commit -m "feat: add legacy dispatch cycle demo"
|
||||
```
|
||||
|
||||
## Task 5: Executable Scenarios and End-to-End Test
|
||||
|
||||
**Files:**
|
||||
- Create: `javaTest/src/main/java/com/ft546/wcs/demo/DemoApplication.java`
|
||||
- Create: `javaTest/src/test/java/com/ft546/wcs/demo/DemoScenarioTest.java`
|
||||
- Create: `javaTest/README.md`
|
||||
|
||||
**Interfaces:**
|
||||
- Produces: `DemoApplication.runScenario(PrintStream out)`
|
||||
- Produces: console lines beginning `CYCLE`, `ASSIGN`, `PATH`, `HOLD`, `AVOID`, `SEND`, `COMPLETE`, `SUMMARY`
|
||||
|
||||
- [ ] **Step 1: Write failing end-to-end test**
|
||||
|
||||
```java
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
DemoApplication.runScenario(new PrintStream(output));
|
||||
String text = new String(output.toByteArray(), StandardCharsets.UTF_8);
|
||||
assertTrue(text.contains("ASSIGN"));
|
||||
assertTrue(text.contains("AVOID"));
|
||||
assertTrue(text.contains("HOLD"));
|
||||
assertTrue(text.contains("SEND"));
|
||||
assertTrue(text.contains("COMPLETE"));
|
||||
assertTrue(text.contains("SUMMARY"));
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run and verify RED**
|
||||
|
||||
Run: `cd javaTest && mvn -Dtest=DemoScenarioTest test`
|
||||
|
||||
Expected: FAIL because `DemoApplication` does not exist.
|
||||
|
||||
- [ ] **Step 3: Implement the complete console scenario**
|
||||
|
||||
Create a two-lane map with a cache point and three vehicles. Run sequential phases for deterministic assignment, same-channel avoidance, avoidance completion, protocol failure/retry, business completion and no-path HOLD. Print every event and a final summary containing cycle count, active queue count and history count.
|
||||
|
||||
`README.md` must document:
|
||||
|
||||
```bash
|
||||
mvn test
|
||||
mvn exec:java
|
||||
```
|
||||
|
||||
and explicitly state the Demo never connects to production systems.
|
||||
|
||||
- [ ] **Step 4: Run focused and full verification**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd javaTest
|
||||
mvn -Dtest=DemoScenarioTest test
|
||||
mvn test
|
||||
mvn exec:java
|
||||
```
|
||||
|
||||
Expected: focused test passes; full Surefire summary has tests > 0, failures=0, errors=0; console output contains all required event types and exits 0.
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add javaTest/src/main/java/com/ft546/wcs/demo/DemoApplication.java javaTest/src/test/java/com/ft546/wcs/demo/DemoScenarioTest.java javaTest/README.md
|
||||
git commit -m "feat: add executable wcs dispatch simulation"
|
||||
```
|
||||
|
||||
## Task 6: Completion Audit
|
||||
|
||||
**Files:**
|
||||
- Verify: `javaTest/**`
|
||||
- Verify: `docs/superpowers/specs/2026-07-30-wcs-dispatch-traffic-demo-design.md`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: all earlier tasks
|
||||
- Produces: objective-by-objective evidence
|
||||
|
||||
- [ ] **Step 1: Verify repository and Java compatibility**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
git rev-parse --is-inside-work-tree
|
||||
mvn -f javaTest/pom.xml clean test
|
||||
```
|
||||
|
||||
Expected: Git prints `true`; Maven exits 0 and compiles with source/target 1.8.
|
||||
|
||||
- [ ] **Step 2: Verify real test counts**
|
||||
|
||||
Inspect `javaTest/target/surefire-reports/TEST-*.xml`; sum `tests`, `failures`, `errors`, and `skipped`.
|
||||
|
||||
Expected: tests > 0, failures=0, errors=0.
|
||||
|
||||
- [ ] **Step 3: Verify executable behavior**
|
||||
|
||||
Run: `mvn -f javaTest/pom.xml exec:java`
|
||||
|
||||
Expected: output includes `CYCLE`, `ASSIGN`, `PATH`, `HOLD`, `AVOID`, `SEND`, `COMPLETE`, and `SUMMARY`, with process exit 0.
|
||||
|
||||
- [ ] **Step 4: Verify production isolation**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
git diff 7b36dfa --name-only
|
||||
```
|
||||
|
||||
Expected: only `javaTest/**` and the implementation plan are added or modified; no production `ruoyi-*` code changes.
|
||||
|
||||
- [ ] **Step 5: Final commit if verification updates documentation**
|
||||
|
||||
```bash
|
||||
git add javaTest docs/superpowers/plans/2026-07-30-wcs-dispatch-traffic-demo.md
|
||||
git commit -m "docs: finalize wcs demo verification"
|
||||
```
|
||||
Reference in New Issue
Block a user