programs/BUILD_PLAN_END_TO_END.md
Status: ACTIVE, 2026-07-22. Produced by a 8-agent Opus trace (7 lane traces + a synthesis) over BOTH
repos, verified against CURRENT repo state rather than the 2026-07-19 wall list (which is partly
stale — see each lane's already-done list). 137 build items enumerated. Companion to
docs/PIPELINE_READINESS_ROADMAP.md (the gate matrix) and docs/ROADMAP_TO_5090.md (the window plan).
The framing, from Josh: these are not capability blockers. They are engineering. Where a lane
reported "blocked", the trace was required to report WHAT TO BUILD instead.
it is waiting on plumbing that can be written today.
| lane | items | buildable now | 5090 | needs ruling | already done since the audit |
|---|---|---|---|---|---|
| audio | 20 | 15 | 2 | 3 | 10 |
| terrain | 18 | 16 | 1 | 0 | 12 |
| quest | 21 | 18 | 1 | 1 | 12 |
| assetgen | 16 | 12 | 2 | 0 | 13 |
| combat | 22 | 20 | 2 | 0 | 9 |
| ue5 | 21 | 20 | 0 | 0 | 10 |
| cinematic | 19 | 17 | 0 | 1 | 13 |
THE CANON→ENGINE TRUNK, three links, none hardware-gated and none needing a Josh ruling: (1) FREEZE THE COLUMNS — build the missing single-writer for the region page's ## Zone Catalog block (verified today: harness/apply_region_page_sections.py only replaces ### Section N spans and STOPS at the next ## header, so the Zone Catalog at flores_island.md:38 has no deterministic writer at all), then land ONE coordinated column pack across the Zone Catalog and the six pending registry extensions in a single docs/registry_extensions.json + --emit-baseline commit; (2) CODEGEN THE TYPES — docs/REGISTRY_ROW_STRUCT_SPEC.md + Tools/gen_row_struct.py, turning a CSV header into a native USTRUCT : FTableRowBase (only 2 of ~36 exist today: BossEncounterRow.h and ChapterIndexRow.h, both hand-authored and both illegally FString on player-facing columns); (3) BULK-IMPORT — Tools/import_all_registries.py over the already-proven DataTable seam (verified at 79 and 281 real rows).
Why this and not any lane's own pick: five of the seven lanes independently nominated a variant of link (2) or (3) as their critical path (ue5 explicitly, audio "THE ONLY BRIDGE", quest Q-10, assetgen, cinematic), and five nominated a Zone Catalog / registry column add as theirs (terrain zone_bounds_wgs84, ue5 worldcover_biome + zone_anchor_wgs84, audio footfall_surface, combat care_tier + EG_ ids, assetgen mesh_tags/asset_routing). Those are the same two pieces of work seen from six angles. Everything else in all seven lanes is either upstream extraction (extract_spine_rows.py, wanted by three lanes) or downstream runtime — and every downstream item terminates in a row type that does not exist.
Critically, the ENGINE half of this project is far more finished than the wall lists say: the Landscape import shim called "the single highest-priority engineering dependency in the whole chain" is OBVIATED, weightmap painting is exposed, World Partition is exposed, PCG graph authoring is smoke-tested, the Sequencer Lua domain is 6,603 lines of full camera/keyframe/track authoring, the UE-Python bridge is a verified universal vector, and 360 real canon rows are already inside the editor. There is almost no missing CAPABILITY left. What is missing is TYPING: canon that exists as prose and markdown, with no machine column, no row struct, and no emitter to carry it across.
Ranked by (lanes served x unblocking power) / effort. Where several lanes independently named the
same missing thing, that convergence is the strongest signal in the dataset.
| # | build item | serves | effort | gated by |
|---|---|---|---|---|
| 1 | harness/spinelib.py + harness/extract_spine_rows.py — factor the existing spine parsers into an emitter | ue5, cinematic, quest | medium | nothing |
| 2 | harness/extract_zone_catalog.py + harness/apply_zone_catalog_columns.py — the missing single-writer for the '## Zone Catalog' block | terrain, ue5, audio, combat, assetgen, cinematic | small | nothing |
| 3 | The ONE coordinated Zone Catalog column pack (zone_bounds_wgs84, meters_per_vertex, worldcover_biome, footfall_surface, care_tier, asset_routing/asset_category, environment_grammar EG_ refs) + a grammar spec for the value encodings | terrain, ue5, audio, combat, assetgen | medium | nothing |
| 4 | docs/REGISTRY_ROW_STRUCT_SPEC.md — the column→UE-type contract | ue5, audio, quest, assetgen, cinematic, combat | medium | nothing |
| 5 | Tools/gen_row_struct.py — CSV header + sidecar overrides → USTRUCT : FTableRowBase | ue5, audio, quest, assetgen, cinematic, combat | medium | docs/REGISTRY_ROW_STRUCT_SPEC.md |
| 6 | The batched registry-extension pass + ONE fidelity re-baseline (quest-schema-v2 §6.5 ~16 cols · assetgen-pipeline ~8 cols · audio ue_sound_asset_path ×3 · cinematic participant mesh_pipeline_type/ue_asset_path/binding_kind · combat phase_trigger/escalation_vector/signature_counters · SFX schema reconcile · §10.6 sfx_id_ref arrays) | quest, assetgen, audio, cinematic, combat | medium | nothing |
| 7 | Generate + compile + import ~20 row structs; Tools/import_all_registries.py (manifest-driven bulk driver with per-table read-back and non-zero exit on row-count mismatch) | ue5, audio, quest, assetgen, cinematic, combat | medium | Tools/gen_row_struct.py + the column freeze |
| 8 | Tools/gen_gameplay_tags.py + Config/Tags/HumanityCanonTags.ini — canon ids → GameplayTags | combat, cinematic, quest, ue5, audio | small | nothing |
| 9 | UWorldStateSubsystem + FWorldStateValue + UWorldStateSaveGame — run the 3-4-key validation spike FIRST | combat, cinematic, quest, ue5 | large | Tools/gen_gameplay_tags.py |
| 10 | harness/condition_expr.py + docs/CONDITION_EXPRESSION_GRAMMAR.md — ONE grammar, one parser, one evaluator | quest, cinematic, combat | medium | nothing |
| 11 | ONE batched Josh ruling brief (mint the 3 new quest_type game-surface categories · GRAND_SAGE_REVEAL_VOICE retire-vs-rescope · the Ch74→Ch76 endgame residue in T0_Worldstate_Variables + Contract §5.5 and the WS_004 'ALL' selector · Sonniss free-now / BOOM spend decision) | quest, audio, cinematic, combat | small | josh_decision |
| 12 | harness/derive_region_bbox.py + the Section-1 PARAMETERS BLOCK instantiated on all 4 pages (via the existing apply_region_page_sections.py writer) | terrain, ue5 | small | the Zone Catalog column pack |
| 13 | terrain_fetch_preprocess.py hardening: absolute-elevation encoding, rasterio.fill void-fill + automated NASADEM fallback, content-addressed DEM cache + 50-call/24h rate limiter | terrain, ue5 | small | nothing |
| 14 | Tools/landcover_fetch.py (ESA WorldCover 10 m + Sentinel-2 L2A via Planetary Computer STAC) + the WorldCover→material-layer reclass table | terrain, ue5, assetgen | medium | harness/derive_region_bbox.py |
| 15 | Terrain→level chain: target_footprint/tile splitter → Tools/import_landscape.py → Tools/build_region_level.py (World Partition + Data Layers + per-zone PCG volumes) | terrain, ue5 | large | the terrain preprocessing chain |
| 16 | Combat data trunk: HumanityGameplayTags + BossRowParse (port the grammar verbatim from check_boss_axes.py) + AHumanityBossCharacter/ASC bootstrap + the real DT_Boss_Encounter import at 281 rows | combat, cinematic | medium | Tools/gen_gameplay_tags.py + the DataTable import |
| 17 | boss-statetree-framework (schema, Tasks, Conditions, ~30 clocks, evolve-not-swap) + the boss cinematic trigger channel with a console debug emitter | combat, cinematic | large | the combat data trunk |
| 18 | d_local resolver + the four dial GameplayEffects + harness/score_greybox.py | combat | medium | boss-statetree-framework |
| 19 | Audio identity + import: Section-10 machine cue table (template + Flores backfill) → T0_Theme_Registry regional cue rows + adaptive-field population → the SFX path convention → Tools/import_audio_assets.py → Tools/compose_audio_prompts.py | audio, cinematic | medium | the row structs + the Zone Catalog footfall_surface column |
| 20 | Cinematic assembly: T99_Cinematic_Shot_Grammar (11 scene_types) → 11 LS_TPL_* templates via Tools/build_shot_templates.py → Tools/assemble_scene_sequence.py → Tools/render_mrq_dailies.py | cinematic, audio | large | extract_spine_rows.py + FSceneSpecRow |
| 21 | Quest lane land-and-author: docs/quest_dialogue/ + the first DD CSVs → harness/apply_quest_spike.py (25 quests + 17 SQ stages + 88 lines) → the quest_type enum proposal → T99_Translation_Quest.md | quest, audio, cinematic | large | the registry-extension pass + condition_expr.py |
| 22 | AssetGen chain: field-grammar spec → capture_rights register + the §17.1 gate teeth → harness/compose_asset_prompt.py → Tools/mesh_finish.py (Blender 5.1 headless) → Tools/import_mesh_asset.py → harness/apply_mesh_writeback.py → the previz round-trip smoke on one fantastical vril-site asset | assetgen, ue5 | large | external_service |
| 23 | PCG binding: docs/translation/PCG_BINDING_AND_POPULATION.md → PCG_Biome_* template graphs → the zone-polygon → UE-local-ENU → PCG bounds-actor → graph-selection binding → Tools/bake_region_pcg.py | ue5, terrain, assetgen | large | the terrain→level chain + the row structs |
| 24 | Gate pack: harness/check_quest_rows.py · harness/check_asset_pipeline.py · harness/check_scene_spec.py · a Quest lane predicate added to check_build_readiness.py LANES | quest, assetgen, cinematic | medium | the lane content items |
| 25 | Write the 5090 benchmark harnesses NOW, run them on arrival (Gaea-vs-Landmass kill test · 69-region throughput extrapolation · World Partition + PCG runtime cost at the 1 m hero tier · MOSS/ACE-Step scoring rigs · the runtime-inference perf budget) | terrain, ue5, audio, assetgen, combat | medium | nothing (authoring); 5090 to run |
| 26 | The 5090-gated runs themselves (see five090_only) | assetgen, audio, combat, ue5, terrain | large | 5090 |
1. harness/spinelib.py + harness/extract_spine_rows.py — factor the existing spine parsers into an emitter — Three lanes independently named this exact missing tool and it is the cheapest thing on the board because the parsers ALREADY EXIST — verified: check_spine_graph.py carries _sections(), parse_beats(), parse_forks(), parse_file(), _kv_fields(), _bracket_list(), _brace_map() and validates 439 scene rows across 80 spine files, but emits nothing. This is a factoring job plus a CSV writer, not a parsing job. It produces sites/beats/forks/fork_options/scenes/sq/boss-index rows that ue5's hop 2, cinematic's entire lane (3.6% row coverage today: 16 of 439), and quest's realized_beat_refs/objectives_array/fork_option_refs FKs all dead-end without. Factor into spinelib.py so the gate and the extractor can never drift.
2. harness/extract_zone_catalog.py + harness/apply_zone_catalog_columns.py — the missing single-writer for the '## Zone Catalog' block — VERIFIED GAP, and the highest lanes-served-per-hour item in the dataset. The Zone Catalog is a top-level '## ' block (flores_island.md:38, 10 columns) sitting OUTSIDE apply_region_page_sections.py's '### Section N' span logic — that script's own SECTION_RE/TOP_RE explicitly stop at '## '. So six lanes each need to add a machine column to the same table and there is no deterministic writer for it; the alternative is hand-editing flag-prone canon 69 times. Build the reader (emits zones.csv, the FZoneRow source) and the all-or-nothing writer mirroring apply_region_page_sections.py's wrong-place and untouched-drift guards.
3. The ONE coordinated Zone Catalog column pack (zone_bounds_wgs84, meters_per_vertex, worldcover_biome, footfall_surface, care_tier, asset_routing/asset_category, environment_grammar EG_ refs) + a grammar spec for the value encodings — This single table add flips FIVE lanes from BLOCKED to READY on the SAME machine-generated scorecard (harness/build_readiness_scorecard.md), because each lane's readiness predicate is literally asking for one or two of these columns. Doing it as one pass on one rail beats five separate passes: five re-baselines, five template-version bumps, five chances to invent a different serialization for a list-in-a-cell. Pin the encoding once (recommend the in-repo precedent: semicolon-delimited key=value, as T0_Boss_Encounter_Registry.composure_nodes already does) so no consumer invents its own. Keep the existing area_bounds untouched — it is the playable design sizing, a deliberately different number from the real-world extent, and that ratio IS the scale-compression policy.
4. docs/REGISTRY_ROW_STRUCT_SPEC.md — the column→UE-type contract — Named as the #1 wall by ue5 and implied by every other engine lane; genuinely absent (no such file in docs/). Pins: id columns→FName; PLAYER-FACING text→FText (a BINDING localization law that the two existing hand-authored structs already violate on title and boss_name); designer prose→FString; closed enums→UENUM with an FString mirror for lossless round-trip; list columns→FString + a named parse helper; nested objects→FString-holding-JSON + typed accessor; FKs→FDataTableRowHandle. Must also record the two hard-won seam facts (RowName = the first CSV column; UE strips the F prefix, so /Script/Humanity.SceneSpecRow resolves and the F-prefixed path returns None).
5. Tools/gen_row_struct.py — CSV header + sidecar overrides → USTRUCT : FTableRowBase — The single highest-leverage script in the whole plan: it converts an O(34-sessions) hand task that START_HERE has named as 'the standing next build item' on three separate days into one script run plus one compile, and it serves six lanes' row-struct items at once (FCreatureRow, FSceneSpecRow, FQuestDefinitionRow, FThemeRegistryRow, FSFXRegistryRow, FVoiceRegistryRow, FWeaponRow, FVrilSiteRow, FZoneRow, the spine typed layer...). Generate the two WIDEST and most-nested structs first (FCreatureRow at 132 rows, FSceneSpecRow at 31 columns) as the pay-off test.
6. The batched registry-extension pass + ONE fidelity re-baseline (quest-schema-v2 §6.5 ~16 cols · assetgen-pipeline ~8 cols · audio ue_sound_asset_path ×3 · cinematic participant mesh_pipeline_type/ue_asset_path/binding_kind · combat phase_trigger/escalation_vector/signature_counters · SFX schema reconcile · §10.6 sfx_id_ref arrays) — Five lanes each named a registry column add as their own critical path or near it; the rail is BUILT AND PROVEN (verified: docs/registry_extensions.json carries 11 registry keys and 20 owner systems today, with check_registry_extensions.py enforcing single-system ownership). Batching them is not a convenience — every add must refresh docs/fidelity_baseline.json in the SAME commit or the gates go red, so five separate passes means five re-baseline windows and five chances for a stale baseline. Verified state confirming the need: quest registry is still 27 cols / 16 rows with no quest owner key; T0_Familiar_Registry is a ONE-LINE file with no header at all.
7. Generate + compile + import ~20 row structs; Tools/import_all_registries.py (manifest-driven bulk driver with per-table read-back and non-zero exit on row-count mismatch) — The terminal hop every lane's data must cross, over a seam already verified at production scale (DT_ChapterIndex 79×51, DT_BossEncounter 281×26, Unicode preserved). Today every import is a hand-typed command line, against the standing lesson that work-lists must be script-emitted. Expect and fix the real-data issues the smoke never hit at 281+ rows: embedded commas/quotes in prose columns, empty cells, payload size, and the FText import round-trip.
8. Tools/gen_gameplay_tags.py + Config/Tags/HumanityCanonTags.ini — canon ids → GameplayTags — Small, ungated, and structurally must precede anything that keys on a tag, because tags load at engine init only. One derivation covers ws.* (from the 42 live T0_Worldstate_Variables rows — verified populated), thread.T01..T22 (canonicalizing the two live encodings), region.*, and the ruled Boss.Phase.* / Boss.Composure.Node.* / Boss.Win.* / Boss.Shape.* sets. Copy the enum members verbatim from check_boss_axes.py so gate and engine cannot drift. UCombatTelemetrySubsystem::RecordNodeBreak(FGameplayTag) already compiles against a tag table that does not exist.
9. UWorldStateSubsystem + FWorldStateValue + UWorldStateSaveGame — run the 3-4-key validation spike FIRST — FOUR lanes independently name this as a blocker and it exists in none of them (verified: Source/Humanity/Public holds only Combat/ and Data/). It is fully specced by T99_Translation_Combat Step 7 and echoed by UE5 Step 10, and the canon side is ready (42 typed ws rows with defaults, enums and named consumers — WS_017's consumer list literally reads 'Ch76_77_cinematic_dispatcher'). It is ORIGINAL engineering with no Epic reference pattern, which is exactly why the ruled 3-4-key end-to-end spike must precede the ~42-key architecture: four lanes rework if the tagged-union or save shape is wrong. RECOMMENDED: keep mark_write's {community_id, valence, persistence, forward_track[]} in a separate DataTable-backed ledger rather than forcing a record into the scalar map.
10. harness/condition_expr.py + docs/CONDITION_EXPRESSION_GRAMMAR.md — ONE grammar, one parser, one evaluator — The §9.5 mini-grammar is RULED and reconciled across every conditional surface (quest gates, objectives_array.completion_condition, sq_gate_condition, dialogue line-variant selection, scene dispatch, boss phase triggers) but has no EBNF, no precedence, no type rules and no parser — check_spine_graph.py:511 only regex-scans has()/flag() for produce-before-consume. Build the Python reference implementation plus a golden accept/reject corpus harvested from the spine's Block-11 gates and the 88 spike dialogue lines; the C++ evaluator is then a port, not a reinvention.
11. ONE batched Josh ruling brief (mint the 3 new quest_type game-surface categories · GRAND_SAGE_REVEAL_VOICE retire-vs-rescope · the Ch74→Ch76 endgame residue in T0_Worldstate_Variables + Contract §5.5 and the WS_004 'ALL' selector · Sonniss free-now / BOOM spend decision) — Every genuine cardinal-canon item across all seven lanes is small, and there are only four of them. Batched into one brief early they cost a day; drip-fed late they serially block the quest seed-typing for all 69 regions, the first unattended voice batch, and the dispatch resolver binding the wrong chapter's forks. Each goes out per the standing protocol with alternatives, deep-dive, adversarial review, a RECOMMENDATION and the strongest objection — never as a bare question.
12. harness/derive_region_bbox.py + the Section-1 PARAMETERS BLOCK instantiated on all 4 pages (via the existing apply_region_page_sections.py writer) — Once zone_bounds_wgs84 exists this is small and it is the terrain lane's formal exit condition: union the zone polygons with a pad, compute the local UTM EPSG from the centroid, emit region_bbox/utm_epsg/meters_per_vertex/target_footprint/dem_source/water_plane/gaea_pass as machine fields. Supersedes the hand-typed Liang Bua smoke bbox and the now-stale 'the ruled per-region mpv remains a Josh number' prose (D-MPV closed 2026-07-21). Also realign check_build_readiness.py:263, which reads a single Section-1 meters_per_vertex while D-MPV rules mpv PER AOI — a live spec/gate mismatch.
13. terrain_fetch_preprocess.py hardening: absolute-elevation encoding, rasterio.fill void-fill + automated NASADEM fallback, content-addressed DEM cache + 50-call/24h rate limiter — Three small fixes that convert a working one-region hand-driven tool into an unattended 69-region batch. Two are real DEFECTS, not gaps: the per-AOI normalization means adjacent World Partition tiles will not stitch and water_plane in absolute metres is unrepresentable; and np.where(np.isnan(dst), lo, dst) slams every NoData void to the region MINIMUM, manufacturing false craters that only a human eyeballing the Landscape would catch. The cache also makes re-resampling at a different mpv ladder tier free instead of costing one of 50 daily API calls.
14. Tools/landcover_fetch.py (ESA WorldCover 10 m + Sentinel-2 L2A via Planetary Computer STAC) + the WorldCover→material-layer reclass table — The single difference between grey geometry and a painted, vegetated, PCG-populated Landscape — and it is a NEW source integration, not a parameter change: WorldCover is NOT served by OpenTopography's /API/globaldem endpoint, contrary to T99_Translation_Terrain §2 Step 2 (correct that doc in the same pass). Resample onto EXACTLY the Step-3 elevation grid so weightmaps are pixel-aligned with the heightmap by construction. Feeds worldcover_biome (named BLOCKED-ON by the UE5 lane on all four pages), the auto-material, and PCG Biome Core keying simultaneously.
15. Terrain→level chain: target_footprint/tile splitter → Tools/import_landscape.py → Tools/build_region_level.py (World Partition + Data Layers + per-zone PCG volumes) — The script that gets run 69 times, riding seams that are ALREADY VERIFIED — lvl:import_heightmap built a real 379×379 / 36-component Landscape from a 16-bit PNG, and lvl:partition exposes enable/configure_grid/set_streaming/create_layer. This is the driver, not the capability. Carry the recorded quirks: save via UnrealEditorSubsystem.GetEditorWorld → EditorLoadingAndSavingUtils.SaveMap (an untitled map otherwise cannot be saved); call PCGComponent.generate() AFTER actor spawn; screenshot focus_actor='Landscape' fails.
16. Combat data trunk: HumanityGameplayTags + BossRowParse (port the grammar verbatim from check_boss_axes.py) + AHumanityBossCharacter/ASC bootstrap + the real DT_Boss_Encounter import at 281 rows — The first live entity in the game driven by a canon row, and everything upstream of it is done: 281 rows × 26 columns with the five combat columns back-filled, gate-enforced by check_boss_axes.py, FBossEncounterRow compiling, UHumanityAttributeSet carrying all eight Composure sub-nodes. Nothing owns the AttributeSet today — there is no pawn, no ASC, no IAbilitySystemInterface. Prove-out assertion to bake in from the first commit: no code path writes any attribute from the density value.
17. boss-statetree-framework (schema, Tasks, Conditions, ~30 clocks, evolve-not-swap) + the boss cinematic trigger channel with a console debug emitter — The largest zero-built block in a lane where everything around it exists, and the named cross-lane dependency the cinematic lane is blocked on. Ship the tag channel + listener + Humanity.Boss.EmitPhase N debug emitter IN THE SAME WORK so the cinematic trigger path is testable with no boss AI at all — otherwise cinematic parks behind a hard engine constraint it does not need to: UStateTree.EditorData is a protected UPROPERTY unreachable by the py-bridge, so the state GRAPH is an in-editor manual pass. Consider the editor-module StateTree authoring helper before boss #3; hand-authoring 281 phase graphs is the alternative.
18. d_local resolver + the four dial GameplayEffects + harness/score_greybox.py — This is where the project's headline combat thesis becomes observable — one authored boss at two world-tensions with ZERO enemy-stat delta. Route every effect through a UGameplayModMagnitudeCalculation so nothing ever reads raw WS_024 [0,2] against a d_local [0,1] expectation. score_greybox.py closes a live orphan (UCombatTelemetrySubsystem already writes Saved/Telemetry/<session>.json to a consumer that does not exist) and gates SHAPES/RELATIONS/FLOORS only — every-mode-broken, tell-window monotone in d_local, zero enemy-attribute delta across a dial change — logging absolute milliseconds as Phase-5M evidence rather than gating them.
19. Audio identity + import: Section-10 machine cue table (template + Flores backfill) → T0_Theme_Registry regional cue rows + adaptive-field population → the SFX path convention → Tools/import_audio_assets.py → Tools/compose_audio_prompts.py — The cue_id namespace is head-of-chain for the whole audio lane and every hop keys to it, yet half the hardest column already exists as authored canon (Flores pass-2 tagged every track brief {adaptive|loop|oneshot} explicitly 'for Music Step 4 stem-splitting'), so this is largely formalization. Verified state: T0_Theme_Registry has the three ruled adaptive columns but ZERO regional rows and all 12 canonical rows empty on those fields. Publish the per-line voice naming convention (V_<voice_id>__<dialogue_line_id>) in the same pass and hand it to the quest lane as a constraint — the cheapest possible de-risking of the one genuine cross-lane audio dependency.
**20. Cinematic assembly: T99_Cinematic_Shot_Grammar (11 scene_types) → 11 LS_TPL_* templates via Tools/build_shot_templates.py → Tools/assemble_scene_sequence.py → Tools/render_mrq_dailies.py — Materially cheaper than the wall list assumes: NeoStack's Sequencer Lua domain is installed and rich (6,603 lines — bindings with spawnable/possessable, camera_cut/subsequence/audio/animation/property tracks, keyframes with interp, marked frames, plus list() read-back), so the 11 templates are a SCRIPTED authoring task with read-back verification, not hand labour. Shot grammar is creative-within-vision — author the recommendation and apply it. A 720p MRQ daily is the lane's fastest visible artifact and needs nothing external; route MRQ through the UE-Python bridge — MRQ is the one genuinely absent module. CORRECTED 2026-08-13:** MetaHuman and IKRig extension modules ARE present and compiled; see build/ops/NEOSTACK_METAHUMAN_BINDING_2026-08-13.json.
21. Quest lane land-and-author: docs/quest_dialogue/ + the first DD CSVs → harness/apply_quest_spike.py (25 quests + 17 SQ stages + 88 lines) → the quest_type enum proposal → T99_Translation_Quest.md — Content that is ALREADY AUTHORED and critic-gated (four fresh-context critics, unanimous GO-WITH-FIXES, zero reveal leaks) currently has nowhere to land — verified: the registry is still 27 columns / 16 rows and docs/quest_dialogue/ does not exist. Landing it produces the evidence base for the quest_type enum proposal, which schema v0.2.2 §11.1 explicitly OWES from the first quest-writing pass and which unblocks the seed harvest identically for all 69 regions. It also hands the audio lane its named blocker's first real canonical line.
22. AssetGen chain: field-grammar spec → capture_rights register + the §17.1 gate teeth → harness/compose_asset_prompt.py → Tools/mesh_finish.py (Blender 5.1 headless) → Tools/import_mesh_asset.py → harness/apply_mesh_writeback.py → the previz round-trip smoke on one fantastical vril-site asset — Everything external is already in place — Blender 5.1 is installed, the FBX→UE import seam is verified, and NeoStack ships a compiled generative provider layer (Tripo exposing text_to_model, texture_model and highpoly_to_lowpoly retopology). Run the whole chain on ONE asset with zero §17.1 exposure first: its real product is the CORRECTED field set, surfaced before 69 regions inherit a wrong schema. The capture-rights register is non-negotiable and has no substitute — the agent currently cannot distinguish a rights-cleared reference photo from a prohibited one on real heritage architecture.
**23. PCG binding: docs/translation/PCG_BINDING_AND_POPULATION.md → PCG_Biome_* template graphs → the zone-polygon → UE-local-ENU → PCG bounds-actor → graph-selection binding → Tools/bake_region_pcg.py** — The last hop from 'a real landscape' to 'a populated playable zone', and the one place both T99 docs correctly say there is 'no existing product feature to point at'. It is composition over verified primitives (Epic's MCP PCG toolset is smoke-tested end to end; lvl:scatter exists), so the work is the inference layer: terrain_type→template routing with an explicit fallback so an unseen enum never silently no-ops, plus ambient_threat→density, vril_density→creature-tier filter, climactic_affordances→marker class. Author those numbers as illustrative defaults under the tuning firewall and flag for veto — Contracts §0 assigns runtime-parameter inference to the Translation layer, not canon. Treat PCG Biome Core as Experimental v0.2.
24. Gate pack: harness/check_quest_rows.py · harness/check_asset_pipeline.py · harness/check_scene_spec.py · a Quest lane predicate added to check_build_readiness.py LANES — Three lanes ship new content classes with no gate, and the Quest lane is INVISIBLE to the readiness matrix entirely (verified: LANES at check_build_readiness.py:112 is the six other lanes). The house pattern is mature — self-testing both directions, refusing to run if its own teeth are broken, enrolled in gates_config.json — so this is template reuse, not gate design. This is what makes autonomous production authoring at 69-region volume trustworthy rather than spot-checked.
25. Write the 5090 benchmark harnesses NOW, run them on arrival (Gaea-vs-Landmass kill test · 69-region throughput extrapolation · World Partition + PCG runtime cost at the 1 m hero tier · MOSS/ACE-Step scoring rigs · the runtime-inference perf budget) — Benchmark day becomes turnkey instead of a week of rig-building, and several of these are KILL TESTS that could delete work: if Gaea's erosion is not perceptibly better than UE Landmass + auto_paint at the chosen scale, the whole Gaea leg and its license question evaporate. Same shape for the TRELLIS.2 GPU-free licence re-check, which could delete the entire PyTorch3D renderer-swap spike before the hardware arrives.
26. The 5090-gated runs themselves (see five090_only) — Kept last and kept short deliberately. Across seven lanes only ~6 work classes are honestly hardware-gated, and every lane's own trace says so explicitly. Anything else parked here is a real cost.
The highest-value section: a solo builder wins by building the shared thing once.
NSAI_MetaHuman_Integration (938,496 B) and NSAI_IKRig_Integration (927,232 B) are both PRESENT and compiled in Plugins/NeoStackAI/Binaries/Win64/; only an MRQ/MoviePipeline module is genuinely absent from the 64 shipped NSAI integrations. Standardize on the bridge for MRQ alone; MetaHuman and IKRig have working Lua domains today (66 MetaHuman functions enumerated in build/ops/NEOSTACK_METAHUMAN_BINDING_2026-08-13.json). The generalisation was drawn from one stub file in the CORE module and applied to three domains without checking the extension modules — the same class of error as calling a tool limited before diffing its real surface.Anything parked here that could ship now is a real cost, so this list is deliberately short.
Critical path: The Section-10 machine cue table (cue_id + track_type + adaptive_class) added to T1_Region_Page_Template §10 and backfilled into flores_island.md. It is head-of-chain, ungated, and small: it is the ONLY thing that mints a stable cue-id namespace, and every hop downstream keys to those ids — the readiness gate (harness/check_build_readiness.py:317 literally tests for cue_id + track_type), the T0_Theme_Registry regional cue rows, the generation prompt compose, the import path convention, the MetaSound graph, and the Scene_Spec music_cue_id_ref FK. Today the richest region page in the repo (Flores, pass-2 audited) carries a genuinely excellent Section 10 that is 100% prose, so the audio lane reports BLOCKED-ON for the one region that is otherwise fully built. Nothing about this is 5090-gated, canon-gated, or vendor-gated — it is a template edit plus one backfill, and it converts the audio lane from "no addressable unit of work" to "69 regions of enumerable, scriptable work." Second-place item is the trio of C++ FTableRowBase row structs, which is the only bridge from canon CSV into the running game.
CHAIN: canon row -> generation -> UE import -> MetaSounds/Quartz adaptive graph -> audible in PIE.
HOP 1 — Canon substrate (region page Section 10 + Section 17). PARTIAL. C:/dev/humanity-forgotten/_source/02_Tier_2_Region_Pages/flores_island.md:845-868 has a rich, pass-2-audited Section 10 (gong-waning ensemble, Thread-21 vril-active instrument, four named track-type briefs, sound-design enums, voice tiering, a substrate-confidence flag) and it even carries inline adaptive-class tags {adaptive|loop|oneshot} added at pass 2. But it is PROSE. No cue_id, no track_type, no machine table. Only 4 region pages exist at all (angkor_khmer, sumatra_java, bali, flores_island) of 69.
HOP 2 — Canon registries. PARTIAL, three ways.
adaptive-audio owning system. However all 12 rows have those three fields EMPTY, and all 12 rows are canonical themes (protagonist, Velheim, Architect, 3x Cassius, Grand Sage, 3x endings, Vimana, Familiar). ZERO Regional Ambient / Combat Cue / Vril Site Cue rows exist — the entire region-driven music track has no rows.HOP 3 — Readiness gate. EXISTS and is the honest reporter. harness/check_build_readiness.py:313-322 lane_audio demands (a) a Section-10 machine cue table with cue_id + track_type, (b) a per-zone footfall_surface field. Flores has NEITHER, so the pilot region reports BLOCKED-ON. This gate is correct, not stale.
HOP 4 — Cue/roster/bank derivation (the orchestration agent that reads schema-bound fields and composes prompts). MISSING. No script exists in either repo. Tools/ contains only terrain_fetch_preprocess.py, generate_sfx.py, import_registry_datatable.py.
HOP 5 — Generation.
HOP 6 — UE import. EXISTS AND PROVEN, but not yet repeatable. The mp3->SoundWave round trip is real: C:/dev/Humanity/Humanity/Content/Audio/SFX/smoke_stone_door.uasset is on disk, produced via AssetImportTask through the UE-PYTHON BRIDGE (NeoStack execute_script -> PythonScriptLibrary.ExecutePythonCommand), documented at game CLAUDE.md:100-104. But it was a one-off ad-hoc invocation — there is no Tools/import_audio_assets.py, so there is no batch/manifest-driven import for region scale.
HOP 7 — Canon data reaching the running game via DataTable. MISSING — and this is the hard structural gap. Tools/import_registry_datatable.py EXISTS and is verified (game CLAUDE.md:113-119, evidence /Game/Data/Smoke/DT_ImportSmoke), BUT it requires a NATIVE C++ USTRUCT(FTableRowBase) row type per registry — UserDefinedStructs are explicitly a DEAD END on this seam. Source/Humanity/Public/Data/ contains exactly ChapterIndexRow.h and BossEncounterRow.h. There is no ThemeRegistryRow.h, no SFXRegistryRow.h, no VoiceRegistryRow.h. So today ZERO audio canon can reach the engine as data.
HOP 8 — MetaSounds/Quartz adaptive graph. MISSING entirely. No MetaSound Source assets, no tempo/bar Data Asset, no builder script. Spike #5 (MetaSoundBuilderSubsystem "does not support variables") has never been run. Content/Audio/ contains exactly one asset: the SFX smoke test.
HOP 9 — Runtime playback driven by game state. MISSING. No audio subsystem in Source/. Note the natural driver already exists: Source/Humanity/Public/Combat/HumanityDensitySubsystem.h is the ruled vril-density difficulty dial — the obvious input to an adaptive-intensity MetaSound parameter, and an integration seam nobody has claimed.
HOP 10 — Cinematic handoff. PARTIAL (correctly). T0_Scene_Spec_Registry [ACTIVE v0.1] carries every audio FK the contract names: music_cue_id_ref, sfx_category_array, sfx_id_ref_array, voice_refs, dialogue_dataset_ref, audio_priority_layer, scene_audio_intent. thematic_anchor and scene_audio_intent are POPULATED with real content (e.g. SCENE_CH77_FINAL_REVEAL carries ["GRAND_SAGE_REVEAL","PROTAGONIST_THEME"] and "silence holds at recognition moment then GRAND_SAGE_REVEAL theme emerges from PROTAGONIST_THEME echo"). The FK columns themselves are empty/[] — which is the CORRECT state, since no cue exists yet to point at. Schema ready, awaiting hops 1-8.
NET: the two ends of the lane are solid (canon substrate is rich; the UE import seam is proven with an artifact on disk). The entire MIDDLE is missing — there is no machine-readable cue identity, no generation orchestration, no C++ row struct bridge, and no adaptive graph. Nothing in that middle is 5090-gated except the local music/SFX model benchmarks.
Already done since the 2026-07-19 audit (was reported as a wall, is not one now):
adaptive-audio owning system; and tempo_bpm, bar_length, per_stem_role are physically present as columns 23/24/25 in the T0_Theme_Registry CSV header. The T99_Translation_Audio PROPOSED-NOT-RATIFIED hedges at Music Step 4/6 were flipped in place (see the doc's own line 143 note). Residual work is POPULATION (all 12 rows carry empty values), not schema.Genuinely external (not ours to build):
| item | kind | effort | gate | what it is | unblocks |
|---|---|---|---|---|---|
| Section-10 machine cue table (template + Flores backfill) | template_asset | small | nothing_buildable_now | Add a machine-readable cue table to T1_Region_Page_Template [ACTIVE v2.0].md Section 10 (currently line 147-150, which just says 'As v1.0 ... prose briefs'), with columns: cue_id, track_type {regional_ambient/combat/vril_site/cinematic/pers | Flips harness/check_build_readiness.py lane_audio (line 317) from BLOCKED-ON to READY for the pilot region. Mints the cue_id namespace that Theme_Registry regional rows, prompt com |
| Per-zone footfall_surface field | schema_field | small | nothing_buildable_now | Add a footfall_surface enum column to the Zone Catalog row schema in T1_Region_Page_Template, and populate it for every Flores zone (Liang Bua cave, cloud-forest, volcanic, waterfall, village, crater-lake). The gate checks p.zone_catalog + | The second half of the lane_audio gate. Also the SFX Step 1 footstep bank plan, which reads terrain enumeration per T1_Build_Pipeline_Contracts §10.3, and the MetaSounds procedural |
| T0_SFX_Registry schema reconcile to Contract §10.5 | registry_extension | medium | nothing_buildable_now | Resolve the recorded mismatch at docs/PIPELINE_ADAPTER.md:212-214: the live registry is 19 columns and shares only sfx_id/notes/extensions with the Contract §10.5 20-column schema; the ID format is 5-digit (SFX_00001) vs the contract's 4-di | The FSFXRegistryRow C++ struct (you cannot author a row type against an unsettled schema), the §10.6 per-registry array adds, and SFX Steps 1/6. |
| FThemeRegistryRow / FSFXRegistryRow / FVoiceRegistryRow C++ row struct | cpp_code | medium | nothing_buildable_now | Author three USTRUCT(BlueprintType) : public FTableRowBase types in C:/dev/Humanity/Humanity/Source/Humanity/Public/Data/ — ThemeRegistryRow.h, SFXRegistryRow.h, VoiceRegistryRow.h — matching the existing pattern of ChapterIndexRow.h and Bo | THE ONLY BRIDGE from canon audio CSV into the running game. Without these, zero audio canon reaches UE as data — no cue lookup, no SFX bank, no voice roster. Once they exist, Tools |
| T0_Theme_Registry regional cue rows + adaptive-field population | registry_extension | medium | nothing_buildable_now | Mint the region-driven Theme_Registry rows that do not exist today — the registry holds only 12 canonical themes and ZERO Regional Ambient / Combat Cue / Vril Site Cue rows. For Flores, that is 4 rows keyed 1:1 to the Section-10 cue table ( | Gives the adaptive-audio columns any data at all — today the ruled schema is an empty shelf. Feeds Music Step 1 prompt composition and is the input the MetaSound/Quartz graph consu |
| Tools/import_audio_assets.py — batch manifest-driven SoundWave importe | tool_or_script | small | nothing_buildable_now | Promote the proven one-off mp3->SoundWave import into a reusable batch script in C:/dev/Humanity/Humanity/Tools/, following the shape of the existing import_registry_datatable.py. Reads a JSON manifest of {source_file, target_package_path, | Region-scale import. Today the import is proven but ad-hoc (one artifact, hand-invoked), so nothing repeats x69. This is the difference between a demo and a pipeline. |
| SFX UE5 asset path convention — apply the proposed default | spec_doc | small | nothing_buildable_now | T99_Translation_Audio spike #15 flags that music (/Game/Audio/Cues/...) and voice (/Game/Audio/Voice/...) each have a ratified in-project path convention but SFX has only a build-asset-STORE path (/Humanity/build-assets/audio/sfx/), never a | The batch importer's SFX leg and the §10.6 FK wiring both need a stable in-project path to resolve against. |
| §10.6 per-registry sfx_id_ref_array column adds | schema_field | medium | nothing_buildable_now | Add the SFX FK arrays that Contract §10.6 names but that exist on only ONE registry today (T0_Scene_Spec_Registry). Missing: T0_Weapon_Registry.weapon_sfx_id_ref_array; T0_Region_Index three arrays (footstep / environmental_ambient / ritual | Makes every SFX bank entry reachable from its owning entity by a stable FK — the SFX Step 6 'Wire' hop. Without it, imported SoundWaves are orphans no gameplay system can look up. |
| Tools/compose_audio_prompts.py — the schema-bound orchestration agent | tool_or_script | medium | nothing_buildable_now | The missing Hop-3 script. Reads a region's Section-10 cue table + Section 17 substrate + T0_Theme_Registry/T0_Voice_Registry/T0_SFX_Registry rows, and emits per-cue generation prompt objects with a generation_prompt_hash for regeneration de | Music Step 1, Voice Step 2, SFX Step 1 — all three chains' compose hop, which today has no implementation in either repo. |
| MetaSounds + Quartz adaptive-graph spike script | tool_or_script | medium | nothing_buildable_now | Run T99_Translation_Audio spike #5, which has never been attempted. Script a representative 3-4-layer adaptive music graph against the live 5.8 editor via MetaSoundBuilderSubsystem.create_source_builder() / add_graph_input_node() / add_node | The single largest unknown in the lane: whether adaptive music can be automated at 69-region scale or needs a human audio designer per cue. That answer sets the entire music-lane l |
| UHumanityAudioSubsystem — runtime adaptive driver | cpp_code | large | nothing_buildable_now | A UWorldSubsystem in Source/Humanity/Public/Audio/ that owns the Quartz clock, resolves cue_id -> MetaSound Source via the Theme DataTable, and binds live game state to MetaSound graph inputs. The obvious first driver already exists and is | The final hop — audio that RESPONDS in the running game rather than just plays. This is what makes the lane 'closed' rather than 'imports files'. |
| Tools/generate_voice.py — Kokoro local + ElevenLabs TTS legs | tool_or_script | medium | nothing_buildable_now | The voice generator that does not exist — grep for Kokoro across the entire game repo returns zero files, and generate_sfx.py wires only the sound-generation endpoint, not text-to-speech. Build both legs: Kokoro-82M (Apache 2.0, CPU-runnabl | Voice Steps 3 and 4. Also de-risks the Kokoro throughput half of spike #7 (the language half is already answered at 54 voices / 8 languages). |
| Per-line voice asset naming convention — publish a default now | spec_doc | small | nothing_buildable_now | T99_Translation_Audio spike #9 notes the voice-LEVEL path is ratified but the per-line join key is specified nowhere, because the dialogue line-ID format lives in the unauthored Quest Writing §6. RECOMMENDATION (apply, do not ask): define V | Removes the audio half of the cross-lane dialogue dependency BEFORE the quest lane writes a line — the cheapest possible de-risking of the lane's one genuine cross-lane blocker. Pr |
| Demucs orchestral stem-separation fitness spike | tool_or_script | small | nothing_buildable_now | Run spike #3. Demucs (MIT) is the proposed unrestricted stem bridge for bulk-lane cues, but it is trained for pop separation (vocals/drums/bass/other) while an orchestral game score wants section stems (strings/brass/woodwinds/percussion/ch | Decides whether bulk-lane music can ever carry adaptive layering, or whether adaptive cues must come exclusively from AIVA's native compositional Stems export (which would material |
| Local music-generation benchmark (ACE-Step / YuE / HeartMuLa) | tool_or_script | medium | 5090 | Run spike #2, the fixed-test-set protocol named in the Translation Doc: 2-3 representative regional themes plus one hero-adjacent cue, scored on instrumentation fidelity, cultural-substrate accuracy against §2.7, and stem/loop usability — e | The entire bulk regional-music lane at scale (Music Step 3), which covers 69 regions of ambient/combat/vril-site cues. Also settles whether the AIVA external constraint actually ma |
| Local SFX-generation benchmark (MOSS-SoundEffect v2.0) | tool_or_script | medium | 5090 | Run spike #12's MOSS half. MOSS-SoundEffect v2.0 (Apache 2.0, 1.3B, DiT + Flow Matching, 48kHz, 30s) is the ruled primary unrestricted local gap-fill candidate but has no independent non-vendor quality benchmark anywhere in the research. Sc | The zero-marginal-cost SFX fill lane, which is what makes SFX affordable at bestiary/region scale instead of per-call-billed through ElevenLabs. |
| Licensed SFX library acquisition (Sonniss + BOOM) | external_service | small | josh_decision | The ruled licensed-FIRST lane (§1 reconciliation #2 reorders licensed libraries ahead of generation). Sonniss #GameAudioGDC bundles are FREE (2026 bundle ~7.47GB/347+ files, plus a ~200GB free historical archive) — acquire immediately, zero | The high-volume generic categories (generic footsteps per terrain, generic weapon hits, generic foley, generic environmental ambient) with zero generation cost and zero benchmark r |
| GRAND_SAGE_REVEAL_VOICE — retire vs re-scope ruling | josh_ruling | small | josh_decision | GENUINE CARDINAL CANON, correctly escalated. T0_Voice_Registry row GRAND_SAGE_REVEAL_VOICE specifies a full speaking voice (timbre, accent, intensity) for a being that HL_0046 says never speaks — 'visions, intuition pulses, vibrational impr | Removes a live hard-line landmine from any unattended voice batch. Low urgency (the row is quarantined and anchor-free) but it must be ruled before the first autonomous voice run t |
| Creature-vocalization category + T0_Creature_Roster read-source | schema_field | small | nothing_buildable_now | Close spike #13. Contract §10.2's six-category SFX taxonomy (WEAPON, FOOTSTEP, FOLEY, ENVIRONMENTAL_AMBIENT, MAGIC_EFFECT, SPECIAL_ASSET_CLASS) and its §10.3 per-category dependency list never name T0_Creature_Roster as an input to ANY cate | Lets SFX Step 1's bank plan enumerate the 132-creature bestiary at all — today creature vocalization is schema-invisible and would be silently dropped by any automated bank planner |
| Krotos creature-lane tooling + seat-hour budget | external_service | large | josh_decision | Spikes #14 and the SFX Step 4 lane. Krotos Dehumaniser 2 + Reformer Pro ($399 each, perpetual, ROYALTY-FREE-OWNED) are the ruled creature-design tools, and the workflow is explicitly sound-designer-in-loop craft (three-layer model: low-end | The bestiary's audio. Flagging honestly: this is the one part of the audio lane that does not automate and cannot be closed by engineering — it needs either purchased seat-hours or |
Critical path: Georeferenced per-zone bounds (zone_bounds_wgs84 on the Zone Catalog). Every downstream terrain hop consumes a world position: region_bbox is spec'd as "derived — union of zone area_bounds" (T99_Translation_Terrain §3) but today's area_bounds is local-ENU size-only prose ("220×180×60 karst interior"), which the readiness gate's _GEOREF regex explicitly rejects ("Size-only bounds never match", check_build_readiness.py:120-123), so the union cannot be computed at all. Without it: the DEM fetch AOI must be hand-typed per region (the Liang Bua smoke bbox was), the alteration_list carve footprints have no polygon to rasterize, the WorldCover weightmaps have no grid to align to, the PCG zone-bounds actors have no polygon to place, and the UE5 lane's own BLOCKED-ON row ("georeferenced zone bounds (area_bounds is size-only, no world position)") does not clear either. It is one column on a template plus ~11 real-site coordinate lookups per page — it is NOT canon invention (Liang Bua, Kelimutu, Wae Rebo, Todo are real published places; the chapter/site assignment is already canonical and untouched), so it needs no Josh ruling, and it is the single item that converts the terrain lane from a hand-driven one-region smoke into an unattended 69-region batch.
CANON ROW -> RUNNING GAME, hop by hop. Verified against the repos on 2026-07-22, not against the 2026-07-19 wall list.
H1. Canon row exists. EXISTS — registries/T0_Region_Index [ACTIVE v1.2]/T0_Region_Index DRAFT v1.1.csv (flores_island row) + the Zone Catalog on _source/02_Tier_2_Region_Pages/flores_island.md (11 typed zone rows, joined VERBATIM from spine §3b). Four pages exist: flores_island, bali, sumatra_java, angkor_khmer.
H2. Zone row -> WGS84 georeferenced polygon. MISSING — the Zone Catalog area_bounds column carries local-ENU DESIGN SIZINGS only ("220×180×60 karst interior + 400 m forest approach", "compang center-stone + lodok fan ~500×500"). The page itself says these are "first-pass design sizings (meters, local ENU origin at the region center)". T0_Region_Index.coordinates holds a free-text DMS POINT ("8.5333°S 120.4400°E (Liang Bua); 8.6110°S 120.4689°E (Ruteng)"), not a bbox and not decimal-parseable. Gate confirms: harness/build_readiness_scorecard.md UE5 row, all 4 pages — "georeferenced zone bounds (area_bounds is size-only, no world position)".
H3. Zone polygons -> region_bbox. MISSING — T99_Translation_Terrain §3 declares region_bbox "derived — union of zone area_bounds + region-ambient rows; not separately authored", but H2 supplies no georeference to union. The only real Flores bbox in the repo is PROSE inside a "Recorded build output (terrain smoke)" bullet (flores_island.md:110), hand-typed into the smoke run, not a machine field. Live gate, all 4 pages: "BLOCKED-ON(Section-1 region_bbox machine field (WGS84))".
H4. meters_per_vertex assignment. PARTIAL — the POLICY is RULED and the wall is stale: D-MPV = Option C, tiered ladder (1 m hero set-piece / 2 m standard playable / 5-10 m ambient-vista), Josh 2026-07-21, recorded in docs/spine/DECISIONS_PENDING_JOSH.md:90-92 and applied into T99_Translation_Terrain §1/§5 item 1. What is MISSING is (a) the per-AOI value assignment on any page and (b) the machine field. Also a live SPEC/GATE MISMATCH: check_build_readiness.py:263 reads a single Section-1 meters_per_vertex, but D-MPV rules mpv PER AOI — so the ruling now wants a per-zone column the gate cannot see.
H5. DEM fetch (OpenTopography COP30). EXISTS — C:/dev/Humanity/Humanity/Tools/terrain_fetch_preprocess.py lines 59-68; key IN and probe-verified, read from env with an HKCU registry fallback (lines 28-37); Liang Bua proven (371×372).
H6. Reproject / resample to local UTM. EXISTS — same tool, lines 70-80, calculate_default_transform + reproject at resolution=(mpv,mpv), bilinear.
H7. Mosaic across DEM tiles / clip to zone polygon. MISSING — the tool fetches ONE GeoTIFF for ONE hand-typed bbox. No gdal_merge mosaic leg, no clip-to-polygon (H2 blocks it anyway).
H8. Void / NoData handling + DEM fallback trigger. MISSING (and actively defective) — line 85 np.where(np.isnan(dst), lo, dst) slams every void to the REGION MINIMUM, manufacturing false pits rather than filling. No rasterio.fill.fillnodata, no void-fraction metric, and therefore no automated NASADEM fallback trigger (T99 §5 item 5's named unknown).
H9. Alteration / carve-composite recipe layer. MISSING on both halves — no alteration_list instantiated on ANY of the 4 pages (grep for alteration_list across _source/02_Tier_2_Region_Pages/ returns zero), and no carve script exists in Tools/ (only 3 files: terrain_fetch_preprocess, generate_sfx, import_registry_datatable). T0_Vril_Site_Registry carries no footprint column by design — the page must supply WHERE.
H10. Era-modification pass (sea level, coastline, deforestation reversal, volcanic state). MISSING — present as Section 1 PROSE on flores (lines 114-121: deep-time sea-level shift, pre-colonial forest reversal, live geothermal) but never structured into the §3 era_modifications field and no raster pass consumes it.
H11. Gaea detail synthesis. MISSING — not installed, no .tor graph, CLI-tier ($99 Indie vs $199 Pro) unconfirmed with QuadSpinner. Note this step is OPTIONAL by spec (gaea_pass is a bool, "false only where relief is negligible") — it does not gate the chain.
H12. 16-bit heightmap emit + Z-scale. PARTIAL — emit EXISTS (tool lines 86-94, uint16 PNG + ue_landscape_z_scale = rng/512*100). DEFECT for the multi-tile path: the encoding is NORMALIZED PER-AOI ((dst_filled-lo)/rng), so every tile of a region gets its own independent lo/rng. Adjacent World Partition tiles will therefore NOT stitch (visible seams), and water_plane in absolute meters is unrepresentable. Fine for the single-actor Liang Bua smoke; wrong the moment a region tiles.
H13. target_footprint / World Partition tiling math. MISSING — nothing computes vertex count from bbox×mpv, nothing decides single_tile vs N-tile against the 8,129-vertex actor cap, nothing splits the PNG into tiles.
H14. Landscape creation from heightmap file. EXISTS — and this retires the wall list's top terrain engineering dependency. T99_Translation_Terrain §5 item 8 calls a C++ ALandscape::Import() shim "the single highest-priority engineering dependency in the whole chain"; it is OBVIATED. NeoStack exposes lvl:import_heightmap({file, scale, location}) as a level-handle method that builds a real Landscape directly from a 16-bit PNG (game CLAUDE.md:105-112, VERIFIED 2026-07-20; Liang Bua 371×372 -> 379×379, 36 components). Binding source: Plugins/NeoStackAI/Source/NeoStackAI/Private/Lua/Bindings/LuaBinding_LevelDesign.cpp:3463, backed by LandscapeImportHelper.h.
H15. Repeatable scripted import. PARTIAL — the seam is verified and was driven BY HAND once. No Tools/import_landscape.py exists (the pattern to copy is Tools/import_registry_datatable.py, which does exactly this shape over the same NeoStack channel).
H16. WorldCover / Sentinel-2 fetch. MISSING — T99 §2 Step 2 says "same-session calls also fetch ESA WorldCover 10 m and Sentinel-2 L2A", but the tool fetches DEM ONLY. Note a spec error worth catching: WorldCover is NOT served by OpenTopography's /API/globaldem endpoint, so this is a NEW source integration (Terrascope / AWS Open Data / Planetary Computer STAC), not a parameter change.
H17. WorldCover -> material-layer reclass + worldcover_biome. MISSING — no reclass table for the 11 WorldCover classes, and no worldcover_biome column on any Zone Catalog (live gate names it on all 4 pages).
H18. Weightmap import onto the Landscape. EXISTS (seam) — second stale-wall correction. T99 §2 Step 8 carries a caveat about "no first-class public painting API"; that is obsolete for THIS project. NeoStack exposes import_weightmap({file, landscape, layer, region}) for 8-bit grayscale PNGs (LuaBinding_LevelDesign.cpp:345, :3613), plus create_landscape_layer, paint, auto_paint (slope/height rules), get_weightmap, and edit_layer. What is MISSING is only the upstream rasterizer that PRODUCES the per-layer PNGs (blocked by H16/H17).
H19. World Partition enable / grid config / data layers. EXISTS (seam) — lvl:partition("enable" | "configure_grid" {cell_size, loading_range} | "set_streaming" | "create_layer" | "add_to_layer" | "set_layer_state") (LuaBinding_LevelDesign.cpp:453-463). Unexercised for terrain, but present.
H20. PCG biome population keyed to zone polygons. PARTIAL/MISSING — Epic's ModelContextProtocol PCG toolset is SMOKE-TESTED end to end (CreateGraph -> AddNode -> ConnectNodePins -> GetGraphStructure, saved at /Game/Data/Smoke/PCG_HelloGraph, game CLAUDE.md:91-99), and lvl:scatter exists. MISSING is the binding layer T99 §5 item 9 flags as having "no existing product feature": no terrain_type -> PCG-template table, and no zone-polygon -> PCG bounds-actor -> graph-selection mechanism (also blocked by H2's missing polygons).
NET SHAPE: the ENGINE half of this lane is substantially more complete than the roadmap says (H14, H18, H19 all verified seams; the "highest-priority C++ shim" is unnecessary). The lane's real remaining work is CANON-SIDE structuring (H2, H3, H4, H9, H10, H17) and PYTHON PREPROCESSING (H7, H8, H12-defect, H13, H16), plus one binding layer (H20). Nothing on the critical path is 5090-gated.
Already done since the 2026-07-19 audit (was reported as a wall, is not one now):
Genuinely external (not ours to build):
| item | kind | effort | gate | what it is | unblocks |
|---|---|---|---|---|---|
| zone_bounds_wgs84 column on the Zone Catalog | schema_field | medium | nothing_buildable_now | Add a machine column carrying real-world WGS84 geometry per zone row, ALONGSIDE (not replacing) the existing design-sizing area_bounds. Format: either 'center:LAT,LON;radius_m:N' or a polygon vertex array 'LAT LON; LAT LON; ...' in decimal | Everything downstream: region_bbox derivation, unattended per-region DEM AOI requests, alteration_list carve footprints, WorldCover weightmap grid alignment, PCG zone-bounds actors |
| harness/derive_region_bbox.py | tool_or_script | small | nothing_buildable_now | A new harness script that parses zone_bounds_wgs84 out of a page's Zone Catalog, unions them with a configurable pad (default ~10 percent), and emits south/north/west/east in decimal degrees plus the correct local UTM EPSG computed from the | The Section-1 region_bbox machine field on every page without hand-typing a bbox per region (the Liang Bua bbox was hand-typed into the smoke run); makes the 69-region AOI set repr |
| Section-1 PARAMETERS BLOCK instantiated on all four region pages | template_asset | small | nothing_buildable_now | Turn T99_Translation_Terrain §3's specified-but-never-instantiated table into an actual machine block at the head of '### Section 1 — Geography and Topography', written via the existing safe writer harness/apply_region_page_sections.py. Key | Flips the Terrain lane from BLOCKED to READY on harness/build_readiness_scorecard.md for all four pages — the lane's formal exit condition. |
| Per-AOI meters_per_vertex column + realign the readiness gate to D-MPV | registry_extension | small | nothing_buildable_now | Two coupled edits closing a live spec/gate mismatch. (1) Add a meters_per_vertex column to the Zone Catalog and assign each zone a D-MPV ladder value — 1 m for hero set-pieces (liang_bua_cave, the Kelimutu cavern climax pocket, wae_water_sp | Makes Step 3's resample resolution deterministic per AOI, from which every other number derives (Z-scale, tile count, World Partition cell count, erosion budget); removes the last |
| Absolute-elevation heightmap encoding in terrain_fetch_preprocess.py | tool_or_script | small | nothing_buildable_now | Fix a real defect that only bites once a region tiles. Tools/terrain_fetch_preprocess.py:82-94 normalizes per-AOI — h16 = (dst_filled - lo)/rng * 65535 — so every tile computes its OWN lo and rng. Adjacent World Partition tiles will not sti | Seamless multi-tile World Partition regions; a meaningful absolute water_plane; cross-region elevation comparability. |
| Void-fill + automated DEM fallback trigger | tool_or_script | small | nothing_buildable_now | Replace terrain_fetch_preprocess.py:85's np.where(np.isnan(dst), lo, dst) — which slams every NoData void to the region MINIMUM and manufactures false pits — with rasterio.fill.fillnodata interpolation. Then add the void-fraction metric tha | Unattended 69-region batching — today a voided DEM would silently produce a terrain crater that only a human eyeballing the Landscape would catch. |
| alteration_list instantiated on the region pages | schema_field | medium | nothing_buildable_now | Instantiate T99_Translation_Terrain §3's specified-but-empty carve/composite schema as a real table in Section 1: zone_id / site_id (FK -> T0_Vril_Site_Registry) / operation {carve, composite, raise, flatten} / footprint (WGS84 polygon) / d | The Step-4 alteration engine; closes the second of the three named terrain walls. |
| Tools/terrain_alter.py — the carve/composite engine | tool_or_script | medium | nothing_buildable_now | The scripted, re-runnable Step-4 leg. Reads the alteration_list rows, reprojects each WGS84 footprint into the working UTM raster CRS, burns it with rasterio.features.rasterize, applies the operation enum (carve = subtract depth_m, flatten | Fantasy/vril-site geometry actually existing in the terrain rather than only on the page; era_modifications reuses the same mechanism. |
| era_modifications structured field + era raster pass | schema_field | medium | nothing_buildable_now | Structure what is currently Section-1 prose (flores lines 114-121: deep-time sea-level and coastline shift at the Homo floresiensis stratum, pre-colonial deforestation reversal at the lingko edge, live volcanic/geothermal state) into the §3 | Time-fluctuation windows rendering as actual different terrain rather than narrative assertion; a per-era heightmap variant set per region. |
| target_footprint computation + World Partition tile splitter | tool_or_script | medium | nothing_buildable_now | The missing sizing math. Given region_bbox and the per-AOI mpv ladder, compute the required vertex grid, compare against the 8,129-vertex single-actor cap, and emit target_footprint as either single_tile or world_partition_NxM with an expli | Any region larger than a single Landscape actor — i.e. most of the 69, since Flores at 2 m/vertex over its real bbox already blows past one actor. |
| Tools/import_landscape.py — scripted Landscape + World Partition impor | tool_or_script | medium | nothing_buildable_now | Turn the hand-driven Liang Bua import into a repeatable script, modelled directly on the proven Tools/import_registry_datatable.py (same NeoStack channel, same shape). Reads the tile manifest + meta JSON, calls lvl:import_heightmap per tile | Unattended region-to-Landscape import; makes the 69-region throughput benchmark measurable at all. The seam is already VERIFIED — this is only the driver. |
| WorldCover + Sentinel-2 fetch leg | tool_or_script | medium | nothing_buildable_now | Build the landcover half of Step 2, which does not exist and cannot be a parameter tweak: ESA WorldCover 10 m and Sentinel-2 L2A are NOT served by OpenTopography's /API/globaldem endpoint, contrary to T99 §2's phrasing. Integrate a real sou | Material weightmaps, PCG biome keying, and the Sentinel-2 base-albedo option — i.e. the entire difference between grey geometry and a populated, painted, vegetated Landscape. |
| WorldCover reclass table + worldcover_biome Zone Catalog column | spec_doc | small | nothing_buildable_now | Author the mapping from WorldCover's 11 classes (tree cover, shrubland, grassland, cropland, built-up, bare/sparse, snow/ice, permanent water, herbaceous wetland, mangrove, moss/lichen) to the project's material-layer taxonomy, as a version | Weightmap generation, PCG graph selection, and the UE5 lane's worldcover_biome block simultaneously — a cross-lane unlock for one small table. |
| Weightmap rasterizer + scripted paint-layer import | tool_or_script | medium | nothing_buildable_now | Produce one 8-bit grayscale PNG per material layer on exactly the heightmap grid (that is the format NeoStack's import_weightmap takes), then drive lvl:create_landscape_layer + lvl:import_weightmap per layer from a script. Include a soft-bl | A painted, materially-correct Landscape rather than a default-material grey mesh — the visible half of Step 8's terminal state. |
| Zone-polygon -> PCG bounds-actor -> graph-selection binding | tool_or_script | large | nothing_buildable_now | The one genuine architecture build in this lane — T99 §5 item 9 correctly notes 'no existing product feature to point at'. Three parts: (a) a WGS84 -> UE local-ENU transform so a zone polygon becomes UE world coordinates relative to the Lan | Foliage, props, and encounter volumes populating per zone according to canon rather than uniformly — the last hop from 'a real landscape' to 'a populated playable zone'. Also the s |
| DEM cache + OpenTopography rate limiter | tool_or_script | small | nothing_buildable_now | A content-addressed local cache keyed on (demtype, bbox rounded to a fixed precision) so re-runs, retries, and per-AOI mpv re-resamples never re-hit the API, plus a call-budget tracker that respects the 50-calls/24h non-academic cap and fai | Multi-day 69-region batching without quota exhaustion; makes re-resampling at a different mpv ladder tier free instead of costing an API call. |
| Gaea erosion leg — .tor graph + CLI wrapper | external_service | medium | external_service | Author the Gaea erosion/thermal/snow graph as a parameterized .tor and wrap the CLI so Step 5 runs headless between the alteration pass and the 16-bit emit, honoring the per-AOI mpv and Real Scale. Blocked on one external answer: whether he | Sediment, scree, and meandering-river detail a raw 30 m COP30 source cannot contain — quality, not capability. |
| Terrain benchmark protocol — Gaea-vs-Landmass and 69-region throughput | tool_or_script | medium | 5090 | The honestly 5090-gated slice, scoped now so benchmark day is turnkey. Three measurements: (1) Gaea Real-Scale erosion vs UE Landmass + auto_paint at 1 m and 2 m mpv on the same Flores AOI, scored for perceptible difference — the documented | The Step-5 keep-or-drop decision, a defensible 69-region schedule, and the mpv ladder's performance validation. |
Critical path: Q-1 — the T0_Quest_Definition_Registry schema extension: append the ~16 already-ruled §6.5 columns to the live CSV, declare them under a 'quest-schema-v2' owner in docs/registry_extensions.json, and refresh docs/fidelity_baseline.json in the same commit. It unblocks the most by a wide margin, and it is the single item where the gap between the spec and the data is pure mechanical work. The §6.5 spec is COMPLETE and RULED — the contract closed 30 of the spike's 32 gaps across the 2026-07-20 mechanical pass and the 2026-07-21 director pass — but the live registry is still the original 27-column, 16-row table with no extension declared anywhere (verified: no quest key in registry_extensions.json, no quest entry in fidelity_baseline added_columns). Until that column set exists: the 25 critic-gated quests and 88 dialogue lines already authored in the spike have nowhere to land; FQuestDefinitionRow cannot be authored because the column set is not final; the verified DataTable import seam has no table to import; check_quest_rows.py has nothing to validate; and Q-7 — the quest_type enum proposal that schema v0.2.2 §11.1 explicitly assigns to the first quest-writing pass, and which unblocks the seed harvest for all 69 regions — has no authored rows to argue from. It needs no hardware, no external service, and no Josh ruling: every column is already ruled contract text. It is a day of careful mechanical work standing in front of the entire lane.
CHAIN: spine beat row -> quest-authoring pack -> authored quest row -> T0_Quest_Definition_Registry -> DD dialogue CSV -> C++ USTRUCT -> UE DataTable -> runtime quest/dialogue subsystem evaluating condition_expression against worldstate.
HOP 1 — Spine beat graph as the authoring skeleton. EXISTS. docs/spine/CH_NN.md x79, v3.1 twenty-block form: beat rows (Block 10, beat_id CH0N_BNN, permanence absolute), fork graph (Block 10b, three closed table grammars CHOICE-8 / DISPATCH-7 / SIX-OPTION-7), site rows (Block 8/§3b site_id), SQ rows (Block 11 sq_stage + gate), scene rows (Block 13 seven-column). Validated by harness/check_spine_graph.py.
HOP 2 — Extract spine rows into machine form. MISSING as a tool. check_spine_graph.py parses every one of those tables but only to validate; it emits no CSV/JSON. harness/enrich.py is chapter-scoped for SPINE authoring (enrich.py chapter CH_NN --json) and has no quest mode. harness/extract_claims.py extracts claims, not spine rows. The roadmap §3 "spine-row extractor does not exist" wall is STILL TRUE and it bites this lane as hard as the ue5 lane — realized_beat_refs, objectives_array.beat_ref, spatial_requirements_array.site_ref and fork_option_refs are all FKs into rows no tool emits.
HOP 3 — Region substrate for regional quests. PARTIAL. Region pages exist (flores_island, bali, sumatra_java, angkor_khmer). The book->seed feed is LIVE: docs/proposals/quest_seed_queue/<region>.md (12 regions; 71 audited flores seeds) regenerated by harness/rag/deep_read.py from docs/book_extractions/EXR_*.json. MISSING: the typed Section-13 seed stub (CG-22, ruled) is instantiated on no page, so seeds have no typed landing and the §7.5 typing step has no target schema.
HOP 4 — Author the quest. PARTIAL/PROVEN. The Ch 2-5 SPIKE RAN (roadmap queue #1): docs/proposals/quest_spike/CH_02..CH_05_quests.md + SPIKE_REPORT.md — 46 beats decomposed, 25 main quests, 17 SQ stages, 88 dialogue lines, four fresh-context critics, all GO-WITH-FIXES, zero reveal leaks, zero §17.1 community-targets. It is proposal-tier markdown, not rows.
HOP 5 — Land the quest row. PARTIAL — THE BREAK. Schema T1_Build_Pipeline_Contracts §6.5 is now FULLY SPECIFIED (mechanical completion pass 2026-07-20 + director pass on the 2026-07-21 ruling batch closed 30 of the spike's 32 gaps). But the LIVE CSV registries/T0_Quest_Definition_Registry [ACTIVE v1.0]/T0_Quest_Definition_Registry.csv still carries the OLD 27 columns and 16 rows. The ~16 new typed fields (encounter_facet, sq_stage, sq_gate_condition, quest_giver, trigger_type, realized_beat_refs, objectives_array, completion_condition, fail_state, progression_guarantee, state_writes, fork_option_refs, reward_class, ability_unlock_refs, reward_drop_refs, reward_seed_refs) have NO column, NO owner entry in docs/registry_extensions.json (verified: no quest key), and NO added_columns entry in docs/fidelity_baseline.json (verified: empty match). Authored content has literally nowhere to land.
HOP 6 — dialogue_dataset. FORMAT RESOLVED / FILES MISSING. §6.5 pins it: one CSV per quest at docs/quest_dialogue/DD_<quest_id>.csv, columns line_id, speaker_ref, trigger_beat, line_text, condition_expression, loc_namespace_key; extension pinned to csv; per-quest not per-character. The dead Drive path and the canon/dialogue_datasets/ proposal (PIPELINE_ADAPTER L120) are both SUPERSEDED. Verified: docs/quest_dialogue/ does not exist, zero DD_* files anywhere in the repo, and no writer or validator exists.
HOP 7 — condition_expression. GRAMMAR RESOLVED / NO PARSER. §6.5 reconciled every conditional surface (quest gates, objective completion_condition, sq_gate_condition, line-variant selection) onto the SINGLE §9.5 mini-grammar: has(local.k), at(site_id), flag(local.k), ws.key with == >= <= in, read(surface), boolean & and |, produce-before-consume. Documented in Contracts §9.5 + SPINE_SCHEMA_v3. MISSING: no EBNF, no operator precedence, no type rules for comparing against a WS_NNN domain, and no parser — check_spine_graph.py:511 only regex-scans (has|flag)\(local\.x\) for produce-before-consume. Nothing can evaluate an expression.
HOP 8 — Registry -> UE DataTable. SEAM EXISTS, ROW TYPES MISSING. C:/dev/Humanity/Humanity/Tools/import_registry_datatable.py is VERIFIED end-to-end over the NeoStack MCP channel (:9315, create_asset 'datatable' with option key Struct = a NATIVE /Script/... USTRUCT, FillDataTableFromCSVString, read-back, save). Two registries already landed: Content/Data/Registries/DT_BossEncounter.uasset, DT_ChapterIndex.uasset. MISSING: FQuestDefinitionRow and FDialogueLineRow — Source/Humanity/Public/Data/ holds only BossEncounterRow.h and ChapterIndexRow.h. The tool's own header states the hard constraint: UserDefinedStructs are a dead end on this seam, so each registry needs a C++ USTRUCT first.
HOP 9 — Runtime. MISSING ENTIRELY. Source/Humanity/ has Combat/ (CombatTelemetrySubsystem, HumanityAttributeSet, HumanityDensitySubsystem) and Data/ (two row structs). There is no UQuestSubsystem, no objective tracker, no dialogue player, no six-option wheel, no condition evaluator, and no UWorldStateSubsystem — the last is referenced in two existing headers as a planned sibling ("the shared UWorldStateSubsystem, Combat TD Step 7") but does not exist. Without it, state_writes commit nowhere and ws.key in any condition resolves to nothing.
HOP 10 — Translation Doc layer. MISSING. docs/translation/ holds AssetGen, Audio, Cinematic, Combat, Terrain, UE5_Build. There is NO T99_Translation_Quest.md — the quest lane is the only major lane with no platform-specific inference doc, so the row-to-UE-mechanism mapping (which subsystem, StateTree vs FSM for objectives, DataTable-driven dialogue, FText String Table from loc_namespace_key, save through the worldstate subsystem) is unauthored.
HOP 11 — Readiness reporting. MISSING. harness/check_build_readiness.py:112 defines LANES = [Terrain, UE5, Combat, Cinematic, Audio, AssetGen]. There is no Quest lane predicate, so the quest lane is invisible to the per-page readiness matrix.
SUPPORTING REGISTRIES: T0_Questline_Index is POPULATED (23 rows: SQ1-SQ12 + TRADE_01-10 + legendary) so questline_id resolves. T0_Worldstate_Variables 42 rows so ws.* resolves. T0_Quest_Seed_Registry 0 rows and T0_RNG_Drop_Table 0 rows — the reward FK slots are pinned but their targets are empty.
Already done since the 2026-07-19 audit (was reported as a wall, is not one now):
Genuinely external (not ours to build):
| item | kind | effort | gate | what it is | unblocks |
|---|---|---|---|---|---|
| Q-1 T0_Quest_Definition_Registry schema extension (the 16 §6.5 columns | registry_extension | medium | nothing_buildable_now | Append the ~16 typed columns the completed §6.5 spec defines to registries/T0_Quest_Definition_Registry [ACTIVE v1.0]/T0_Quest_Definition_Registry.csv: encounter_facet, sq_stage, sq_gate_condition, quest_giver, trigger_type, realized_beat_r | Everything downstream: the spike's 25 authored quests get a landing surface, the C++ USTRUCT gets a final column set, the DataTable import gets a table, the quest gate gets somethi |
| Q-2 harness/condition_expr.py + docs/CONDITION_EXPRESSION_GRAMMAR.md | tool_or_script | medium | nothing_buildable_now | The single reference implementation of the §9.5 gate-and-condition mini-grammar: a formal EBNF (operands has(local.k) / at(site_id) / flag(local.k) / ws.key OP value with == >= <= in / read(surface); operators & and / with stated precedence | Machine validation of every conditional surface in the lane (quest gates, objectives_array.completion_condition, sq_gate_condition, line-variant selection) and gives the UE runtime |
| Q-3 harness/extract_spine_rows.py | tool_or_script | medium | nothing_buildable_now | The spine-row extractor the roadmap §3 names as absent. Reads docs/spine/CH_NN.md and emits per-node machine rows for beats (beat_id, seq, role, mode, site, boss, fork, objective, actors, systems, threads, in/out state, layers, reveal), for | realized_beat_refs / objectives_array.beat_ref / spatial_requirements_array.site_ref / fork_option_refs can be resolved and FK-checked instead of hand-transcribed; also closes the |
| Q-4 harness/check_quest_rows.py (the quest-lane gate) | tool_or_script | medium | nothing_buildable_now | A run_gates.py-enrolled gate over the quest registry and the DD dialogue CSVs. Checks: every §6.5 enum value is a legal member; realized_beat_refs resolve against Q-3's beat index; spatial site_ref/zone_ref resolve against spine §3b and reg | Makes authored quest content verifiable rather than asserted — the precondition for autonomous production authoring at volume, and the thing that makes a green gate mean something |
| Q-5 docs/quest_dialogue/ + the first real DD CSV | template_asset | small | nothing_buildable_now | Create the directory the §6.5 repoint names (verified missing) and land the pinned six-column header contract as a README plus DD_<quest_id>.csv files: line_id, speaker_ref, trigger_beat, line_text, condition_expression, loc_namespace_key. | Turns the resolved-on-paper landing path into a real one; gives the audio lane its named cross-lane blocker ("dialogue line text does not exist anywhere") its first actual canonica |
| Q-6 harness/apply_quest_spike.py — land Ch 2-5 as typed rows | tool_or_script | large | nothing_buildable_now | A deterministic transform (the proven O-1 apply vector) converting the four critic-gated spike drafts into 25 main-story quest rows + 17 side-questline-stage rows on the extended registry, with quest_id minted per the PINNED rule QUEST_<que | The first real quest rows in the game's history; the evidence base for Q-7; the input the UE DataTable import and the runtime smoke both need. |
| Q-7 The quest_type enum proposal (the §11.1 standing instruction) | spec_doc | medium | nothing_buildable_now | docs/proposals/QUEST_TYPE_ENUM_PROPOSAL.md — the deliverable schema v0.2.2 §11.1 explicitly assigns to the FIRST quest-writing pass: propose the quest_type vocabulary from what the authored quests actually needed, as evidence-backed canon. | Types all 71 flores seeds and, identically, every one of the 69 regions' seed harvests — the highest-leverage single unblock in the Phase-3B pipeline, and it is owed BY this lane. |
| Q-8 Josh ruling: mint the three new game-surface quest_type categories | josh_ruling | small | josh_decision | Ratify (or re-name) minigame_stage, festival_or_daily_immersion, trade_expression as quest_type members, on the evidence of Q-7. This IS cardinal canon — they are new game-surface categories, not restatements, and Josh said in the 2026-07-2 | The ~35 flores seeds (and their per-region equivalents) that fit no existing type — the minigame, festival/daily-immersion and trade-expression buckets that are exactly the L1/L1.5 |
| Q-9 docs/translation/T99_Translation_Quest.md | spec_doc | large | nothing_buildable_now | The missing Translation Doc — the only major lane without one. Authored to the same five-doc bar as the landed T99_Translation_Combat: quest row -> UE mechanism mapping (DataTable-backed quest definitions; objective progression as a lightwe | Every C++ item below — today they would be authored against no spec, which is exactly the failure mode the combat lane's missing Translation Doc caused before it landed. |
| Q-10 FQuestDefinitionRow + FDialogueLineRow USTRUCTs | cpp_code | small | nothing_buildable_now | Two native row structs in C:/dev/Humanity/Humanity/Source/Humanity/Public/Data/QuestDefinitionRow.h and DialogueLineRow.h, USTRUCT(BlueprintType) : FTableRowBase, snake_case members mirroring the extended CSV headers 1:1 — exactly the patte | The DataTable bulk import of quest + dialogue canon into UE via the already-verified Tools/import_registry_datatable.py, producing DT_QuestDefinition and DT_QuestDialogue alongside |
| Q-11 UWorldStateSubsystem (C++) | cpp_code | medium | nothing_buildable_now | The shared GameInstance subsystem two existing headers already name as a planned sibling but which does not exist: holds the ws.* key/value store typed against the 42 T0_Worldstate_Variables rows, exposes Get/Set with the §6.5 compose rule | CROSS-LANE and heavily so: quest state_writes, quest/dialogue branch conditions, the cinematic lane's convergence_node_scene_dispatch (named as a wall precisely because ws.* does n |
| Q-12 UQuestSubsystem + objective tracker (C++) | cpp_code | large | nothing_buildable_now | Reads DT_QuestDefinition, starts a quest on its trigger_type, walks objectives_array in order, evaluates each completion_condition through the Q-11 evaluator, commits state_writes on completion, and honours fail_state / progression_guarante | The first quest that actually exists in the running game — the lane's end-to-end proof. |
| Q-13 Dialogue runtime + six-option wheel (C++/UMG) | cpp_code | large | nothing_buildable_now | A DataTable-driven dialogue player: pulls DD rows by quest_id + trigger_beat, selects among line variants by evaluating condition_expression (falling back to default_variant), routes line_text through the FText String Table via loc_namespac | Playable dialogue; the audio lane's VO consumption path; the cinematic lane's dialogue-track placement. |
| Q-14 Quest lane predicate in harness/check_build_readiness.py | tool_or_script | small | nothing_buildable_now | Add 'Quest' to LANES (line 112) and a lane_quest(Page) predicate: READY iff the page carries a typed Section-13 seed stub (proposed_quest_type / suggested_questline_id / zone_or_site ref / realized_beat_ref or an explicit region_ambient mar | Makes the quest lane visible in the per-page readiness matrix instead of silently absent — the difference between a known BLOCKED-ON and an unnoticed gap. |
| Q-15 Region-page Section-13 typed seed stub (CG-22) | schema_field | medium | nothing_buildable_now | Add the ruled typed seed-stub block to T1_Region_Page_Template Section 13 and instantiate it on the four slice pages (flores_island, bali, sumatra_java, angkor_khmer): per-seed proposed_quest_type, suggested_questline_id, zone_ref or site_r | The §7.5 seed-typing step — the step schema v0.2.2 §11.1 moved quest_type assignment INTO — currently has no target schema, so the 71 audited flores seeds cannot be typed anywhere. |
| Q-16 harness/enrich_quest.py (a quest-authoring pack) | tool_or_script | medium | nothing_buildable_now | The quest-lane twin of enrich.py's chapter pack: for a given CH_NN emits ONE grounded pack — the extracted beat/fork/site/SQ/scene rows (via Q-3), the chapter's region-page Zone Catalog + Section-12 cast, the persona substrate for every par | Production quest authoring at volume with bounded per-agent reading cost and no substrate omission — the enrich-pack-completeness lesson applied to this lane. |
| Q-17 Populate T0_Quest_Seed_Registry and T0_RNG_Drop_Table | registry_extension | medium | nothing_buildable_now | Both are 0 rows today (verified) while §6.5 pins reward_seed_refs and reward_drop_refs as FKs into them. Load T0_Quest_Seed_Registry deterministically from the audited docs/proposals/quest_seed_queue/*.md rows (they carry seed_id, seed_kind | reward_seed_refs / reward_drop_refs stop being dangling FKs; the seed harvest becomes queryable canon rather than a regenerable markdown view. |
| Q-18 quest_status spike/proposal enum value (CG-12 residue) | schema_field | small | nothing_buildable_now | Add a 'proposal' (or 'spike') member to the §6.7 quest_status enum and to the registry, so a validation-tier row is machine-distinguishable from a real pending one. Named explicitly in the SPIKE_REPORT as the last unclosed half of CG-12. | Lets Q-6 land the 42 spike-derived rows without them reading as production-pending canon. |
| Q-19 FText String Table asset + loc_namespace_key convention | template_asset | small | nothing_buildable_now | A UE String Table asset per chapter or region under /Game/Localization/, plus a pinned namespace/key convention (e.g. HUM.CH02.<quest_id>.<line_id>) written into T99_Translation_Quest, and a harness check that every DD row's loc_namespace_k | Localization-correct dialogue from the first authored line rather than a retrofit across millions of words; the ritual-term glossary (caci, larik, semangat, naga tana) gets a real |
| Q-20 CHAR_0008 Rangku Wera persona depth (CG-30) | spec_doc | small | cross_lane | The one genuinely open non-book-gated spike gap: the freed-register dialogue reaches for a loss the corpus does not name, and the draft correctly held it unspecified rather than invent a dead relative. Resolve in the boss-persona pass again | CH_02 production dialogue at full emotional depth without inventing canon. |
| Q-21 Persona-voice LoRA dataset accumulation (start NOW, train later) | tool_or_script | small | 5090 | A collector that accretes training rows as the lane authors: ratified personas + gate-passed dialogue lines as positives, validator-rejected and fallback-bank lines as hard negatives. Every row ratified or gate-passed, never model-generated | A persona-voice model mapping persona cards to in-voice lines — the named first fine-tune target. Building the collector now means the 5090 arrives to a ready dataset instead of st |
Critical path: The assetgen-pipeline registry extension — declaring and scattering the T1_BPC §2.6 column set (mesh_tags, asset_category, asset_routing, generation_status, generation_prompt_hash, last_generated_timestamp, regeneration_trigger, plus mesh_id_ref on the five registries lacking it) across the six live asset-bearing registries via docs/registry_extensions.json + a fidelity re-baseline. It is zero-gated (the mechanism is built and proven across 10 registries already), and every hop downstream of prompt composition dead-ends without it: the composer has nothing to read, the state machine has no state to hold, the writeback has nowhere to land, and the region-page asset block and the Blender/import legs both terminate in these columns. It is also the field set the gate that measures this lane (harness/check_build_readiness.py lane_assetgen) is literally asking for.
CANON ROW -> A MESH IN THE RUNNING GAME. Ten hops.
HOP 1 — the canon entity row exists. PARTIAL. Live and populated: T0_Weapon_Registry/Sheet1 (72 rows), T0_Creature_Roster/Sheet1 (132), T0_Vril_Site_Registry/Sheet1 (42), T0_Boss_Encounter_Registry/Sheet1 (281 — the roadmap already refuted the "0 rows" claim), T0_Character_Index (163), T0_Antagonist_Network_Registry/Sheet1 (64). MISSING: registries/T0_Familiar_Registry [DRAFT v0.1]/Sheet1.csv contains exactly ONE line — the doc title — no header, no rows, though §2.2 makes it a required generation source (33 species / 22 slots / 12 Father-bonded). Architectural Features have no registry BY CONTRACT (§2.6 puts them inline on region-page Section 7) and Section 7 is 100% prose on all four built pages (flores_island.md L776-793).
HOP 2 — per-asset routing tag (which backend; real-cultural vs fantastical vs MetaHuman). MISSING everywhere. No asset_category / mesh_category / asset_routing column on any registry; no such machine field on any region page. The rule lives as a prose sentence (flores_island.md L778: "REAL cultural architecture is reference-built, never raw-generated"). The Zone Catalog protected boolean is NOT a usable proxy — real heritage sits in protected:false zones (flores wae_water_spring, angkor west_baray).
HOP 3 — mesh_tags {morphology, region, style, material, era}, the §2.5 prompt-composition input. MISSING on every registry and every page. Confirmed mechanically, not by inspection alone: harness/check_build_readiness.py lane_assetgen reports all four pages BLOCKED-ON("per-asset morphology/asset_concept field"; "asset_category / mesh_tags field") in harness/build_readiness_scorecard.md.
HOP 4 — prompt composition + generation_prompt_hash (the §2.4 orchestration agent). MISSING. No such script in harness/ or C:\dev\Humanity\Humanity\Tools\ (grep for blender|trellis|assetgen|mesh_tags across both returns only check_build_readiness.py's own docstring and NeoStack plugin source). The SUBSTRATE side it would read is EXISTS and strong: the region-filtered RAG (~661k chunks, harness/rag/), harness/recall.py, and the flores pass-2 page (555 -> 1721 lines, 8 critic-corrected sections).
HOP 5 — generation. PARTIAL, and much more live than the wall list implies. EXISTS at the interim/cloud tier on the CURRENT machine: NeoStack ships a full generative provider layer in source — Plugins/NeoStackAI/.../Lua/Bindings/LuaBinding_Generate.cpp registers a global generate(opts) (L38-49, L1239-1249) routing to registered providers with actions text_to_3d / rig / retexture / check / import / get_result / cancel / balance / discover; Providers/MeshyProvider.cpp and Providers/TripoProvider.cpp are both compiled in. Tripo alone exposes text_to_model, image_to_model, multiview_to_model, refine_model, texture_model, mesh_segmentation, mesh_completion, highpoly_to_lowpoly (retopology), animate_prerigcheck, animate_rig, animate_retarget. Reachable today through the verified NeoStack MCP channel (127.0.0.1:9315, execute_script). Gated only on a MeshyApiKey (MeshyProvider.cpp L193) / Tripo key + cloud credits. MISSING/5090: the ruled SHIPPED-path local stack (TRELLIS.2 / Hi3DGen / Hunyuan3D-2.1) — a real 24-29GB VRAM floor.
HOP 6 — Blender finishing (retopo, UV, LOD chain, collision, FBX export). PARTIAL. Blender 5.1 IS INSTALLED at C:\Program Files\Blender Foundation\Blender 5.1\blender.exe (not on PATH) — the roadmap queue-#10 prerequisite is satisfied. MISSING: no finishing script exists in either repo. T99_Translation_AssetGen §4.3 specifies the mechanism exactly (blender.exe --background --python, Decimate LOD chain under UE's _LOD0/_LOD1 auto-detect, convex-hull collision) and pins the Decimate target to T1_BPC §1.7's steam_deck_minimum column — whose NUMBERS are 5090-benchmark-deferred, but the script is not.
HOP 7 — FBX -> UE import. EXISTS, two independent proven vectors. (a) the UE-PYTHON BRIDGE through NeoStack — invoke('/Script/PythonScriptPlugin.PythonScriptLibrary','ExecutePythonCommand'), VERIFIED 2026-07-20 with unreal.AssetImportTask (mp3 -> SoundWave at /Game/Audio/SFX/smoke_stone_door), which is precisely the API §4.3 claims as this doc's owned seam; (b) NeoStack's own generate{action='import'}, which downloads and imports a provider result directly.
HOP 8 — registry writeback (mesh_id_ref + the five supporting columns). PARTIAL -> MISSING. mesh_id_ref exists as column 8 of T0_Weapon_Registry/Sheet1 and is 0/72 populated; it exists on NO other registry despite §2.6 requiring it on all seven. The other five required columns exist on ZERO registries. The gate-safe mechanism to add them EXISTS AND IS PROVEN: docs/registry_extensions.json (per-system column ownership; 10 registries already carry extension columns) + docs/fidelity_baseline.json added_columns/extension_hashes + harness/check_registry_extensions.py. There is no assetgen owner block in that manifest today. Note the seam constraint: the game repo is READ-ONLY against canon (game CLAUDE.md, one-writer-per-repo hard rule), so writeback must cross as a manifest file, not a direct write.
HOP 9 — UE consumption (row -> DataTable -> spawned/placed actor). PARTIAL, cross-lane to ue5. The DataTable bulk seam is VERIFIED (Tools/import_registry_datatable.py; /Game/Data/Smoke/DT_ImportSmoke), but each registry needs a C++ USTRUCT(FTableRowBase) row type authored in Source/ first — UserDefinedStructs are a proven DEAD END on this seam. No row struct exists for any asset-bearing registry.
HOP 10 — the §17.1 capture-rights gate on the reference-built path. MISSING. No reference_image_ref / capture_rights / reference_source / use_class field anywhere in the asset lane. The PATTERN exists and is live one lane over — use_class governs the book-substrate citations (flores_island.md L1683), which is the exact parallel T99_Translation_AssetGen §6 names ("parallel to the use_class discipline already governing the book-processing substrate lane").
Already done since the 2026-07-19 audit (was reported as a wall, is not one now):
Genuinely external (not ours to build):
| item | kind | effort | gate | what it is | unblocks |
|---|---|---|---|---|---|
| mesh_tags value-grammar + asset_category/asset_routing enum spec | spec_doc | small | nothing_buildable_now | A short spec (a §2.5A addendum inside docs/translation/T99_Translation_AssetGen.md, or docs/proposals/ASSET_FIELD_GRAMMAR.md) pinning three things the contract left as prose: (1) how a 'structured object column' serializes in a CSV cell — r | Every column add and every parser downstream; without it each consumer invents its own mesh_tags encoding. |
| assetgen-pipeline registry extension (the §2.6 column set on six regis | registry_extension | medium | nothing_buildable_now | Add an 'assetgen-pipeline' owner block to docs/registry_extensions.json declaring: mesh_tags, asset_category, asset_routing, generation_status, generation_prompt_hash, last_generated_timestamp, regeneration_trigger — plus mesh_id_ref on the | Prompt composition, the generation state machine, registry writeback, the UE row structs, and the §17.1 gate — every hop from 3 onward. |
| Region-page asset machine block (T1_Region_Page_Template v2.1 + 4-page | template_asset | medium | nothing_buildable_now | Apply the ALREADY-APPROVED review items J/L/M/N/O/Q from docs/pipeline_review/PAGE_PIPELINE_REVIEW_2026-07-20.md §AssetGen into T1_Region_Page_Template [ACTIVE v2.0].md, then onto flores_island / bali / sumatra_java / angkor_khmer. Four con | The region-driven generation track (§2.4), the AssetGen readiness gate, and Architecture — the only category with no registry home. |
| harness/compose_asset_prompt.py — the §2.4 orchestration agent's promp | tool_or_script | medium | nothing_buildable_now | The script the contract has always named and nothing implements. Reads one entity row + its region page Section 3/5/6/7 + region-filtered substrate through harness/rag + harness/recall.py, composes the per-asset generation prompt from mesh_ | Actual generation at more than one-off scale; the whole regeneration state machine. |
| docs/capture_rights_register.json + the §17.1 reference-built gate tee | tool_or_script | medium | nothing_buildable_now | The missing capture-rights/use_class layer, built as the direct analog of the book lane's use_class discipline. A register file keyed per real structure — structure_id, site_name, rights_status {clear/prohibited/unknown-gather}, reference_s | Any reference-built work on real cultural architecture — currently the agent literally cannot distinguish a rights-cleared photo from a prohibited one. |
| Tools/mesh_finish.py — the Blender-headless finishing chain (game repo | tool_or_script | medium | nothing_buildable_now | The §4.3 finishing stage as a real script. Invoked as "C:\Program Files\Blender Foundation\Blender 5.1\blender.exe" --background --python Tools/mesh_finish.py -- --in <glb> --out <fbx> --category <asset_category> (Blender 5.1 IS installed | Game-ready output from any generator, cloud or local; the interim Tripo previz path immediately. |
| Tools/import_mesh_asset.py — the FBX->UE import leg + writeback manife | tool_or_script | small | nothing_buildable_now | Mirrors the two proven Tools scripts. Routes unreal.AssetImportTask + unreal.AssetToolsHelpers.get_asset_tools().import_asset_tasks([...]) (filename/destination_path/replace_existing/automated/save) through the VERIFIED UE-PYTHON BRIDGE | The last hop into the editor; closes the seam T99_Translation_AssetGen §4.3 explicitly claims for this doc. |
| harness/apply_mesh_writeback.py — the canon-side writeback applier | tool_or_script | small | nothing_buildable_now | Consumes the import manifest emitted by Tools/import_mesh_asset.py and applies mesh_id_ref / generation_status / last_generated_timestamp / regeneration_trigger onto the owning registry rows, then re-emits docs/fidelity_baseline.json in the | The closed loop; without it mesh_id_ref stays 0/72 on the weapon roster forever. |
| harness/check_asset_pipeline.py — the assetgen state-machine gate (gat | tool_or_script | medium | nothing_buildable_now | A self-testing gate in the established harness shape (both-directions fixtures, refuses to run if its own teeth are broken, wired into harness/gates_config.json). Enforces: generation_status is one of the five §2.7 enum values; complete imp | Autonomous batch generation — the volume tier cannot run without a machine-checkable invariant set. |
| The previz round-trip smoke (roadmap queue #10) on one fantastical ass | tool_or_script | small | external_service | Prove all ten hops on one asset with zero §17.1 exposure — a vril-site orb or obelisk from T0_Vril_Site_Registry (asset_routing=fantastical, the doc's own best-case category). Chain: compose_asset_prompt.py -> NeoStack `generate{provider='t | Confidence in the whole chain; converts the design into a measured time-to-game-ready number that feeds scheduling. |
| T0_Familiar_Registry schema + 33-species population | registry_extension | medium | nothing_buildable_now | registries/T0_Familiar_Registry [DRAFT v0.1]/Sheet1.csv is a ONE-LINE FILE containing only the doc title — no header, no rows — while §2.2/§2.3 make it a required generation source and CVD numerical canon already fixes 33 legendary species | An entire ruled generation category (Familiars) that currently has no row to generate from. |
| Row USTRUCTs for the asset-bearing registries (FWeaponRow / FCreatureR | cpp_code | medium | cross_lane | C++ USTRUCT(BlueprintType) : public FTableRowBase types in the game repo Source/ mapping each registry's CSV columns to UE types (FText for player-facing, FString for ids, int32/float, UENUM for the enums, FDataTableRowHandle for FKs, FStri | Anything reaching a spawnable, placeable thing in the level — hop 9. |
| One MetaHuman NPC built in-engine + stable asset-id emission | tool_or_script | small | nothing_buildable_now | §2 rules NPCs MetaHuman-first and supersedes the old Meshy-generates-NPCs text. Build ONE named flores cast member (a Section-12 entry, e.g. Mama Klara) through the in-engine MetaHuman creator (native since 5.6; the browser Creator sunsets | The NPC category end-to-end plus a cross-lane cinematic blocker, for one afternoon of editor time. |
| The GPU-free §5 pre-flight license re-check | spec_doc | small | nothing_buildable_now | The one part of the §5 benchmark protocol that needs no GPU and is now materially urgent per the roadmap's own §6 asset-lane correction. Re-fetch microsoft/TRELLIS.2 issue #22 and Tencent-Hunyuan/Hunyuan3D-2.1 issue #111; instrument (do not | Possibly deletes two large 5090-day work items; at minimum replaces a stale 'empty set' framing with evidence. |
| Per-category poly/LOD/collision budget numbers (D-POLY-BUDGETS) | spec_doc | small | 5090 | Fill T1_BPC §1.7's per-category-by-spec-class table with measured numbers — the steam_deck_minimum LOD0 triangle budgets that Tools/mesh_finish.py's Decimate target reads. The table STRUCTURE already landed (2026-07-20 ruling batch); only t | Ship-viable LODs; retires the ILLUSTRATIVE tag across §1.7 and §4.3/§4.4. |
| The PyTorch3D renderer-swap fork (the shipped-path PBR spike) | tool_or_script | large | 5090 | Maintain a real fork of TRELLIS.2 with the nvdiffrast/nvdiffrec renderer swapped for PyTorch3D (Meta, BSD-3-Clause) — proven possible by the archived-since-Nov-2025 kg-git-dev/trellis-refactored course project, but that artifact has no forw | A commercially-clean automated PBR texture leg for the shipped path — the single largest quality/throughput unknown in the lane. |
Critical path: BUILD THE BOSS STATETREE FRAMEWORK (boss-statetree-framework) — the C++ StateTree schema, Tasks and Conditions in Source/Humanity/Public/Combat/StateTree/. It is the single largest zero-built block in a lane where everything around it already exists: the canon rows are populated and gate-enforced (281 rows, 26 columns, boss_axes green), the row struct exists, the DataTable seam is verified, the AttributeSet with all eight Composure nodes compiles, the density subsystem holds WS_024, and the telemetry producer already fires. StateTree is what consumes all of it — it carries the phase transitions (making composure_nodes and character_engagement_node load-bearing rather than merely validated), the ~30 clocks, the Withdrawal enrage-replacement, every [DIAL] react-slack lever that makes the vril-density thesis observable, the habit-vector consumer, and the environmental-boss protocol state machine. It is also the named CROSS-LANE dependency the cinematic lane is blocked on (spike C-14 / roadmap §3: 'boss cinematics fire off a boss combat-state event that no boss-AI framework yet emits'). Its own prerequisites are three small items in the same commit series — the GameplayTag source, the row parser, and the boss actor/ASC bootstrap — none of which is gated on anything. Nothing in this critical path touches the 5090.
CHAIN: canon boss row → machine combat columns → gate → UE row struct → DataTable → boss actor/ASC → abilities+phases → clocks+dial → environment → worldstate/save → cinematic event → telemetry/scorer → runtime barks.
H1 CANON ROW — EXISTS. C:/dev/humanity-forgotten/registries/T0_Boss_Encounter_Registry [DRAFT v0.1]/Sheet1.csv, 281 data rows x 26 columns (boss_kind populated main/sub/environmental).
H2 MACHINE COMBAT-SPEC COLUMNS — EXISTS (this was the named wall; it is CLOSED). win_condition, win_shape, composure_nodes, character_engagement_node, ws_writes are live on the header and back-filled on all 281 rows (verified BE_0002/BE_0002_S1/BE_0002_S2 carry real values e.g. REDUCE;FREE / standard / direct=lunge_feint_dodge__cornered_frenzy_punish;stealth=... / phase=P2;verb=weigh;integrity_routed=true). Declared through the standing discipline in docs/registry_extensions.json under system combat-encounter; docs/fidelity_baseline.json re-baselined. STILL MISSING from the T99 §4 proposal: signature_counters, phase_trigger, escalation_vector, and the boss_kind enum extension (trade_gate|school|weapon|mmo_world).
H3 MACHINE VALIDATION — EXISTS. harness/check_boss_axes.py v2 (335 lines) enforces five invariants (never-zero axis; the ruled 10-verb win_condition + 9-value win_shape binding incl. fixed CH_55/59/60/61/62/63/67/70/75/76 main shapes; main-row character node regex; composure presence; sub-ladder >=3 mode span; ladder character beat) with shrink-only, adjudicated waivers in docs/boss_axes_baseline.json. Enrolled as gate boss_axes in harness/gates_config.json (20-gate roster). Non-vacuous by construction.
H4 CANON ROW → UE TYPE — EXISTS. C:/dev/Humanity/Humanity/Source/Humanity/Public/Data/BossEncounterRow.h — FBossEncounterRow : FTableRowBase mirrors all 26 columns 1:1 including the five new ones.
H5 CSV → DATATABLE ASSET — PARTIAL. C:/dev/Humanity/Humanity/Tools/import_registry_datatable.py is a verified bulk seam over NeoStack MCP (create_asset 'datatable' with native /Script/... Struct → FillDataTableFromCSVString → read-back → save). It has only ever been run on the 3-row Chapter smoke: Content/Data/Smoke/DT_ImportSmoke.uasset. No DT_Boss_Encounter exists anywhere under Content/. The import has never been run for this lane.
H6 DATATABLE → LIVE ATTRIBUTE GRAPH — PARTIAL. Source/Humanity/Public/Combat/HumanityAttributeSet.h compiles and declares the J7 bars (Health/Vril/Stamina/Rage) + Composure + all EIGHT mode sub-node attributes incl. the standalone Composure_Character (R4 correct). But NOTHING owns it: there is no boss actor/pawn, no AbilitySystemComponent owner, no IAbilitySystemInterface, and no code that reads a FBossEncounterRow and initializes anything. Source/ contains exactly 4 .cpp files (Humanity.cpp + the three Combat ones).
H7 VERBS → GAMEPLAYABILITIES / PHASES → GAMEPLAYTAGS / VFX → CUES — MISSING. Zero UGameplayAbility subclasses, zero UGameplayEffect, zero GameplayCue, zero GA_/GE_/GC_ Content assets. No GameplayTag source declares Boss.Phase.* or Boss.Composure.Node.* — yet UCombatTelemetrySubsystem::RecordNodeBreak(FGameplayTag) already takes a mode tag with no tag table behind it.
H8 PHASE/CLOCK AI → STATETREE — MISSING. GameplayAbilities, StateTree, GameplayStateTree, PCG, PCGToolset are all enabled in Humanity.uproject, and StateTreeModule is in Source/Humanity/Humanity.Build.cs. Zero StateTree assets, zero C++ StateTree Tasks/Conditions/schema. Nothing carries the ~30 clocks, phase transitions, or evolve-not-swap.
H9 THE DIAL — PARTIAL. Source/Humanity/Public/Combat/HumanityDensitySubsystem.h holds WS_024 clamped [0,2] with the C1 realm+site law and the d_local note in the class comment. But tier_baseline has no home, d_local = clamp(tier_baseline * WS_024/2, 0, 1) is computed nowhere, and nothing feeds a GameplayEffect SetByCaller or a MetaSound Builder Input. The headline thesis (one authored boss at two world-tensions, zero enemy-stat delta) has no executable path today.
H10 DIAL SOURCE OF TRUTH — PARTIAL. The C1-authoritative pair T0_Region_Index.env_density_band_default + env_emitter_site_ids/env_drain_site_ids are declared as environment-grammar extension columns in docs/registry_extensions.json; nothing in-engine reads them.
H11 ENVIRONMENT AS COMBAT SURFACE (Chaos + D-verbs) — MISSING/PARTIAL. registries/T0_Environment_Grammar_Registry [DRAFT v0.1]/Sheet1.csv has exactly TWO rows (EG_0001 Lava Vent, EG_0002 Sieidi Stone) against an 11-verb D-verb vocabulary. NO region page cites a single EG_ id — harness/build_readiness_scorecard.md reports the Combat lane BLOCKED on all 4 built pages (flores_island, bali, sumatra_java, angkor_khmer) on exactly two inputs: a machine care_tier field and EG_ ids. Verified: flores_island.md contains neither. No Chaos destruction assets exist.
H12 WORLDSTATE / SAVE — PARTIAL. WS_041 composure_node_mastery and WS_042 banked_tell_reads ARE minted in registries/T0_Worldstate_Variables [ACTIVE v0.1]/Sheet1.csv (R8 landed), and harness/check_ws_value_form.py gates the form. The UWorldStateSubsystem / UWorldStateSaveGame C++ does NOT exist — so the ws_writes column on all 281 rows has no consumer. This is the shared trunk the cinematic lane is also blocked on.
H13 BOSS COMBAT-STATE EVENT → CINEMATIC TRIGGER — MISSING (C-14). Depends entirely on H8.
H14 TELEMETRY → SCORER — PARTIAL. UCombatTelemetrySubsystem (producer) EXISTS and compiles, writing Saved/Telemetry/<session>.json with node-breaks/tell-reads/dial-samples. Its named consumer harness/score_greybox.py (spec'd at docs/proposals/SELF_IMPROVING_QUALITY_LOOPS.md §2.2 L153-155, emitting harness/combat_greybox_scorecard.{md,json}) DOES NOT EXIST — a live orphan: a producer with no consumer.
H15 RUNTIME GENERATIVE BARKS — MISSING. harness/recall.py EXISTS and works (node/aliases/hardlines/counts/open/types, --json). The recall packs exporter, the V1-V5 validator, the authored-fallback bank, and the runtime_generation_log + pass-rate scorer do not exist in harness/. No local generative model on the machine (fastembed is embeddings-only). T0_Hard_Lines.applies_to_pipeline has no Runtime enum value, so the pack's hardline_rule_vector would be vacuous today.
H16 CONTRACT PARENT — MISSING (C-1). _source/01_Tier_1_Foundation/T1_Build_Pipeline_Contracts [ACTIVE v1.0].md has §0-§10 (UE5, Meshy, AIVA, ElevenLabs, Cinematic, Quest, Region Page, Book, Story Spine, SFX). There is NO combat/runtime section. Combat is the only lane with a Translation Doc and no contract parent.
H17 DOC STATUS — PARTIAL. docs/translation/T99_Translation_Combat.md is still labelled DRAFT v0.1. Both declared ACTIVE-flip gates have now landed (the §5 D-COMBAT-TD rulings; the §4 registry extension declared + back-filled + gate-enforcing). Only the fresh-context normalize-doc critic pass remains.
Already done since the 2026-07-19 audit (was reported as a wall, is not one now):
combat-encounter; docs/fidelity_baseline.json re-baselined. The 'lacks machine combat-spec columns' wall is now only PARTIALLY open (3 of 8 proposed columns remain).boss_axes in harness/gates_config.json — enforcing five invariants over all 281 rows, non-vacuous by construction (missing registry/column/malformed cell = hard FAIL), with shrink-only adjudicated waivers in docs/boss_axes_baseline.json (4 mode-span, 18 ladder-beat, each carrying its author+critic+director evidence).Struct not RowStruct; must be a NATIVE /Script/ UScriptStruct; UserDefinedStructs are a dead end; first CSV column is the row name; every post-init request must echo MCP-Session-Id). Evidence: /Game/Data/Smoke/DT_ImportSmoke.Genuinely external (not ours to build):
| item | kind | effort | gate | what it is | unblocks |
|---|---|---|---|---|---|
| boss-statetree-framework | cpp_code | large | nothing_buildable_now | The C++ StateTree layer for boss phase AI + the ~30 combat clocks. Create Source/Humanity/Public/Combat/StateTree/: FHumanityBossStateTreeSchema (exposing the boss ASC + UHumanityDensitySubsystem as schema context); Tasks FSTTask_TellWindup | All phase/clock behavior; the dial's react-slack levers becoming observable; the habit-vector consumer; the environmental-boss protocol state machine; the greybox exit criterion; a |
| humanity-gameplaytag-source | cpp_code | small | nothing_buildable_now | Author Source/Humanity/Public/Combat/HumanityGameplayTags.h/.cpp (native tag declarations) plus Config/DefaultGameplayTags.ini entries for: Boss.Phase.1/2/3; Boss.Composure.Node.{direct,stealth,puzzle_routed,environmental,vril_management,fa | Everything tag-shaped: StateTree conditions, ability mode-tagging, GameplayCues, the ws.* map key type, and UCombatTelemetrySubsystem::RecordNodeBreak(FGameplayTag) which today tak |
| boss-row-parser | cpp_code | small | nothing_buildable_now | Source/Humanity/Public/Combat/BossRowParse.h/.cpp — typed parsers for the serialized registry cells: composure_nodes ('mode=node;mode=node', '__' joining multiple nodes in one mode) -> TMap<FGameplayTag, FName>; character_engagement_node (' | The boss actor bootstrap, the Composure node graph, the character node resolution, and the ws_writes consumer. This is the actual seam that turns the extension columns into runtime |
| boss-actor-asc-bootstrap | cpp_code | medium | nothing_buildable_now | Source/Humanity/Public/Combat/HumanityBossCharacter.h/.cpp — an ACharacter implementing IAbilitySystemInterface, owning a UAbilitySystemComponent + UHumanityAttributeSet, with a UPROPERTY FDataTableRowHandle BossRow. On BeginPlay it resolve | The first live entity in the game driven by a canon row. Precondition for every GAS/StateTree/telemetry step and for the greybox. |
| dt-boss-encounter-import | tool_or_script | small | nothing_buildable_now | Run the already-verified bulk seam for real: python Tools/import_registry_datatable.py --csv "<canon>/registries/T0_Boss_Encounter_Registry [DRAFT v0.1]/Sheet1.csv" --struct /Script/Humanity.FBossEncounterRow --dest /Game/Data/Registries/DT | Every in-engine consumption of boss canon; the boss actor bootstrap; the first real proof the DataTable seam scales past a smoke. |
| d-local-resolver-and-dial-effects | cpp_code | medium | nothing_buildable_now | Two pieces. (a) Extend UHumanityDensitySubsystem with TierBaseline (the 5 world-tensions normalized to [0,1]) and GetDLocal() = clamp(TierBaseline * VrilDensity/2.0, 0, 1), plus a UDLocalMagnitudeCalculation : UGameplayModMagnitudeCalculati | The headline thesis becomes executable: the same authored boss at two world-tensions with zero enemy-stat delta. This is greybox step 4, the exit criterion. |
| worldstate-subsystem | cpp_code | medium | nothing_buildable_now | Source/Humanity/Public/State/WorldStateSubsystem.h/.cpp — UWorldStateSubsystem : UGameInstanceSubsystem holding TMap<FGameplayTag, FWorldStateValue> (a tagged union over bool/int32/uint8-enum/float), persisted by UWorldStateSaveGame : USave | Combat persistence (mastery credit, banked tell-reads, the death economy's Hades-on-both-outcomes loop), the boss rows' ws_writes column, AND the cinematic lane's convergence_node_ |
| score-greybox-harness | tool_or_script | small | nothing_buildable_now | harness/score_greybox.py — reads the Saved/Telemetry/<session>.json that UCombatTelemetrySubsystem ALREADY writes and emits harness/combat_greybox_scorecard.{md,json} in the run_gates.py scorecard shape (gatelib.write_scorecard), with a wor | Closes a live orphan (a built producer with no consumer) and turns the greybox exit criterion from a play-feel opinion into a gated, git-remembered measurement. Named verbatim at d |
| recall-packs-exporter | tool_or_script | medium | nothing_buildable_now | harness/recall_packs.py — the offline per-entity context-pack exporter atop the existing harness/recall.py (C-9; the roadmap §3 wall, correctly scoped: recall itself exists). For each entity id it runs the recall node union query once at ba | All runtime-generation population — the barks leg, the guardrail's V3 name resolution, and the R7 launch-posture fact_whitelist exclusions (Dreaming/songline/joik, HL_0007). Produc |
| runtime-v1-v5-validator | tool_or_script | medium | nothing_buildable_now | harness/runtime_validator.py — the deterministic, ZERO-GPU runtime cousin of lint_canon_graph.py. V1 cultural denylist (the §17.1 forbidden-framing corpus, HL_0005) -> V2 hard-line rule-vector (protected-community no-combat-provocation, no | The whole deterministic runtime spine stands up with no model at all — the sim is coherent on fallbacks alone and the model becomes pure upside. It is also the scoring rig any late |
| hardlines-runtime-pipeline-value | schema_field | small | nothing_buildable_now | Add the enum value Runtime to T0_Hard_Lines.applies_to_pipeline (verified absent today — the column exists at registries/T0_Hard_Lines [ACTIVE v0.2]/Sheet1.csv header, and no row carries Runtime), and tag the rows the runtime V2 rule-ve | Makes the recall-pack hardline_rule_vector non-vacuous. Without it the runtime guardrail's V2 stage has nothing to match against and would pass everything. |
| boss-schema-round-2-columns | registry_extension | medium | nothing_buildable_now | The half of the T99 §4 extension that did NOT land. Declare three more columns on T0_Boss_Encounter_Registry/Sheet1 under the existing combat-encounter system in docs/registry_extensions.json + docs/fidelity_baseline.json added_columns: ` | Per-row phase transitions and evolve-not-swap parameters in StateTree (today all 281 rows would default to composure_break with no escalation parameter), and makes the counter-cove |
| region-page-combat-readiness-fields | schema_field | small | nothing_buildable_now | Flip the Combat lane from BLOCKED to READY on the four built region pages. harness/check_build_readiness.py lane_combat needs exactly two things: (a) a machine care_tier field — add it as a Zone Catalog column in T1_Region_Page_Template a | The only lane-level BLOCKED-ON the combat readiness gate reports. Also the per-region input the Chaos D-verb binding and the §17.1 protected-community combat routing both read. |
| environment-grammar-population | registry_extension | medium | nothing_buildable_now | T0_Environment_Grammar_Registry has TWO rows (EG_0001 Lava Vent, EG_0002 Sieidi Stone) against an 11-verb D-verb vocabulary (D1_COLLAPSE..D11_OBSCURE) and an 18-column schema. Populate the per-feature rows for the four built regions' arenas | Chaos D-verb binding (TD Step 5), the environmental-boss protocol arenas, the region-page combat readiness predicate, and the C2 permanence firewall having anything to enforce. |
| environmental-boss-protocol-statetree | template_asset | medium | nothing_buildable_now | The 4-step Perception -> Vril-management -> Restraint -> Purgation protocol as its own StateTree state machine (NOT GAS — there is no damage attribute to deplete), with a hidden vril-state field carrying genuine_echo + negative_manifestatio | The Ch 10/20/38/57 boss class, and Josh's ruling that L1 stays action-packed in protected/relief chapters (the protocol IS the playable layer there). Ch 57's fully-disabled faction |
| habit-vector-and-sigma-selector | cpp_code | medium | nothing_buildable_now | UPlayerHabitVectorComponent — a rolling histogram over dodge direction / opener / turtle ratio / input spam — plus FSigmaBoundedSelector applying the CVD §17.13 Sigma Constraint (+/-1 sigma, anti-streak floor, drop ceiling) to the boss move | The 'smarter opponent, not a stronger one' proof (greybox step 3: roll-spam produces a baited sweep), and the concrete demonstration that the dial adds pressure without inflation. |
| contracts-section-11-combat-runtime | spec_doc | medium | nothing_buildable_now | Add §11 Combat/Runtime Pipeline Contract to _source/01_Tier_1_Foundation/T1_Build_Pipeline_Contracts [ACTIVE v1.0].md (verified: it has §0-§10 and no combat section; combat is the only lane with a Translation Doc and no contract parent — sp | Makes combat a first-class pipeline with a contract parent, so a build step can run unattended against a contract rather than an inference doc. |
| combat-td-active-flip | spec_doc | small | nothing_buildable_now | Flip docs/translation/T99_Translation_Combat.md from DRAFT v0.1 to ACTIVE. Both declared gates have landed: the §5 D-COMBAT-TD rulings (R1-R9, Josh 2026-07-19) plus D-EVADE-TOKEN (2026-07-20), and the §4 registry extension declared + back-f | The build lane's authority chain (GAME repo CLAUDE.md treats the Translation Docs as implementation contracts); removes the stale 'DRAFT / extension not applied' framing that makes |
| local-bark-smoke-3-4b | tool_or_script | medium | nothing_buildable_now | The runtime-generation smoke on the CURRENT GPU (roadmap execution-queue item #6). Build llama.cpp, pull one 3-4B GGUF (Qwen3-3B / Phi-4-mini class — the SHIP target, not the 14B reference), author a GBNF grammar constraining output to {emo | The barks leg of the greybox (step 6) and the evidence base for the eventual 5090 perf audit. Explicitly NOT 5090-gated — the 3-4B ship target runs on the current GPU; only the 14B |
| phase-5m-balance-audit-workflow | spec_doc | large | nothing_buildable_now | Run the Phase-5M balance audit as its own workflow against the enumerated §8.1 PARAMETERS BLOCK (11 rows: dial_telegraph_slack / dial_window_width / dial_well_latency coefficients over d_local, answer_pruning step, tell_windup_ms / punish_w | A faithful TUNED build (as distinct from a shape-correct greybox). Reporting this as a blocker on the greybox would be wrong — it is the follow-on, not the gate. |
| chaos-dverb-perf-at-scale | template_asset | medium | 5090 | Chaos destruction perf profiling and the D-verb-to-feature binding at scale across regions (spike C-13). One binding for the greybox arena is buildable now on the current machine; the at-scale profiling (fracture budgets, cache-system deter | Environment-combat becoming load-bearing across all 69 regions rather than one greybox arena. |
| runtime-inference-perf-budget | tool_or_script | medium | 5090 | The runtime perf audit (the Phase-5M analog, spike C-11): batching, speculative/draft decode (2-3x), KV/prefix cache, the ~8-15 gen/s busy-scene target, latency P99s, VRAM/quant budgets — plus the 14B on-device reference model for dev-side | Trusting the runtime generative layer's perf at ship scale. Genuinely 5090-gated by the design's own pin; the 3-4B ship target and the entire deterministic spine run today without |
Critical path: docs/REGISTRY_ROW_STRUCT_SPEC.md plus Tools/gen_row_struct.py — the column-to-UE-type contract and the codegen that consumes it. Every other hop in this lane is either already proven or waiting behind a row type. The DataTable seam is verified production-grade and has already carried 360 real rows into the engine, so the ONLY thing standing between canon and the engine for the remaining ~34 registries is 'a native USTRUCT exists for this table' — a step START_HERE has named as the standing build-lane next item on three separate days and which is still being done by hand, one struct at a time. It is also upstream of the second-most-critical item: the spine-row extractor's output (sites, beats, forks, scenes, SQ) cannot enter the engine without row structs either, so codegen serves both branches. It costs nothing external, is not 5090-gated, needs no Josh ruling (type mapping is engineering, and the one canon-adjacent choice — FText for player-facing columns — is already a binding ruled law that the current hand-authored structs violate), and it converts an O(34 sessions) hand task into one script run plus one compile. Second on the path, and buildable in parallel by a different worker: harness/extract_spine_rows.py, whose effort just dropped materially because harness/check_spine_graph.py already contains the corpus-hardened section router and beat/fork parsers it needs.
CHAIN: canon row -> USTRUCT -> DataTable -> PCG -> World Partition level. Verified against the live tree 2026-07-22 (canon repo C:/dev/humanity-forgotten @ master 6f98b70; game repo C:/dev/Humanity/Humanity @ master 76691a2).
HOP 1 — Canon row at rest. EXISTS. 36 registries as CSV under registries/<name>/<tab>.csv (T0_Chapter_Index 79 rows, T0_Boss_Encounter_Registry 281, T0_Creature_Roster 132, T0_Region_Index 76, T0_Vril_Site_Registry 42, T0_Environment_Grammar_Registry 2). Live-canon layer; divergence declared in docs/fidelity_baseline.json; open columns declared in docs/registry_extensions.json and enforced by harness/check_registry_extensions.py.
HOP 2 — Spine typed rows (site/beat/fork/scene/SQ/boss-thin-index) -> extractable table. PARTIAL/MISSING. The rows are real and machine-shaped inside docs/spine/CH_NN.md (e.g. CH_02 - liang_bua_cave: terrain cave_system · functions [...] · ambient_threat moderate · vril_density low · climactic_affordance none · protected true; the §13 scene table is a 7-column markdown table). The PARSERS already exist inside harness/check_spine_graph.py (_sections() header router, parse_beats(), parse_forks(), parse_file() which already buckets sites/scene/sq/boss/seam bodies). What is MISSING is the emitter: no harness/extract_spine_rows.py, no CSV/JSON output anywhere. extract_claims.py and enrich.py do not produce it. This is the §3 pre-step the Translation Doc says every UE step depends on.
HOP 3 — Region page Zone Catalog -> extractable table. PARTIAL. _source/02_Tier_2_Region_Pages/flores_island.md ## Zone Catalog carries 10+ real zone rows (zone_id | source site_id | terrain | gameplay functions | ambient_threat | vril_density | climactic_affordances | protected | area_bounds | build_priority). MISSING: (a) worldcover_biome (the PCG Biome Core / auto-material vegetation key) — absent on all 4 live pages; (b) georeferenced bounds — area_bounds is size-only prose ("220×180×60 karst interior", "300×300"), no world anchor; (c) any extractor. harness/check_build_readiness.py run TODAY reports UE5 = BLOCKED on exactly those two inputs for all four pages (angkor_khmer, bali, flores_island, sumatra_java). Note the georeference IS partly recoverable: T0_Region_Index.coordinates already carries WGS84 point anchors (flores_island = 8.5333°S 120.4400°E Liang Bua; 8.6110°S 120.4689°E Ruteng) and terrain_feature_class_ids already carries EG_ ids. Also note harness/apply_region_page_sections.py (the only deterministic page writer) replaces ### Section N spans ONLY — ## Zone Catalog is a top-level block outside its span logic, so there is no writer for these columns.
HOP 4 — CSV column -> C++ USTRUCT : FTableRowBase. PARTIAL, 2 of ~36. Source/Humanity/Public/Data/ChapterIndexRow.h (FChapterIndexRow, 51 cols) and BossEncounterRow.h (FBossEncounterRow, 26 cols incl. the five ruled combat columns) exist and compile (UE 5.8.0). Both hand-authored, all-FString for player-facing text — which VIOLATES the binding localization law (game CLAUDE.md "localization from the first string"; Translation Doc §2.4 requires FText for title, boss_name, any player-facing column). MISSING: the column-to-UE-type spec doc (no such file in docs/), any codegen tool, and the other ~34 row types (FCreatureRow, FRegionIndexRow, FVrilSiteRow, FCharacterRow, FWorldstateVariableRow, ...). Hard-won constraint recorded: UserDefinedStructs are a DEAD END on this seam (NeoStack add_variable is Blueprint-only; Epic bug UE-152346).
HOP 5 — CSV -> DataTable asset. EXISTS, VERIFIED, PRODUCTION-GRADE. Tools/import_registry_datatable.py runs the whole import through the UE-PYTHON BRIDGE (invoke('/Script/PythonScriptPlugin.PythonScriptLibrary','ExecutePythonCommand') over the NeoStack MCP channel :9315) -> unreal.DataTableFactory create-or-load -> fill_data_table_from_csv_string -> row-name read-back -> save. REAL imports landed: /Game/Data/Registries/DT_ChapterIndex (79 rows) and DT_BossEncounter (281 rows), all columns field-verified, Unicode preserved. Two real transport bugs already fixed (Lua 5.3 rejects JSON \uXXXX escapes; NeoStack Lua create_asset trips on a stale in-memory empty package). Quirk recorded: UE strips the F prefix — /Script/Humanity.ChapterIndexRow resolves, the F-prefixed path returns None.
HOP 6 — GameplayTag taxonomy from registry ids. MISSING. No Config/Tags/*.ini and no generator. Tags load at engine init, so this must precede any Blueprint/StateTree that keys on ws.* or THREAD_01..22.
HOP 7 — DEM -> heightmap -> Landscape actor. EXISTS. Tools/terrain_fetch_preprocess.py (OpenTopography COP30 fetch -> UTM reproject at chosen m/vertex -> 16-bit PNG + machine meta JSON: Liang Bua bbox -8.58/-8.48/120.39/120.49, EPSG:32751, 30 m/vertex, 371x372 px, elev 141.75-1187.07 m, ue_landscape_z_scale 204.164). The LANDSCAPE SEAM is verified: open_level() handle method lvl:import_heightmap({file, scale}) produced a REAL Landscape at Content/Maps/LiangBua_TerrainSmoke.umap (379x379, 36 components) with World Partition external actors committed. This obsoletes the Translation Doc's Step-4 C++ ALandscape::Import() shim, which §4 spike 2 calls "the single highest-priority engineering dependency in the whole chain." No shim is needed.
HOP 8 — World Partition level per region + Data Layers. PARTIAL. One WP level exists (the smoke map). MISSING: a per-region scaffolder script, CellSize setting, and the protected-zone -> SafeZone Data Layer tagging pass (unreal.DataLayerEditorSubsystem is scriptable; nothing has run it).
HOP 9 — Landscape auto-material from ESA WorldCover. MISSING. No master material, no layer-blend graph, and terrain_fetch_preprocess.py fetches DEM only — there is no WorldCover fetch/sample leg at all.
HOP 10 — Zone row -> parameterized PCG graph. PARTIAL (seam proven, content absent). The Epic MCP PCG seam is VERIFIED LIVE (http://127.0.0.1:8000/mcp, PCG+PCGToolset+EditorToolset enabled, auto-start seeded via repo-tracked Config/DefaultEditorPerProjectUserSettings.ini; smoke: CreateGraph -> AddNode "Surface Sampler" -> ConnectNodePins -> GetGraphStructure, saved at Content/Data/Smoke/PCG_HelloGraph). MISSING: any biome/terrain_type template graph, any Load Data Table / Data Table Row to Attribute Set wiring, the terrain_type->template binding table (grep-confirmed absent across docs/ and _source/), and the population numbers (ambient_threat->density, vril_density->creature-tier filter, climactic_affordances->marker class) — the Translation Doc assigns these to its own inference layer and the layer is empty.
HOP 11 — Headless whole-region bake. MISSING. PCGWorldPartitionBuilder never invoked; the community cell-loading/Grid-Size edge case is untested against our graphs.
HOP 12 — Boss marker -> playable fight. PARTIAL. GAS foundation compiles (UHumanityAttributeSet with the eight ruled Composure sub-nodes, UHumanityDensitySubsystem = the vril-density dial, UCombatTelemetrySubsystem). Content/Combat/ST_BossPhases_Greybox.uasset exists with a valid StateTreeComponentSchema and the three phases recorded as asset metadata — but the internal state graph is EMPTY: UStateTree.EditorData is a protected UPROPERTY, unreachable via py-bridge/find_object, and NeoStack exposes no StateTree authoring domain. No PCG-spawned marker actor class exists yet.
HOP 13 — ws.* worldstate + save. MISSING ENTIRELY. Source/Humanity/ contains only Humanity.Build.cs/cpp/h, three Combat classes, and two Data row headers. No UWorldStateSubsystem, no FWorldStateValue, no UWorldStateSaveGame. This is the shared blocker the cinematic lane also names.
HOP 14 — DataValidation + cook/package. MISSING. No UEditorValidatorBase subclass, no RunUAT invocation.
NET: hops 1, 5, 7 and the three automation channels are solid and proven with real data. The chain breaks in three places at once — nothing extracts the spine/zone rows into tables (hop 2/3), nothing types a registry column into C++ at scale (hop 4), and nothing binds a zone row to a PCG graph (hop 10). Everything downstream of hop 10 (bake, fight, worldstate, cook) is unstarted but unblocked-by-construction once those three close.
Already done since the 2026-07-19 audit (was reported as a wall, is not one now):
Genuinely external (not ours to build):
| item | kind | effort | gate | what it is | unblocks |
|---|---|---|---|---|---|
| docs/REGISTRY_ROW_STRUCT_SPEC.md | spec_doc | medium | nothing_buildable_now | The per-registry column-to-UE-type contract the roadmap names as the lane's #1 wall, and it is still genuinely absent (no such doc in docs/). Rules to pin, one table per registry plus a default policy: id/key columns -> FName; PLAYER-FACING | Codegen; all ~34 remaining registry row structs; the spine-layer row structs; the FText localization law being satisfiable at all; DataTable FK resolution |
| Tools/gen_row_struct.py | tool_or_script | medium | nothing_buildable_now | Codegen: read a registry CSV header (+ the spec's per-registry type overrides in a sidecar JSON) and emit Source/Humanity/Public/Data/<Name>Row.h with USTRUCT(BlueprintType) struct HUMANITY_API F<Name>Row : public FTableRowBase, member name | Turns 'author 34 row structs by hand' (the standing build-lane step named in START_HERE three separate times) into one scripted run + one compile |
| The 14 UE5-consumed registry row structs + DataTable imports | cpp_code | medium | nothing_buildable_now | Generate, compile, and import the registries Contracts §1.3 says UE5 reads: FCreatureRow (T0_Creature_Roster, 132 rows — the named exit-criterion for roadmap queue #7), FRegionIndexRow (76), FVrilSiteRow (42), FCharacterRow, FAntagonistNetw | PCG creature/boss population; quest wiring FK resolution; the environment-grammar combat surfaces; every downstream DataTable consumer |
| harness/extract_spine_rows.py | tool_or_script | medium | nothing_buildable_now | The spine-row extractor — still genuinely absent. Emits per-chapter CSV/JSON from docs/spine/CH_NN.md into a staging dir (e.g. build/spine_rows/CH_NN/{sites,beats,forks,fork_options,scenes,sq,boss}.csv). CRITICAL EFFORT REDUCER discovered t | Every UE step downstream of the Translation Doc §3 pre-step: DT_Sites, DT_Beats, DT_ForkRules, DT_Scenes, DT_SQ, boss-phase binding. Nothing else in either repo can produce these r |
| Spine typed-layer row structs + DataTables | cpp_code | medium | nothing_buildable_now | FSiteRow, FBeatRow, FForkNodeRow, FForkOptionRow, FSceneRow, FSQBeatRow, FBossThinIndexRow generated from the extractor's CSV headers, imported as DT_Sites / DT_Beats / DT_ForkNodes / DT_ForkOptions / DT_Scenes / DT_SQBeats / DT_BossIndex. | Quest wiring (Step 8), Sequencer population (Step 9), PCG boss-marker placement (Step 6) |
| Tools/import_all_registries.py | tool_or_script | small | nothing_buildable_now | Manifest-driven bulk driver over import_registry_datatable.py: one JSON manifest (csv, struct path, dest, name-col) x N tables, one editor session, per-table read-back verification and a summary report with a non-zero exit on any row-count | Repeatable full-canon refresh into the engine after any registry edit; CI-able re-ingest |
| Zone Catalog machine columns: worldcover_biome + zone_anchor_wgs84 | schema_field | small | nothing_buildable_now | Add two columns to the T1_Region_Page_Template Zone Catalog and populate them on the four live pages (flores_island, bali, sumatra_java, angkor_khmer). worldcover_biome = an ESA WorldCover class per zone (already proposed as review item AU; | PCG zone instantiation with real world positions; the Biome Core / auto-material vegetation key; the UE5 readiness gate |
| Tools/worldcover_sample.py | tool_or_script | medium | nothing_buildable_now | Extend the terrain chain with the missing landcover leg: fetch ESA WorldCover 10 m tiles for a region bbox (same bbox the terrain meta JSON already emits), and emit (a) a per-zone majority-class + class-mix record keyed on zone_id (the valu | worldcover_biome population without hand-authoring; the landscape auto-material's initial weightmaps; PCG Biome Core flora |
| harness/extract_zone_catalog.py + harness/apply_zone_catalog_columns.p | tool_or_script | small | nothing_buildable_now | Reader and deterministic writer for the '## Zone Catalog' block. The reader emits zones.csv per region (the FZoneRow source). The writer adds/populates a named column across the catalog table in place with an all-or-nothing validation contr | The Zone Catalog columns item at scale; DT_Zones; the per-region PCG parameterization input |
| docs/translation/PCG_BINDING_AND_POPULATION.md | spec_doc | medium | nothing_buildable_now | The empty inference layer, populated. Two tables plus a defaults policy. TABLE A, terrain_type -> PCG template binding: one row per live terrain enum value observed in the spine site rows (cave_system, sacred_site, mountain, water_body, agr | PCG template authoring; per-zone parameterization; the whole Step 6 scatter |
| PCG biome template graphs (/Game/PCG/Templates/PCG_Biome_*) | template_asset | large | nothing_buildable_now | One reusable PCG graph per terrain_type, authored over the VERIFIED Epic MCP PCGToolset seam (call_tool dispatch, display-name node types, fromPinLabel/toPinLabel — all quirks already recorded). Each graph: Load Data Table (DT_Zones) -> Dat | A populated zone — the first real 'canon row visible in the running game' artifact; roadmap queue #7's exit criterion |
| Tools/build_region_level.py | tool_or_script | large | nothing_buildable_now | The per-region scaffolder — the script that gets run 69 times. Inputs: region_id, the terrain meta JSON, zones.csv. Steps over the NeoStack channel + UE-python bridge: create/open a World-Partitioned .umap at /Game/Maps/<region_id>; set Run | Region N+1 costs a command line instead of a session; the whole ×69 scale story |
| Source/Humanity/Public/World/WorldStateSubsystem.h + .cpp | cpp_code | large | nothing_buildable_now | Genuinely absent from Source/ today. UWorldStateSubsystem : UGameInstanceSubsystem holding TMap<FGameplayTag, FWorldStateValue>, where FWorldStateValue is a small tagged union (enum discriminator + bool/int/enum payload) so all three ws.* t | Quest fork ws_writes; the cinematic lane's LOCKED/path-conditional scenes (it names this subsystem as its blocker); save/load; the combat lane's boss ws_writes column |
| Tools/gen_gameplay_tags.py + Config/Tags/HumanityCanonTags.ini | tool_or_script | small | nothing_buildable_now | Emit a GameplayTag ini from canon ids: ws.* keys from T0_Worldstate_Variables, thread.T01..T22 (canonicalizing the two live encodings — Chapter_Index packs T01..T22, Thread_Grid keys THREAD_01..22), region.<region_id> from T0_Region_Index, | WorldStateSubsystem tag keys; StateTree Enter Conditions; PCG attribute filters that key on threads/regions |
| M_Landscape_Auto + WorldCover layer mapping | template_asset | medium | nothing_buildable_now | The author-once landscape master material: LandscapeLayerBlend / LandscapeLayerWeight / LandscapeLayerCoords self-assigning layers by ESA WorldCover class + slope + height, so no region is ever hand-painted. Authored once through the NeoSta | A region that looks like its real landcover with zero per-region art time; PCG Biome Core flora keyed on layer weights |
| StateTree authoring escape hatch (C++ editor helper) | cpp_code | large | nothing_buildable_now | A small editor-module UFUNCTION(BlueprintCallable/CallInEditor) that constructs StateTree states, transitions, and Enter Conditions programmatically, exposed to the py-bridge — because UStateTree.EditorData is a protected UPROPERTY, unreach | Scripted boss-phase graphs from DT_BossEncounter.phase_breakdown_object/composure_nodes; removes the ×281 manual pass |
| FText retrofit on player-facing columns | cpp_code | small | nothing_buildable_now | FChapterIndexRow.title and FBossEncounterRow.boss_name (and every player-facing column in every generated struct) are FString today, which violates the binding localization-from-the-first-string law in both the game CLAUDE.md and Translatio | Ship-everywhere localization; prevents a whole-corpus retrofit later |
| Section-1 machine PARAMETERS BLOCK writeback | tool_or_script | small | nothing_buildable_now | The terrain meta JSON already holds every number the pages lack (region_bbox_wgs84 south/north/west/east, projection EPSG, meters_per_vertex, elevation range, ue_landscape_z_scale) but flores Section 1 records them as PROSE bullets ('- dem | Per-region Landscape scaling without hand-reading a JSON; the terrain readiness gate; the alteration_list instantiation that depends on the bbox |
| Tools/bake_region_pcg.py + PCGWorldPartitionBuilder edge-case test | tool_or_script | medium | nothing_buildable_now | Wrap UnrealEditor.exe -run=WorldPartitionBuilderCommandlet -Builder=PCGWorldPartitionBuilder -IncludeGraphNames=... -Unattended -AllowCommandletRendering, and test it against OUR specific template graphs before any CI reliance — the known c | Headless per-region population; the ×69 batch story (the batch itself is 5090-gated, the harness is not) |
| Canon-integrity DataValidation validators | cpp_code | medium | nothing_buildable_now | UEditorValidatorBase subclasses run by -run=DataValidation: RowName integrity (every DataTable row name still matches its registry id — re-import fully overwrites a table and silently breaks any FDataTableRowHandle keyed to a renamed row, w | Trustworthy re-imports; a cook-time gate; catching the rename class of silent breakage |
| The 11 scene_type shot-template Level Sequences | template_asset | large | cross_lane | One Level Sequence template per VERBATIM scene_type value carrying camera blocking/timing/cut rhythm — which is not in the seven-column scene schema at all and never will be. UE5 Step 9 duplicates these per scene row; the cinematic lane own | Step 9 Sequencer population from DT_Scenes |
Critical path: harness/extract_spine_scene_rows.py + the Scene_Spec population it feeds. The lane's canon input is COMPLETE and gate-validated — 439 typed scene rows across all 79 spine nodes (| scene_anchor_id | beat_ref | scene_type | path_bucket | anchor_type | participant_refs | hard_line_relevance |), already checked by harness/check_spine_graph.py (scene_type against the §5.5 eleven, beat_ref resolving to a real beat). But only 16 of those 439 exist as machine rows anywhere: T0_Scene_Spec_Registry covers Ch 55/58/76/77/Prologue/Epilogue and nothing else. Every downstream hop — the FSceneSpecRow struct, the DataTable import (seam PROVEN at 79 and 281 rows), template selection, participant resolution, dispatch, the cinematic gate — operates on rows that today live only as markdown in 79 files. The extractor is small, depends on nothing, is gated by nothing, and is the single item that moves the lane from 3.6% row coverage to 100%. Runner-up: UWorldStateSubsystem (item 8) — but that only unblocks the LOCKED/path-conditional minority of rows, whereas the extractor unblocks all of them.
CANON ROW -> THING IN THE RUNNING GAME. Eleven hops. Verified against the live tree 2026-07-22, not against the 2026-07-19 wall list.
HOP 1 — Spine §13 scene row. EXISTS (and is far stronger than the wall list implies). 439 typed scene rows across all 79 nodes, shape | scene_anchor_id | beat_ref | scene_type | path_bucket | anchor_type | participant_refs | hard_line_relevance | (e.g. docs/spine/CH_02.md:193-199, CH_76.md:183, CH_PROLOGUE.md:162). Already gate-validated: harness/check_spine_graph.py:645-680 checks scene_type against the §5.5 eleven-value set, resolves every beat_ref to a real beat, and validates path_bucket. DOC-CURRENCY DEFECT FOUND: T99_Translation_Cinematic §3 Step 1 states the 7th spine column is thematic_anchor and that hard_line_relevance has "no spine column at all" — the executed spine is the exact reverse on all 79 nodes. Step 1's inference instruction is inverted.
HOP 2 — extract markdown table -> CSV. MISSING. No extractor in harness/ (28 scripts; enrich.py and extract_claims.py do not produce it). This is the roadmap's named "spine-row extractor" wall, still true, and it is the lane's bottleneck.
HOP 3 — T0_Scene_Spec_Registry (31 columns, ACTIVE v0.1). PARTIAL. registries/T0_Scene_Spec_Registry [ACTIVE v0.1]/T0_Scene_Spec_Registry.csv holds 16 rows for 6 nodes only (Ch 55, 58, 76, 77, Prologue, Epilogue) — a 2026-07-21 director pass re-keyed them to the executed v3.1 spine. ~423 spine scene rows have no registry row. The Contract §5.5 audio-trio (audio_priority_layer / scene_audio_intent / hard_line_relevance) is populated only on those 16.
HOP 4 — registry CSV -> UE DataTable. PARTIAL — mechanism PROVEN, struct MISSING. C:/dev/Humanity/Humanity/Tools/import_registry_datatable.py landed real imports at scale (commit 76691a2: DT_ChapterIndex 79 rows / 51 cols, DT_BossEncounter 281 rows / 26 cols), with the transport bugs already fixed (CSV rides a UTF-8 temp file through the UE-Python bridge, not a Lua string literal; create-or-load via unreal.DataTableFactory). Missing: Source/Humanity/Public/Data/SceneSpecRow.h — only ChapterIndexRow.h and BossEncounterRow.h exist. UserDefinedStructs are a RULED dead end on this seam (NeoStack add_variable is Blueprint-only), so the native USTRUCT is mandatory. Gotcha already learned: UE strips the F prefix — /Script/Humanity.SceneSpecRow resolves, the F-prefixed path is None.
HOP 5 — scene_type -> shot-template Level Sequence. MISSING (spec AND asset) — but the SEAM IS MUCH BETTER THAN THE WALL LIST SAYS. No shot-grammar doc exists anywhere in docs/ or _source/ (only the roadmap's own mention of the gap). Content/Cinematics/ does not exist; zero Level Sequences in the project. HOWEVER: NeoStack's Sequencer Lua domain IS installed and rich — Plugins/NeoStackAI/Source/NeoStackAI/Private/Lua/Bindings/LuaBinding_Sequencer.cpp is 6,603 lines exposing add("binding",{actor_name,spawnable,spawn_ownership,component_name}), add("track",{track_type,binding,start_time,end_time,camera_binding,sequence,sound_asset,animation_asset,property_name,shot_display_name,row_index}), add("keyframe",{binding,track_type,channel_index,time,value,string_value,object_path,interp}), add("section"), add("marked_frame"), add("folder"), add("binding_tag"), plus list("channels"/"keyframes"/"properties") read-back and _enrich_sequencer handles. Camera blocking, cut timing and shot rhythm ARE fully scriptable. The 11 templates are an authoring task with a proven automation vector, not a hand-only wall.
HOP 6 — beat_ref -> site -> region -> .umap. PARTIAL. The join is specified (TD Step 3, corpus-corrected: anchor_type is a TRIGGER class, not a map anchor) and all inputs exist (spine beats carry site; region pages carry Zone Catalogs). Missing: any joiner tool, and any region .umap — Content/Maps holds only LiangBua_TerrainSmoke (the terrain-lane smoke), no region base map for any of the 69 regions.
HOP 7 — participant_refs (CHAR_id) -> MetaHuman asset path. MISSING — wall CONFIRMED, and the roadmap's fix-route is mis-ordered. Byte-verified: registries/T0_Character_Index [ACTIVE v1.1]/T0_Character_Index DRAFT v1.1.csv is 163 rows / 20 columns with NO mesh_pipeline_type and NO asset-path column; T0_Antagonist_Network_Registry/Sheet1.csv is 8 columns, likewise none. Contract §1.5.1's claim that both registries "default mesh_pipeline_type to metahuman" is not true of the live CSVs. The roadmap calls this "cross-lane — the UE build must generate MetaHumans and emit stable asset IDs first"; that ordering is wrong — the COLUMN can be declared and left empty now, which unblocks the extractor, the row struct and the gate immediately, and is populated as MetaHumans land. Second constraint found: NeoStack's core LuaBinding_MetaHuman.cpp is a 2-line stub reading "moved to the NSAI_MetaHuman extension module". CORRECTED 2026-08-13 — that sentence names where the code WENT, and this line read it as absence. The extension module is present, compiled and fully implemented: Plugins/NeoStackAI/Binaries/Win64/UnrealEditor-NSAI_MetaHuman_Integration.dll at 938,496 bytes (ControlRig 1,278,464 / IKRig 927,232 for scale; a WITH_NSAI_METAHUMAN_INTEGRATION=0 stub build would be a few KB), linking MetaHumanCharacter.dll + MetaHumanCharacterEditor.dll + MetaHumanCharacterPalette.dll + MetaHumanIdentity.dll — imports that appear ONLY in the Build.cs bHasMetaHumanCharacter branch, so it compiled with the integration ON. It exposes 66 Lua functions including metahuman_fit_face_to_vertices (Mesh-to-MetaHuman), metahuman_conform_body, metahuman_request_textures, metahuman_is_auto_rigging, metahuman_build, metahuman_spawn_actor and metahuman_compare_face. A Build.cs-only Source dir is the shipping format for all 64 NSAI integrations (bUsePrecompiled = true), and LoadingPhase: None is load-on-demand used by 62 of them including working modules — neither is disablement. All nine engine MetaHuman plugins are installed and MetaHumanCharacter is enabled at Humanity.uproject:105. So MetaHuman work does NOT have to route through the UE-Python bridge; the Lua domain is available and the roster-scale auto-rig path is scriptable. Evidence, with the DLL sha256 and the full function list: build/ops/NEOSTACK_METAHUMAN_BINDING_2026-08-13.json. Not yet verified: no call has been executed live — that is one character end to end, and it is the next step, not a claim.
HOP 8 — audio FKs -> SoundWave. PARTIAL — the wall is stated imprecisely. The scene ROW does carry audio FKs: T0_Scene_Spec_Registry already has music_cue_id_ref, voice_refs, sfx_id_ref_array, sfx_category_array, dialogue_dataset_ref. Three real gaps: (a) those cells are empty on nearly every row; (b) T0_Theme_Registry [DRAFT v0.1] (12 rows), T0_Voice_Registry [DRAFT v0.1] (10 rows) and T0_SFX_Registry [ACTIVE v1.0] (12 rows) carry NO UE asset-path column, so an id cannot resolve to /Game/Audio/...; (c) the SPINE seven-column row carries no audio column at all — that is the true form of "no SoundWave FK on the scene row". Import mechanism is PROVEN: Content/Audio/SFX/smoke_stone_door landed via AssetImportTask over the bridge, and Tools/generate_sfx.py + a live ElevenLabs key produce the source WAV/MP3.
HOP 9 — path_bucket dispatch -> DT_SceneDispatch + ws.* WorldStateSubsystem. MISSING in code; MUCH better specified than the wall says. registries/T0_Worldstate_Variables [ACTIVE v0.1]/Sheet1.csv is LIVE and POPULATED (42 rows) with exactly the dispatch keys: WS_004 path_bucket (enum TRULY_GOOD/GOOD_ENOUGH/EVIL/UNLOCKED, default UNLOCKED), WS_005 path_lock_in_state, WS_013 cassius_velheim_state (RESOLVED_TGP_PURGE/RETREATED_GE/VICTORY_EVIL), WS_017 father_encounter_variant (REUNION_TGP/NEGOTIATION_GE/COMBAT_EVIL) — and WS_017's consumer list literally names "Ch76_77_cinematic_dispatcher". T99_Translation_Combat Step 7 now FULLY SPECS the shared subsystem: UWorldStateSubsystem : UGameInstanceSubsystem holding TMap<FGameplayTag, FWorldStateValue> (tagged union bool/int/enum), persisted via UWorldStateSaveGame : USaveGame with AsyncSaveGameToSlot, "shared verbatim with UE5_BUILD Step 10". So the ws.* design is RULED; only the C++ is absent, and it is gated by nothing. Two live defects: WS_004's enum omits ALL (which SPINE_SCHEMA_v3 §1 and every Scene_Spec row use), and WS_013/WS_017 consumer strings still name the SUPERSEDED chapter homes ("Ch74_phase_3_resolver", "Ch75_father_encounter_dispatcher") after the endgame re-cascade moved them to Ch 76.
HOP 10 — boss combat-state event. MISSING in code; the SPEC NOW EXISTS (wall is stale). T99_Translation_Combat Step 2 maps boss phase state to GameplayTags Boss.Phase.1/2/3 and Boss.Composure.Node.<mode>.Broken; Step 7 says verbatim "Boss cinematics fire off a boss combat-state event StateTree emits (the cinematic lane's spike 4 dependency resolves here — a GameplayTag/StateTree event the Sequencer trigger listens for)." A greybox asset exists at /Game/Combat/ST_BossPhases_Greybox. NEW ENGINE CONSTRAINT discovered at commit 76691a2: UStateTree.EditorData is a protected UPROPERTY unreachable via the py-bridge or find_object, and the asset exposes 0 editable properties — the state GRAPH must be authored in-editor by hand. Cinematic does NOT have to wait for that: define the tag channel + a listener component + a debug emitter in C++ and the whole cinematic trigger path is testable today.
HOP 11 — delivery: realtime LevelSequenceActor / MRQ dailies. MISSING as run; mechanism available. NeoStack's MRQ Lua domain is NOT installed (LuaBinding_MovieRenderQueue.cpp is a 2-line "moved to the NSAI_MovieRenderPipeline extension module" stub), as is IKRig/IKRetargeter. Route via the VERIFIED universal UE-Python bridge (invoke('/Script/PythonScriptPlugin.PythonScriptLibrary','ExecutePythonCommand',...) -> MoviePipelineQueueEngineSubsystem / MoviePipelinePythonHostExecutor) or headless UnrealEditor-Cmd. Nothing external gates a 720p placeholder render.
BONUS FINDING — one named wall is currently VACUOUS: "ambient rows carry no beat_ref". All four live region pages (flores_island, bali, sumatra_java, angkor_khmer) state "page-authored ambient-cinematic additions: none yet". Zero ambient rows exist, so nothing is blocked by it today; fixing it now is cheap pre-emption, not unblocking.
Already done since the 2026-07-19 audit (was reported as a wall, is not one now):
UnrealEditor-NSAI_MetaHuman_Integration.dll 938,496 B with 66 Lua functions; UnrealEditor-NSAI_IKRig_Integration.dll 927,232 B). A stub that names its successor is a forwarding address, not an absence. MRQ routes through the bridge; MetaHuman and retargeting have native Lua domains. Evidence: build/ops/NEOSTACK_METAHUMAN_BINDING_2026-08-13.json.Genuinely external (not ours to build):
| item | kind | effort | gate | what it is | unblocks |
|---|---|---|---|---|---|
| harness/extract_spine_scene_rows.py — the spine scene-row extractor | tool_or_script | small | nothing_buildable_now | A harness script that walks all 79 docs/spine/CH_NN.md files, locates the §13 scene table by its header row / scene_anchor_id / beat_ref / scene_type / path_bucket / anchor_type / participant_refs / hard_line_relevance /, parses all 439 r | Everything. Converts the lane's canon input from markdown-only (423 of 439 rows machine-invisible) to a CSV the registry, the USTRUCT, the DataTable import, the dispatch table and |
| T0_Scene_Spec_Registry population to 439 rows + fidelity re-baseline | tool_or_script | small | nothing_buildable_now | A deterministic scatter (the proven O-1 transform vector) that merges the extractor output into registries/T0_Scene_Spec_Registry [ACTIVE v0.1]/T0_Scene_Spec_Registry.csv — preserving the 16 hand-authored director-pass rows verbatim as the | A real DataTable import at corpus scale; the per-region cinematic build loop; the dispatch completeness gate. Turns Scene_Spec from a 6-node sample into the lane's actual work queu |
| Source/Humanity/Public/Data/SceneSpecRow.h — FSceneSpecRow USTRUCT | cpp_code | small | nothing_buildable_now | A USTRUCT(BlueprintType) struct HUMANITY_API FSceneSpecRow : public FTableRowBase with 31 snake_case FString UPROPERTY members mirroring the live CSV header 1:1 (scene_id, scene_anchor_id, scene_name, scene_type, chapter, path_bucket, par | The scene corpus becomes queryable inside UE — the input to every Sequencer assembly, dispatch lookup and trigger binding. This is the standing per-registry build-lane step the Dat |
| docs/translation/T99_Cinematic_Shot_Grammar.md — the 11 scene_type sho | spec_doc | medium | nothing_buildable_now | The missing mapping the roadmap names as this lane's first-artifact true gate: one spec block per scene_type across the eleven VERBATIM values (canonical_set_piece, architect_appearance, boss_encounter_intro, boss_encounter_phase_transition | The 11 template Level Sequences; the whole Step-4 assembly leg. Without it every template is an improvised shot list, which TD §2.2 forbids. |
| Content/Cinematics/Templates/LS_TPL_<scene_type> ×11 + Tools/build_sho | template_asset | medium | nothing_buildable_now | Eleven template Level Sequences, one per scene_type, built by a scripted driver rather than by hand — NeoStack's Sequencer Lua domain is installed and rich (LuaBinding_Sequencer.cpp, 6,603 lines). The script drives open_asset() -> `add('b | Per-row duplication + population (the scene-driven track's whole mechanism). Retires the top named cinematic wall — and retires it as automation, not as manual labour. |
| Tools/assemble_scene_sequence.py — the per-row duplicate-and-populate | tool_or_script | medium | nothing_buildable_now | The TD Step-4 native/bulk leg: reads DT_SceneSpec, for each row duplicates LS_TPL_<scene_type> to /Game/Cinematics/Scenes/<scene_category>/LS_<scene_id> (the Contract §5.4 path convention), rebinds the placeholder participant bindings to th | The scene-driven track at volume (per-chapter cutscenes + ambient) — the 90% of the 439 rows that never need a director pass. |
| Participant asset-path columns on T0_Character_Index + T0_Antagonist_N | registry_extension | small | nothing_buildable_now | Three columns declared under a new cinematic-participants system in docs/registry_extensions.json and mirrored into docs/fidelity_baseline.json added_columns (both registries already carry declared extensions, so the vector and its gate | TD Step 2 participant resolution; the cinematic readiness gate; the assembly driver's rebinding step. Retires the 'participant CHAR_id has no MetaHuman asset-path lookup' wall at t |
| Source/Humanity/Public/World/WorldStateSubsystem.h/.cpp — UWorldStateS | cpp_code | medium | nothing_buildable_now | The shared ws.* subsystem, fully specced by T99_Translation_Combat Step 7 and UE5_Build Step 10 and gated by nothing: UWorldStateSubsystem : UGameInstanceSubsystem holding TMap<FGameplayTag, FWorldStateValue> where FWorldStateValue is a | Path-conditional dispatch (TD Step 5) for every LOCKED / TRULY_GOOD / GOOD_ENOUGH / EVIL row; the combat lane's save wiring; the Ch 76 two-fork showcase. Retires half the 'converge |
| Tools/generate_ws_tags.py + Config/DefaultGameplayTags.ini ws.* seed | tool_or_script | small | nothing_buildable_now | Derives the FGameplayTag naming convention from canon instead of inventing it — reads the 42 rows of T0_Worldstate_Variables and emits ws.path_bucket, ws.path_lock_in_state, ws.cassius_velheim_state, ws.father_encounter_variant, … i | The subsystem's key space; StateTree property bindings that read/write ws.* tags; the dispatch resolver's lookups. |
| DT_SceneDispatch + FSceneDispatchRow + the dispatch resolver | cpp_code | medium | nothing_buildable_now | The TD Step-5 realization of Contract §5.6's named-but-unspecified convergence_node_scene_dispatch: an FSceneDispatchRow (scene_anchor_id, path_bucket, fork_id, ws_key, ws_value, scene_spec_ref) DataTable keyed scene_anchor_id + committed b | Every path-conditional and post-lock scene. The Ch 76 Two Courts is the verification case (the TD is explicit that Ch 77's reveal is path-INVARIANT and is the wrong test). |
| Boss cinematic trigger channel — FHumanityCombatTags + UBossCinematicT | cpp_code | small | nothing_buildable_now | Decouples the cinematic lane from the boss-AI lane instead of waiting on it. Declares the native GameplayTags T99_Translation_Combat Step 2 already ruled (Boss.Phase.1/2/3, Boss.Composure.Node.<mode>.Broken), a component that listens on tha | All boss_encounter_* scene rows (a large slice of the 439). Retires the wall 'boss cinematics need a combat-state event no boss AI emits' — the spec landed with the combat Translat |
| harness/check_scene_spec.py — the cinematic completeness gate | tool_or_script | small | nothing_buildable_now | The teeth this lane has no equivalent of yet. Asserts: every spine §13 scene row has a Scene_Spec row (the extractor's own regression guard); every scene_anchor_id group carries either a complete TRULY_GOOD/GOOD_ENOUGH/EVIL set, an ALL/UNLO | Trustworthy autonomous assembly at volume — TD §5 step 11's own closing discipline ('a region can look cinematic-ready and still be blocked'), made mechanical. |
| Audio asset-path columns on T0_Theme_Registry / T0_Voice_Registry / T0 | registry_extension | small | nothing_buildable_now | One ue_sound_asset_path column per registry (plus asset_import_status), declared in docs/registry_extensions.json under an audio-assets system and mirrored into fidelity_baseline added_columns — T0_Theme_Registry already carries a dec | TD Step-4's audio track population and the dependency-check walk (a scene currently routes to blocked_on_dependencies with no way to ever clear). Also unblocks the MetaHuman Animat |
| Tools/render_mrq_dailies.py — headless MRQ over the Python bridge | tool_or_script | small | nothing_buildable_now | Drives a Movie Render Queue job for a named LevelSequence + MapName at 1280x720 placeholder quality and writes to Saved/Dailies/. Must route through the VERIFIED UE-Python bridge (`invoke('/Script/PythonScriptPlugin.PythonScriptLibrary','Ex | Roadmap queue item #11 (one scene row -> a 720p video with placeholders) and the batch cultural-authenticity/quality audit the scene-driven track requires pre-build. Zero external |
| Ambient-row anchor: site_ref on page-authored ambient_cinematic rows | schema_field | small | nothing_buildable_now | Closes TD §4 spike 6 with the obvious sane default rather than a question: an ambient row authored on a region page has no spine beat to join through, so it anchors on site_ref (a site_id already present in every page's Zone Catalog) and | The ambient_cinematic category's map anchoring, before it can silently produce unanchorable rows. |
| Region-page Scene-index shape fix (flores/bali) to clear the Cinematic | schema_field | small | nothing_buildable_now | harness/check_build_readiness.py currently reports Cinematic BLOCKED on all four live pages. flores_island and bali carry bare scene slugs with no CHnn_Bnn (BLOCKED-ON beat_ref too); sumatra_java and angkor_khmer bind beat_ref but are BLOCK | The first four pages flipping Cinematic to READY on the scorecard — the machine-visible signal that the lane's per-region loop can start. |
| Mocap / retarget library acquisition + Tools/retarget_participants.py | template_asset | medium | external_service | A licensed body-animation source (Fab / ActorCore / Mixamo class) plus an IK Rig + IK Retargeter chain so cinematic participants get body performance without per-character keyframing (TD Step 2's stated mechanism). Constraint found: NeoStac | Any participant that must move rather than stand. Placeholder assembly, camera work, dispatch and MRQ all proceed WITHOUT it — do not let it gate the lane. |
| Canon correction: the Ch 74 -> Ch 76 endgame re-cascade residue in T0_ | josh_ruling | small | josh_decision | The one genuine canon call in this lane, presented as a brief, not a question. Three live artifacts still name the SUPERSEDED chapter homes after the endgame re-cascade moved the Cassius/Father encounters to Ch 76: T0_Worldstate_Variables W | A dispatch resolver that binds the right chapter's forks. Prevents the re-cascade residue hardening into code. |
| T99_Translation_Cinematic currency pass (Step 1 column inversion + the | spec_doc | small | nothing_buildable_now | Living-source fix-ups, all factual not canon. (1) §3 Step 1 states the spine's 7th column is thematic_anchor and that hard_line_relevance is 'Cinematic-expanded DOWNSTREAM, not a spine column' — the executed spine is the exact reverse o | Stops the next agent building against an inverted column map or re-opening two spikes that the combat doc already closed. |