feat: 게임 시계 reconciliation 권위 기반 추가

This commit is contained in:
2026-09-03 08:44:43 +00:00
parent b91dcbcaaa
commit ae7d55ef47
29 changed files with 1265 additions and 81 deletions
@@ -0,0 +1,81 @@
# Game clock reconciliation implementation plan
Baseline: `main@b91dcbcaaac5acd4c7349cd3ed0996c547f58756`
Branch: `test/game-clock-reconciliation-20260903`
This plan is the status source for the long-running user test branch. A checked
item means code and focused automated evidence exist on this branch; it does not
mean deployment or production validation.
## Milestone 1 - authority and inventory
- [x] Branded `GameTick`, `ObservedGameInstant`, `ScheduleInstant`,
`WallInstant`, and `ClockRevision` boundaries.
- [x] Explicit clock phase and monotonic RUNNING projection.
- [x] Exact alignment arithmetic preserving millisecond/sub-turn remainder.
- [x] Opening tick zero and PREOPEN executable floor in the shared seeder.
- [x] Schema columns for phase, revision, and deadline generation.
- [x] Suspension, participant-checksum, and Redis projection outbox tables.
- [x] Machine-readable DB/Redis/JSON participant inventory and architecture gate.
- [x] Turn flush lock prefix and phase/revision/generation fence.
- [ ] Empty and upgraded database migration execution evidence.
## Milestone 2 - exact DB reconciliation
- [ ] Suspension start command with DB wall time and idempotent source revision.
- [ ] Exact resume plan transaction with deterministic participant lock order.
- [ ] SHIFT adapters for cursor, generals, active auctions, message expiry, vote
end, select pool, and NPC selection windows.
- [ ] KEEP checksum adapters for occurrences and history.
- [ ] Explicit `LEGACY_COMPLETE_TURNS` and bounded `CATCH_UP` policies.
- [ ] Property tests for remaining distance, ordering, and history invariants.
- [ ] 24-hour and 65m17.250s PostgreSQL integration evidence.
## Milestone 3 - revisioned Redis and workers
- [ ] Projection outbox claimer/retry/recovery state machine.
- [ ] Redis active revision and atomic due-pop script.
- [ ] Auction OPEN/FINALIZING revision and generation fence.
- [ ] Tournament durable tick dual-write and projection rebuild.
- [ ] DB-commit/Redis-failure restart tests and readiness integration.
## Milestone 4 - command and lifecycle workflows
- [ ] All durable input events record accepted tick and accepted revision.
- [ ] Processing converts accepted coordinates across revisions or fails closed.
- [ ] Gateway pause/resume/open orchestration writes the DB clock phase.
- [ ] Unification wait becomes a durable `UNIFICATION_WAIT` suspension.
- [ ] Alignment, optional rate change, invader IDs/RNG, creation, first schedule,
outbox, verification, and RUNNING transition form one retry-safe workflow.
- [ ] Multi-host drift and general-access/clock-operation deadlock tests.
## Milestone 5 - test-branch release gate
- [ ] Full typecheck, architecture, lint, unit, build, and non-conditional
integration suites.
- [ ] Dedicated PostgreSQL/Redis conditional integration suite with skip count
recorded.
- [ ] Recovery runbook exercised from each incomplete status.
- [ ] Admin status/readiness exposes revision, phase, participant checksums, and
incomplete outbox state.
- [ ] User-test deployment evidence is recorded separately from Git push.
- [ ] All `FORBID` inventory entries are removed by typed migrations or proven
inactive preconditions.
## Evidence log
### 2026-09-03 - authority foundation
- `pnpm test:bootstrap`: dependency installation, Prisma generation, and package
preparation passed in the dedicated worktree.
- `CI=1 TURBO_CONCURRENCY=1 pnpm typecheck`: 21/21 tasks passed.
- `CI=1 TURBO_CONCURRENCY=1 pnpm test`: 12/12 package tasks passed. Conditional
suites remain classified separately and are not integration evidence.
- `CI=1 TURBO_CONCURRENCY=1 pnpm build`: 26/26 tasks passed.
- `TURBO_CONCURRENCY=1 pnpm lint`: passed with 36 pre-existing frontend
warnings and no errors.
- `pnpm check:architecture`: package boundaries passed; 21 authoritative clock
fields and 18 participants were registered.
- Migration SQL was generated, formatted, validated, and registered as the
release manifest head. Empty/upgraded PostgreSQL execution is still pending.
+40
View File
@@ -0,0 +1,40 @@
# Game clock reconciliation recovery
This runbook is intentionally fail-closed. Do not force a profile to `RUNNING`
or delete an outbox row merely because its process is alive.
## Observe
Read only the target game schema. Record `world_state.clock_phase`,
`clock_revision`, `deadline_generation`, the latest `clock_suspension`, all its
participant checksums, and the matching `clock_projection_outbox`. Compare that
target revision with `sammo:{profile}:clock:active-revision`. Never print DB or
Redis credentials.
## Status meaning
- `SUSPENDED`: the cut is durable; no alignment DB transaction has committed.
- `RECONCILING` with `PENDING`/`FAILED` outbox: DB schedules moved, Redis is not
authoritative yet, and gameplay must remain stopped.
- `RECONCILING` with `APPLIED` outbox: verify Redis active revision and all
participant checksums before finalizing.
- `RUNNING`: DB revision, deadline generation, and Redis active revision must
agree. A mismatch is an incident and workers must not dequeue.
## Retry
Retry the same suspension ID and target revision through the clock-operation
service. The service must re-read participant checksums and either return the
already-applied result or resume the pending outbox. Never create a replacement
revision to hide a failed target revision.
## Rollback
There is no blind inverse update. Before enabling exact reconciliation in an
environment, keep the normal database backup required for schema migrations.
If participant verification shows an unexpected mutation, stop the profile,
retain the ledger/outbox evidence, and restore the whole game schema from that
backup. Redis projections are then rebuilt from the restored DB revision.
The implementation-plan release gate remains open until these steps have an
automated fixture and an operator-facing status endpoint.