maniator / maniator/verticopolis
[Feature]: [P3] Move-in gate: known approximations (household mean, intra-pass staleness, inspector cause map)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 5
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
Deferred from the /gds-code-review of the move-in sustainability gate (spec-move-in-sustainability-gate-2026-07-23, branch claude/move-in-sustainability-gate). Three real-but-minor approximations in wouldEvictFreshTenant / the gate, parked for scope. The gate ships correct for the reported churn (noise/far-walk/lobby-far/rent), and the congestion over-block found in the same review was fixed inline (congestion is neutralized in the gate context).
-
Probe household fixed at mean 3 (Edge Case Hunter, under-block). The probe uses
residents: CLASSIC_HOUSEHOLD(3) in both modes. A real Modern condo draws 2-5. ThedaycareFamilyBonus(dist, residents)scales with household size, so a noisy condo whose survival depends on a daycare halo can pass the gate at 3 yet churn a real 2-person buyer who gets less bonus. Narrow (needs a daycare-offset-dependent spot AND a below-mean buyer). Fix shape: probe the worst-case (smallest) household for the halo term, or fold into the horizon calibration below. Relates to spec §11move-in-gate-horizon-calibration. -
Intra-pass context staleness (Edge Case + Blind, under-block).
attemptMoveInsbuildssatCtxonce and reuses it while the same pass seats tenants, so thedemandMap/occupancy a later candidate is judged against does not reflect earlier same-pass fills. A later condo can pass the gate on pre-fill coverage and then erode on unmet demand. Deterministic, and the next tick rebuilds the context, so it self-heals within one in-game hour. Fix shape: invalidate/rebuild the gate'sdemandMapafter N move-ins in a pass, or rebuild the context per candidate (perf cost + a golden re-pin). -
Inspector
wontLeaseTextverdict vs cause use two demand maps (Edge Case, legibility). The verdict comes from a freshcomputeDemandMapinside the predicate; the cause comes fromdominantGripe->sim.demandMap()(hour-memoized). Within an hour of an occupancy change they can disagree, so the line can show "Won't lease" but drop the specific "too few shops" cause and fall to the generic string. No crash (fallback handles it); the actionable cause is just less specific in a narrow window. Inspector-only. Fix shape: thread one demand map through both the verdict and the cause.
Also noted (not a row): a floor-1 served-check divergence between the engine gate (servedSet.has) and wontLeaseText (isFloorServed, always true on floor 1) is currently unreachable (offices are not founded on floor 1, condos are not placed there); revisit only if a floor-1 rentable becomes possible.
Story: move-in sustainability gate. Notes mirror the backlog row of the same id.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with wouldEvictFreshTenant, the move-in gate, and attemptMoveIns to trace household sizing and the reused satCtx demandMap. Then inspect dominantGripe and sim.demandMap() for the inspector cause path. Done means the three listed approximation cases are addressed without reintroducing the already-fixed congestion behavior, with any needed golden result re-pinned.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- game-dev
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100