docs: say what order the outstanding work goes in

The backlog listed what is left but not what to do first, and priority
labels do not answer that: #33 is P2 yet belongs before the P0 cluster,
because standing the cluster up first means migrating a running one
afterwards.

Add an explicit ordering to TODO.md in three parts -- a critical path
where each item unblocks the next, a Steam track that runs in parallel
and should start early because its lead time is Valve's, and the set
that is unblocked today and waiting on nobody. The playtests, training
runs and asset work need no cluster and could start now, which was not
obvious from a flat list sorted by priority.

#31 is called out as the highest-leverage item: two answers unblock the
whole of Phase 8, and the work behind them is an agent's.

Two open issues were in no list at all -- #23's design question and
#32's backfill work -- so TODO.md now covers every open issue.

Also record the dependency direction on GitHub rather than only here:
#17, #32 and #33 carried no blocked-by statement, so the graph was
invisible from the issue tracker. And note in §7 task 8.12 why the
workload namespace enforces privileged and where the split is tracked.
This commit is contained in:
Josh Creek
2026-09-05 22:50:26 +01:00
parent 4912837dd7
commit 4560d2de8a
2 changed files with 58 additions and 1 deletions
+57
View File
@@ -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.
+1 -1
View File
@@ -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