task 10 context - xopherdeep/do-it-for-the-xp GitHub Wiki

Task 10 context from the lead (decisions the brief cannot know)

Earlier tasks you consume (on this branch; read with chemx read <file> --outline / --symbol=<name>):

  • T3 src/lib/services/projects/projectSchedule.ts (PhaseWindow, daysBetween) and floorBonus.ts (floorMultiplier(window, clearedOn)).
  • T5 the floorCleared climb lock: the stairs up of a tower floor stay locked until the floor's chores are cleared; the room context field floorCleared?: boolean is typed but NOT filled yet: fill it in getLiveContext (the liveContext object literal in src/app/Console/TempleGrounds/templeGrounds/useRoomOutcomes.ts).
  • T6 the tower record: temple id gen-project-<typeId>, floors 1F..nF, roof roofFloorKey (${phaseCount + 1}F, phaseId "roof"); chore rooms are open monster rooms; the last phase's floor boss is a sealed miniboss that drops the Boss Key; the roof holds the finale (sealed boss) and a Master Room "The Trophy".
  • T7 src/lib/databases/ProjectDb.ts (getProjectDb().getActive()), projectRecord.ts (ProjectFloor: floorKey, phaseId, window, questIds, wokenAt?, clearedAt?, multiplier?).
  • T8 src/lib/services/projects/projectProgress.ts (pure: wakeFloor, questsWokenBy, isFloorCleared, isPaidEntry, settleFloor, rescheduleFloors, FloorSettlement) and projectService.ts (onQuestPaid, onEntryPaid, startProject, extendProject(newEndOn, today), abandonProject(), ProjectStores fakes for specs). The phase names come from the project type (src/lib/services/core/packs/projects/projectTypes.ts).

Rulings (decided; follow them):

  1. The arrival wake for a gen-project- temple is the FAMILY's (spec section 5): reaching a floor wakes it for everyone through the project (T8's wakeFloor + save its quests), not the per-hero wake map of wakeOnEntry. Add one service entry in projectService.ts, e.g. onFloorReached(floorKey, now), that wakes the floor if it is not woken and then calls T8's settleReadyFloors() (it settles every woken, unsettled floor that reads cleared, lowest first, and climbs), so a floor emptied by deleted chores settles on arrival. Call settleReadyFloors() too when the tower loads in TempleGrounds and when the Hometown sheet opens (a cheap retry for a stuck floor). Waking twice changes nothing. Keep the pure part in projectProgress.ts with a test.
  2. floorCleared in the room context is isFloorCleared(floor, quests, paidEntries) for the hero's current floor of a gen-project- temple (an empty floor reads true), and undefined for every other temple (they never use the lock).
  3. "Floor cleared!" is a reveal prompt (useRevealPrompt, the in-world prompt the temple already uses for floor wakes), not an Ionic alert, with the floor's multiplier when it was above x1. Show it once per hero per floor (when the hero is in the tower and the floor has clearedAt); say in the report how you remember "seen".
  4. The deleted key-guard chore (parked from T8): check what a sealed miniboss room whose questIds all point to deleted quests does in play (src/lib/services/temples/questRooms.ts, resolvePicks); if it can never be cleared, the Boss Key must still be reachable: make that room open and drop its key when it holds no live quest. Pin it with a test. If it already works, say so in the report with the code path.
  5. Reset the heroes' saved runs in the tower (TempleProgressDb, the Old House's forgetOldHouseWalks pattern: find it with chemx q -g "forgetOldHouseWalks") when a project starts and when it is abandoned, so a re-run tower does not open on an old run's position. This goes in projectService.ts (startProject / abandonProject) with a spec case each.
  6. floorClockLine / bonusOfferLine copy lives in the copy catalogue (src/lib/services/copy/catalog/, three voices simple / adventure / classic, copyFor(key, voice, vars)); the brief's English lines are the simple voice. "due today" on the due day, "late" after it; the offer is floorMultiplier(window, today) formatted with one decimal ("x1.6" written with the multiplication sign as in the brief), null when the floor is cleared or the multiplier is 1. No em dashes.
  7. The Hometown sheet (ProjectTowerSheet.vue): heroes see the tower name, current floor and its clock; the Game Master also sees "Move the end date" (a date picker that refuses a date before today, then extendProject) and "Abandon project" (an in-world confirm, then abandonProject). With no active project the spot is hidden (earlier ruling R5); Task 11 wires the trophy into this spot, so leave a clear seam (an empty state is enough). Extending from today can overlap a floor cleared early whose due day is still ahead: show it as cleared, never as late.
  8. The voxel project-tower shape: a narrow stack of the floor count plus a roof, in theme colours (no hex literals in .vue/.scss: use --gs-* tokens; buildingShapes.ts follows its own existing palette convention). Do not change the BGM (the guard plays <element>-temple for gen- temples).
  9. Do not hide, relabel or reorder any bottom-nav tab (owner rule). Controls (pickers, action buttons) sit at the bottom of phone screens; content reads above. Screens stay thin: rules live in pure modules with specs.
  10. Out of scope: Task 11's trophy, credits and reward reveal; Task 12's Old House retirement.
  11. startProject never reuses a project id (found in Task 9's review): when ProjectDb already holds a record with input.projectId (an abandoned run started the same day), give the new run a fresh id by suffixing "~2", "~3", ... (a pure helper with a test) and build its quests with that id, because the abandoned run's paid log entries still name the old quest ids and would settle 1F at once. Add a projectService spec case: abandon and restart the same type on the same day, 1F is not cleared.
⚠️ **GitHub.com Fallback** ⚠️