Raised during review of #348 (W83 — Buildings Get Dirty, Wear Out, and Break).
applyWorldEffects's deferred building-meter branch (src/engine/src/kinds/world-graph/tick/effects.ts, the buildingMeters loop's context.deferBuildingMeters branch) marks applied[index] = true as soon as the local group.delta is nonzero — before system 14 (cleanliness-wear) has composed/clamped the total across all deferred sources for that building/meter. The non-deferred branch just below, and the guestMeters branch above, only mark applied once the final clamped value actually differs from previous.
Concrete failure scenario: a scenario/policy building_meter_delta effect that nets to zero once system 14 sums it with same-tick service/staff/litter deltas for the same building/meter still fires kind.world-graph.scenario.effect.applied, even though the meter never moved. Low severity today — debug-level, and scenario is the only caller reading .applied — but a real semantic drift.
Why not fixed inline: a true fix needs to know the post-composition outcome before applyWorldEffects returns, which conflicts with the whole point of deferring. The existing test in pipeline.test.ts ("applies every effect family, groups/clamps meters once...") already locks in "every staged effect counts as applied" for the single-source case, so a fix would need to update that assertion's intent, not just the implementation.
Reference: PR #348 review thread on src/engine/src/kinds/world-graph/tick/effects.ts:283.
Raised during review of #348 (W83 — Buildings Get Dirty, Wear Out, and Break).
applyWorldEffects's deferred building-meter branch (src/engine/src/kinds/world-graph/tick/effects.ts, thebuildingMetersloop'scontext.deferBuildingMetersbranch) marksapplied[index] = trueas soon as the localgroup.deltais nonzero — before system 14 (cleanliness-wear) has composed/clamped the total across all deferred sources for that building/meter. The non-deferred branch just below, and theguestMetersbranch above, only markappliedonce the final clamped value actually differs fromprevious.Concrete failure scenario: a scenario/policy
building_meter_deltaeffect that nets to zero once system 14 sums it with same-tickservice/staff/litterdeltas for the same building/meter still fireskind.world-graph.scenario.effect.applied, even though the meter never moved. Low severity today — debug-level, andscenariois the only caller reading.applied— but a real semantic drift.Why not fixed inline: a true fix needs to know the post-composition outcome before
applyWorldEffectsreturns, which conflicts with the whole point of deferring. The existing test inpipeline.test.ts("applies every effect family, groups/clamps meters once...") already locks in "every staged effect counts as applied" for the single-source case, so a fix would need to update that assertion's intent, not just the implementation.Reference: PR #348 review thread on
src/engine/src/kinds/world-graph/tick/effects.ts:283.