diff --git a/TODO.md b/TODO.md index 7ccc3d13..5c5aa51f 100644 --- a/TODO.md +++ b/TODO.md @@ -43,6 +43,61 @@ Everything below needs a person — hardware, a design decision, an external acc Each item is also a GitHub issue (linked inline), labelled `needs:human` plus a `P0-blocker`…`P3-low` priority. Close the issue and tick the box together. +**Priority labels say how much something matters; this says what to do first.** +They differ: #33 is P2 but belongs before the P0 cluster, because standing the +cluster up first means migrating a running one afterwards. + +#### Do these in order — each unblocks the next + +1. **[#31](https://github.com/jcreek/CosmicClash/issues/31) — answer two + questions.** Which registry namespace (`ghcr.io/cosmic-clash/*` is in every + manifest and no such org exists), and whether packages are public (this repo + is private and no manifest declares `imagePullSecrets`). Publishing needs no + new credential. **This is the highest-leverage thing on the list**: two + answers unblock the whole of Phase 8, and the work behind them is an agent's. +2. **[#33](https://github.com/jcreek/CosmicClash/issues/33) — split the + game-server namespace.** Agent work, no decision owed. Before #17 rather than + after, so the cluster is stood up on the final topology instead of being + migrated later. +3. **[#17](https://github.com/jcreek/CosmicClash/issues/17) — stand up the + cluster.** Needs #31's images to exist. Unblocks the production halves of + most of Phase 8. +4. **[#32](https://github.com/jcreek/CosmicClash/issues/32) — casual backfill.** + Mostly agent work; the design decision is already made. Needs #17 to verify + a late roster reaching a running server. +5. **[#22](https://github.com/jcreek/CosmicClash/issues/22) — release gates.** + Last: needs the cluster and the App ID. + +#### Steam, in parallel — long external lead time, start early + +6. **[#15](https://github.com/jcreek/CosmicClash/issues/15) — App ID and + publisher key.** Valve coordination, so the calendar time is theirs, not + yours. The adapter is written and config-gated: sign-in returns 503 until + both values are set. +7. **[#16](https://github.com/jcreek/CosmicClash/issues/16) — GodotSteam build + templates.** The client-side ticket code is written and needs the custom + build to run. + +#### Unblocked today — nothing is stopping these + +- **[#19](https://github.com/jcreek/CosmicClash/issues/19)** then + **[#18](https://github.com/jcreek/CosmicClash/issues/18)**: the 3v3 gate is + the cheaper session to arrange and exercises #18's latency conditions + incidentally, so doing it first can settle both. + **[#20](https://github.com/jcreek/CosmicClash/issues/20)** needs two machines + and the internet, not a cluster. +- **[#24](https://github.com/jcreek/CosmicClash/issues/24)** then + **[#25](https://github.com/jcreek/CosmicClash/issues/25)**: training runs, + independent of everything above. +- **[#21](https://github.com/jcreek/CosmicClash/issues/21)**, + **[#26](https://github.com/jcreek/CosmicClash/issues/26)**, + **[#27](https://github.com/jcreek/CosmicClash/issues/27)**, + **[#28](https://github.com/jcreek/CosmicClash/issues/28)**: hardware, audio, + font, graphics QA. No dependencies, no ordering between them. +- **[#23](https://github.com/jcreek/CosmicClash/issues/23)**, + **[#29](https://github.com/jcreek/CosmicClash/issues/29)**: open design + questions with no deadline. Neither blocks anything. + - [x] ([#14](https://github.com/jcreek/CosmicClash/issues/14)) **Join-signing design decided and implemented.** Resolved as HMAC-SHA256 over the canonical claim bytes with a **key ID inside those bytes**: the allocator signs with one named key while allocated servers hold the set of currently-valid keys, so rotation does not invalidate authorisations already issued for in-flight matches. `allocator.Worker` now publishes the signed roster after binding, and `cmd/allocator` refuses to start without key material. Rotation procedure is in `docs/MATCHMAKING.md` §2; see `multiplayer-next.md` §8.31. Nothing human-only remains here — live verification is covered by [#17](https://github.com/jcreek/CosmicClash/issues/17). - [ ] ([#18](https://github.com/jcreek/CosmicClash/issues/18)) **Phase 4 playtest at ~100 ms RTT** — does the ship/ball feel local, do contact corrections read as bumps or glitches? Every numeric gate is green; this is a feel judgment no metric can answer. `multiplayer-next.md` §0, gate A. - [ ] ([#19](https://github.com/jcreek/CosmicClash/issues/19)) **Phase 5 3v3 gate** — a full 6-player match start to finish, with a mid-match disconnect and a late joiner. Only verified so far at 1v1 plus a two-bot CI match. `multiplayer-next.md` §0, gate B. @@ -54,6 +109,8 @@ Each item is also a GitHub issue (linked inline), labelled `needs:human` plus a - [ ] ([#31](https://github.com/jcreek/CosmicClash/issues/31)) **Build, push and pin the container images the Kubernetes manifests reference.** Every image target builds, but no workflow publishes any of them and all manifest digests are still all-zero placeholders, so `deploy/k8s/base` cannot pull running images. **Only two things need a person**: the `ghcr.io/cosmic-clash/*` namespace in the manifests does not exist (no such org), and this repo is private while no manifest declares `imagePullSecrets`, so package visibility must be chosen. Publishing itself needs no new credential — GHCR accepts the built-in `GITHUB_TOKEN` with `packages: write` — so the workflow, digest pinning and enabling `--require-concrete` are agent work once those two are answered. Blocks [#17](https://github.com/jcreek/CosmicClash/issues/17). - [ ] ([#33](https://github.com/jcreek/CosmicClash/issues/33)) **Move game servers to their own namespace** so `cosmic-clash` can enforce `restricted` again. Agones' Dynamic port policy needs a `hostPort`, which `baseline`/`restricted` forbid, so the whole namespace dropped to `privileged` — including the control plane, which mounts the database DSN, workload secret and Steam publisher key. Deferred until the Agones gate was green so a new failure could not be ambiguous. - [x] (no issue — agent-actionable) **Phase 8.48 has its own Compose smoke fixture.** `compose.allocated-smoke.yml` and `scripts/verify_allocated_compose.sh` are independent of `compose.phase6-smoke.yml` — the script states so explicitly and reuses none of its ports — so the allocated-mode flow no longer inherits that fixture's hardcoded port, first-come slots or `--max-matches=2`. Exercised by `make verify-allocated-compose`. +- [ ] ([#23](https://github.com/jcreek/CosmicClash/issues/23)) **Decide the contact-cohort-only client-side shadow world** (open question F in `multiplayer-next.md` §0). A design call about whether contact pairs get a client-side shadow simulation; nothing is blocked on it, and it can stay open indefinitely without holding anything up. +- [ ] ([#32](https://github.com/jcreek/CosmicClash/issues/32)) **Implement casual backfill** — proposal, matcher pass, client offer UI and late roster delivery. Listed here because it has an issue, not because it needs you: the roster-delivery design is decided (`docs/MATCHMAKING.md` § Casual) and candidate selection has landed, so the rest is agent work. End-to-end verification needs the cluster ([#17](https://github.com/jcreek/CosmicClash/issues/17)). - [ ] ([#22](https://github.com/jcreek/CosmicClash/issues/22)) **Release-evidence and human sign-off gates for Phase 8 production launch** — once the above are done, someone needs to actually run and sign off the production-shaped checks `multiplayer-next.md` §7 lists as infrastructure/production-dependent. Defect **C** (slot reservation keyed on display name alone — real, demonstrated, exploitable during the 30 s disconnect window) is not its own action item: it is fixed for free by the Steam auth tickets in task 7.4 above, so nothing to do until Steam identity lands. diff --git a/multiplayer-next.md b/multiplayer-next.md index af848683..9803b241 100644 --- a/multiplayer-next.md +++ b/multiplayer-next.md @@ -237,7 +237,7 @@ are done; everything below is what's left on the tasks still open. | 8.8 `[D:8.7]` | Session policy (opaque tokens, digests, revocation) | Distributed revocation coordination is done by construction: sessions are durable and `PostgresSessions.Authenticate` reads the row on every authenticated request, so a revocation takes effect immediately on every replica without any cross-replica protocol, and `ApplyIdentityBan` revokes an identity's sessions in the same transaction as the ban. Live Steam/session integration remains ([#15](https://github.com/jcreek/CosmicClash/issues/15)) | | 8.9 `[D:8.4,8.7]` | Join policy, durable reconnect leases | Live PostgreSQL/Godot process-restart and outage recovery verification remains | | 8.10 `[D:8.5,8.31]` | Workload credential policy (signed tokens, not Kubernetes JWTs), delivery channel, conflict alerting | Never run against a real Agones cluster; alert validated only statically, not against live Prometheus/Alertmanager traffic | -| 8.12 `[D:8.11]` | Kubernetes hardening baseline, rate/quota limiting, degraded-mode gate | Private-store provisioning, distributed/global quotas, edge DDoS/WAF/origin shielding, encrypted backups, live policy/load tests remain | +| 8.12 `[D:8.11]` | Kubernetes hardening baseline, rate/quota limiting, degraded-mode gate | Private-store provisioning, distributed/global quotas, edge DDoS/WAF/origin shielding, encrypted backups, live policy/load tests remain. The workload namespace currently enforces `privileged` because Agones' Dynamic port policy injects a `hostPort` that `baseline`/`restricted` forbid; splitting game servers into their own namespace so `cosmic-clash` can enforce `restricted` again is tracked by [#33](https://github.com/jcreek/CosmicClash/issues/33) | | 8.13 `[D:8.12]` | Digest-pinned images, supply-chain policy checker | Registry SBOM/scan/sign/admission execution and a concrete production overlay remain — the build-and-pin half is tracked by [#31](https://github.com/jcreek/CosmicClash/issues/31) | #### 8C — Queueing, matchmaking, playlists and rating