Full correctness check against the docs: safer writes, reverts and texts

Safety
- Writes are serialized (Workspace.lock): two background jobs rebuilding one
  package (a sound and its subtitle applied side by side) lost an edit.
- A store copies a bank file or package as "original" only if it matches the
  shipped catalog (Workspace.unoriginal_files: in-memory sounds, bank copies of
  voice lines, subtitles); the editor refuses to switch stores while changes
  are applied. A second store could otherwise resurrect a reverted sound.
- Mod import in the editor asks before overwriting files changed outside the
  tool (it forced silently).
- Revert all in the editor reverts texts too; the uninstaller counts text
  edits before offering to delete the store.
- ackit restore-backup: the full-backup restore decisions.md described; it
  keeps the sounds of WADs without a full copy recorded.
- build_catalog also stops when a subtitle differs from the catalog.

Languages and texts
- Game.language() returns languages without voices (JPN, RUS, ...) and
  Game.voice_archive() their INT voices; ackit text --lang JPN works.
- Menu lookups parse one cached file (find & replace: minutes -> ms).
- Subtitles decode cp1252 as Windows does: the UTF-8-in-cp1252 line
  Speech_TAPE_J_Answer_1_00 (KOR/POL/POR/RUS) is written back byte-for-byte;
  SUB_KOR/SUB_RUS rebuilt from the original game (only those rows changed).
- Mods exported while another language is loaded keep name and line.

Other fixes
- Down-mix folds extra channels in at -3 dB (a 5.1 centre voice was dropped).
- e2e_editor no longer overwrites the user's settings.json; kill_game waits
  for the game to exit before reverts.
- Recorder handles Int32/UInt8 input and split frames; package block cache
  locked; conflict messages, CLI help examples, stale docstrings and doc
  references fixed; tests no longer read this PC's game language.

Docs (decisions, user guide, README, subtitles.md, banks.md, catalog README,
REPORT, NOTES, CLAUDE.md) updated; check_docs: 102 claims match. 148 tests;
e2e_features 9/9, e2e_editor and verify PASS; game original afterwards.
This commit is contained in:
2026-10-13 21:34:13 +02:00
parent a6ef3b9458
commit 1ccaa8b398
41 changed files with 846 additions and 186 deletions

View File

@@ -126,6 +126,42 @@
action bar level with the others; A/B and Loop are icons next to the volume. Fits a 1000-px window
without horizontal scrolling (minimum 984 px). Docs: recordings the game shares between languages (user saw
English lines "leaking" into other languages: the game's own data, banks.md *Lines*).
- 2026-10-13 (user: "full check of the source code for correctness, also against the documentation"): figures
all matched (`check_docs --scan`), the formats code matched the docs; fixed: editor **Revert all** reverted
sounds only (docs and uninstaller promised everything; the uninstaller also counted only sound records and
could offer to delete the store while texts were modified) -> sounds + texts, uninstaller counts texts;
concurrent background writes to one package lost an edit (reproduced) -> `Workspace.lock` serializes every
write; editor mod import forced over conflicts silently -> asks; a second originals store (Settings / `--store`)
copied a package modified by the first as its "original" (reproduced: a replaced sound survived both reverts)
-> `Workspace.unoriginal_files` (catalog checksums, heads, subtitles; 1,447 files, no false alarm, ~15 s for
all) makes it a conflict and the editor refuses a store change while changes exist; `ackit text --lang JPN`
(text-only languages) failed -> `Game.voice_archive`; menu lookups reloaded all ~37 files per call (find &
replace of "the" in INT: ~4 min frozen) -> one cached file per lookup (0.04 s for 1,193 keys);
build_catalog's safety check ignored subtitles -> also compares them; `ackit restore-backup` added (decisions
named a restore that nothing exposed; it also forgot WAD sounds without a full copy); recorder handles
Int32/UInt8 input and split frames; stale docstrings, `ackit -h` examples, conflict message, case-insensitive
Localization path in `verify --catalog`. 146 tests. During the checks an e2e_editor game launch failed
("code never decrypted") and its revert found the WAD still locked by the dying game (left Music_393BC53A
modified; reverted by hand, SFX catalog OK): `debugger.kill_game` now waits until the game has exited.
- 2026-10-13 second full check (user: "do this again to make sure"): codec (wwvorbis, codebooks, allocsize, ogg),
classify vs categories.md, verify harness, tools and widgets re-read; fixed: `tools/e2e_editor.py` saved its own
settings over the user's settings.json (lost store/device/background settings; it now uses the user's
settings and never saves); `Game.language()` ignored languages without voices (a JPN game opened the editor
and `ackit text` in INT; now the game's language, `Game.voice_archive` for its speech archive) and the tests
read this PC's UserEngine.ini (conftest isolates it); a mod exported while another language was loaded lost
name + line of that language's changes (`Workspace.sound_for_key`); down-mix dropped the extra channels (a
5.1 centre-only voice became silent stereo; now folded in at -3 dB, peak-limited); `Texts.for_sound` default
for shared in-memory lines; package block cache locked (concurrent readers); `catalog._whole_recordings` ->
`whole_recordings` in docs/comments; the user guide no longer sends app users to the CLI-only restore.
148 tests.
- 2026-10-13 third check (property checks on the real game data): every menu file rewrites byte-identically,
no ambiguous menu keys, every subtitle copy has the catalog's room; 2 of 103,658 subtitle strings could not be
written back as stored: one line (`Speech_TAPE_J_Answer_1_00`) is UTF-8 bytes in a cp1252 string in KOR, POL,
POR, RUS (the game's data; KOR's damaged), and the RUS/KOR ones contain the 5 bytes Python's cp1252 leaves
undefined (decoded as U+FFFD, lossy) -> cp1252 as Windows maps it (lossless; all 103,658 reproduce), catalog
rebuilt from the original game (`--accept-changes`: exactly those 2 rows changed), subtitles.md documents it
(claim derived by check_docs). User guide: Space plays the replacement once one is loaded (not always the
original); tooltip too. App smoke test on the real game PASS.
- DONE by the user in game: replaced voice lines, edited subtitles and replaced footsteps (after the fill fix).
- OPEN: channel order for >2 channels unverified; 19 speaker labels to check by listening; the Linux build was
never built or run (no Linux here).