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

7.4 KiB
Raw Permalink Blame History

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.