skara-brae-common/docs/openup/test/test-report-wi-2-architecture-cleanup.md

65 lines
7.4 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.

# WI-2 Test Report — Architecture Cleanup + OpenUP Work Set (skara-brae-server#2, PSP1)
Date: 2026-10-03 · Phase: CMP + TST · Executor: agent (psp-tester session, Kilo/glm-5.3)
## Scope under verification
- **Code** — `skara-brae-server`, branch `wi-2-architecture-cleanup`, 7 commits over base `899fde8`: `337e9bc` fmt baseline, `093012a` constants module, `423997f` DomainError + signature conversions, `6d9f02b` adventure service, `5d5a594` responses module + handler rewiring, `f065942` label helpers + policy constants, `c613142` 2B findings rework. Working tree clean at verification start.
- **Docs** — `skara-brae-common`, branch `wi-2-openup-docs`, 4 commits: `4798f55` WI-2 OpenUP work set move (verbatim), `2343d5e` WI-1 artifact migration, `7a9a5a3` game-canon migration from Joplin, `41f1ec2` EA model preparation. Working tree clean at verification start.
## Verification gates (CMP)
| # | Command | Result | Evidence (summary line) |
|---|---|---|---|
| 1 | `cargo fmt --check` (server) | **pass**, exit 0 | no output — zero formatting diffs |
| 2 | `cargo clippy --all-targets -- -D warnings` (server) | **pass**, exit 0 | `Finished \`dev\` profile [unoptimized + debuginfo] target(s) in 0.11s` — zero warnings emitted |
| 3 | `cargo build --workspace` (server) | **pass**, exit 0 | `Finished \`dev\` profile [unoptimized + debuginfo] target(s) in 2.13s` |
| 4 | Docs-side sanity (common): `git status --porcelain` clean; `python3 scripts/openup/markdown-to-json.py` regenerates the export | **pass**, script exit 0 | `wrote docs/openup/model/exports/uc-realizations.json: 12 realizations, 36 elements`; sha256 before == after: `23c9617f34ae8e92882b49bfc48c990d9c79d975b9756a93b250391dc3aa6f41` — **byte-identical, no drift**; working tree still clean after regeneration |
## Test matrix (TST)
`cargo test --workspace`: **exit 0 — 71 passed, 0 failed, 0 ignored**.
| Target | Count | Summary line |
|---|---|---|
| sb-api (bin unittests) | 6 | `test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out` |
| sb-core (lib unittests) | 63 | `test result: ok. 63 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out` |
| sb-auth / sb-db | 0 | `test result: ok. 0 passed` (both) |
| sb-shared (lib unittests) | 2 | `test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out` |
| Doc-tests (4 targets) | 0 | all `test result: ok. 0 passed` |
Count reconciliation: 45 baseline (WI-1) + 26 new `#[test]` fns (diff vs `899fde8`: 26 added, 0 removed) = 71.
Coverage classes within the 71:
- **Adventure service vectors A1–A8** (8 new, sb-core `adventure.rs`; mapping per `test-cases.md`): A1 `run_adventure_win_applies_rewards_and_loot` (seeded win → xp/gold/nerve/loot/inventory), A2 `run_adventure_defeat_sets_hp_to_zero`, A3 `run_adventure_rejects_incapacitated`, A4 `run_adventure_rejects_insufficient_nerve`, A5 `run_adventure_applies_regen_before_guards`, A6 `run_adventure_charges_spell_upkeep_on_win_and_loss`, A7 `run_adventure_filters_loot_to_catalog_items`, A8 `run_adventure_is_deterministic_under_seeded_rng`. Targeted run: `cargo test -p sb-core run_adventure_ -- --nocapture` → exit 0, `8 passed; 0 failed … 55 filtered out`.
- **Wire-identity goldens W1–W6** (6 new, sb-api `routes/responses.rs`): all six pass under `cargo test -p sb-api wire_identity_ -- --nocapture` → exit 0, `6 passed; 0 failed`. Representative assertions (responses.rs:156/167/237):
- `assert_eq!(serde_json::to_string(&dto).unwrap(), GOLDEN_W1)` — W1 keys in lexicographic order (`combat_log`, `enemy`, `loot`, `zone`) with nested sorted round/crit keys, pinning the §4.3 `Value` bridge (defect #14).
- `assert_eq!(serde_json::to_string(&dto).unwrap(), GOLDEN_W2)` — `{"gold":123,"healed":true,"hp":45,"max_hp":80}`.
- `assert_eq!(serde_json::to_string(&dto).unwrap(), GOLDEN_W6)` — `{"gold":19700,"learned_count":4,"max_spell_points":40,"spell_points":40}` (incl. the Q1 fenced `learned_count` wart, byte-preserved).
- **Baseline 45 + mechanical edits** — the only permitted test edits were the **9 mechanical assertion updates** from design §4.1 / `test-cases.md` §3. Verified in `git diff 899fde8..HEAD`: 3 × `level_up` (`Err("…")` → `Err(DomainError::AlreadyAtMaxLevel | NotEnoughXp | NotEnoughGold)`), 3 × `train_stat` (`NotEnoughEnergy | NotEnoughGold | InvalidStat`), 1 × `equip_item` (`ItemNotInInventory`), 1 × `unequip_item` (`NothingEquippedInSlot`), 1 × `pick_enemy_respects_weights` gains Ok-path `.unwrap()` (service now `Result`-returning). No test logic changes.
- **New table-coverage / data / spot-check tests** (12 new: 10 sb-core, 2 sb-shared): `gym_display_order_covers_all_training_grounds`, `race_table_covers_all_variants`, `class_table_covers_all_variants`, `crit_tables_parse`, `enemies_json_parses`, `zones_json_parses`, `all_items_json_parses`, `caster_spell_level_spot_values`, `spell_learn_cost_guard_spot_checks`, `spells_json_parses`, `item_type_as_str_matches_serde_wire`, `quality_as_str_matches_serde_wire`.
## Wire-invisible deltas — recorded, verified as documented
Both deliberate semantic deltas from design §4.2/§6 are present in the wired code exactly as recorded (1B review finding 5 dispositions), with no reachable wire-visible change:
1. **Lock consolidation** — the refactored adventure handler holds one write-lock span around the service call (`routes/mod.rs:488`); the dead "character vanished between acquisitions" branch is structurally impossible (no character-deletion path exists). Recorded, not claimed away.
2. **Enemy-pick failure** — data-impossible `DomainError::UnknownEncounterEnemy` maps to `StatusCode::INTERNAL_SERVER_ERROR` (`routes/mod.rs:61`) where the pre-refactor code panicked; same in-memory side effects (nerve already spent).
## Verification limits
- **2B finding #3 evidence limit (docs move):** the verbatim-ness of the OpenUP work-set move from untracked `skara-brae-server/docs/openup/` into `skara-brae-common/docs/openup/` is **not cryptographically verifiable** — the source files were never committed, so no git hash chain exists to diff against. Verification is therefore **content sanity only**: exports regenerate byte-identical from the moved markdown sources (CMP gate 4), the `markdown-to-json.py` invariants hold (12 use cases, 36 realization elements), and the tree is clean. W2–W6 goldens were recorded by the coder per the design protocol (§7: serialized from the pre-refactor `json!` expressions with fixed representative values); **W1 was independently reconstructed by the 2B reviewer** and both agree with the shipped bytes.
- **No manual wire spot-check** was executed (design regression-protocol step 4 is "recommended once", not mandatory); byte-identity of the live HTTP surface rests on the W1–W6 golden tests.
## Platform note
The EA pipeline (`scripts/openup/build-model.ps1`, `export-model.ps1`) is **Windows-gated** (PowerShell + EA COM automation); both scripts are committed but were **not executed on this Linux host** — only the pure-Python intermediate step (`markdown-to-json.py`, stdlib-only) ran. The human gate (design §11.d: EA session, `.eapx` commit) is **pending** and outside this verification's scope.
## Defects found in test phase
None. No defect candidates.
## Verdict
**PASS** — all four CMP gates green (fmt, clippy zero-warning, build, docs drift check byte-identical); all 71 tests green across the workspace; the two recorded wire-invisible deltas verified as documented; docs work set internally consistent. Human EA gate outstanding by design.