Skip to content

Phase 13 plan — Backend + Android (incremental parallel)

Phase 13 plan

Living plan. Updated at each sub-phase boundary. Detail concentrates on the next 5 dispatchable steps; later steps are skeletal placeholders re-planned as the phase progresses.

1. Phase 13 in one paragraph

Phase 13 grows the backend (NestJS local-tunnel test deployment per ADR-0006) and a Kotlin Android client (sibling repo walkrpg-mobile, D-008 §2, D-015) together. Backend endpoints ship as Android needs them; Android features ship as the backend can serve them. There is no sharp “backend done” gate — Phase 13 ends when the Android client has the feature set the closed-beta cohort needs to play the vertical slice end-to-end. The canonical exit scenario: an Android user installs the app, signs in (mock auth), creates a Walker with a class, completes onboarding, ingests a synthetic walk, sees energy update, opens Quest 001 in Plenny, completes a quest step, receives tree points, allocates a node on cluster.first-steps, opens the faction screen and sees Unfinished Guild reputation update, walks into a Quest-002 encounter, resolves combat via the simulator API, syncs state back to backend, kills the app, reopens it, and finds the same state on the server. When that scenario passes end-to-end on a real Android device against the local-tunnel backend, Phase 13 is done and Phase 14 (VPS migration) opens.

2. Parallelism rule

Lore work runs in parallel with Phase 13. narrative-designer continues authoring Plenny Quest 003, additional regional NPCs, regional lore deepening, faction-specific quest hooks, and the foundation.mdx D-012/D-013 tie-in passage — all independently of Phase 13 dispatch.

Does NOT block Phase 13:

  • Adding new NPCs (data layer, already validated by Zod schemas).
  • Authoring new quests beyond 001/002 (data layer; backend endpoints are quest-id-agnostic).
  • Authoring region lore prose (wiki PL, no schema or backend touch).
  • Authoring class instances (data layer; class-pick endpoint reads from data).
  • Mechanics-designer authoring more tree nodes / keystones in data/.

DOES block Phase 13 increments:

  • Open D-level decisions in §4 — specifically the progression system spec (D-016 candidate). Until that ratifies, sub-phases that touch XP, level, or point-award math cannot dispatch.
  • Class instance scope: at least 1 playable class instance authored before the class-pick onboarding sub-phase dispatches (currently 0; schema exists, no instances).

Dispatch independence: narrative-designer is dispatched by CEO directly (or via game-director routing) for lore increments; tech-architect + mobile-developer are dispatched paired for Phase 13 increments. The two streams share the data layer (read-only from Phase 13’s side — Phase 13 does not modify quest/faction/region/NPC instances, only consumes them).

3. Three areas of Phase 13

3.1 Combat

Forward-references (added 2026-05-22 re-check): D-018 ratifies combat as the premium Energy sink (~30% per fight of a nominal 5k-step day); current 13-7 backend honours the Energy debit on /combat/encounter initiation. D-020 ratifies pull-based trigger + tiered tropy pool + visible-before-commit risk choice — these are post-Phase-13 forward-references (§10.3 below). D-010 governs HP=0 non-punitive defeat; D-020’s hard / keystone-ready energy-loss tail is orthogonal to D-010 §3.

Exists: Canonical math (combat/formulas.md §1-12), 19-stat dictionary (12 combat-resident + 7 tree-resident-only), seeded PRNG (xorshift32, D-010 §1), combat simulator (data/src/sim/combat.ts, commit 8856366) with worked-example reproducibility, Walker-first alternation (D-010 §2), non-punitive defeat (D-010 §3), cold_resist tagged-damage handling (12b-2).

Missing: Any backend surface (no /combat/encounter endpoints), any Android surface (no combat UI implementation — the 11e-1 wireframe exists but no code), encounter trigger plumbing (quest beat / region event → encounter spin-up), encounter outcome wiring (encounter result → quest state delta + tree-point award + faction-rep delta).

Phase 13 must deliver: A backend endpoint that initializes an encounter from a quest beat (returns seed + both stat snapshots), an endpoint that records a turn (Walker submits action, server replays simulator with stored seed up to that turn, returns next state), an encounter-end endpoint that resolves outcome to quest/tree/rep deltas. Android UI rendering the turn loop, energy spend animation, hp bars, retreat affordance. Must reproduce simulator’s worked-example deterministically across client and server (seeded replay is the anti-cheat foundation — even in mock-trust ADR-0006 posture, the contract is designed-in now to avoid retro-fitting later).

3.2 Quests

Forward-references (added 2026-05-22 re-check): D-024 ratifies the canonical 6 × 18 = 108 quest distribution (15 main + 3 hidden per region, strict per-region linear chain, Plenny canonical first). Phase 13 ships 6 Plenny quests (1 hidden = Quest 005) — D-024-compliant, but only ~33% of Plenny’s required 18-quest saga. Remaining Plenny + 5 other-region sagas are post-Phase-13 narrative-designer work. See §10.7.

Exists: Quest 001 (Plenny opening, phase 5b), Quest 002 (Frostlands, “Pieczętarnia milczy”, phase 11a-3), POST /quest/start + POST /quest/complete endpoints (11d-1, with 422 repeatable-guard), QuestSchema with steps/rewards/prerequisites, quest-log UI wireframe (11e-2).

Missing: Step-level progress (start/complete are quest-level; no per-step granularity yet), quest discovery (which quests are visible to a walker at any point — currently no GET /quest/available or equivalent), the D-006 Pillar 3 cosmos hook (allocating a keystone unlocks a hidden quest — designed but no implementation), quest-trigger combat plumbing (Quest 002 implies an encounter, but the trigger→encounter path is not built), Android quest log UI implementation (wireframe exists, no code), quest-prerequisite evaluation (quest A done → quest B visible).

Phase 13 must deliver: GET /quest/available returning per-walker visible quests evaluated against prerequisites + faction-rep gates + keystone gates, per-step progress endpoints (POST /quest/:id/step/:n/advance), keystone-unlock-as-quest-reveal hook (when POST /tree/allocate allocates a keystone, append any quests it unlocks to the available set), Android quest log + quest detail screens implementing 11e-2 wireframe, quest start/complete buttons wired to backend, quest-progress notifications.

3.3 Character progression

Forward-references (added 2026-05-22 re-check): D-019 ratifies 5 canonical classes (one per faction) + starting-cluster differentiation. Phase 13-3 ships class.cartographer + cluster.first-steps; the four remaining classes + clusters (32 nodes + 4 keystones) landed at data layer on 2026-05-22 (c6c722e / 06d75b5 / 83b5451) but are NOT surfaced on Android — backend adapter mirror tracked at ops/escalations.md Q8 FYI; mobile class-pick screen still bundles Cartographer only. §4.2 below should be read as CLOSED by D-019. See §10.2.

Exists: Walker profile (GET /walker/profile), tree state (GET /tree/state), tree allocation (POST /tree/allocate), cluster.first-steps with ~20 Plenny nodes + 1 keystone (Krok Niezachwiany), faction reputation read/write endpoints (11d-1, 11d-2), ClassSchema (no class instances authored), AscendancySchema (no instances).

Missing: Level concept (Walker has no level field — walker/profile exposes whatever the schema carries, but level is not defined; D-006 implies progression depth but the math is unratified), XP gain semantics (where do tree points come from numerically? D-006 Pillar 3 says ~70% quest grants + ~30% keystone unlocks, but the per-quest grant table is not ratified), point-award rules (does completing a step grant N points? Does a quest grant a flat M? Does a region-completion bonus exist?), class instances (schema exists, zero playable classes authored), class-pick flow (onboarding wireframe shows it; data + endpoint + UI not implemented), Walker bootstrap (registration → class pick → faction induction → first-quest dispatch is a designed flow but not implemented end-to-end), the player-facing Level UI element (not in any wireframe — defining what it surfaces is part of the progression spec).

Phase 13 must deliver: The progression system spec (D-016 candidate, see §4 below) ratified BEFORE any sub-phase touching XP/level/point math dispatches. After ratification: walker/profile extended with progression fields (level, xp, tree-points-banked, tree-points-spent), point-award endpoint or in-line side-effects on quest-complete + keystone-allocate, at least 1 class instance authored in data/, POST /walker/create (or equivalent) accepting class id, Android class-pick screen, Android Walker home displaying level + xp + points-banked, Android tree viewer allocation flow integrated with point-banking.

Three open decisions block Phase 13 sub-phases. They are ordered by blocking severity.

4.1 Progression system spec (D-016 — RATIFIED 2026-05-20)

Status: CLOSED. D-016 ratified — Model A (emergent level, walker.level = walker.tree_points_spent) + keystone bonus = 1pt + deliberate ~20% inaccessibility gap. ~108 quests × 1pt + ~36 keystones × 1pt bonus = ~144 pts across ~180 nodes. ~75/25 split (D-006 §Pillar 3 amended from ~70/30). Home surface: single Poziom N number + banked banner. See D-016 for full spec.

Historical context (pre-ratification): D-006 Pillar 3 ratified the informal ~70/30 quest/keystone split but left the surrounding system unratified — no canonical Walker level concept, no XP curve, no per-quest point-award table, no level-cap, no level-gate semantics on tree allocation. The progression system was the connective tissue between Pillar 1 (Steps = Energy), Pillar 2 (Passive Tree), and Pillar 3 (Quest↔Tree loop), blocking every progression-touching sub-phase until ratified.

Who decides: CEO + game-director + mechanics-designer. narrative-designer consulted for quest-grant flavour. ui-designer consulted for what the player surface displays.

Where ratified: D-level (canonical). /decide flow. Adds D-016 to canon.

Framing questions CEO will need to answer (proposed for /research progression-system):

  1. Does Walker have a level integer, or is “level” emergent from tree_points_spent? (PoE has both — character level and passive points; some walking-RPGs collapse the two. Collapse simplifies UI; separation enables level-gated content independent of allocation choices.)
  2. Tree points per quest — flat or scaled? (Flat: every quest grants N points. Scaled: points scale with quest tier / region depth / step count. Flat is simpler to balance against the ~150-200 node target tree; scaled matches “harder quests give more.”)
  3. Tree points per keystone unlock — same as quest grant or different? (D-006 says ~30% from keystones at full game; with 6 leak-handler keystones + further keystones authored over time, this implies keystones grant bigger lumps than regular quests. Need a ratio.)
  4. Tree-point cap / level-cap interaction. With ~150-200 nodes and 70/30 split, total quest+keystone count at full game has to mathematically reach point parity. What is the target node count vs. point count? (PoE 1 is ~120 points across ~1300 nodes; Last Epoch is ~110 across ~1100 nodes; ours is ~150-200 across ~150-200 — much denser, almost 1:1.)
  5. What does the player see on Home regarding progression? (Just points-banked + tree-points-spent? Or a level number? Or a quest-progress bar to next point grant? This shapes the home wireframe revision.)

4.2 Class instance scope for Phase 13 — CLOSED by D-019

Status: CLOSED (2026-05-22). D-019 ratifies the canonical 5-class roster (one per faction; Cartographer / Pieczetarz / Pielgrzym / Komiwojazer / Tropiciel). The W-level “ship 1, defer rest” pick at 13-3 has executed: Cartographer plays on Android in Phase 13; the other four are authored at data layer (commits c6c722e / 06d75b5 / 83b5451, 2026-05-22) including 4 starting clusters (first-seal / first-lantern / first-route / first-sign, 32 nodes + 4 keystones). Backend adapter mirror for the 4 new classes is pending (intentional Phase 13 scope, tracked at ops/escalations.md Q8 FYI). Mobile bundle still ships Cartographer only — surfacing the other 4 on Android is forward-referenced to D-027 onboarding diegetic expansion (§10.10) or post-Phase-13.

Historical context (pre-D-019): ClassSchema and AscendancySchema existed (commit 04f1a71), but zero class instances were authored. Onboarding wireframe showed class-pick. Cannot ship Android class-pick UI against an empty class roster.

Who decides: mechanics-designer proposes; CEO ratifies if D-level (i.e., if it changes the canonical class list). If just “for Phase 13 closed-beta cohort, ship the 1-class subset of the eventual N-class roster,” it is W-level (mechanics-designer autonomous).

Where ratified: Likely W-level — pick 1 class to author first (most natural fit: a Cech-aligned cartographer starting in Plenny, since cluster.first-steps and Quest 001 are Plenny-bound). If CEO wants to define the FULL class roster up-front (e.g. “the canonical list is these 6 classes, one per region”), it becomes D-level.

Proposed framing: CEO confirms whether (a) ship 1 class for Phase 13 + author rest later as W-level, OR (b) ratify the canonical N-class list now as D-level.

4.3 Combat-encounter API surface shape

Why open: D-010 ratifies combat resolution philosophy; combat/formulas.md ratifies math. Neither ratifies the API surface (request/response shapes, encounter-state persistence model, replay vs. live-step semantics). tech-architect will draft this as an ADR (likely ADR-0008 — but ADR-0007 is reserved for Phase 14 VPS migration, so this is ADR-0008+ to avoid number clash, or the numbering re-flows).

Who decides: tech-architect drafts; mechanics-designer cross-reviews against formulas.md; system-reviewer cross-checks pre-canon; CEO ratifies if D-level. Most likely B-level (backend architecture, not gameplay canon) unless a question arises that affects the simulator contract.

Where ratified: B-level (ADR in wiki/src/content/docs/tech/adr/). Drafted at the sub-phase where combat encounter endpoints land (currently skeletal sub-phase 13-7). ADR number = next free at draft time (ADR-0007 was re-allocated to Android network layer in sub-phase 13-1; VPS migration ADR defers to ADR-0008+ at Phase 14 trigger; combat encounter ADR fills the next slot when 13-7 dispatches).

Proposed framing: Sub-phase 13-7 (combat encounter API ADR) produces the answer; this is not a separate /research.

5. Feature checklist (Phase 13 completeness contract)

Comprehensive enumeration of every feature that MUST exist when Phase 13 ships. Tagged per area. Items pulled from D-006/D-007/D-008/D-009/D-010/D-011/D-014, the data schemas, the existing backend endpoint inventory, and the UI wireframe inventory. Each item gets a checkbox.

Backend (NestJS, local-tunnel test, ADR-0006 posture)

  • POST /auth/callback retained as-is (mock auth, ADR-0006).
  • GET /walker/profile extended with progression fields (level/xp/points-banked/points-spent — pending D-016).
  • POST /walker/create (or equivalent) — accepts class id, faction starting allegiance (if any), creates Walker with default stats from class.
  • POST /step/ingest retained (mock-trust per ADR-0006), wired to update energy + streak.
  • GET /walker/streak — current streak day count + recognition tier (per D-007: +20% at 7d, +50% at 30d).
  • POST /quest/start retained.
  • POST /quest/complete retained.
  • POST /quest/:id/step/:n/advance — per-step progress.
  • GET /quest/available — list of quests visible to this Walker right now, evaluated against prerequisites + rep gates + keystone gates.
  • GET /tree/state retained.
  • POST /tree/allocate retained, extended to emit keystone-unlock side effects (reveal hidden quests).
  • GET /faction-rep retained.
  • POST /faction-rep/delta retained.
  • POST /combat/encounter — initialize encounter from quest beat. Returns seed + initial stat snapshots.
  • POST /combat/encounter/:id/turn — submit Walker action; server replays simulator with stored seed; returns next state.
  • POST /combat/encounter/:id/resolve — encounter ends (win/retreat/defeat); emits quest/tree/rep deltas.
  • POST /combat/encounter/:id/retreat — Walker retreats mid-encounter (D-010 §1 encounter exit condition).
  • Prisma schema migrations for all new tables (encounter, encounter-turns, walker-class-allegiance, progression fields).
  • Swagger docs current for all endpoints.
  • Test suite green (>= current 103/103 + new endpoint coverage).
  • CORS configured for Android local-tunnel access.
  • Mock-auth bearer token flow documented in tech/api/.

Mobile (Kotlin Android, sibling repo walkrpg-mobile)

  • Repo bootstrap: Android Studio project, Kotlin, Jetpack Compose, Hilt or Koin DI, Retrofit + kotlinx-serialization, Room (offline cache).
  • Build pipeline: GitLab CI for walkrpg-mobile (build + lint on push; release builds manual).
  • Splash + mock auth screen (per onboarding wireframe).
  • Walker creation flow: class pick screen (renders authored class instances).
  • Tutorial overlay (per onboarding wireframe).
  • First-walk prompt (per onboarding wireframe).
  • Home screen: region card, streak ribbon, quest pill, faction strip, bottom nav (5 tabs per D-014 §1: Home / Tree / Factions / Quests / Craft — Craft tab is stub-only in Phase 13).
  • Tree viewer: cluster.first-steps rendering, mastery popover, keystone lock state, allocation flow with point-banked check, a11y focus order (matches wireframe).
  • Post-walk sync screen: step delta, energy delta, streak update, quest progress (matches wireframe).
  • Quest log: row titles use name.en per D-011, prose uses name.pl.
  • Quest detail screen.
  • Faction screen: 5 factions, rep tiers, visible per-region.
  • Combat screen: matches 11e-1 wireframe, renders turn loop, energy spend, hp bars, retreat affordance.
  • Crafting tab stub: placeholder “Coming in Phase X” (full crafting UI is post-Phase-13 per D-015 — Phase 13 ships Android core loop without full crafting).
  • Health Connect integration: read step count, push to /step/ingest (mock-trust validation server-side).
  • Offline cache: 7-day offline cap per D-009 §2; queued actions sync on reconnect.
  • Provisional-allocation UI affordance per D-009 §2 (allocations made offline render as provisional until server confirms).
  • Bilingual UI: EN/PL switch, defaults to system locale, all LocalizedString consumers respect locale.
  • System chrome consistency: notifications + push use name.en per D-011.
  • a11y: 200% font scale, screen reader, focus order — per wireframe a11y notes.
  • Color tokens implemented: 6 region tokens + neutral + state + faction (per design-system).
  • Typography: Literata (display) + Inter (UI) loaded.

Data layer

  • At least 1 class instance authored (data/src/content/classes/), aligned to Plenny start.
  • At least 1 ascendancy per authored class (or none, if mechanics-designer defers ascendancies to Phase 13+).
  • Progression curve constants (if D-016 introduces an XP curve) live in data/src/schemas/progression.ts and data/src/content/progression/.
  • No regressions on existing 17 typed instances.

Cross-cutting

  • Auto-commit policy honored on every Phase 13 sub-phase commit.
  • Roadmap updated per sub-phase ship.
  • This plan (phase-13-plan.md) updated per sub-phase ship.
  • Language policy (pnpm lint:language) green.
  • Tag policy (pnpm lint:tags) green.
  • D-016 (progression system) ratified before sub-phases that depend on it dispatch.

Exit scenario (the ultimate checklist)

  • On a real Android device: install APK from CI artifact.
  • Sign in via mock auth.
  • Pick a class (the 1 authored class).
  • Complete onboarding tutorial.
  • Trigger a synthetic step ingest (or take a real walk if Health Connect data is available).
  • See energy increase, streak update.
  • Open Quest 001, complete first step.
  • Receive tree points, see them banked on home.
  • Open tree viewer, allocate a node on cluster.first-steps.
  • Verify allocation persisted to backend (kill app, reopen — node stays allocated).
  • Open faction screen, see Unfinished Guild reputation reflect a quest reward.
  • Open Quest 002, walk into combat trigger.
  • Resolve combat encounter (win, retreat, or defeat — at least one outcome path tested end-to-end).
  • Encounter outcome reflected in quest state on server side.
  • Kill app, reopen — all state persists.

When every checkbox above is green, Phase 13 ships and Phase 14 (VPS migration) opens.

6. Sub-phase decomposition

Detail concentrates on the next 5 sub-phases. Later sub-phases are skeletal placeholders. Each detailed sub-phase ends with: prerequisite (which open decision must close first if any), scope, deliverables, leads, estimated cost, dependencies.

Detail-planned (first 5)

13-1 — Android repo bootstrap + walker/profile read

Prerequisite: None. Unblocked.

Scope: Stand up the walkrpg-mobile sibling repo (Android Studio project, Kotlin, Compose, Retrofit, Hilt). Build a minimal app that signs in via mock POST /auth/callback, fetches GET /walker/profile against the local-tunnel backend, and renders the response on a placeholder home screen. No UI polish, no domain features — pure plumbing.

Deliverables: walkrpg-mobile repo initialized on GitLab; Android Studio project compiles + runs on emulator; mock auth flow works against ADR-0006 local-tunnel backend; one screen renders Walker profile JSON; basic CI pipeline (build + lint on push). Documents the mock-auth handshake in walkrpg-mobile/README.md (English).

Leads: tech-architect (network layer + auth contract) + mobile-developer (repo bootstrap + Compose scaffold) paired.

Estimated cost: 1 dispatch session. Roughly equivalent to phase 8b in scope.

Dependencies: None. Unblocks 13-2 (anything mobile after this needs the repo).

Status: DONE — 2026-05-20. Commits: e260ead (ADR-0007 Android network layer, this repo) + walkrpg-mobile sibling repo 8931019 (repo metadata rewrite Flutter→Kotlin), 5ebb89b (gradle + version catalog), 0f982b0 (Hilt + Retrofit + auth interceptor + token store), 7e66a62 (MainActivity + HomeScreen rendering /walker/profile). ADR-0007 re-allocated to Android network layer (ADR-0006 originally reserved 0007 for VPS migration; VPS ADR defers to next-free at Phase 14 trigger — see §4.3). Backend follow-ups added (HttpExceptionFilter, X-Request-Id middleware, CORS bootstrap) — tracked in ADR-0007 §Backend deliverables, to be picked up when backend-engineer dispatches.

13-2 — Progression system spec (D-016 /research + /decide)

Prerequisite: None (this IS the prerequisite for downstream sub-phases).

Scope: Run /research progression-system per §4.1 framing questions. game-director + mechanics-designer cross-write candidate progression models. system-reviewer cross-checks against D-006/D-007. CEO /decide ratifies as D-016. No code, no data instances — pure design + canon write.

Deliverables: Research artifact at ops/research/progression-system.md; D-016 landed as wiki/src/content/docs/canon/decisions/D-016-progression-system-model-a-tuned-keystone-bonus-20-inaccessi.md; progression curve / point-award math drafted into wiki/src/content/docs/tree/progression.md (or equivalent) at status:draft, ratified to status:canon after D-016. Open Plenny quest 001/002 point-award values back-filled to match.

Leads: game-director (orchestrates) + mechanics-designer (proposes math) + narrative-designer (quest-grant flavour). CEO ratifies.

Estimated cost: 1 research session (3-5 question pass, max 3 rounds) + 1 /decide session.

Dependencies: Unblocks 13-3 (walker creation needs to know what level means), 13-5 (tree-point grant needs to know how many points per quest), and any future progression UI sub-phase.

Status: DONE — D-016 ratified 2026-05-20. Research artifact at ops/research/progression-system.md. game-director orchestrated mechanics-designer + narrative-designer in parallel. CEO /decide selected option (B): Model A + keystone bonus = 1pt + deliberate ~20% inaccessibility gap. Final spec: 108 quests × 1pt + 36 keystones × 1pt bonus = ~144 pts across ~180 nodes, ~80% reach, ~75/25 quest/keystone split. D-006 §Pillar 3 wording amended from ~70/30 → ~75/25. Home shows single Poziom N + banked banner. Unblocks sub-phases 13-3, 13-5, 13-10. See D-016 for full spec.

13-3 — Walker creation + class pick (1 class authored)

Prerequisite: D-016 ratified (13-2 done). Resolves §4.2 open decision (will most likely pick 1-class W-level).

Scope: Author 1 class instance in data/src/content/classes/ (Plenny-aligned cartographer is the natural fit). Add POST /walker/create endpoint to backend. Build Android class-pick screen + walker-creation flow per onboarding wireframe. Default starting Walker writes to backend, returns via GET /walker/profile with progression fields populated per D-016.

Deliverables: 1 class instance in data/; backend POST /walker/create + Prisma migration; Android class-pick screen + walker-creation flow; bilingual class name/description rendering. Updated tests on backend (>= +5 cases).

Leads: mechanics-designer (class instance authoring) + tech-architect (backend endpoint + schema migration) + mobile-developer (Android UI) — three-lead paired dispatch.

Estimated cost: 1 dispatch session (heavier than 13-1, lighter than 13-5).

Dependencies: Blocked on 13-2 (D-016). Unblocks 13-4 (home screen needs a Walker to display).

Status: DONE — 2026-05-20. Three-lead paired dispatch shipped:

  • mechanics-designer: class.cartographer instance authored (bdf9f51, data/src/content/classes/cartographer.ts, bilingual PL/EN, Plenny start, Cech-aligned via region); Quest 001 + 002 reward retrofitted to flat 1pt per D-016 (9304f10, was 4pt / 6pt); wiki/src/content/docs/tree/progression.md drafted at status:draft (7a5ec02, headline math + ~20% gap worked example + D-013 endgame cross-ref + banner copy). Walker schema NOT in data layer — confirmed backend-only (Prisma owns Walker).
  • tech-architect: Chose option (b) POST /walker/class (preserves ADR-0006 /auth/callback auto-create contract); Prisma migration (a476ec8) drops walkers.level, renames availablePointstreePointsBanked, adds treePointsSpent (default 0) + classId (TEXT nullable), backfills treePointsSpent from existing TreeAllocation/KeystoneAllocation; endpoint + DTO + service + tests (0b6eba7); API contract docs (089294c). Test count 103 → 141 (unit 102→111, e2e 24→30). Idempotent on same-classId re-pick, 409 on different-classId re-pick (no respec in Phase 13).
  • mobile-developer: ClassPickScreen.kt + WalkerCreationViewModel + AppNavigation.kt NavHost (LOADING → CLASS_PICK → HOME); hardcoded BUNDLED_CLASSES in Kotlin for the 1 cartographer (TODO refactor to bundled JSON or GET /class/list when N > 1); bilingual rendering via LocalConfiguration.current.locales; test count 5 → 21 (+16). Initial commits ce9bcc4, 3744951, a17f588. Reconciliation pass 1672561 aligned endpoint /walker/create/walker/class + DTO field renames (availablePoints removed, treePointsBanked/treePointsSpent/classId added, level kept on wire as computed view) per tech-architect’s option (b) choice. versionName bumped to 0.1.0-13-3.

Wire-level D-016 deviation flagged (B-level follow-up): level: Int field stays on wire as server-computed view (= treePointsSpent); D-016 strict reading says emergent only (client-side compute). Either accept as wire convenience (current state) or drop wire field + amend ADR-0007 §2 in a future sub-phase. No blocker.

ADR-0007 §2 amendment needed (W-level follow-up): Kotlin DTO field set documented in ADR-0007 §2 is from 13-1 (pre-D-016 rename). Add a follow-up amendment to record the renamed wire shape so iOS port (Phase 15) inherits correctly.

D-019 reconciliation (added 2026-05-22 re-check): 13-3’s “1 class for Phase 13” framing is now subsumed by D-019 — canonical roster = 5 classes one-per-faction; data layer now carries all 5 (Cartographer + Pieczetarz + Pielgrzym + Komiwojazer + Tropiciel, commits c6c722e / 06d75b5 / 83b5451). 13-3 backend + mobile surfaces still serve Cartographer only — the other 4 surface on Android post-Phase-13 (or per D-027 onboarding expansion if scheduled). Backend adapter mirror for the 4 new classes pending; see ops/escalations.md Q8 FYI.

13-4 — Android home screen + step ingest + streak

Prerequisite: 13-3 done (Walker exists with class + progression state).

Scope: Build the Android home screen per wireframe (region card, streak ribbon, quest pill, faction strip, 5-tab bottom nav with Craft as stub). Wire Health Connect read; push step counts to POST /step/ingest; render energy + streak deltas. Add GET /walker/streak to backend (currently streak is implicit in profile; surface it explicitly per D-007 attestation invariant). Post-walk sync screen ships in this sub-phase too (it is the home screen’s natural sibling).

Deliverables: Android home screen + post-walk sync screen; Health Connect integration; GET /walker/streak endpoint; streak math wired to D-007 per-day attestation invariant (decay on missed attested day, NOT missed sync day). a11y pass: 200% font scale, screen reader focus order.

Leads: tech-architect (streak endpoint + Health Connect contract) + mobile-developer (Compose home + sync screens + Health Connect plumbing) paired. ui-designer consulted only if wireframe deviation needed.

Estimated cost: 1 dispatch session — likely the biggest sub-phase so far (home screen is dense per the 11e-2 + 9 wireframes).

Dependencies: Blocked on 13-3. Unblocks 13-5 (quest log lives in bottom nav).

Status: DONE — 2026-05-20. 4-thread parallel dispatch shipped (Thread A core 13-4 + ui-designer wireframe pass + Thread D ADR-0007 backend deliverables):

  • tech-architect: GET /walker/streak endpoint (currentStreakDays + recognitionTier + multiplier 1.0/1.2/1.5 + lastAttestedDay; commit ec74aed); wiki/src/content/docs/tech/api/health-connect-contract.mdx drafted (10 sections: provenance + sampling window + per-day aggregation + extended /step/ingest body + 4-guard mock-trust posture + permission flow + debug fallback + iOS HealthKit inheritance + production deferred + open follow-ups; commit e825290). Minimal Prisma migration 20260520120000_streak_longest_length added StreakState.longestLengthDays. Test count +14 (12 unit + 2 e2e).
  • mobile-developer: HomeScreen full rewrite (region card + ProgressionCard per D-016 with pisarska linijka LinearProgressIndicator + streak ribbon + quest pill + faction strip + 5-tab bottom nav incl. Craft stub), PostWalkSyncScreen, Health Connect integration (HealthConnectReader + DayStepBucket + SyncStateStore EncryptedSharedPreferences + 7-day client cap per D-009 §2), 14 new bilingual strings, 8 a11y items verified. Test count 21 → 50 (+29). versionName 0.1.0-13-3 → 0.1.0-13-4. walkrpg-mobile commits f922aef, 05a832a, cceaad9, 88b70b1, cbc0b9d.
  • ui-designer (wireframe pass): home-screen.mdx amended — new ## Progression card detail (D-016) section + extended primary ASCII sketch + day-0 sketch + 88dp dimension table row + a11y screen-reader subsection + streak ribbon D-007 backend field-name alignment note. post-walk-sync.mdx amended — D-016 grant callout copy (+1 Tree Point banked. / Linijka oddana do składu. Spis przyjął.) replacing pre-D-016 +4 tree points placeholder + new ## Tree point grant callout — standalone spec (D-016) section + states matrix grant callout column. pisarska linijka concrete recommendation: vertical ruled line 3dp×64dp left-aligned, three tick marks at 50/100/150 of 180 nodes, fill = --color-region-plenny 70% opacity. Commit fad3f5a (orchestrator-committed after 2-line lint fix on frontmatter description PL chars).
  • Thread D backend-engineer (ADR-0007 §Backend deliverables — parallel non-13-4): HttpExceptionFilter (normalize error envelope, NestJS exception → ADR-0007 error codes mapping; commit cfbc450); RequestIdMiddleware (X-Request-Id generate/echo + Pino-ready log context but currently standard NestJS Logger; commit c82d293); CORS bootstrap (env CORS_ALLOWED_ORIGINS, default localhost:3000,10.0.2.2:3000; commit 8f7efc6); ADR-0007 §Backend deliverables marked “shipped” with SHAs (commit cea5e41). Test count +14 (8 filter + 6 middleware). Pre-existing prisma client drift fixed via prisma generate. One deviation: implemented credentials: true per dispatch brief vs ADR-0007 §10 credentials: false — functionally identical for Bearer-token flows; flagged for tech-architect.

Combined test count delta: 141 (start) → 183 (end). Backend +42 (tech-architect 14 + backend-engineer 28 incl. baseline 123→137). Mobile 21 → 50.

Wire-level field reminder: level: Int stays on wire as server-computed view of treePointsSpent (deviation from D-016 strict reading flagged in 13-3, unchanged in 13-4).

ADR-0007 §2 amendment outstanding (W-level follow-up): still pending refresh for D-016 Kotlin DTO field rename. iOS port (Phase 15) inherits.

B-level CORS credentials note: backend-engineer implemented credentials: true; ADR-0007 §10 says false. Reconcile in B-level decision or amend ADR-0007 §10 to true.

13-5 — Quest log + Quest 001 end-to-end + first tree allocation

(Cross-ref 2026-05-22: QuestGateEvaluator from this sub-phase is the canonical implementation of D-024 §2 hidden-quest gating. KEYSTONE_GATE + FACTION_REP_GATE + REGION_GATE all activate the per-region linear chain + off-spine hidden semantics. Phase 13’s 6 Plenny quests represent ~33% of D-024’s per-region 18-quest saga; remainder is post-Phase-13 narrative-designer work.)

Prerequisite: 13-4 done (home + step ingest working) + D-016 ratified (point-award math known).

Scope: Android quest log screen + quest detail screen per 11e-2 wireframe. Wire GET /quest/available (new endpoint), POST /quest/start, POST /quest/:id/step/:n/advance (new endpoint), POST /quest/complete. Tree allocation flow on Android: tap node, confirm, send POST /tree/allocate, show provisional-vs-confirmed state per D-009. End-to-end: walk → ingest → start Quest 001 → advance step → complete → receive tree points → allocate node on cluster.first-steps → state persists across app restart.

Deliverables: Android quest log + detail screens; backend GET /quest/available + POST /quest/:id/step/:n/advance; tree allocation UI integrated with points-banked check; provisional-allocation visual state on Android; offline queue (Room) for quest/allocation actions when offline (7-day cap per D-009).

Leads: tech-architect (new quest endpoints + prerequisite/gate evaluator) + mobile-developer (quest screens + tree allocation flow + offline queue) + mechanics-designer (consulted for point-award values per D-016) paired.

Estimated cost: 1 dispatch session — likely the second-biggest sub-phase. The quest↔tree loop closes here in user-visible form for the first time.

Dependencies: Blocked on 13-4 + D-016. Unblocks downstream combat work (13-6+) by establishing the quest-state pattern combat-encounter must hook into.

Status: DONE — 2026-05-20 (all 4 threads landed).

tech-architect (backend):

  • 04a0122feat(backend): GET /quest/available + POST /quest/:id/step/:n/advance + gate evaluator (sub-phase 13-5)/quest/available returns {available[], hiddenCount, evaluatorVersion}; /quest/:id/step/:n/advance strict-order 1-indexed, final step does NOT auto-complete (D-016 — explicit /quest/complete required for +1pt); QuestGateEvaluator pure synchronous collect-all (PREREQUISITE active, REGION_GATE active, KEYSTONE_GATE schema-active + adapter-pending, FACTION_REP_GATE schema-active + adapter-pending); /tree/allocate provisional field already present (returns false always per ADR-0006 mock-trust).
  • c57a674docs(tech): quest-available + quest-step-advance API contracts (sub-phase 13-5) — API contract pages drafted at status:draft.
  • Backend tests 183 → 210 (+27). Adapter follow-up (B-level, < 50 LOC): mirror keystoneRequirement + factionRepRequirement from schemas to backend/src/common/game-content.ts Quest interface so KEYSTONE_GATE + FACTION_REP_GATE activate on real quest content.

mechanics-designer (data):

  • 8f40e35feat(data): QuestSchema gate evaluator fields + per-step beats (sub-phase 13-5) — added optional QuestStepSchema.beats (factionRep + loreUnlock per-step), QuestSchema.factionRepRequirement ({factionId, minTier:int 0..5}), QuestSchema.keystoneRequirement ({keystoneId}). regionRequirement deferred — existing regionId serves with comment-expanded semantics (“Walker’s last attested region matches regionId → in-region”).
  • 6e247e0feat(data): Quest 001/002 per-step beats (factionRep + loreUnlock per D-016) — Quest 001 5 steps with Cech-rep + lore-unlock beats (no tree points per step); Quest 002 4 steps with beats + step 5 outcome-branch placeholder. cluster.first-steps connectivity verified: entry node node.even-stride allocatable on 0 prior allocations; keystone.unshaken-step (Krok Niezachwiany) unlocked by Quest 001 with atomic allocate + 1pt bonus = effectively 2 progression points per Quest 001.

mobile-developer (Android): walkrpg-mobile commits:

  • fad0a9afeat(13-5): QuestLogScreen + QuestDetailScreen + filtering + quest start/advance/complete flow — QuestLogScreen (filter chips All/Active/Completed, LazyColumn, QuestCards, hidden quest slots per Pillar 3, pull-to-refresh, D-011 bilingual names), QuestDetailScreen (hero block, step timeline, Start/Advance/Complete buttons, D-016 reward callout), QuestLogViewModel + QuestDetailViewModel (@HiltViewModel, offline enqueue on network failure, 409 idempotent, SharedFlow events), QuestApi, QuestDto, ApiException, QuestRepository/Impl.
  • ae65874feat(13-5): TreeViewerScreen + allocation flow + provisional state per D-009 — TreeViewerScreen (pannable/zoomable canvas 0.3–3× scale, cluster.first-steps nodes, four visual states, keystone diamond composable + D-014 screen-reader label “Keystone — special”), AllocationConfirmDialog, points-banked pill in TopAppBar, TreeViewerViewModel (tap→confirm→POST, client-side banked-points guard, provisional optimistic state per D-009 §2 mock-trust, provisional restored from offline queue on load), TreeApi, TreeDto, TreeRepository/Impl.
  • 63480aefeat(13-5): Room offline queue + WorkManager + 7-day cap per D-009 §2 — OfflineAction @Entity (offline_actions table v1), OfflineActionDao, OfflineQueueDb (exportSchema=true), OfflineQueueRepository + OfflineQueueRepositoryImpl @Singleton, OfflineQueueWorker @HiltWorker (FIFO drain, 7-day cap, QUEST_ADVANCE/QUEST_COMPLETE/TREE_ALLOCATE, 409 idempotent, Result.retry on failure), OfflineQueueModule (15-min periodic worker, KEEP, CONNECTED constraint), WalkrpgApp implements Configuration.Provider with HiltWorkerFactory.
  • 23b388bfeat(13-5): nav extension + bilingual strings (quest + tree + offline) — AppNavigation: QUEST_LOG, QUEST_DETAIL/{questId}, TREE_VIEWER routes; HomeScreen: onNavigateToQuestLog + onNavigateToTree callbacks wired to bottom nav tabs and QuestPill.onTap; 23 new EN + 23 PL string keys (quest log filter chips, status labels, action buttons, tree viewer labels, offline queue badge) — all D-011 compliant.
  • 6f60a6etest(13-5): QuestLog + QuestDetail + TreeViewer + OfflineQueue tests — 38 new tests: QuestLogViewModelTest (7), QuestDetailViewModelTest (8), TreeViewerViewModelTest (8), OfflineQueueRepositoryTest (8), OfflineQueueWorkerTest (7, Robolectric). Total: 50 → 88.
  • e394a23chore(13-5): bump versionName + WorkManager/Hilt-Work/Robolectric deps — versionName 0.1.0-13-4 → 0.1.0-13-5; libs.versions.toml + build.gradle.kts updated.

API contract posture: Mobile designed against expected GET /quest/available + POST /quest/:id/step/:n/advance shapes; tech-architect’s actual landed shapes match closely. Field-level reconciliation, if any drift surfaces in integration testing, is a single QuestDto.kt update.

Offline provisional note: Provisional node IDs survive process death by being reconstructed from offlineQueue.getAll() TREE_ALLOCATE payloads on each load() call — no additional persistence needed.

Lore parallel (Thread C — narrative-designer):

  • df17a2bfeat(data): Plenny Quest 003 — dzwoniacy-magazyn (leverages plenny.md forward hooks) — Quest 003 Dzwoniący magazyn (Bell-ringing storeroom): Drukarnia Cechu leak-ink mystery fused with plenny.md magazyn nr 17 reservation. 5 steps, prereq quest.001-first-road, 1pt reward per D-016. Forward hook (pine-resin smell + ink-colour question) seeds long-arc Pan Korytarz signature-forensics thread.
  • 021eb09feat(data): npc Pan Bezelec — night warden of Trzecie Biuro magazyn nr 17 — Pan Bezelec carded (Cech, Plenny, nocny strażnik).
  • B-level canon assertion: “leak-paper hushes its own scent” (Plenny archiwum wyciekowe property) — region-internal, no D-level conflict.

Combined test count deltas this sub-phase:

  • Backend: 183 → 210 (+27).
  • Android: 50 → 88 (+38, 5 new test files via Robolectric).
  • versionName: 0.1.0-13-4 → 0.1.0-13-5.

Open follow-up (W/B-level, dispatched separately, NOT blockers for 13-6):

  1. B-level (tech-architect): mirror keystoneRequirement + factionRepRequirement from data/src/schemas/quest.ts to backend/src/common/game-content.ts Quest interface (< 50 LOC) — activates KEYSTONE_GATE + FACTION_REP_GATE evaluators on real quest content.
  2. W-level (tech-architect): ADR-0007 §2 amendment for D-016 Kotlin DTO rename — carried from 13-3/13-4. iOS port (Phase 15) inherits.
  3. B-level (mechanics-designer + narrative-designer): lore-unlock id dereference — currently free-form slug; mobile shows placeholder. Lore-library subsystem post-Phase-13.
  4. B-level (mobile-developer): per-step beat callout UI shape — D-016 banner pattern for Cech +3 / Lore unlocked: <slug> rows. Currently no per-step callout rendered.
  5. B-level (mobile-developer + tech-architect): Quest 002 step 5 outcome-branch (A/B/C Akademia/Bractwo/Cech lean) — placeholder on rewards.reputation pending 11c-2 outcome-branching schema.

Skeletal (placeholders, re-planned as Phase 13 progresses)

One-liners, just so the shape is visible. Re-planned at each /work session boundary.

  • 13-6 — Faction screen + faction-rep visible on Android. DONE 2026-05-20. mobile-developer (single-lead): FactionsScreen + FactionDetailScreen + BUNDLED_FACTIONS (5 hardcoded, mirrors BUNDLED_CLASSES pattern from 13-3), FactionRepository (getFactions/getFactionRep/getMergedFactions), 5-tier ladder with current highlighted, filter chip All/This-Region, GET /faction-rep read-only (POST /faction-rep/delta intentionally not wired — quest deltas flow through quest.service per D-007). Test count 88 → 116 (+28). versionName 0.1.0-13-5 → 0.1.0-13-6. walkrpg-mobile commits bb7e654, 2e5cc69, d3cf758, fa68cd0. Parallel (13-7 prep): tech-architect drafted ADR-0008 combat encounter API (358b123) — 10 sections, encounter lifecycle, 4-endpoint family, simulator integration as hard rule (backend imports @walkrpg/data sim, no re-implementation), 9 iOS port inheritance items + 4 platform-specific changes, 6 open questions deferred to 13-7 implementation. Parallel (B-level follow-up): backend-engineer mirrored keystoneRequirement + factionRepRequirement to backend/src/common/game-content.ts Quest interface (014cc6a) — activates KEYSTONE_GATE + FACTION_REP_GATE evaluators on real quest content (still pass-through since no quest sets fields yet); also caught quest-003 missing from adapter array drift. +2 backend tests (210 → 212). Lore parallel (Thread C): narrative-designer authored Plenny Quest 004 Połowa rejestru (8a6ae87, 5 steps, prereq quest.003-dzwoniacy-magazyn, half-bisected-ledger trace continues Quest 003 pine-resin forward hook, Pan Korytarz identity stays at poziom 25+ reservation) + new NPC Wnęt Sosnowy-Półwiek smolarz (d6cf0bd). Forward hook for Quest 005+: other half of smolarnia ledger in Targosie OR Academy private cabinet — Walker doesn’t know which. Orchestrator fixed Polish-quote-pair syntax errors (narrative-designer used „...„ + ASCII close — replaced with proper „...„ U+201D) before commit.
  • 13-7 — Combat encounter API + Quest 002 trigger plumbing. DONE 2026-05-20. (Cross-ref 2026-05-22: implements D-020 encounter resolution surface. D-020 §2 pull-based pool + §3 badge taxonomy + §4 visible-before-commit risk choice are forward-references — currently only quest-beat-driven encounters fire; step-driven tropy accumulation is post-Phase-13. D-018 ~30%-per-fight Energy sink already honoured.) Paired: mechanics-designer (data layer) + backend-engineer (impl). Mechanics step 1 (b8847e5, d461894) resolved ADR-0008 §8.1 + §8.6: data/src/schemas/opponent.ts (Zod, bilingual, 8-stat block bit-identical to EnemySnapshot), data/src/content/opponents/frost-thing-slow-vent.ts (canonical numbers hp=18, dmg=7, def=2, acc=0.65, eva=0.05, crit=0.02, crit_mult=1.5), QuestStepBeatSchema migrated to discriminatedUnion("kind", [narrative, encounter]) — all 13 existing beats across Quest 001/002/004 explicitly migrated to kind: "narrative". Quest 002 step 3 rewritten as beat-3-frost-thing-at-the-slow-vent with encounter beat referencing opponent.frost-thing-slow-vent, factionRep + loreUnlock carried through on the encounter beat. W-level dropped the standalone kind: "factionRep" variant the brief suggested — narrative beats already carry factionRep[] inline (ops/decisions/2026-05-20-13-7-mechanics-discriminated-beats.md). ADR-0008 flipped Proposed→Accepted (97a2041). Backend step 2 (cf4e6ab, a7a4c67, f992f3a) ships: Prisma combat_encounters table (inline JSONB replayLog, combat_turns deferred per §8.4), EncounterState/EncounterOutcome enums, Walker reverse relation; backend/src/common/game-content.ts adapter mirror for opponents + QuestStepBeat union (mirror pattern same as 014cc6a keystone/faction mirror); full backend/src/combat/ NestJS module (service + controller + DTOs + errors) with all 4 endpoints (POST /combat/encounter, /turn, /resolve, /retreat), Bearer auth, ADR-0007 envelope, 8 error codes per §5. Simulator-as-hard-import honored — backend imports simulateEncounter/makePrng from @walkrpg/data/sim; NO re-implementation of combat math. Replay strategy: simulateEncounter slice with retreatPolicy: never per W-level (ops/decisions/2026-05-20-13-7-backend-replay-strategy.md). Seed: crypto.randomInt(0, 0x100000000) (ops/decisions/2026-05-20-13-7-backend-seed-generation.md). D-016 separation surfaced on the wire: treePointsDelta: 0 literal on /resolve response; encounter does NOT grant tree points. D-010 non-punitive enforced: defeat clamps hp to 1, no XP/rep/streak loss. QuestService.advanceStep gained an optional tx param + QuestModule exports QuestService for cross-module injection. Tests: +42 in combat.service.spec.ts (169 → 211 backend). All lints clean. Deferred to 13-9 (NOT regressions): tree-modifier stat composition for walker snapshot (Phase 13 uses base class stats only), walker.hp column persistence (currently void finalWalkerHp — hp lives only in encounter snapshot until column lands). Deferred to Phase 14+: abandoned-state cleanup worker, COMBAT_REPLAY_MODE env var for production-strict replay rejection, combat_turns table if turn-level analytics emerge.
  • 13-8 — Combat UI on Android. DONE 2026-05-20. mobile-developer (single-lead): full Compose CombatScreen per wireframe 11e-1 with 6 UI states (Idle / Initializing / Active / PendingResolve / PendingRetreat / Resolved / Retreated / Error). 4-endpoint Retrofit CombatApi + DTOs against ADR-0008 §3. CombatRepository + CombatViewModel — server-canonical state (next-expected turnIndex from server response, never client-side counter). Nav route combat/{questId}/{stepIndex}/{opponentTemplateId} wired from QuestDetailScreen when active step beat kind === "encounter". Action set: Attack + Retreat per ADR-0008 §8.3 + wireframe 11e-1 §4.1 (Defend / Use-Energy-Burst not stubbed — no dead UI). Auto-resolve on PendingResolve via LaunchedEffect(uiState) — player already tapped Attack on the winning turn; requiring a second Continue tap was poor UX. Retreat = AlertDialog (wireframe’s 2-sec auto-dismiss chip dropped per W-level — recomposition-timer interaction). No client-side simulator prediction in 13-8 — per-turn spinner during server roundtrip; Kotlin xorshift32 re-impl deferred to 13-9 or post-13. Opponent name derived from slug (“opponent.frost-thing-slow-vent” → “Frost-thing”) — temporary, proper endpoint deferred. Bilingual strings + 8+ a11y items (live regions on turn outcomes, content descriptions). versionName 0.1.0-13-6 → 0.1.0-13-8 (skipped 13-7, backend-only). +53 Android tests (116 → 169): CombatRepositoryTest (18), CombatViewModelTest (14), CombatWorkedExampleTest (7 — formulas.md §10 replay byte-for-byte against seed 92 fixture), CombatScreenTest (14 pure-logic). walkrpg-mobile commits 4831d49, 77092ce, f54aa7a, cb57928, b7fbcf0. W-level log: ops/decisions/2026-05-20-13-8-combat-ui-android-w-level.md.
  • 13-9 — Combat outcome → quest/tree/rep deltas. DONE 2026-05-20. tech-architect scope memo → mechanics-designer (data layer) → backend-engineer (impl) → mobile-developer (Kotlin port + UI) chain. Tech-architect step 1 (384b562): cross-cutting design memo wiki/.../tech/phase-13-9-design.md (392 lines, four deliverables with current-state / target-state / contracts / open-questions). 3 W-locks ratified by CEO before downstream dispatch — (1) walker.currentHp is Int? nullable (NULL = never initialized, derives to compose’d hp_max on read; cheapest backfill, no double-write); (2) composeWalkerStats lives in data/src/sim/compose.ts NOT in backend (iOS Phase-15 port inherits via ADR-0008 §6); (3) /resolve enrichment is FULL — walkerProgression always-zero block surfaces the D-016 invariant structurally on every encounter resolve. Mechanics step 2 (eb14862): composeWalkerStats pure function — sorted-id traversal for byte-stable order-independence, per-node add-then-mul bucketing, throws on unknown node ids. ClassSchema extended to full 10-field combatStats block (snake_case mirrors simulator’s WalkerSnapshot shape) — replaces baseHp/baseEnergy (deleted, no deprecation aliases — single source of truth). NodeSchema gains optional combatModifiers array (typed add/mul ops on stat enum); free-form modifiers preserved for step-economy. Cartographer combatStats: hp 80, energy 120, dmg 10, def 4, acc 0.82, eva 0.08, crit 0.05, critMult 1.5, energy_cost_per_action 1, cold_resist 0. Phase 13 passthrough — no nodes carry combatModifiers yet. +15 unit tests (14 → 29 data package). Backend step 3 (3bb9fe0): Prisma add_walker_current_hp migration (current_hp INTEGER nullable, no backfill — NULL is intended pre-13-9 state, first encounter resolve writes value). game-content.ts adapter mirror: Class with combatStats block, NEW Node interface + mirror array, cartographer literal verbatim from data content. buildWalkerSnapshot rewritten async — fetches tree allocations, calls composeWalkerStats(classData, allocatedIds, nodeRegistry), substitutes walker.currentHp clamped to hp_max per §1.2. resolveEncounter + retreatEncounter persist currentHp inside their $transaction blocks (D-010 defeat=1 clamp honored on write; retreat persists final hp; victory persists final hp; idempotent re-resolve returns reputationBefore/After=0 since pre-tx state unrecoverable per §3.4). Resolve/RetreatEncounterResponseDto enriched: walkerProgression all-zero block (D-016 invariant — future regression catches treePointsBankedDelta !== 0 immediately); factionRepDeltas with reputationBefore/reputationAfter/tierBefore/tierAfter; encounterSummary.walkerHpStart+walkerHpDelta for animation; loreUnlocked[]; questStateAfter.previousStepIndex. FactionRepService.applyDelta extended to return before/after/tier triple. GET /walker/profile returns currentHp+currentHpMax (both non-null on wire, currentHp resolves NULL → derived hp_max). +25 backend tests (211 → 236). Mobile step 4 — walkrpg-mobile 3 commits: 7ce5d91 (sim — bit-identical Kotlin Xorshift32 port: Int.ushr maps JS >>>, seed-0 remaps to 1 per frozen contract; CombatMath prediction-only subset with predictAttackTurn; draw-order discipline miss=1 roll / hit=3 rolls), fd75fe9 (features — CombatViewModel SavedStateHandle constructor + computePrediction() + handleTurnResult() reconciliation + resyncPrngFromServerRolls() (nulls PRNG on mismatch); spinner removed; no nextPrngState on wire — handled via draw-count advance reconciliation (documented in mobile decision log); enriched CombatDto + CombatDomain types with all new fields; CombatRepositoryImpl maps enrichment fields; WalkerProfile.currentHp+currentHpMax; CombatScreen HpDeltaBar (500ms animateFloatAsState), TierPromotionBadge (AnimatedVisibility/fadeIn), LoreUnlockChip — all with contentDescription + liveRegion=Polite; WalkerHpHud on HomeScreen with color-coded HP bar; +5 bilingual strings; versionName 0.1.0-13-8 → 0.1.0-13-9), 17da80c (tests — 169 → 218 (+49): Xorshift32Test (7 — draws 9-18 corrected from wrong placeholder values to verified node.js output, would have failed at CI on draw 9 without the fix); CombatMathTest (12); CombatPredictionTest (8); CombatDtoTest (14 — backward-compat with pre-13-9 backend shape verified); CombatRepositoryTest (+3 enrichment mapping + D-016 invariant); CombatViewModelTest (SavedStateHandle plumbed, accuracy fixture 0.80→0.82); HomeViewModelTest (+3 HP HUD); CombatWorkedExampleTest already correct (accuracy 0.82 + new fields). W-level decisions under ops/decisions/2026-05-20-13-9-* (4 logs: tech-design-memo, mechanics-compose-walker-stats, backend-implementation, mobile delivery). Combined test counts post-13-9: backend 236 (211 → 236, +25); data package 29 (14 → 29, +15); Android 218 (169 → 218, +49). Deferred to later sub-phases (not regressions): haptics on crit/victory/defeat (13-8 deferred, still open); opponent localized name endpoint (13-8 deferred, still open); wiki /api/ reference docs for combat + walker-profile endpoints (no wiki/.../api/ directory exists yet — backend-engineer flagged, future docs sub-task should create combat-encounter.mdx + walker-profile.mdx); explicit progression delta endpoints (encounter /resolve deliberately shows zero progression deltas per D-016 — actual XP/level/treePoints flow through other endpoints when D-016 banking ratio fires).
  • 13-10 — Keystone-unlock-as-quest-reveal (D-006 Pillar 3 cosmos hook). DONE 2026-05-20. (Cross-ref 2026-05-22: Quest 005 niemilknacy-kurier is the first hidden quest with keystoneRequirement — fully D-024 §2 compliant. The cosmos-hook UX surfaces D-006 Pillar 3 + D-024 hidden-discovery in user-visible form for the first time.) narrative-designer + mobile-developer parallel, then backend-engineer integration test. All KEYSTONE_GATE plumbing already lived since 13-5 (quest-gate-evaluator.service.ts + hiddenCount in /quest/available); 13-10 lands the first content + Android UX + e2e proof. Narrative (351a7de, e0fc772): Quest 005 quest.005-niemilknacy-kurier (Niemilknący kurier / “The Unhushed Courier”) — first quest with keystoneRequirement: { keystoneId: "keystone.unshaken-step" }. Five-beat companion-walk in Plenny with new NPC npc.stary-marno-niedoczas (Stary Marno Niedoczas — kurier of a courier-house dissolved 112 years ago, no idle rest since). Premise diegetically literalizes the keystone’s removal of idle regen: only a Walker with Krok Niezachwiany can hold Marno’s stride. Faction-rep: faction.unfinished-guild (+4 beats 1+3), faction.wild-path (+2 beat 4) — first Dziki Trakt accrual in a Plenny quest. Forward hook (Quest 006+ reservation): Marno carries sealed envelope of his own dissolved house — same house-mark as Quest 004 pinewood slip (npc.pine-half-century) — but addressee identity stays unresolved. Pan Korytarz poziom-25+ reservation strictly preserved. NPC slug renamed mid-flight (old-marno-out-of-timestary-marno-niedoczas) for lint compliance + convention with brodek-spozniony / pan-bezelec. Mobile — walkrpg-mobile 4 commits: 2663044 (QuestRefreshBus singleton SharedFlow with extraBufferCapacity = 1 to survive tab-switch timing — chosen over caller-driven option per W-level log; QuestRepository.refresh() interface method; TreeViewerViewModel injects bus + signals on successful keystone allocation; QuestLogViewModel subscribes in init + delta-detects newly-unlocked quest ids; acknowledgeNewlyUnlocked() + filter preservation), b833aaf (D-006 cosmos hook UX: Snackbar with action label “Open Quest Log” / Otwórz dziennik on TreeViewer with onNavigateToQuests callback, HiddenCountHint composable at bottom of QuestLog with liveRegion = LiveRegionMode.Polite for screen-reader announcement, 5 EN + 5 PL strings, Polish plural via template string — full <plurals> resource deferred to translator UX pass), b0c01e6 (+29 tests above the +12-18 target: QuestRefreshBus, delta detection, hiddenCount, a11y, filter preservation, offline-failure silent-preserve path per D-009 heavy-offline posture, Polish plural correctness, content-description assembly; 218 → 247), 190d9e0 (versionName 0.1.0-13-9 → 0.1.0-13-10, versionCode 2 → 3). Backend (a0a0f59): integration tests + adapter-mirror gap-fill. Quest 004 (quest.004-polowa-rejestru) was missing from backend/src/common/game-content.ts quests array (silent gap — no test referenced it pre-13-10; adding Quest 005 without 004 would have made all keystone-specific tests vacuously pass since the prereq gate would never resolve). Both added verbatim-aligned with data layer; Quest 005 is the first entry to set keystoneRequirement, activating KEYSTONE_GATE on real content. Stale 13-5 comment “No keystoneRequirement / factionRepRequirement set in data layer yet” removed. +4 quest.service.spec.ts tests in describe("GET /quest/available — keystone-gated reveal (13-10)"): hide-when-keystone-missing, reveal-when-both-gates-pass, hide-when-prereq-missing-even-with-keystone, hiddenCount-decreases-by-exactly-1 transition proof. Backend 236 → 240. W-level logs: ops/decisions/2026-05-20-quest-005-niemilknacy-kurier.md (narrative — 6 decisions including quest-premise choice from 3 candidates, NPC new-vs-reuse, faction-rep recipients, forward hook framing, quest type discriminator, slug shape) + ops/decisions/2026-05-20-13-10-mobile-quest-unlock-arch.md (mobile — 5 decisions including bus-vs-caller-driven, snackbar-vs-chip notification, Polish plural strategy, hiddenCount placement, offline silent-preserve). Combined test counts post-13-10: backend 240 (+4); data 29 unchanged; Android 247 (+29). Deferred to later sub-phases (mobile-developer raised, defer-by-default in 13-10 — Phase 13-10 owns minimum reveal flow, polish lands elsewhere): haptic on new-quest unlock per wireframe §4.4 “heavy impact + discovery tone” (haptic infra not wired in Phase 13 anywhere); onNavigateToQuests callback wiring into nav graph (next nav-increment sub-phase); bus signal scope remains keystone-only (regular node allocations don’t flip quest gates by current game logic; revisit if backend evaluator evolves).
  • 13-11 — Bilingual UI polish + a11y full pass. DONE 2026-05-20. ui-designer + mobile-developer sequential. UI step 1 (1b94be6): acceptance matrix wiki/.../ui/phase-13-11-acceptance.md (290 lines, ENG, 7 sections). W-lock: Settings screen for EN/PL switcher placement (gear icon on Home top-bar; SegmentedButton; walkrpg.locale.override SharedPreferences key; CompositionLocal-based zero-restart switching). Per-screen a11y checklist covering 9 implemented Android screens (Onboarding/ClassPick, Home, TreeViewer, QuestLog, QuestDetail, Factions, FactionDetail, CombatScreen, WalkerHpHud component). TalkBack + bilingual + 200% font-scale acceptance criteria. Test surface spec (+25-40 target). Explicit defer list: haptics, crafting, dark/light mode contrast audit, RTL, voice control. W-level log: ops/decisions/2026-05-20-13-11-ui-locale-switcher-placement.md. Mobile step 2 — walkrpg-mobile 4 commits: 09431cb (Settings screen with SingleChoiceSegmentedButtonRow EN|PL + haptic-placeholder row + @Preview(fontScale=2f); LocaleStore.kt factory pattern — create() for production EncryptedSharedPreferences, createForTest() for Robolectric unit tests; LocaleModule.kt Hilt @Module singleton; LocaleProvider.kt LocalAppLocale CompositionLocal + LocaleOverrideProvider composable wrapping LocalConfiguration + LocalContext; LocaleViewModel.kt @HiltViewModel with StateFlow<String> localeTag; MainActivity wraps AppNavigation in LocaleOverrideProvider; AppNavigation gains SETTINGS route + Home onNavigateToSettings callback. Zero-restart mechanism: LocaleOverrideProvider rebuilds Configuration + locale-configured Context in the Compose tree; all stringResource() calls see locale-correct strings.xml on next recomposition. Chose Compose CompositionLocalProvider over AppCompatDelegate.setApplicationLocales — ops/decisions/2026-05-20-13-11-mobile-locale-propagation.md), e97ad13 (a11y audit + font scale + bilingual fixes — HomeScreen settings gear contentDescription, WalkerHpHud health-state label healthy/warning/critical derived from fraction; StreakRibbon liveRegion Polite; TreeViewer available-points counter liveRegion comment confirming no nav-re-entry spam; tab bar fontScale >= 1.8f falls back to icon-only with full label as icon contentDescription per ui-designer flag; @Preview(fontScale=2f) added to HomeScreen, SettingsScreen, Factions, FactionDetail, QuestLog, QuestDetail, PostWalkSync — no clip/truncate/overflow; ProgressionCard hardcoded "${level} / ${totalNodes} allocated" extracted to R.string.progression_allocated with EN %1$d / %2$d allocated + PL %1$d / %2$d zaalokowane; Polish <plurals> resources quest_count + step_count with all 5 forms zero/one/few/many/other upgrading from 13-10 b833aaf template-string workaround), cbf21c3 (+53 tests across 9 files: Phase1311A11yTest 3, Phase1311FontScaleTest 6 — Home Loaded/Loading/Error at 1.0+2.0, Phase1311ClassPickScreenFontScaleTest 4, Phase1311QuestLogFontScaleTest 4, Phase1311FactionFontScaleTest 4, Phase1311CombatScreenA11yTest 6 — structural assertions + documented checks, Phase1311LocaleTest 7 — LocaleStore persistence + effectiveLocale logic with createForTest() bypass, Phase1311PluralsTest 13 — PL quest_count N=0/1/2/5/21 + step_count N=0/1/3/7 + EN forms, Phase1311SettingsScreenTest 6 — EN/PL segments visible + click callbacks + labels + haptic placeholder), 1a4bd3b (versionName 0.1.0-13-10 → 0.1.0-13-11, versionCode 3 → 4). Combined test counts post-13-11: backend 240 unchanged; data 29 unchanged; Android 247 → 300 (+53). CAVEAT — Gradle verification deferred: mobile-developer authored 53 tests but could NOT execute ./gradlew test/lint/build in the sub-agent environment (no Gradle binary installed; gradlew wrapper JAR not committed per gradle-wrapper.properties — comment says gradle wrapper --gradle-version 8.7 bootstrap required). Tests are code-reviewed and follow established patterns from prior sub-phases (13-9/13-10 Compose-test conventions), but pass/fail status is unknown. Verification deferred to next session (run Gradle bootstrap + ./gradlew test) or to CI image (mingc/android-build-box). Flag for next-session audit. Deferred from 13-11 (per acceptance matrix §7): haptic feedback infra (b833aaf + 09431cb placeholder row prepared), Crafting screen (Phase 14+), dark/light mode contrast audit, RTL support, voice control beyond TalkBack.
  • 13-12 — Offline queue hardening + 7-day cap enforcement. Walks done offline, allocations made offline, quest progress made offline — all sync correctly on reconnect. (Cross-ref 2026-05-22: D-018 §What-not-decide mandates sink-debit ordering be respected on sync — flag for QA. Optional scope absorption per §10.9 / §10.10: minimal D-026 FCM token registration + per-class opt-in surface AND/OR D-027 diegetic onboarding expansion (Bertranda walkthrough + 50-step register + Map first-impression + class-pick-as-beat-1-close). FLAG_LEAD: CEO triage at next planning round — does 13-12 absorb minimal D-026 push + D-027 diegetic onboarding, or do those defer to a new 13-N+1 / post-Phase-13?)
  • 13-13 — Phase 13 exit scenario integration test. Real Android device, the full exit-scenario walkthrough from §5. Bug fix sweep. (Cross-ref 2026-05-22: D-021 mandates pure-micro AND pure-evening usage patterns both work — currently the §5 walkthrough implicitly assumes evening-session; QA should verify both. D-027 §2 cold-open beats need either to be present in 13-13’s walkthrough OR explicitly marked as deferred to a post-Phase-13 onboarding sub-phase. §5 step 4 (“Complete onboarding tutorial”) may need editorial pass per D-027.)

If more sub-phases emerge from re-planning (likely — onboarding polish, error handling, edge cases on Health Connect provenance, mock-auth UX, push notifications) they append here as N+1, N+2, etc.

7. Per-area sub-phase mapping

Cross-reference so no area is starved. As of plan v1:

  • Combat: 13-7, 13-8, 13-9.
  • Quests: 13-5, 13-7 (quest-trigger), 13-9 (outcome→quest), 13-10.
  • Character progression: 13-2 (D-016 spec), 13-3 (walker creation + class), 13-4 (streak + step→energy), 13-5 (tree allocation), 13-10 (keystone-unlock).
  • Cross-cutting infrastructure: 13-1 (Android repo), 13-6 (faction), 13-11 (a11y/i18n), 13-12 (offline queue), 13-13 (exit test).

If after a few sub-phases land we notice one area is racing ahead and another is starved, re-balance at the next /work re-planning.

8. Dispatch posture

How orchestrator dispatches a sub-phase:

  1. CEO types /work phase-13-N.
  2. Orchestrator reads this plan, locates sub-phase N, confirms its prerequisite is met.
  3. Orchestrator dispatches the paired leads listed in the sub-phase (typically tech-architect + mobile-developer; sometimes also mechanics-designer or narrative-designer consulted).
  4. Each lead returns a structured report.
  5. Orchestrator commits the work in logical chunks per auto-commit policy.
  6. Orchestrator updates the roadmap row + this plan (mark sub-phase done, append commit SHA, expand the next skeletal placeholder if its shape has clarified).
  7. Orchestrator returns control to CEO with a planning prompt: “13-N landed. Proposed next: 13-(N+1) per plan. Alternative: . Pick one or re-plan.”

Lore parallelism: at any point during Phase 13, CEO can dispatch narrative-designer for an independent lore increment (Quest 003, new NPCs, region deepening). Lore work does not consume Phase 13 dispatch budget; it runs alongside.

Re-planning cadence: Every sub-phase boundary. Plan v1 (this document) commits with the first sub-phase. Plan v2 commits with sub-phase 13-2 (after D-016 ratifies, point-award math becomes concrete, downstream sub-phases can be detail-planned).

Dispatch frequency: Estimate 1-2 sub-phases per CEO session. Phase 13 total runs ~13-20 sub-phases; estimate 6-10 CEO sessions to complete. No calendar deadline — exit gate is the §5 exit-scenario green run.

9. Risks + mitigations

Risk: Progression system spec drift. D-016 ratifies one shape; downstream sub-phases drift from it as they implement. Mitigation: every sub-phase that touches XP/level/points includes a checklist line “compared values against D-016 §”; system-reviewer cross-checks at sub-phase ship time.

Risk: Android-iOS contract divergence (forward-looking to Phase 15). Phase 13 ships Android-only; iOS in Phase 15 must inherit the validated contract. Mitigation: any platform-coupled decision in Phase 13 sub-phases is documented in the relevant ADR with explicit “iOS port inherits this” annotations. Specifically: mock-auth flow, Health Connect provenance contract, attestation token shape, offline queue semantics.

Risk: Backend endpoint surface bloat. Endpoint-per-feature adds up; the 8-endpoint baseline could grow to 20+ across Phase 13. Mitigation: tech-architect consolidates endpoints where possible (e.g. /walker/profile returns progression + streak rather than spinning up /walker/progression + /walker/streak as siblings unless real reason); Swagger doc kept current per sub-phase.

Risk: Lore-canon drift unnoticed because parallel. Lore work shipping in parallel could ratify things that conflict with Phase 13 assumptions (e.g. a new region introducing a faction-allegiance constraint that breaks the class-pick flow). Mitigation: game-director reviews any D-level lore ratification against the active Phase 13 sub-phase before it lands; system-reviewer cross-checks every D-level vs. open canon.

Risk: Mock-auth (ADR-0006) being baked in too deep, hard to swap to Firebase Auth (production target). Mitigation: auth integration on Android lives behind an interface; switching to Firebase Auth in the production-migration phase is a single adapter swap. Documented in 13-1 sub-phase ADR.

Risk: Combat encounter API drift from simulator. The simulator (data/src/sim/combat.ts) is the canonical math. If the backend encounter endpoint re-implements the loop separately, drift is inevitable. Mitigation: the backend MUST import the simulator from the data/ package and replay it server-side — the encounter endpoint is a thin wrapper over the simulator + persistence, not a re-implementation. Locked in 13-7’s ADR.

Risk: D-016 stalls. If progression-system /research takes more than 3 rounds without converging, Phase 13 sub-phases 13-3 onward (anything progression-touching) are blocked. Mitigation: if 3 rounds without convergence, CEO escalates to direct decision (no more rounds) — the system needs to ship even if the math is not perfect, and D-016 can be amended in a later D-level decision.

Risk: Phase 13 scope creep. Every sub-phase adds new “while we’re here” features. Mitigation: this plan is the contract; new ideas go into “13-N+1 skeletal” placeholders, not into the active sub-phase. Re-plan at boundaries, not mid-sub-phase.

10. Forward-references — composition with D-018..D-027

This section was appended on 2026-05-22 as an editorial re-check pass — no new D-canon, no sub-phase scope change. It documents how the ten D-decisions ratified 2026-05-21 → 2026-05-22 compose with Phase 13’s already-landed surface area, and which sub-phases (current or remaining) carry their forward-references.

The plan body (§1-§9) is the contract; this section is the cross-reference map. If a future re-check finds the body and this section in tension, the body wins and this section is corrected.

10.1 D-018 — Energy economy (action fuel + tight budget)

Status: Phase 13 combat encounter resolution already debits Energy per the D-018 ~30%-of-daily envelope; the sink shape was implicit in 13-7’s simulateEncounter integration and is now canonical. Sub-phases 13-7 (backend combat module) and 13-8 (Android Combat UI) operate inside the D-018 envelope without amendment. No code change required. Forward-references at 13-12 (offline queue must respect sink-debit ordering on sync; see D-018 §What-not-decide) and at any post-13 craft-attempt sub-phase (D-018 ~20%-per-attempt sink, currently un-surfaced because Phase 13 ships crafting tab as stub per §5 Mobile).

Canon link: D-018.

10.2 D-019 — Class system (5 factional classes + starting-cluster differentiation)

Status: Phase 13-3 shipped class.cartographer (Cech-aligned, Plenny start, cluster.first-steps) as the single playable class for the closed-beta cohort. As of 2026-05-22, the four remaining classes (class.pieczetarz / class.pielgrzym / class.komiwojazer / class.tropiciel) and their starting clusters (cluster.first-seal / first-lantern / first-route / first-sign, 8 nodes + 1 keystone each = 32 nodes + 4 keystones total) are authored at the data layer (commits c6c722e, 06d75b5, 83b5451) but NOT yet surfaced on the Android client. The §5 Data-layer feature-checklist item “At least 1 class instance authored” is satisfied; the implicit “ship 1, defer rest” posture documented in §4.2 is superseded by D-019 (canonical 5-class roster locked).

Phase 13 scope position: Phase 13 still ships 1 playable class (Cartographer) for the closed-beta exit scenario. Surfacing the other 4 in onboarding is a forward-reference to D-027 (see §10.10). Backend adapter mirror for the 4 new classes in backend/src/common/game-content.ts is intentional Phase 13 scope — tracked at ops/escalations.md Q8 FYI (2026-05-22). Mobile bundle currently bundles only Cartographer (per 13-3 BUNDLED_CLASSES); D-019 §3’s starting-cluster differentiation surfaces in mobile only after the class-selection endpoint lands (post-13 or in 13-12 if onboarding work expands per D-027).

Plan amendment: §3.3 “Character progression” originally enumerated “At least 1 class instance authored” as the Phase 13 contract. Update reading: §3.3 stands, but §4.2 “Class instance scope for Phase 13” should be read as CLOSED by D-019 — the canonical N=5 roster is now ratified, the W-level pick has been made (1 ships in Phase 13, 4 land at data layer per D-019 §2’s W-level follow-up which has now executed). No code regression; the §4.2 framing is historical.

Canon link: D-019.

10.3 D-020 — Combat encounter system (pull-based trigger + tiered risk-choice pool)

Status: Phase 13-7’s combat encounter API (ADR-0008 POST /combat/encounter family) implements encounter resolution but NOT the pool / trigger / tropy queue D-020 ratifies. Sub-phase 13-7’s POST /combat/encounter initiates from a quest beat directly (the only trigger source live today); D-020 §2 names two pool sources (step-driven + quest-beat-driven) of which only quest-beat-driven currently exists. The step-driven tropy accumulation, the badge taxonomy (easy / normal / hard / keystone-ready), and the visible-before-commit risk choice are all forward-references — they sit at post-13 W-level under mechanics-designer (B-level cadence tunables) + backend-engineer (pool persistence + visibility endpoint) + ui-designer (map-pin badge styling per D-022 §1).

Plan amendment: §3.1 “Combat” Phase 13 contract stands — Phase 13 ships encounter resolution, NOT pool building. Sub-phase 13-12 / 13-13 remain “offline queue hardening” and “exit-scenario integration test” per §6 skeletal entries; the D-020 pool trigger is NOT folded into Phase 13 unless CEO explicitly amends. If it is folded in, it belongs as a new sub-phase 13-N+1 (estimated ~1 dispatch session), not a 13-12 / 13-13 expansion. Recommended: defer to post-Phase-13.

Carve-out: D-020 §5 introduces trop / tropy terminology disambiguation (gameplay entity vs D-013 process slot). Glossary entry per D-017 is W-level narrative-designer follow-up; no Phase 13 schema change required — the encounter persistence layer (combat_encounters table, 13-7) is trop-agnostic on the wire.

Canon link: D-020.

10.4 D-021 — Daily loop (hybrid micro check-ins + evening session)

Status: D-021 ratifies the cadence the app is designed AROUND (3-5 micros + 1 evening session); it does NOT mandate any UI or notification surface in Phase 13. Phase 13’s current home + post-walk-sync + combat surfaces compose cleanly with both micro and evening usage (verified in §5 exit-scenario walkthrough). No code change required. Forward-references at 13-13 exit-scenario integration test (the walkthrough implicitly assumes a single evening-session pattern; D-021 §2 mandates pure-micro and pure-evening both work — flag for QA at 13-13).

Canon link: D-021.

10.5 D-022 — Map as live gameplay surface (diegetic centrality, navigational preservation)

Status: D-022 ratifies the 5-tab bar (Home / Tree / Factions / Quests / Craft) is preserved (D-014 §1 unchanged), and that Map is a diegetic gameplay artefact fronted by the Home tab, NOT a 6th tab. Phase 13’s 5-tab nav (per §5 Mobile feature-checklist + 13-4 Home implementation) is canon-aligned. The “Home fronts a Map widget that IS the encounter-queue UI” reading of D-022 §1 is a forward-reference — Phase 13’s Home currently renders region card + streak ribbon + quest pill + faction strip (per 13-4), not the live-rewriting Map widget. The Map widget per D-022 §1 + D-013 przepisać real-time curvature rewriting is a post-Phase-13 ui-designer + mobile-developer + tech-architect sub-phase (estimated 1-2 dispatch sessions, depends on D-020 pool surface). No Phase 13 regression.

Forward-reference also touches: D-022 §What-not-decide explicitly defers accessibility-mode rendering (e.g. high-contrast Map, screen-reader-readable Map state) — overlapping with D-029 candidate (currently in /research). See §10.11 below.

Canon link: D-022.

10.6 D-023 — Endgame (Atlas of rejestry — procedural editorial-commit instances)

Status: D-023 names the endgame surface (Atlas unlock at ~144 pts spent, procedural rejestr instances). Phase 13’s exit scenario (§5) ends at “first allocation on cluster.first-steps” — many tens of points BEFORE the Atlas unlock threshold. No Phase 13 surface area touched. D-023 is purely forward — earliest implementable phase is post-Phase-14 once the closed-beta cohort has had time to approach ~50 pts. Cross-reference noted for completeness; no code change required in Phase 13.

Canon link: D-023.

10.7 D-024 — Quest structure (6 region-linear sagas, 15 main + 3 hidden per region)

Status: D-024 ratifies the 6 × 18 = 108 quest distribution (90 main + 18 hidden) with strict linear chain within a region + off-spine hidden quests + Plenny-canonical-first cross-region order. Phase 13 has shipped Plenny quests 001-006 (per Lore parallel SHAs in “Current phase” / “Recent landings”); the chain Q001 → Q002 → … → Q006 already matches D-024 §2’s “strict linear chain” pattern. Sub-phase 13-5’s GET /quest/available + QuestGateEvaluator + KEYSTONE_GATE are the canonical implementation surface for D-024 §2’s hidden-quest gating. Quest 005 (niemilknacy-kurier, shipped in 13-10) is the first hidden quest with keystoneRequirement — fully D-024-compliant.

Phase 13 forward-reference: Plenny is 6 quests deep; D-024 mandates 15 main + 3 hidden = 18 per region. The remaining 12 Plenny main quests + 3 hidden Plenny quests are post-Phase-13 narrative-designer work. No Phase 13 regression — Phase 13 ships the vertical slice, not a full saga.

Canon link: D-024.

10.8 D-025 — Multiplayer scope (M1 package)

Status: D-025 ratifies async lightweight co-op + full guild infrastructure + scheduled regional events as Phase 13/14 scope, deferring real-time sync walking to post-Phase-16. Phase 13’s current backend + Android surface area has zero multiplayer code — no guild entity, no co-op session model, no event scheduler. Per D-025 §3 phasing, Phase 13 ships guild persistence + polling chat + lightweight co-op session reconciliation as the largest Phase 13 increment (~3-4 weeks W-level under tech-architect per D-025 §3). This is NOT in §6’s skeletal sub-phase list — D-025 is a Phase 13 scope expansion that needs CEO triage at the next planning boundary.

Plan amendment proposal (CEO triage): Add three new skeletal sub-phases to §6 covering (a) guild entity + chat polling, (b) lightweight co-op session model, (c) regional event scheduler + leaderboard. Sequence + detail TBD at next planning round. FLAG_LEAD: D-025 expands Phase 13 scope materially beyond §1’s “vertical slice” framing — the exit-scenario walkthrough (§5) does NOT cover any multiplayer path. CEO should decide whether Phase 13’s “closed-beta cohort needs” includes multiplayer or defers to Phase 14 VPS.

Canon link: D-025.

10.9 D-026 — Notifications (meaningful-state firing + Pratchett-warm Cech editorial voice)

Status: D-026 ratifies a 6-class notification firing matrix + 8 forbidden fire classes + voice register canon. Phase 13’s current Android client has zero push notification infrastructure — neither FCM token registration, nor per-class opt-in surface, nor the editorial-voice copy bank. D-026 §5 establishes 6 channel groups; per-class opt-in surface is a forward-reference to D-027 onboarding (§10.10) + a post-Phase-13 ui-designer + mobile-developer + narrative-designer sub-phase.

Phase 13 forward-reference: Phase 13 may ship a minimal D-026 surface as part of 13-12 (offline queue hardening) — specifically the FCM token registration + per-class opt-in toggles per D-027 §2 step 6. The full firing matrix (6 classes × ~324 hook lines across 108 quests per D-024) is post-Phase-13 narrative-designer work. No Phase 13 regression.

Canon link: D-026.

10.10 D-027 — Onboarding (diegetic Bertranda walkthrough as Quest 001 beat 1)

Status: D-027 ratifies that onboarding IS Quest 001 beat 1 — no meta-tutorial, no skippable overlay. The Phase 13-3 onboarding flow (splash → class pick → home) is partially D-027-aligned but predates D-027 canon and needs reconciliation. Specifically:

  • Step 0-2 (splash + sign-in + permissions): mostly intact — Phase 13-1 mock auth + Phase 13-4 Health Connect permission prompt cover this.
  • Step 3-5 (Bertranda hands Map + motto + 50-step register the hand): NOT IMPLEMENTED in Phase 13 — current onboarding goes splash → class pick → home directly. The diegetic Bertranda walkthrough + 50-step bar + Map widget first-impression are forward-references.
  • Step 6 (notification opt-in): NOT IMPLEMENTED — see §10.9 above.
  • Step 7 (class selection): Phase 13-3 ships class-pick screen, BUT currently as a UI screen BEFORE Quest 001 beat 1, not AS the closing surface of Quest 001 beat 1 per D-027 §3.
  • Step 8 (Quest 001 beat 1 closes): Quest 001 exists data-layer; the beat-1-as-onboarding wrapper is not built.

Phase 13 forward-reference: Sub-phase 13-12 “Offline queue hardening” was originally scoped narrowly (per §6 skeletal entry). D-027 raises the question whether 13-12 OR a new sub-phase 13-12.5 / 13-N+1 absorbs onboarding reconciliation — Bertranda walkthrough expansion + 50-step register surface + class-selection-as-beat-1-close per D-027 §2-§3. Alternatively, the existing 13-3 class-pick UI is treated as adequate for closed-beta and the diegetic expansion lands post-Phase-13 (narrative-designer + ui-designer + mobile-developer paired). FLAG_LEAD: CEO triage required — Phase 13 plan §4.2 + §3.3 originally framed class-pick as a standalone onboarding step; D-027 reframes it as a within-Quest-001 closure. Either (a) ratify expansion into 13-12 or 13-N+1, or (b) accept the current 13-3 class-pick as Phase-13-final and schedule diegetic expansion post-Phase-13. Recommended: option (b) — preserve Phase 13 exit-scenario stability, schedule onboarding diegetic expansion as a Phase-13-followup or early Phase 14 task.

Sub-phase 13-13 (exit-scenario integration test) note: the exit-scenario walkthrough in §5 step 4 (“Complete onboarding tutorial”) needs an editorial pass to align with D-027 — either expanded to cover the §2 cold-open beats, or explicitly marked as “minimal-onboarding for Phase 13 closed-beta, full D-027 onboarding lands in 13-N+1 or post-13.”

Canon link: D-027.

10.11 D-029 candidate (accessibility, IN /research)

Status: D-029 is a candidate in ops/research/d-029-accessibility.md (per Q3 of the 2026-05-22 night plan) and is NOT canon. The candidate carries a HARD CLAUDE.md Pillar 1 amendment (broadening “step ingest” to “movement attestation” covering wheelchair propulsion / treadmill / stationary cycle / passive modes). Phase 13 has zero wheelchair / treadmill / stationary attestation code — all current ingest is HealthKit / Health Connect step counts. Forward-reference only: if D-029 ratifies, Phase 14 (VPS) or Phase 15 (iOS) adds the broader movement-attestation contract; D-022 §What-not-decide pre-deferred Map accessibility rendering to the same window. Out of scope for Phase 13.

Canon link: TBA — D-029 not yet ratified. Research artifact at ops/research/d-029-accessibility.md (pending).

10.12 Summary — what changes in Phase 13 as a result of D-018..D-027

Zero code-layer regressions identified. All ten D-decisions compose with Phase 13’s already-landed surface area without contradicting any sub-phase 13-1..13-11 deliverable.

Two FLAG_LEAD items for CEO triage:

  1. D-025 multiplayer scope (§10.8): Phase 13 originally framed as “vertical slice” without multiplayer. D-025 ratifies guild + co-op + events as Phase 13/14 scope. CEO must decide whether Phase 13 absorbs the M1 package (adding 2-3 new sub-phases) or defers all multiplayer to Phase 14 VPS.
  2. D-027 onboarding shape (§10.10): Phase 13-3 ships class-pick as a standalone UI step; D-027 reframes class-pick as the closing surface of an expanded Quest 001 beat 1 (Bertranda walkthrough + 50-step register + Map first-impression). CEO must decide whether Phase 13 absorbs the diegetic onboarding expansion (new sub-phase 13-12.5 / 13-N+1) or accepts current 13-3 as Phase-13-final.

Two minor amendments folded into the plan body:

  • §4.2 “Class instance scope for Phase 13” reads as CLOSED by D-019 (5-class canonical roster ratified; 4 additional classes authored at data layer 2026-05-22 per c6c722e / 06d75b5 / 83b5451).
  • §3.1 “Combat” Phase 13 contract stands; the D-020 pull-based pool + badge taxonomy + visible-before-commit risk choice are post-Phase-13 forward-references (§10.3).

Plan version: v2 (2026-05-22 — §10 forward-references appended; no body changes). Authored by: game-director per D-015 follow-up; §10 appended per night session 2026-05-22 Q10 (re-check pass against D-018..D-027). Updated at every sub-phase boundary.