# FT546 WMS Shadow-Only 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:** Build a clean `origin/main`-based branch that observes inbound and outbound allocation with the Java algorithm while preserving every Legacy decision and business write. **Architecture:** Reuse the existing `fortucky-algorithm` planner as an internal module, but expose it to WMS only through a fail-open shadow gateway. The gateway plans in a separate timed `READ_UNCOMMITTED` transaction; the original Legacy procedures remain unchanged and authoritative. A reduced SQL package installs only read-model and diagnostic objects, creates no Legacy-table triggers, and refreshes its read model in full before planning. **Tech Stack:** Java 17, Spring Boot, Spring JDBC transactions, MyBatis, SQL Server 2016, JUnit 5, Mockito, AssertJ, Maven 3.9.11. ## Global Constraints - Base commit is `origin/main` commit `916ac6bda32a5b102a3181cc8c5dbd5319c5656d`. - No license, TLS, Security, frontend, tidy, replay, PDA, WCS callback, reservation, or ACTIVE workflow integration changes. - Legacy procedures execute exactly once and their current response construction remains authoritative. - Shadow observation is disabled by default and fails open on every runtime error. - Legacy request threads never execute, queue behind, or wait for shadow database work. - A single daemon worker with zero queue capacity admits at most one shadow observation cycle per JVM; busy submissions are dropped. - Installation refuses an existing `alg` schema; uninstall requires the exact package manifest and object allow-list. - Shadow database scripts never insert, update, or delete WMS business rows. - Shadow database scripts never create triggers on WMS business tables. --- ### Task 1: Import the algorithm core without unrelated WMS integration **Files:** - Create: `fortucky-algorithm/pom.xml` - Create: `fortucky-algorithm/src/main/java/com/ruoyi/algorithm/**` - Create: `fortucky-algorithm/src/test/java/com/ruoyi/algorithm/**` - Modify: `pom.xml` - Modify: `ruoyi-admin/pom.xml` - Test: `ruoyi-admin/src/test/java/com/ruoyi/algorithm/shadow/ShadowModuleStructureTest.java` **Interfaces:** - Produces: `WarehouseApplicationService`, `AlgorithmProperties`, and JDBC read-model repository beans. - [ ] Add a Maven structure test that expects `fortucky-algorithm` in the reactor and `ruoyi-admin` dependency graph. - [ ] Run `mvn -pl ruoyi-admin -am -Dtest=ShadowModuleStructureTest test` and confirm RED because the module is absent. - [ ] Import only the algorithm module from `8b84459072fb21a65e11f96e97df14c5b9a340ba`; do not import `ruoyi-license`, UI, WMS workflow, or application bootstrap changes. - [ ] Add the module and dependency using the existing Maven compiler and test plugin versions from `origin/main`. - [ ] Run the focused test and compile reactor; confirm GREEN. - [ ] Commit as `feat: add algorithm core for shadow observation`. ### Task 2: Add the fail-open shadow planning boundary **Files:** - Create: `ruoyi-admin/src/main/java/com/ruoyi/algorithm/shadow/ShadowObservationProperties.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/algorithm/shadow/ShadowSafetyGuard.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/algorithm/shadow/ShadowPlanningEngine.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/algorithm/shadow/ShadowObservationGateway.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/algorithm/shadow/InboundShadowObservation.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/algorithm/shadow/OutboundShadowObservation.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/algorithm/shadow/ShadowStockReference.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/algorithm/shadow/mapper/ShadowInputMapper.java` - Create: `ruoyi-admin/src/main/resources/mapper/algorithm/ShadowInputMapper.xml` - Test: `ruoyi-admin/src/test/java/com/ruoyi/algorithm/shadow/ShadowObservationGatewayTest.java` - Test: `ruoyi-admin/src/test/java/com/ruoyi/algorithm/shadow/ShadowPlanningEngineTest.java` - Test: `ruoyi-admin/src/test/java/com/ruoyi/algorithm/shadow/ShadowSafetyGuardTest.java` **Interfaces:** - Produces: fail-open `planInbound`, `planProjectOutbound`, `planExactStockOutbound`, and comparison methods. - Guarantees: runtime failures return empty observations; planning uses `PROPAGATION_REQUIRES_NEW` with configured timeout. - [ ] Write gateway tests proving disabled/missing engine and thrown planning exceptions return empty observations. - [ ] Run focused tests and confirm RED because gateway types do not exist. - [ ] Implement immutable observation records and the fail-open gateway. - [ ] Run gateway tests and confirm GREEN. - [ ] Write engine tests capturing the transaction definition and asserting `REQUIRES_NEW` plus timeout. - [ ] Run engine tests and confirm RED. - [ ] Implement the planning engine, minimal input mapper, and algorithm request conversion. - [ ] Run engine tests and confirm GREEN. - [ ] Write guard tests proving enabled SHADOW starts while ACTIVE, LEGACY, and disabled database writes are rejected. - [ ] Run guard tests RED, implement the guard, then run GREEN. - [ ] Commit as `feat: add fail-open shadow planning boundary`. ### Task 3: Preserve inbound Legacy behavior **Files:** - Modify: `ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToWmsServiceImpl.java` - Test: `ruoyi-admin/src/test/java/com/ruoyi/api/service/impl/ToWmsServiceImplShadowTest.java` **Interfaces:** - Consumes: `ShadowObservationGateway.planInbound` and `compareInbound`. - Preserves: `MydoJobMapper.allotInJobSpace` invocation count, arguments, return handling, and reloaded Legacy job. - [ ] Write a success test that asserts order: shadow plan, Legacy procedure once, Legacy reload, comparison; assert returned data is the Legacy job. - [ ] Write a failure test where the shadow gateway throws and assert the same Legacy success result and one procedure call. - [ ] Run both tests and confirm RED because the service has no shadow hook. - [ ] Add only pre-procedure observation and post-result comparison around the existing Legacy block; catch gateway failures without changing Legacy branches. - [ ] Run both tests and confirm GREEN. - [ ] Commit as `feat: observe inbound allocation without changing legacy`. ### Task 4: Preserve outbound Legacy behavior **Files:** - Modify: `ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/service/impl/OutStockoutServiceImpl.java` - Test: `ruoyi-admin/src/test/java/com/ruoyi/out/outStockout/service/impl/OutStockoutServiceImplShadowTest.java` **Interfaces:** - Consumes: project/manual shadow planning and comparison methods. - Preserves: `autoAllot` and `manualAllot` calls, loop behavior, warning messages, and return codes. - [ ] Write automatic allocation tests proving missing project data and thrown shadow failures still call `autoAllot` exactly once and preserve the Legacy response. - [ ] Write manual allocation tests proving missing shadow stock data still calls `manualAllot` once per selected stock and preserves the Legacy response. - [ ] Run focused tests and confirm RED. - [ ] Add observation before each original stored-procedure call and comparison afterward without branching on shadow output. - [ ] Run focused tests and confirm GREEN. - [ ] Commit as `feat: observe outbound allocation without changing legacy`. ### Task 5: Add the shadow-only database package **Files:** - Create: `fortucky-algorithm/src/main/resources/db/sqlserver/install-shadow.sql` - Create: `fortucky-algorithm/src/main/resources/db/sqlserver/uninstall-shadow.sql` - Create: `fortucky-algorithm/src/main/resources/db/sqlserver/diagnostics-shadow.sql` - Test: `fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/ShadowSqlServerMigrationScriptTest.java` **Interfaces:** - Produces: read-model tables/views/procedures and decision log; planning performs a full warehouse-scoped read-model refresh. - Excludes: ACTIVE mutation procedures and WMS business-table DML. - [ ] Write static SQL tests with an allow-list for tables, views, and procedures; reject all triggers, dirty queues, tidy/workflow/replay/reservation mutation names, and business-table DML. - [ ] Add an install/uninstall symmetry test and a test requiring initial synchronization plus diagnostic queries. - [ ] Run focused tests and confirm RED because scripts are absent. - [ ] Build the reduced scripts from the reviewed SQL Server 2016-compatible read-model portions. - [ ] Run focused tests and confirm GREEN. - [ ] Commit as `feat: add shadow-only SQL Server package`. ### Task 6: Add field configuration and operating guide **Files:** - Modify: `ruoyi-admin/src/main/resources/application.yml` - Create: `doc/algorithm-shadow/README.md` - Test: `ruoyi-admin/src/test/java/com/ruoyi/algorithm/shadow/ShadowConfigurationTest.java` **Interfaces:** - Produces: disabled-by-default settings and exact IDEA deploy/rollback instructions. - [ ] Write configuration test requiring disabled default, SHADOW mode, write-enabled read model, warehouse fallback, and three-second timeout. - [ ] Run test RED, add configuration, then run GREEN. - [ ] Document backup-copy rehearsal, IDEA dual-workspace deployment, startup checks, data export, fast application rollback, and full SQL uninstall rollback. - [ ] Commit as `docs: add IDEA shadow deployment and rollback guide`. ### Task 7: Remove shadow latency from Legacy threads **Files:** - Create: `ruoyi-admin/src/main/java/com/ruoyi/algorithm/shadow/InboundShadowCompletion.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/algorithm/shadow/OutboundShadowCompletion.java` - Modify: `ruoyi-admin/src/main/java/com/ruoyi/algorithm/shadow/ShadowObservationGateway.java` - Modify: `ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToWmsServiceImpl.java` - Modify: `ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/service/impl/OutStockoutServiceImpl.java` - Test: `ruoyi-admin/src/test/java/com/ruoyi/algorithm/shadow/ShadowObservationGatewayTest.java` - Test: `ruoyi-admin/src/test/java/com/ruoyi/api/service/impl/ToWmsServiceImplShadowTest.java` - Test: `ruoyi-admin/src/test/java/com/ruoyi/out/outStockout/service/impl/OutStockoutServiceImplShadowTest.java` **Interfaces:** - Produces: `observeInbound`, `observeProjectOutbound`, and `observeExactStockOutbound`, each returning a nonblocking completion token. - Guarantees: one daemon worker, `SynchronousQueue`, `AbortPolicy`, no caller-runs fallback, zero queued observations, and background-only comparison. - [ ] Add gateway tests that block the planning engine and prove submission returns before planning completes, a concurrent submission is dropped, and Legacy completion is accepted without waiting. - [ ] Update service tests to require order: observation submission, Legacy procedure exactly once, Legacy reload/result construction, completion-token notification. - [ ] Run focused tests and confirm RED against the synchronous gateway. - [ ] Implement completion tokens and the dedicated executor; catch rejection, timeout, interruption, and runtime failures inside the gateway. - [ ] Replace synchronous plan/compare calls in both Legacy services with submit/complete calls only. - [ ] Run focused tests and confirm GREEN. - [ ] Commit as `fix: keep shadow work off legacy threads`. ### Task 8: Protect SQL package ownership **Files:** - Modify: `fortucky-algorithm/src/main/resources/db/sqlserver/install-shadow.sql` - Modify: `fortucky-algorithm/src/main/resources/db/sqlserver/uninstall-shadow.sql` - Modify: `fortucky-algorithm/src/main/resources/db/sqlserver/diagnostics-shadow.sql` - Modify: `fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/ShadowSqlServerMigrationScriptTest.java` - Modify: `doc/algorithm-shadow/README.md` **Interfaces:** - Produces: manifest id `FT546WMS_SHADOW_ONLY` and version `2026-08-12-1`. - Guarantees: install refuses any existing `alg` schema; uninstall refuses missing/wrong manifest or any unknown top-level `alg` object. - [ ] Add static tests requiring the exact manifest, fail-fast existing-schema guard, uninstall manifest validation, and unknown-object rejection. - [ ] Run the SQL migration test and confirm RED. - [ ] Add `alg.shadow_package_manifest`, fail-fast install guard, and refusal-first uninstall validation before any `DROP`. - [ ] Add manifest output to diagnostics and exact recovery instructions to the field guide. - [ ] Run the SQL migration test and confirm GREEN. - [ ] Commit as `fix: verify shadow SQL package ownership`. ### Task 9: Review, verify, and publish **Files:** - Review all changes relative to `origin/main`. **Interfaces:** - Produces: pushed branch `test/ft546wms-shadow-from-main-20260811`. - [ ] Run focused shadow tests. - [ ] Run full Maven tests with Maven 3.9.11. - [ ] Run `mvn package -DskipTests` and calculate the JAR SHA-256. - [ ] Audit `git diff --name-status origin/main...HEAD` and confirm no forbidden runtime areas changed. - [ ] Request independent code review; fix every Critical and Important finding. - [ ] Re-run full tests and package after review fixes. - [ ] Push the branch to `origin` and retain the worktree for field-test feedback.