Pre-Flight — WP-008 — 2026-06-03

Filled-in copy of docs/reference/pre-flight for WP-008. Verdict at the bottom.

Paired session prompt: session-WP-008-2026-06-03 — operationalizes this artifact for the execution session (drafted after this verdict lands).


Pre-flight intent

Validating readiness for WP-008. Not implementing the parsers, not extracting samples, not editing scooby-exe.md Findings. Verdict only.

Dependency check

WORK_INDEX row for WP-008 shows Deps: — (no strict prereq WPs). WP-003 and WP-007 are recommended-not-strict and both ✅ Done — their outputs are load-bearing inputs for the cross-check (WP-003 name table) and for Scooby.eng spot-checks (WP-007 strings dump).

Prereq Status in WORK_INDEX Locked on Notes
— (strict) n/a n/a WP-008 has no strict prereqs; vacuously satisfied
WP-003 (recommended) ✅ Done 2026-06-02 (commit ee143bf closed; baseline propagated through 9ac3b7f + b279351) Name-table baseline drives Exit criterion #6 cross-check. Extracted name table regeneration recipe lives in tgifile-art.md §Pre-payload region; regen lands at tools/samples/wp003-name-table.txt (gitignored).
WP-007 (recommended) ✅ Done 2026-06-02 (commit 49ad5ee) Strings dump at tools/exes/showdown/strings-ansi.txt is the cross-check input for Scooby.eng spot-checks per EC-004 Step 4.

Repo + disc state

Source binary identity (carry-forward into Findings citations):

File Path Size (bytes) SHA-256
object.ini (Showdown, Gen 1) tools/exes/showdown/object.ini 25,196 027928BB0219B9EADFEC1E066278D9BD3521B48B3E2D420DD7FEA69558A41C49
Scooby.eng (Showdown, Gen 1) tools/exes/showdown/Scooby.eng 2,823 EE9BE93A024FF9B7F5EA1C2445B711FB7C13CEF61A079A4609EDF1201CBAB19B
object.ini (Phantom, Gen 1, stretch) tools/exes/phantom/OBJECT.INI 28,788 67B9EF7967B1EDEB7331D3D41F9EFABC326F4740A6C8D7A8781965CFE9D67870
Scooby.eng (Phantom, Gen 1, stretch) tools/exes/phantom/SCOOBY.ENG 2,823 EE9BE93A024FF9B7F5EA1C2445B711FB7C13CEF61A079A4609EDF1201CBAB19B

Pre-execution finding from the SHA pass. Showdown’s Scooby.eng and Phantom’s SCOOBY.ENG are byte-identical (same SHA-256, same size). The “exact byte-size match” prediction in tools/exes/README §Phantom — Notable findings is now confirmed at the hash level: Gen 1 ships a shared error-string table across both titles. This is a cross-Gen-1 finding that WP-008 §Findings can record verbatim without a Phantom-side parse, sharpening the “Gen 1 share what across titles” picture.

Showdown’s object.ini and Phantom’s OBJECT.INI are different files (different SHAs, 25,196 vs 28,788 bytes) — different games, different room/object counts, expected.

Both Showdown SHAs above are recorded for the first time here; tools/exes/README §Showdown currently mentions the files as cached without listing their hashes. The execution session should propagate these two SHAs into that README in the same commit that closes WP-008.

Scope lock

Anything not explicitly allowed is forbidden.

Allowed paths for WP-008:

tools/parse_ini.py
tools/parse_eng.py
docs/formats/scooby-exe.md
docs/execution-checklists/EC-004-object-ini-catalog.md
docs/reference/pre-flight-WP-008-2026-06-03.md
docs/sessions/session-WP-008-2026-06-03.md
docs/work-packets/WP-008-object-ini-catalog.md
docs/work-packets/WORK_INDEX.md
tools/exes/README.md   (Showdown §Additional cached text files — propagate the two new SHAs; no other section)

Allowed but local-only (never committed; covered by .gitignore on tools/samples/* per the comment block updated in b279351):

tools/samples/asset-catalog.json
tools/samples/unmatched-assets.txt
tools/samples/wp003-name-table.txt   (regenerated input from WP-003 — may already exist locally)
tools/samples/phantom-asset-catalog.json   (conditional — only if the §Notes stretch is exercised; never commit)

Forbidden (any change fails the WP):

Exit check (must run before staging a commit):

git diff --cached --name-only

Any file in the output that doesn’t match the allowed list = scope violation. Remediate with git restore, not by widening the allowlist post-hoc.

Risk review

Risk Likelihood Impact Mitigation
Parser-mode-lock skipped — operator opens tools/parse_ini.py straight into the editor before completing the EC-004 Step 1 survey, writes the parser against a guessed format, finds out mid-Step-3 that asset references are a different shape, has to rewrite. med high EC-004 Step 1 ends in a non-reopenable gate (MODE_A/B/C/D with recorded justification) added in b279351. The session prompt drafted off this pre-flight must cite the gate as a “you MUST not proceed past Step 1 until the mode is recorded” rule. The first Findings line in scooby-exe.md should be the selected mode + one-sentence justification — written into the doc before any parser code is committed.
Output schema drift — parser emits JSON whose shape diverges from WP-008 §Output schema (v1) (e.g. arrays where objects were specified, missing extra_fields for unknowns, drops <asset_ref> whose literal form is the locked mode), breaking the downstream contract with WP-002 probe labeling. med med Schema is locked in WP-008 §Scope → Output schema (v1) (commit b279351). Mitigation in EC-004 Step 5: python -m json.tool validation is a presence check, not a schema check — add a quick sanity assertion in the parser itself that every emitted top-level key matches the v1 contract before writing. The session prompt should require pasting the top-level key list into Step 5 of EC-004 as a recorded artifact.
Silent failure handling — parser logs a warning where WP-008 §Failure handling specifies a hard error (duplicate IDs, unparseable lines in known sections), or vice versa drops extra_fields instead of preserving them. med high WP-008 §Failure handling is explicit (commit b279351): warn / preserve / hard-fail / hard-fail (dup IDs) / hard-fail (malformed JSON). Mitigation: the parser ships with at least one synthetic-input test per policy line — feed it a duplicate ID, confirm non-zero exit; feed it an unknown key, confirm it lands in extra_fields; feed it a malformed section, confirm hard-fail. These run from a pytest-free shell harness so they cost nothing to wire up.
Cross-check metric not computed — Exit criterion #6 turns into a spot-check (“looks like most names match”) instead of the recorded total / matched / unmatched / rate numbers. Loses the load-bearing answer to “is the engine name-driven against TGIFILE.ART?” med high Exit criterion #6 is a numeric contract (commit b279351); EC-004 Step 5 carries the recording slots. The session prompt should require the four numbers to be in the Step 6 Findings note text BEFORE the close commit is staged. A close commit whose Findings note carries any __ placeholder is a process violation.
Generation conflation — Findings stated as “the engine resolves assets via X” when X is Gen-1-specific. The cross-Gen-1 finding (Scooby.eng byte-identical Showdown↔Phantom, recorded above) makes a Gen-1-spanning claim tempting; the parser-resolved interpreter behavior may not generalize past Gen 1. med med Every Findings subsection labeled #### Gen 1 (Showdown) (with a footnote noting Phantom byte-identical Scooby.eng if the stretch was exercised). Gen 2/3 claims are explicitly deferred. The session prompt re-enforces this as a “you MUST…” rule per the pre-flight gate’s common risk shapes.
Phantom stretch creep — operator gets curious, runs the parser on Phantom’s OBJECT.INI, finds something interesting, tries to fold a Phantom Findings table into scooby-exe.md in the same WP. Sprawls scope and entangles WP-006 (Phantom archive-format verification) territory. low med WP-008 §Notes is explicit: Phantom run is stretch and output stays local-only. Findings citations to Phantom are limited to (a) the Scooby.eng byte-identical observation already recorded above (cheap, no parse needed) and (b) a one-line “section structure match: yes/no” if exercised. Anything richer is its own WP.
Copyright leak via catalog JSON content — asset-catalog.json carries verbatim asset-name strings and resolved Scooby.eng text extracted from copyrighted game data. Although the parser scripts and the format-spec Findings are factual/uncopyrightable, the catalog itself is a structured derivative work. med high The §Scope lock allowlist routes tools/samples/asset-catalog.json to local-only. The .gitignore blanket tools/samples/* rule (with the comment-block widened in b279351 to name diagnostic outputs alongside copyrighted artifacts) catches it. Mitigation discipline: git diff --cached --name-only against the allowlist before every commit; the catalog JSON should never appear in the output. Findings prose in scooby-exe.md cites counts and patterns (room count, section structure, match rate), never verbatim asset-string dumps.
WP-002 hand-off naming-rule violated — WP-008 §Notes locks entry_<index>_<sanitized_name>.png for WP-002’s probe_art.py. If the parser emits names whose sanitization rule diverges from the locked one (e.g. lowercases, drops underscores, strips numeric suffixes), WP-002’s output names will diff against expectations and need a backwards-compat shim. low low Sanitization rule is one paragraph in WP-008 §Notes (commit b279351): uppercase preserved verbatim, [A-Za-z0-9_] allowed, anything else → _. The parser implements this once as a documented helper function; the Findings note records 3–5 worked examples (e.g. OBJ_DAPHNE_A → OBJ_DAPHNE_A, hypothetical bg=ghost mine! → ghost_mine_) so a future reader can verify it from prose.

Verdict

Rationale: every section carries concrete content. Dependency check vacuously satisfied on strict prereqs; both recommended prereqs (WP-003, WP-007) are ✅ Done with citations. Disc-on-hand SATISFIED — both Gen 1 discs fully cached, all four source files SHA-256-locked above (two of those SHAs are recorded for the first time here, to be propagated into tools/exes/README §Showdown in the close commit). Scope lock is explicit; the gitignored-output allowlist is consistent with the .gitignore widening landed in b279351. Risk review carries eight concrete mitigations, each tied to a specific WP-008 / EC-004 clause or session-prompt discipline. Spec-drift cross-check row vacuously satisfied and noted explicitly. A bonus cross-Gen-1 finding (Showdown↔Phantom Scooby.eng byte-identical) fell out of the pre-flight SHA pass and is captured here for the execution session to fold into Findings.

Authorization: the executing session may open against the §Scope lock allowlist above. Outputs land per WP-008 §Exit criteria. The §Exit criteria from the WP body govern when the WP can flip to ✅ Done.

Reviewer: Jeff (BarefootBetters) Date: 2026-06-03

A READY verdict authorizes opening the execution session. It does not authorize any change beyond the §Scope lock allowlist.


After execution — lessons learned

The parser-mode-lock gate (Step 1) was load-bearing: walking the file structure manually surfaced the single biggest surprise (no top-level [ROOM_*]/[CURSOR_*]/[INVENTORY_*] sections — everything is [OBJ_*] with ID= discriminators) before any parser code was written, which would have driven a rewrite mid-Step-3 had it been guessed at. The schema-and-failure-handling spec changes that landed in b279351 also held — the four synthetic-input checks shipped without friction and the v1 top-level-key audit caught my first-pass rooms[room_id]["exits"] recursion (storing the destination room as its own exit) before the close commit staged. One minor gap pre-flight could have caught: the cross-check metric threshold language (≥95 % → name-driven) treats “fraction of references that match the TGIFILE.ART name table” as a proxy for “engine is name-driven,” but those are different claims — a low match rate against one name-keyed store doesn’t refute name-drivenness if every reference is still a string. The Findings note addressed this nuance, but a future pre-flight for a similar cross-check WP could spell out the “% match rate vs % string-shaped references” distinction up front.