fix(shadow): respect queue phases and compress input evidence

This commit is contained in:
zgw
2026-09-08 11:23:50 +08:00
parent 414b3bf4a9
commit af8b5f1830
40 changed files with 1035 additions and 46 deletions

View File

@@ -0,0 +1,27 @@
# FT546 shadow phase and evidence repair
The user approved repairing the five findings in the 2026-09-08 field assessment. Execute in the existing `optimize/wcs` worktree. Subagents inspect/review only; the main agent implements and verifies.
## Constraints and design
- Preserve Java 8, Maven 3.6.0, offline dependencies, the formal Admin/PLC/WMS runtime, existing evidence and SQL permissions. No live migration, deletion, threshold increase or process operation.
- Read queue `issued` and `execution_status` from the existing source views. Only explicit pending `0/1` rows may produce new predictions; executing, completed, unknown and already-arrived phases produce observation evidence. Preserve an existing vehicle binding with a shadow-only assignment adapter. Do not relax busy-vehicle checks.
- Reconstruct legacy PLC endpoints using the actual sending rules, including lift endpoint rewriting and stale path/phase rejection. Observation rows are separate from algorithm differences.
- Store new input JSON losslessly as a versioned gzip envelope; share the first stored input within a save batch through a bounded cycle reference. Preserve original logical hashes. Keep old raw JSON readable. All input rows/references remain in existing tables, in the existing transaction. A loopback input export endpoint returns original JSON with its verified hash, so readers do not need to understand physical storage.
- Configure explicitly approved safe wait/yield site IDs; validate topology membership and safe-exit constraints. Empty configuration remains protected and produces an explicit diagnostic. Never infer physical safety from ordinary passability.
- Publish an embedded repair build ID and a computed digest of nonsecret effective runtime settings independently of operator-supplied artifact/config hashes. Record the required IDEA field correction in the upgrade notes; do not rewrite historical runs.
## Execution checklist
- [x] Baseline `mvn -o -pl ruoyi-wcs-shadow -am test` passes; keep the baseline log outside the worktree.
- [x] Add failing lifecycle and legacy projection tests, including already-issued, completed-at-destination, pending bound vehicle and lift `tsj` cases. Add fields to `ShadowQueueFact`/`SqlServerShadowFactReader`, a shadow eligibility classifier/assignment adapter, and observation support in evidence collection/comparison. Preserve old fixture hashes when new fields are absent; absent lifecycle is observation-only for dispatch.
- [x] Add failing storage round-trip, tamper, inflation-limit, reference, rollback and old-format tests. Implement `ShadowInputPayloadCodec`, repository input resolution and a bounded loopback input endpoint. Budget physical inserted payload while enforcing logical input bounds.
- [x] Add configured-safe-point and invalid-point tests. Wire the settings into `ShadowDispatchSnapshotAssembler` and expose blocked-resource/safe-point diagnostics without enabling unconfigured avoidance.
- [x] Add independent runtime build/config identity tests and wire identity into the status/heartbeat. Document source-only deployment fields and physical input export format.
- [x] Run focused tests after each change, then the full reactor and historical/new captured-input replay. Validate real field inputs remain immutable and incomplete old lifecycle cannot authorize dispatch.
- [x] Run independent read-only review of phase safety and evidence compatibility. Resolve findings, update the runbook and confirm no formal runtime source changes.
- Delivery after this plan snapshot: commit/push the scoped shadow repair under the existing authorization for `optimize/wcs`; record the exact revision in the handoff. Do not deploy remotely.
Implementation decisions: `BaseSRgvThread` passes the live vehicle site to the sender, so bound phase predictions now start there directly. Cross-floor and two-stage handoffs remain observation-only pending state-machine evidence. Reviewer suggestion to reject all lift-entry paths was not adopted: the formal sender explicitly rewrites the endpoint after path construction. Final review identified IPv4-mapped loopback compatibility; a failing regression reproduced it and numeric `InetAddress.isLoopbackAddress` parsing fixes it without DNS or forwarded-header trust.
Private field replay: 25 rows / 17 unique raw inputs preserve their exact JSON and input hashes. New gzip root payloads total 604,048 nvarchar bytes versus 3,294,254 raw bytes (18.34%). This is input payload only, not total SQL allocation. The earlier 300-row archive is no longer at its attachment path; current verification uses the available 2026-09-08 audit exports plus explicit pending lifecycle fixtures.