docs(clock): record lifecycle recovery boundaries

This commit was merged in pull request #1.
This commit is contained in:
2026-09-03 21:08:48 +00:00
parent b77276f202
commit ffbd51a2ef
5 changed files with 65 additions and 2 deletions
+10 -1
View File
@@ -40,7 +40,7 @@ representation.
| `input_event.processing_game_tick`, `processing_clock_revision`, `processing_deadline_generation` | actual mutation boundary | GAME metadata | stop | KEEP | effect validation/RNG uses this coordinate |
| `input_event.created_at`, `processing_at`, `completed_at`, `lease_until` | request receipt, processing audit, lease | WALL, DB UTC | advance | excluded | external occurrence and worker lease |
| `read_model_outbox.*_at`, `web_push_outbox.*_at` | availability, claim, delivery, audit | WALL, DB UTC | advance | excluded | retry and notification delivery are operational |
| `turn_daemon_lease.lease_until`, `heartbeat_at` | daemon liveness | WALL, DB UTC | advance | excluded | a paused game must still lose a dead daemon lease |
| `turn_daemon_lease.lease_until`, `heartbeat_at` | daemon liveness | WALL, DB UTC | advance | excluded | acquire/renew/assert/release use `CURRENT_TIMESTAMP AT TIME ZONE 'UTC'`, including KST sessions |
| `general.turn_tick` | next general turn | GAME | stop | SHIFT; `turn_time` projection | determines engine order |
| `general.recent_war_tick` | past battle occurrence | GAME | stop | KEEP; `recent_war_time` projection | historical event does not move |
| `general.meta.next_change_tick` | N-turn reselection cooldown | GAME | stop | SHIFT; `next_change`/`nextChangeAt` projections | expressed in turns; missing tick fails closed |
@@ -164,3 +164,12 @@ Old projection columns remain during rolling deployment, but new code never
chooses a clock by NULL fallback: GAME rules require their tick; WALL rules use
their wall column. The disposable migration verifier covers populated upgrade,
indexes/constraints, replay safety, and a second no-op deploy.
Migration `20260903183000_turn_daemon_lease_utc_wall` treats daemon leases as
ephemeral WALL authority: it expires pre-deployment rows, changes the heartbeat
default to DB UTC, and requires the new daemon to acquire a fresh fencing epoch.
Migration `20260903201500_complete_invader_game_clock` moves historical
`isUnited>=3` worlds from `RUNNING`/`MANUAL` to `COMPLETED` and resolves pending
unchosen invader actions at `max(created_game_tick, world_state.clock_tick)`.
Neither migration shifts a WALL occurrence or turns one rule into a clock
fallback.