magicciv/.project/objectives/p1-14-guide-magic-school-scope-drift.md
Natalie c5b62ddc0b feat(@projects/@magic-civilization): update ai state and production systems
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-04-17 17:03:27 -07:00

7.3 KiB
Raw Blame History

id title priority status scope owner updated_at evidence
p1-14 Gate Game 2/3/4 magic-school content behind EpisodeGate (future-game scope) p1 oos game2 2026-04-17
public/games/age-of-dwarves/guide/src/pages/DevSpritesPage.tsx
public/games/age-of-dwarves/guide/src/data/game.ts
public/games/age-of-dwarves/guide/src/data/index.ts
public/games/age-of-dwarves/guide/src/app/guide-data.ts
public/games/age-of-dwarves/guide/src/pages/HomePage.tsx
public/games/age-of-dwarves/guide/src/pages/LensesPage.tsx
public/games/age-of-dwarves/guide/src/pages/SurvivalGuidePage.tsx
src/packages/guide/src/components/climate-sim/HexGLRenderer.tsx
src/packages/guide/src/components/cards/TerrainCard.tsx
src/packages/guide/src/components/ui/SchoolPip.tsx
src/packages/guide/src/data/ecology.ts
public/games/age-of-dwarves/guide/e2e/all-routes.spec.ts

Summary

Per CLAUDE.md's hard Game 1 scope rule (Dwarves only, NO magic; leylines / Green school / spacefaring → Game 2; Archons / Ascension / 5 magic schools → Game 3), no magic content may ship into the Game 1 guide. The 2026-04-17 p2-09 scope-narrow pass deleted 10 Game 2/3 pages. But a prophylactic Explore audit on the same day — triggered by the Tourguide route-coverage spec catching magic-data imports in Game 1 pages that still rendered — surfaced 2 RED and 6 YELLOW residual leaks that survived the first purge:

RED (runtime crash risk if data drifts)

  • public/games/age-of-dwarves/guide/src/pages/DevSpritesPage.tsx:5 — live import of @resources/magic/schools.json. (Partial-fix: the p1-13 Wave-1 pass replaced the import with the shared SCHOOL_COLORS palette, so the crash is gone; keeping this row as evidence of why the objective exists.)
  • src/packages/guide/src/components/climate-sim/HexGLRenderer.tsx:7,749,783 — live ley-line network rendering via LEY_COLORS[edge.school]. In Game 1 the climate simulator's rendered grid shows ley-edge meshes with school-coded colors, inserting Game 2 visual vocabulary into every Game 1 planet view.

YELLOW (renders stale Game 2+ content into Game 1 UI, inert but wrong)

  • public/games/age-of-dwarves/guide/src/data/game.ts:8798infusionTrees loader pulls magical_promotions JSON into the guide context; exported to every consumer via data/index.ts:40.
  • public/games/age-of-dwarves/guide/src/app/guide-data.ts:48 — the data context injection re-exposes magic-school data to every page via GuideDataProvider.
  • public/games/age-of-dwarves/guide/src/pages/HomePage.tsx:220224 — nav items /magic/schools, /magic/spells, /magic/archons still defined; the routes were purged, so clicking these in Game 1 hits the <Navigate to="/" replace /> fallback. Broken-link UX.
  • public/games/age-of-dwarves/guide/src/pages/LensesPage.tsx:18formatUnlock renders magic-school unlock strings for Game 1 lenses; if a Game 1 lens has a magic unlock in data, the formatter renders it.
  • public/games/age-of-dwarves/guide/src/pages/SurvivalGuidePage.tsx:23,143,152ManaUpkeep interface + render.
  • src/packages/guide/src/components/cards/TerrainCard.tsx:256264mana_major field render block.

Additional front-page prose (Game 1 HomePage) already displays "5 Magic Schools" and "16 Asymmetric Races" in its feature grid — evidence that the <EpisodeProvider episode={1}> wrapping isn't being consulted by every page's content block.

Why this is P1 (ship-readiness), not P2 (polish)

Game 1 "Age of Dwarves" Early Access cannot ship with Game 2 content bleeding into Game 1 screens. Magic schools are deferred scope by an explicit CLAUDE.md rail. The Explore findings are proof-of-drift, not hypothetical. Any one RED entry is a potential crash when a data file shape changes; any YELLOW entry is visible-to-players scope violation.

Acceptance

  • RED fixes: HexGLRenderer ley-edge rendering is gated behind <EpisodeGate min={2}> OR the edge data's .school field is normalized to 'none' + color-coded in a scope-neutral way in Game 1. Verified by e2e/all-routes.spec.ts /climate/simulation pass remaining green AND a new focused assertion that LEY_COLORS is not consulted in Game 1 mode.
  • YELLOW fixes: every reference in the audit table above either (a) deleted if the feature it gates is strictly Game 2/3, (b) gated behind <EpisodeGate min={2}>, or (c) normalized to episode-agnostic content. The /magic/* nav items in HomePage are removed. formatUnlock returns empty / omits magic unlocks for Game 1 lenses. mana_major field is not rendered when episode === 1.
  • HomePage prose: the "5 Magic Schools" feature card is rewritten to an episode-1-appropriate Dwarf feature, OR moved into a <EpisodeGate min={2}> branch. The feature grid reflects Game 1 scope.
  • Regression guard: a new e2e assertion (in all-routes.spec.ts or a dedicated scope-hygiene.spec.ts) greps the rendered DOM of every Game 1 route for the strings mana, ley, school, disciplines, archon, ascension and fails if any are rendered outside an <EpisodeGate min={2}>. Scope becomes a mechanically-enforced invariant, not a doc rule.

Non-goals

  • Deleting src/packages/guide/src/pages/magic/ or equivalent universe-level Game 2/3 content — those pages are consumed by the future Game 2/3 guide shells, must NOT be removed.
  • Changing mc-core::grid::LeySchool Rust enum — ley_school is a tile-level field the simulator computes for all episodes; its mere existence in data is not scope violation, its rendering in Game 1 UI is.
  • Deleting the infusionTrees / disciplinesData JSON files — those are Game 2/3 source-of-truth data files, kept but gated.
  • Fixing the sim-cache server-mode dev path — see p2-20.

Reclassification — 2026-04-17 (user directive)

Out-of-scope for Game 1 ship-readiness. Per the user's scope clarification ("magic-school isnt apart of scope?! OOS! unless you mean as part of game2? game3 and game4?"), the work this objective describes belongs to Game 2 / Game 3 / Game 4 milestone prep, not to the Age of Dwarves Early Access ship.

  • Game 1 ship scope: NO magic content ships in the prod build. The minimal Game-1-side work (removing dead /magic/* nav links from HomePage so clicks don't redirect-to-root) landed 2026-04-17 along with the VITE_DEV_GUIDE dev-bundle flag. No further Game-1-side gating is required to ship.
  • Dev-bundle scope (VITE_DEV_GUIDE=1): contributors DO see Game 2+ content because the nav appends EP2_NAV / EP3_NAV / EP4_NAV / EP5_NAV from the shared guide-engine when the flag is set. That's intentional visibility, not a leak.
  • The remaining items originally captured here (HexGLRenderer ley-edges, infusionTrees export gating, formatUnlock magic branch, ManaUpkeep render, feature-grid prose) are all appropriate Game 2+ content-presentation work and will be picked up by whoever owns the Game 2 guide shell at public/games/age-of-kzzkyt/guide/ (which already has its own App.tsx + nav covering magic routes). Gate-behind-EpisodeGate in shared components is a Game 2 presentation-layer task.

Ownership cleared; Tourguide does not carry this objective. Kept as an oos / scope: game2 marker so the next agent working on the Game 2 guide has the audit trail from the Explore scan (see below).