diff --git a/AGENTS.md b/AGENTS.md index 8a68c5294..14ec13860 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ Architecture, commands, and binding rules for AI agents. Humans: [`README.md`](README.md), [`docs/contributing.md`](docs/contributing.md). -**Gameplane:** Kubernetes-native game server control panel (CubeCoders AMP alternative); identical on single-node k3s and multi-node clusters. **Status:** Pre-v1 release (`v0.3.0`); v1 scope feature-complete, stabilizing. +**Gameplane:** Kubernetes-native game server control panel (CubeCoders AMP alternative); identical on single-node k3s and multi-node clusters. **Status:** Pre-v1 release (`v0.4.0`); v1 scope feature-complete, stabilizing. ## ⏳ Session start: blocked dependency upgrades (delete an entry once unblocked) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a72e788a..6cfdc17b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,32 @@ reaches `1.0.0`. Pre-1.0 minor versions may contain breaking changes. ## [Unreleased] +## [0.4.0] — 2026-11-10 + +A pre-v1 release with every change made since v0.3.0: an independent central +panel, languages, the extended telemetry tier, safer backups and restores, +fleet-wide node inventory, and a pre-release security hardening pass. Read the +upgrade notes below before upgrading; several of them change behaviour. It +does not claim v1 or production support; see [`docs/roadmap.md`](docs/roadmap.md). + ### Fixed +- **Backup, restore and wipe exclusion (#718):** backups, restores and wipes + of the same server now take one lifecycle ownership, so a backup can no + longer read a filesystem a restore or wipe is changing, and wipe workers are + drained before workloads come back (PRs #760, #619). +- **Backup captures:** backup workers are prepared before quiesce, CSI + snapshot captures are bounded, and a capture taken across a game container + restart is invalidated instead of being kept (PRs #836, #846). +- **Backups with retention disabled are kept** (PR #618). +- **Wake on connect:** wake requests are bounded, HostPort hand-offs are + preserved, and shared wakes retry within their budget instead of failing on + the first cold-start error (PRs #840, #860). +- **Tunnels:** frp identities are isolated per server and report relay + connection health; Tailscale forwards every advertised TCP and UDP port and + keeps active UDP sessions (PRs #768, #765). +- **New files are created atomically** and never overwrite an existing file + (PR #621). - **Standalone Helm CRD isolation:** the central panel profile excludes bundled native CRDs and their apply hook/RBAC without requiring `--skip-crds`. Default operator installations keep Helm's native CRD lifecycle; existing @@ -16,6 +40,35 @@ reaches `1.0.0`. Pre-1.0 minor versions may contain breaking changes. ### Upgrade Notes +- **Breaking: admin-level grants need a full administrator:** holders of + `users:manage`, `roles:manage` or `config:manage` without `*` can no longer + grant `*` or another admin-level permission, edit or reset an administrator, + or edit auth providers (`/admin/config/auth`, `/admin/auth` need `*`) + (PR #862). +- **Breaking: kubelet probes reach only probe ports:** a new per-server + `-probes` NetworkPolicy admits kubelet CIDRs to the game container's + probe ports only, on by default with `networkPolicies.probeIngress.enabled`. + The old all-ports `allow-kubelet-probes` rule renders only when that is + `false` or extra `probePorts` are listed. Set + `networkPolicies.probeIngress.enabled: false` to restore the old rule + (PR #862). +- **Breaking: custom CSS:** stylesheets with `\` escapes or absolute, + `http(s):` or protocol-relative `//` references are now rejected (PR #862). +- **Share links get their own Ingress:** `/share` and `/shares` go through a + second Ingress, `gameplane-share`, with access logging off for ingress-nginx + (`ingress.shareLinks.*`). Other controllers need their own switch in + `ingress.shareLinks.annotations`; see [`docs/install.md`](docs/install.md) + (PR #862). +- **Password reset ends every session** of that account (migration + `019_session_epoch.sql`, applied on API startup) (PR #862). +- **The API is a singleton in every mode:** every database driver uses the + `Recreate` strategy and `api.replicas` other than 1 is rejected, so upgrades + no longer overlap two API processes (#726, PR #758). +- **Auxiliary resource requests and management placement:** agent, + config-init, sentinel, tunnel and Restic pods now request resources on every + install, and chart-managed pods accept placement settings. Game and + auxiliary pods can restart on upgrade; see + [`docs/release-notes.md`](docs/release-notes.md) (#724, PR #762). - **Standalone panel/API:** run the central panel with Docker Compose or the standalone Helm profile, without a local game cluster or operator. Compose needs no Kubernetes installation on the panel host. @@ -183,6 +236,17 @@ reaches `1.0.0`. Pre-1.0 minor versions may contain breaking changes. bundle's files together up to 4 MiB. `gp-module i18n extract|stamp` and `gp-module validate` support authoring. See [`docs/module-authoring.md`](docs/module-authoring.md). +- **Fleet-wide node inventory:** clusters are organized on their own pages and + a Nodes page lists the nodes of every cluster you can see, with the same + search and filters as Backups (PR #859). +- **Game performance and relay monitoring:** bounded per-game performance and + relay metrics (PR #838). +- **Stopped multi-volume Restic recovery:** a stopped server with several data + volumes can be recovered from its Restic backups (PR #861). +- **Wake on connect from server settings:** users can turn wake on connect on + from the server's Lifecycle settings (PR #818). +- **Reserve less than the limits:** a server can request less CPU and memory + than its limits (Burstable QoS) from Resources and Create Server (PR #815). ### Changed @@ -202,6 +266,24 @@ reaches `1.0.0`. Pre-1.0 minor versions may contain breaking changes. ### Security +- **Pre-release hardening (PR #862):** OIDC discovery, key fetches and code + exchange, and operator OCI registry dials go through the dial guard; agent + and capture proxies can no longer override the API's security headers; a + login-device cookie stops failed logins elsewhere from locking the owner + out; the API pod no longer mounts the agent CA key; a ValidatingAdmissionPolicy + (Kubernetes 1.30+) limits waker service accounts to the wake annotation; + template env Secret and ConfigMap references follow the server ownership + rule; the agent serves regular files only and confines mod installs to the + mods root; the dashboard ships Monaco in the image and sends a + Content-Security-Policy and security headers; share tokens stay out of + access and error logs. +- **Snapshot restores** authorize their data source against the live Backup + owner and reject unfinished or aborted snapshots (PR #756). +- **Operator Secret access** is scoped to the configured namespaces (PR #757). +- **Image CVE fixes:** eMudhra CA distrust and Alpine/Debian updates in game + images, the Tailscale tunnel built with fixed Go modules, and updated `expat`, + `musl`, `zlib`, `brotli` and `curl` in the dashboard image (PRs #775, #845, + #816). - **Standalone credential protection:** encryption keys are kept outside database volumes, with durable publication, fail-closed file-access checks, read-only provisioned custody, and authenticated transactional rotation. @@ -1294,7 +1376,8 @@ testing. Not yet recommended for unattended production workloads — see runner (retry + longer readiness window), eliminating a cascade of flaky API e2e failures. -[Unreleased]: https://github.com/GameplanePanel/gameplane/compare/v0.3.0...HEAD +[Unreleased]: https://github.com/GameplanePanel/gameplane/compare/v0.4.0...HEAD +[0.4.0]: https://github.com/GameplanePanel/gameplane/compare/v0.3.0...v0.4.0 [0.3.0]: https://github.com/GameplanePanel/gameplane/compare/v0.3.0-rc.1...v0.3.0 [0.3.0-rc.2]: https://github.com/GameplanePanel/gameplane/compare/v0.3.0-rc.1...v0.3.0 [0.3.0-rc.1]: https://github.com/GameplanePanel/gameplane/compare/v0.2.0-beta.8...v0.3.0-rc.1 diff --git a/FEATURES.md b/FEATURES.md index adeb2add4..85f90e730 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -6,7 +6,7 @@ Default column: **on** (enabled by the chart or the product), **off** (opt-in, s Notification rows take effect once a notification sink is configured. -Status date: 2026-10-14 (v0.3.0, pre-v1). +Status date: 2026-11-10 (v0.4.0, pre-v1). See [docs/roadmap.md](docs/roadmap.md) for what is planned and in progress. diff --git a/README.md b/README.md index 746ca3dd2..a876286ad 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ The dashboard and API can also run on a host without Kubernetes using [standalone Docker Compose](docs/standalone-panel.md). Game servers still run on registered Kubernetes clusters, each with its own operator and agents. -> Status: **pre-v1 release** (`v0.3.0`). The operator, API, agent, and dashboard +> Status: **pre-v1 release** (`v0.4.0`). The operator, API, agent, and dashboard > are feature-complete for the v1 scope and stabilized for external testing. > See [Pre-v1 status & known limitations](#pre-v1-status--limitations) before > running it for anything you can't afford to lose. @@ -44,7 +44,7 @@ Screenshots are captured against mocked data for consistency and reproducibility ## Pre-v1 Status & Limitations -Gameplane is a **pre-v1 release** (`v0.3.0`). Core workflows — server deployment, live consoles, file management, backups/restores, game modules, multi-cluster management, and RBAC — work end-to-end and are verified by automated unit, integration, upgrade, and end-to-end test suites on every commit. +Gameplane is a **pre-v1 release** (`v0.4.0`). Core workflows — server deployment, live consoles, file management, backups/restores, game modules, multi-cluster management, and RBAC — work end-to-end and are verified by automated unit, integration, upgrade, and end-to-end test suites on every commit. Here are a few items to keep in mind: @@ -66,7 +66,7 @@ and Agones (a Kubernetes operator library). While not direct competitors, Agones is included as a reference point for teams building on Kubernetes primitives. -Status: **pre-v1 release** (`v0.3.0`). The operator, API, agent, and dashboard +Status: **pre-v1 release** (`v0.4.0`). The operator, API, agent, and dashboard are feature-complete for the v1 scope and stabilized for external testing. | Dimension | Gameplane | Pterodactyl | CubeCoders AMP | Agones | diff --git a/agent/specs.md b/agent/specs.md index b9bd5697e..2ee465f71 100644 --- a/agent/specs.md +++ b/agent/specs.md @@ -1,6 +1,6 @@ # agent — Specification -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** `github.com/GameplanePanel/gameplane/agent` ## Purpose diff --git a/api/specs.md b/api/specs.md index f67b5de7d..ad8318a19 100644 --- a/api/specs.md +++ b/api/specs.md @@ -1,6 +1,6 @@ # api — Specification -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** github.com/GameplanePanel/gameplane/api ## Purpose diff --git a/audit-syslog-bridge/specs.md b/audit-syslog-bridge/specs.md index e1ae9153a..a98d2aee7 100644 --- a/audit-syslog-bridge/specs.md +++ b/audit-syslog-bridge/specs.md @@ -1,6 +1,6 @@ # audit-syslog-bridge — Specification -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** `github.com/GameplanePanel/gameplane/audit-syslog-bridge` ## Purpose diff --git a/capture-sidecar/specs.md b/capture-sidecar/specs.md index 10d8bb994..b6bb81ace 100644 --- a/capture-sidecar/specs.md +++ b/capture-sidecar/specs.md @@ -1,6 +1,6 @@ # capture-sidecar — Specification -**Status:** pre-v1 (v0.3.0), Phase 2 Foundational (implementation complete) +**Status:** pre-v1 (v0.4.0), Phase 2 Foundational (implementation complete) **Module / command:** `github.com/GameplanePanel/gameplane/capture-sidecar` **Dependencies (current):** stdlib + external libraries for packet capture and filtering (github.com/gopacket/gopacket v1.7.2, github.com/packetcap/go-pcap, golang.org/x/net) diff --git a/charts/gameplane/Chart.yaml b/charts/gameplane/Chart.yaml index ba38b4ccb..ec4dd33a2 100644 --- a/charts/gameplane/Chart.yaml +++ b/charts/gameplane/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: gameplane description: Kubernetes-native game server control panel (open-source alternative to CubeCoders AMP). type: application -version: 0.3.0 -appVersion: "0.3.0" +version: 0.4.0 +appVersion: "0.4.0" home: https://github.com/GameplanePanel/gameplane sources: - https://github.com/GameplanePanel/gameplane @@ -19,5 +19,5 @@ dependencies: # Vendored locally so installs never fetch another chart. Helm resolves this # condition before installing native CRDs, including on a fresh cluster. - name: gameplane-crds - version: 0.3.0 + version: 0.4.0 condition: operator.enabled diff --git a/charts/gameplane/charts/gameplane-crds/Chart.yaml b/charts/gameplane/charts/gameplane-crds/Chart.yaml index cd9616bb8..b378889f1 100644 --- a/charts/gameplane/charts/gameplane-crds/Chart.yaml +++ b/charts/gameplane/charts/gameplane-crds/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v2 name: gameplane-crds description: Native CRDs bundled with the Gameplane operator. type: application -version: 0.3.0 +version: 0.4.0 diff --git a/charts/gameplane/values.yaml b/charts/gameplane/values.yaml index e35c1eaa7..503c95481 100644 --- a/charts/gameplane/values.yaml +++ b/charts/gameplane/values.yaml @@ -786,7 +786,7 @@ defaultModuleSource: # own cluster). Bump this ref only in lockstep with a chart release that # was actually tested against the matching module-repo tag. Set to # "main" explicitly if you want the bleeding edge instead. - ref: v0.3.0 + ref: v0.4.0 subPath: "" # module directories live at the repo root oci: url: ghcr.io/gameplanepanel/gameplane-modules diff --git a/docs/dependencies.md b/docs/dependencies.md index 6e76c71ca..d43326fc9 100644 --- a/docs/dependencies.md +++ b/docs/dependencies.md @@ -26,11 +26,11 @@ to find call sites (or `go mod why -m ` from inside the module). For Toolchain versions come from `Makefile`, `.github/workflows/*.yaml`, and `.devcontainer/versions.toml` (dev container pins; `.devcontainer/setup.sh` installs them). -Accurate as of **2026-09-02**, repo state `v0.3.0`; the `gameproto`, +Accurate as of **2026-09-02**, repo state `v0.3.0`; the `gameproto`, `svcutil`, `sentinel`, `capture-sidecar`, `tunnel`, and `gp-module` sections were added and verified on **2026-09-26**. -> **Note:** The dependency versions listed in the table below reflect the state at v0.3.0. For the most current versions, refer to [CHANGELOG.md](../CHANGELOG.md). +> **Note:** The dependency versions listed in the table below reflect the state at v0.3.0. For the most current versions, refer to [CHANGELOG.md](../CHANGELOG.md). ## At a glance @@ -334,7 +334,7 @@ package a game module before publishing it. Direct deps from ### web React 18 + TypeScript strict + Vite dashboard (`web/package.json` version -`0.3.0`, matching the repo version): +`0.4.0`, matching the repo version): **Framework / core** - `react` `^19.2.8`, `react-dom` `^19.2.8` — base UI framework, rendered via `createRoot` in `src/main.tsx`, used throughout every component. diff --git a/docs/install.md b/docs/install.md index 269a65bcb..f0b5767d7 100644 --- a/docs/install.md +++ b/docs/install.md @@ -16,7 +16,7 @@ installation, with an operator and a local game cluster. The chart and its images are published to the GitHub Container Registry (GHCR) as OCI artifacts — no `helm repo add` needed. Install a tagged release straight -from the registry (replace `` with a release, e.g. `0.3.0`): +from the registry (replace `` with a release, e.g. `0.4.0`): ```sh helm upgrade --install gameplane oci://ghcr.io/gameplanepanel/charts/gameplane \ @@ -166,7 +166,7 @@ Top-level knobs (see `values.yaml` for the full list): `--config-init-image` / `--restic-image` flags, mirroring `operator.agentImage` - `operator.backupJobBackoffLimit` / `operator.backupJobActiveDeadlineSeconds` — retry limit (default `2`, must be >= 0) and wall-clock deadline in seconds (default `86400`, must be > 0) for the restic backup/restore Jobs. They map to the operator's `--backup-job-backoff-limit` / `--backup-job-active-deadline-seconds` flags. Negative or non-integer values fail the render; an unset key (e.g. `helm upgrade --reuse-values` from an older release) or a `0` deadline uses the default, while an explicit `0` backoff is honoured. - `operator.gameDataStorage.storageClassName` — install-time default storage class - for game server data volumes (since v0.3.0) (default `""`). Empty string uses the cluster's + for game server data volumes (since v0.3.0) (default `""`). Empty string uses the cluster's default StorageClass. Applies to all GameServers where neither the GameTemplate nor GameServer-level override specifies a class. **Precedence**: GameServer override > GameTemplate default > install-time default > cluster default. @@ -188,7 +188,7 @@ Top-level knobs (see `values.yaml` for the full list): - Core connection: `issuer` / `clientID` / `clientSecretRef` / `redirectURL` / `displayName` — OIDC provider credentials and endpoints. Per-IdP walkthroughs (Keycloak, Authentik, Google) live in [oidc.md](oidc.md) - - Role mapping (new, seeded at install time) (since v0.3.0): + - Role mapping (new, seeded at install time) (since v0.3.0): - `groupsClaim` — OIDC claim name containing group memberships (default `""`). Typically `"groups"` or `"roles"` depending on your IdP. Empty/omitted = read the `"groups"` claim. This only chooses which claim is read; it does diff --git a/docs/oidc.md b/docs/oidc.md index 4ff29e276..5806f4ce3 100644 --- a/docs/oidc.md +++ b/docs/oidc.md @@ -18,7 +18,7 @@ Fill in: The callback URL is automatically set to `{External URL}/auth/oidc/{provider-name}/callback`. -**Note**: The Helm-flag single OIDC provider supports group→role mapping via Helm values `api.oidc.groupsClaim` and `api.oidc.roleMappings.{admin,operator,viewer}` (or CLI flags `--oidc-groups-claim` and `--oidc-role-mapping-{admin,operator,viewer}`) (since v0.3.0). See "Role Mapping at Install Time (No Bootstrap-Admin Required)" below for setup details and worked examples. +**Note**: The Helm-flag single OIDC provider supports group→role mapping via Helm values `api.oidc.groupsClaim` and `api.oidc.roleMappings.{admin,operator,viewer}` (or CLI flags `--oidc-groups-claim` and `--oidc-role-mapping-{admin,operator,viewer}`) (since v0.3.0). See "Role Mapping at Install Time (No Bootstrap-Admin Required)" below for setup details and worked examples. ## Provider guides diff --git a/docs/release-notes.md b/docs/release-notes.md index ff07383fa..359f79c57 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -1,4 +1,4 @@ -# Unreleased operational changes +# v0.4.0 operational changes ## Auxiliary resource requests and management placement (#724) diff --git a/docs/roadmap.md b/docs/roadmap.md index 3f6b6efef..8e7aee91e 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -2,11 +2,11 @@ ## Current release -- **Version:** `v0.3.0` (pre-v1), released 2026-10-05. See the [changelog](../CHANGELOG.md). -- **Status as of 2026-10-14:** The CRDs, operator, API, agent, and dashboard are +- **Version:** `v0.4.0` (pre-v1), released 2026-11-10. See the [changelog](../CHANGELOG.md). +- **Status as of 2026-11-10:** The CRDs, operator, API, agent, and dashboard are feature-complete for the v1 scope and stabilized for external testing, but the project is not yet recommended for unattended production. This page tracks what - stands between v0.3 and a v1 GA release. + stands between v0.4 and a v1 GA release. - **What works today:** see [`README.md`](../README.md) and [`architecture.md`](architecture.md). It is a living document: items move out of it as they ship, and anything @@ -14,9 +14,9 @@ discovered along the way gets added. --- -## Shipped in v0.3.0 and since +## Shipped releases -### Since v0.3.0 (Unreleased) +### Shipped in v0.4.0 - Independent central panel: Docker Compose runs the API and dashboard without a host Kubernetes cluster; a standalone Helm profile runs without the central operator or workloads ([changelog](../CHANGELOG.md)). - Credential maintenance: standalone key custody, offline `rotate-panel-key`, `PUT /clusters/{name}/kubeconfig`, and `PUT`/`DELETE /clusters/{name}/gateway` ([changelog](../CHANGELOG.md)). @@ -34,7 +34,7 @@ discovered along the way gets added. - Breaking: selected-cluster module and template grants need a cluster-wide grant for remote catalogs ([changelog](../CHANGELOG.md)). - Feature catalog: [FEATURES.md](../FEATURES.md) lists every capability with its maturity and default, mirrored on the website and kept in step by `make check-features-sync` (spec 024, PR #703). -### Shipped in v0.3.0 +### Shipped in v0.3.0 - Configurable backup/restore Job retry limit and deadline Helm values ([changelog](../CHANGELOG.md)). - Multicluster gateways and unified server management across clusters ([changelog](../CHANGELOG.md)). @@ -57,7 +57,7 @@ discovered along the way gets added. - Multi-cluster request scoping, OIDC role re-evaluation, bootstrap-admin reset, cluster registration removal, mod bundle integrity, and tunnel credential handling hardened ([changelog](../CHANGELOG.md)). - Upgrade note: every game pod gains an empty capture `emptyDir`, so existing GameServers roll once on upgrade ([changelog](../CHANGELOG.md)). -### Earlier releases (before v0.3.0) +### Earlier releases (before v0.3.0) #### Multi-cluster: dashboard cluster selector (PR #107) (shipped v0.2.0-beta.6) diff --git a/docs/security.md b/docs/security.md index 5df4c2b6f..bf2a0a202 100644 --- a/docs/security.md +++ b/docs/security.md @@ -1154,7 +1154,7 @@ Access to cluster credentials is protected by several layers: ## Install-Time OIDC Role Mappings When OIDC authentication is configured at install time via Helm values -(`api.oidc.groupsClaim`, `api.oidc.roleMappings`, `api.oidc.defaultRole`) (since v0.3.0), +(`api.oidc.groupsClaim`, `api.oidc.roleMappings`, `api.oidc.defaultRole`) (since v0.3.0), Gameplane automatically assigns roles to users based on their OIDC provider's group/role claims on every login. This eliminates the need for a bootstrap-admin account in OIDC-only deployments — an operator can configure group mappings at diff --git a/docs/telemetry-provider.md b/docs/telemetry-provider.md index ebec85dd4..3a0a7943a 100644 --- a/docs/telemetry-provider.md +++ b/docs/telemetry-provider.md @@ -315,7 +315,7 @@ spec: Key points: - Values to change are marked `# CHANGE ME`: the image tag, the storage class, the hostname (in the Ingress `tls` and `rules`), the ClusterIssuer email and zone, the Cloudflare API token, the monitoring namespace, and `POD_CIDR` if your cluster is not on the k3s default. Also replace `telemetry.gameplane.net` in the Cloudflare rule and in the Verify commands. -- The provider features (dashboard, signed extended reports, proof-of-work) ship in the first release after v0.3.0. Pin that release or a later one. A v0.3.0 or older receiver has no dashboard and no `/v1/challenge`, and answers 400 to extended reports, so installs fall back to basic-only reports for 7 days. +- The provider features (dashboard, signed extended reports, proof-of-work) ship in v0.4.0. Pin v0.4.0 or a later release. A v0.3.0 or older receiver has no dashboard and no `/v1/challenge`, and answers 400 to extended reports, so installs fall back to basic-only reports for 7 days. - `edge` follows master. If you run it, keep `imagePullPolicy: Always` so that a restart pulls the latest build; with `IfNotPresent` a node keeps the image it already has. - One replica with `Recreate`, because SQLite has a single writer. `fsGroup: 65532` makes `/data` writable for the distroless nonroot user. - `AUTH_TOKEN` is deliberately unset: a public provider accepts reports from any install. diff --git a/gameaction/specs.md b/gameaction/specs.md index 2cbbb0107..ad283bd81 100644 --- a/gameaction/specs.md +++ b/gameaction/specs.md @@ -1,6 +1,6 @@ # gameaction — Specification -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** `github.com/GameplanePanel/gameplane/gameaction` **Dependencies:** stdlib only (Go 1.27+) diff --git a/gameproto/specs.md b/gameproto/specs.md index 9eb84e725..3b32254ae 100644 --- a/gameproto/specs.md +++ b/gameproto/specs.md @@ -1,6 +1,6 @@ # gameproto — Specification -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** `github.com/GameplanePanel/gameplane/gameproto` **Dependencies:** stdlib only (Go 1.27+) diff --git a/mcp-server/specs.md b/mcp-server/specs.md index 054914ea3..2520f8474 100644 --- a/mcp-server/specs.md +++ b/mcp-server/specs.md @@ -1,6 +1,6 @@ # mcp-server — Specification -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** `github.com/GameplanePanel/gameplane/mcp-server` ## Purpose diff --git a/netguard/specs.md b/netguard/specs.md index 50638e4b3..ef3056b2a 100644 --- a/netguard/specs.md +++ b/netguard/specs.md @@ -1,6 +1,6 @@ # netguard — Specification -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** github.com/GameplanePanel/gameplane/netguard ## Purpose diff --git a/operator/specs.md b/operator/specs.md index e5c2f9de6..ad0254e01 100644 --- a/operator/specs.md +++ b/operator/specs.md @@ -1,6 +1,6 @@ # operator — Specification -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** github.com/GameplanePanel/gameplane/operator **Go version:** 1.27.0 diff --git a/sentinel/specs.md b/sentinel/specs.md index 47a2db9f5..79a5396bb 100644 --- a/sentinel/specs.md +++ b/sentinel/specs.md @@ -1,6 +1,6 @@ # sentinel — Specification -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / command:** `github.com/GameplanePanel/gameplane/sentinel` **Dependencies:** Kubernetes `client-go` (dynamic client, in-cluster config), `k8s.io/apimachinery`, gameproto diff --git a/telemetry-receiver/README.md b/telemetry-receiver/README.md index a9ac3a199..98f2da834 100644 --- a/telemetry-receiver/README.md +++ b/telemetry-receiver/README.md @@ -6,7 +6,7 @@ JSON report once a day while the admin's telemetry switches are on. There are two tiers: ```json -{ "version": "0.3.0", "servers": 3, "templates": 7 } +{ "version": "0.4.0", "servers": 3, "templates": 7 } ``` The basic tier is that and nothing else. The extended tier adds an `ext` @@ -94,7 +94,7 @@ version that doesn't report it count as other. On the dashboard listener, Bearer token required: ``` -gameplane_telemetry_reports_total{version="0.3.0"} # reports by reported version +gameplane_telemetry_reports_total{version="0.4.0"} # reports by reported version gameplane_telemetry_servers # histogram of GameServer counts gameplane_telemetry_templates # histogram of GameTemplate counts gameplane_telemetry_duplicates_total # same-day repeat extended reports diff --git a/telemetry-receiver/specs.md b/telemetry-receiver/specs.md index 447e7f6e2..121b85900 100644 --- a/telemetry-receiver/specs.md +++ b/telemetry-receiver/specs.md @@ -1,6 +1,6 @@ # telemetry-receiver — Specification -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** github.com/GameplanePanel/gameplane/telemetry-receiver **Go version:** 1.27 diff --git a/test/e2e/internal/7-days-to-die/spec.md b/test/e2e/internal/7-days-to-die/spec.md index f7d9fd16e..7b100fa87 100644 --- a/test/e2e/internal/7-days-to-die/spec.md +++ b/test/e2e/internal/7-days-to-die/spec.md @@ -20,7 +20,7 @@ GAMEPLANE_E2E_REUSE_CLUSTER=1 GAMEPLANE_E2E_CONTEXT= GAMEPLANE_E2E A successful run is the only event that licenses updating `Last Verified` to the current date. -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** `github.com/GameplanePanel/gameplane/test/e2e/internal/7-days-to-die` **Dependencies:** stdlib + shared protocol family `a2s` (Go 1.25+); tested against vinanrra/7dtd-server:v0.9.3 (UNMEASURED against a real server — see "Measured connectivity") diff --git a/test/e2e/internal/ark-survival-ascended/spec.md b/test/e2e/internal/ark-survival-ascended/spec.md index cad436a14..261fdea7a 100644 --- a/test/e2e/internal/ark-survival-ascended/spec.md +++ b/test/e2e/internal/ark-survival-ascended/spec.md @@ -20,7 +20,7 @@ GAMEPLANE_E2E_REUSE_CLUSTER=1 GAMEPLANE_E2E_CONTEXT= GAMEPLANE_E2E A successful run is the only event that licenses updating `Last Verified` to the current date. -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** `github.com/GameplanePanel/gameplane/test/e2e/internal/ark-survival-ascended` **Dependencies:** stdlib only (Go 1.25+); tested against mschnitzer/asa-linux-server:1.5.1 diff --git a/test/e2e/internal/cs2/spec.md b/test/e2e/internal/cs2/spec.md index 00f747275..a73bd73ee 100644 --- a/test/e2e/internal/cs2/spec.md +++ b/test/e2e/internal/cs2/spec.md @@ -20,7 +20,7 @@ GAMEPLANE_E2E_REUSE_CLUSTER=1 GAMEPLANE_E2E_CONTEXT= GAMEPLANE_E2E A successful run is the only event that licenses updating `Last Verified` to the current date. -**Status:** pre-v1 (v0.3.0); probe depth measured: **QUERY** (A2S query success) +**Status:** pre-v1 (v0.4.0); probe depth measured: **QUERY** (A2S query success) **Module / package:** `github.com/GameplanePanel/gameplane/test/e2e/internal/cs2` **Dependencies:** stdlib only (Go 1.25+); tested against CS2 Image 4.0.1 (joedwards32/cs2); image pin required (floating tag drifts) **Heavy game (never runs in CI):** See "Why CS2 is heavy and never in CI" section below diff --git a/test/e2e/internal/dont-starve-together/spec.md b/test/e2e/internal/dont-starve-together/spec.md index 7505f54ac..e7f31eec7 100644 --- a/test/e2e/internal/dont-starve-together/spec.md +++ b/test/e2e/internal/dont-starve-together/spec.md @@ -20,7 +20,7 @@ GAMEPLANE_E2E_REUSE_CLUSTER=1 GAMEPLANE_E2E_CONTEXT= GAMEPLANE_E2E A successful run is the only event that licenses updating `Last Verified` to the current date. -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** `github.com/GameplanePanel/gameplane/test/e2e/internal/dont-starve-together` **Dependencies:** stdlib + shared `protocol/a2s` (Go 1.25+); tested against jamesits/dst-server:vanilla (query-port assertion UNMEASURED against a real server — see "Measured connectivity") diff --git a/test/e2e/internal/enshrouded/spec.md b/test/e2e/internal/enshrouded/spec.md index 86eb750a6..7e8965af4 100644 --- a/test/e2e/internal/enshrouded/spec.md +++ b/test/e2e/internal/enshrouded/spec.md @@ -20,7 +20,7 @@ GAMEPLANE_E2E_REUSE_CLUSTER=1 GAMEPLANE_E2E_CONTEXT= GAMEPLANE_E2E A successful run is the only event that licenses updating `Last Verified` to the current date. -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** `github.com/GameplanePanel/gameplane/test/e2e/internal/enshrouded` **Dependencies:** stdlib only (Go 1.25+); tested against mornedhels/enshrouded-server:1.7.2 diff --git a/test/e2e/internal/factorio/spec.md b/test/e2e/internal/factorio/spec.md index b17cf4a9e..4ef931f63 100644 --- a/test/e2e/internal/factorio/spec.md +++ b/test/e2e/internal/factorio/spec.md @@ -10,7 +10,7 @@ - **Blocker**: Wire format undocumented; server and client must match exactly (version-locked) - **Blocker Class**: documentation -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** `github.com/GameplanePanel/gameplane/test/e2e/internal/factorio` **Dependencies:** stdlib only (Go 1.25+); tested against factoriotools/factorio:stable (2.0.x); image: `factoriotools/factorio:stable@sha256:7052b3cca8ca7790f99f4058617d5c8089df544de736b1baa23f2c5f58fb7f48` diff --git a/test/e2e/internal/garrys-mod/spec.md b/test/e2e/internal/garrys-mod/spec.md index 70e700ced..05aeae576 100644 --- a/test/e2e/internal/garrys-mod/spec.md +++ b/test/e2e/internal/garrys-mod/spec.md @@ -10,7 +10,7 @@ - **Blocker**: C2S_CONNECT field offsets unknown; challenge exchange already decoded, sv_lan 1 removes the Steam gate - **Blocker Class**: documentation -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** `github.com/GameplanePanel/gameplane/test/e2e/internal/garrys-mod` **Dependencies:** stdlib only (Go 1.25+); tested against ceifa/garrysmod:debian; shared protocol families `a2s`, `source` diff --git a/test/e2e/internal/minecraft-java/spec.md b/test/e2e/internal/minecraft-java/spec.md index 6392a2afe..72d0ff95f 100644 --- a/test/e2e/internal/minecraft-java/spec.md +++ b/test/e2e/internal/minecraft-java/spec.md @@ -10,7 +10,7 @@ - **Blocker**: — - **Blocker Class**: — -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** `github.com/GameplanePanel/gameplane/test/e2e/internal/minecraft-java` **Dependencies:** stdlib only (Go 1.25+); tested against Minecraft 1.21.4; image: `itzg/minecraft-server:java21` diff --git a/test/e2e/internal/palworld/spec.md b/test/e2e/internal/palworld/spec.md index 39d9d38c7..fa62a4f11 100644 --- a/test/e2e/internal/palworld/spec.md +++ b/test/e2e/internal/palworld/spec.md @@ -20,7 +20,7 @@ GAMEPLANE_E2E_REUSE_CLUSTER=1 GAMEPLANE_E2E_CONTEXT= GAMEPLANE_E2E A successful run is the only event that licenses updating `Last Verified` to the current date. -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** `github.com/GameplanePanel/gameplane/test/e2e/internal/palworld` **Dependencies:** stdlib only (Go 1.25+); tested against Palworld via thijsvanloef/palworld-server-docker:latest diff --git a/test/e2e/internal/project-zomboid/spec.md b/test/e2e/internal/project-zomboid/spec.md index e642fdbe5..9870204f0 100644 --- a/test/e2e/internal/project-zomboid/spec.md +++ b/test/e2e/internal/project-zomboid/spec.md @@ -20,7 +20,7 @@ GAMEPLANE_E2E_REUSE_CLUSTER=1 GAMEPLANE_E2E_CONTEXT= GAMEPLANE_E2E A successful run is the only event that licenses updating `Last Verified` to the current date. -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** `github.com/GameplanePanel/gameplane/test/e2e/internal/project-zomboid` **Dependencies:** stdlib + shared `protocol/a2s` (Go 1.25+); tested against sknnr/zomboid-dedicated-server:v1.1.1 (UNMEASURED against a real server — see "Measured connectivity") diff --git a/test/e2e/internal/protocol/a2sproto/spec.md b/test/e2e/internal/protocol/a2sproto/spec.md index 45c09690d..ab8587272 100644 --- a/test/e2e/internal/protocol/a2sproto/spec.md +++ b/test/e2e/internal/protocol/a2sproto/spec.md @@ -1,6 +1,6 @@ # A2S (Valve Source Query) Protocol -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** `test/e2e/internal/protocol/a2s` **Dependencies:** stdlib only (Go 1.25+) diff --git a/test/e2e/internal/satisfactory/spec.md b/test/e2e/internal/satisfactory/spec.md index a4035ec96..a2d8fbac7 100644 --- a/test/e2e/internal/satisfactory/spec.md +++ b/test/e2e/internal/satisfactory/spec.md @@ -20,7 +20,7 @@ GAMEPLANE_E2E_REUSE_CLUSTER=1 GAMEPLANE_E2E_CONTEXT= GAMEPLANE_E2E A successful run is the only event that licenses updating `Last Verified` to the current date. -**Status:** pre-v1 (v0.3.0), in-progress (QUERY depth measured; in-game claim gate blocks authentication) +**Status:** pre-v1 (v0.4.0), in-progress (QUERY depth measured; in-game claim gate blocks authentication) ## Purpose diff --git a/test/e2e/internal/specs.md b/test/e2e/internal/specs.md index 0f3156382..9b05fed69 100644 --- a/test/e2e/internal/specs.md +++ b/test/e2e/internal/specs.md @@ -1,6 +1,6 @@ # e2e game-bot harness — Specification -**Status:** pre-v1 (v0.3.0), in-progress (fast set JOINED, heavy set not yet implemented) +**Status:** pre-v1 (v0.4.0), in-progress (fast set JOINED, heavy set not yet implemented) **Module / package:** `test/e2e/internal/{probe,protocol,}` — per-game protocol clients and the shared probe harness (plus `internal/fakeoidc`, an unrelated e2e fixture — see `test/e2e/api_auth_e2e_test.go`) **Dependencies:** stdlib only (Go 1.27+) — per-game binaries build against `test/e2e/go.mod` with `GOWORK=off`, dragging zero Kubernetes or external modules into the probe image diff --git a/test/e2e/internal/terraria/spec.md b/test/e2e/internal/terraria/spec.md index 4490d9385..d0680e8ba 100644 --- a/test/e2e/internal/terraria/spec.md +++ b/test/e2e/internal/terraria/spec.md @@ -10,7 +10,7 @@ - **Blocker**: — - **Blocker Class**: — -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** `github.com/GameplanePanel/gameplane/test/e2e/internal/terraria` **Dependencies:** stdlib only (Go 1.25+) diff --git a/test/e2e/internal/v-rising/spec.md b/test/e2e/internal/v-rising/spec.md index f460bdbd5..17accc77a 100644 --- a/test/e2e/internal/v-rising/spec.md +++ b/test/e2e/internal/v-rising/spec.md @@ -20,7 +20,7 @@ GAMEPLANE_E2E_REUSE_CLUSTER=1 GAMEPLANE_E2E_CONTEXT= GAMEPLANE_E2E A successful run is the only event that licenses updating `Last Verified` to the current date. -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** `github.com/GameplanePanel/gameplane/test/e2e/internal/v-rising` **Dependencies:** stdlib + shared protocol family `a2s` (Go 1.25+); tested against trueosiris/vrising:2026-04-23-1036 (UNMEASURED against a real server — see "Measured connectivity") diff --git a/test/e2e/specs.md b/test/e2e/specs.md index 95c4ac292..9caad3502 100644 --- a/test/e2e/specs.md +++ b/test/e2e/specs.md @@ -1,6 +1,6 @@ # test/e2e — Specification -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** `github.com/GameplanePanel/gameplane/test/e2e` **Go version:** 1.27.0 diff --git a/tunnel/specs.md b/tunnel/specs.md index 687d5b285..7a7b6d667 100644 --- a/tunnel/specs.md +++ b/tunnel/specs.md @@ -1,6 +1,6 @@ # tunnel — Specification -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / command:** `github.com/GameplanePanel/gameplane/tunnel` **Dependencies:** Go stdlib and `tailscale.com/tsnet` (F-173, #722) diff --git a/web/package-lock.json b/web/package-lock.json index 6420a7d20..b4677c930 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,12 +1,12 @@ { "name": "@gameplane/web", - "version": "0.3.0", + "version": "0.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@gameplane/web", - "version": "0.3.0", + "version": "0.4.0", "dependencies": { "@heroui/react": "3.2.7", "@heroui/styles": "3.2.7", diff --git a/web/package.json b/web/package.json index fd53cb2d6..3ee1bb285 100644 --- a/web/package.json +++ b/web/package.json @@ -1,7 +1,7 @@ { "name": "@gameplane/web", "private": true, - "version": "0.3.0", + "version": "0.4.0", "type": "module", "scripts": { "dev": "vite", diff --git a/web/specs.md b/web/specs.md index 6ef3779f7..b5f38ca1d 100644 --- a/web/specs.md +++ b/web/specs.md @@ -1,6 +1,6 @@ # web — Specification -**Status:** pre-v1 (v0.3.0) +**Status:** pre-v1 (v0.4.0) **Module / package:** @gameplane/web **Build:** Vite 8.3 + React 19.3 + TypeScript 6.0 (strict) @@ -776,7 +776,7 @@ tsconfig.json # TS strict, noUnusedLocals, noUnusedParameters, noF vitest.config.ts # Coverage gates (lines 92 / functions 76 / branches 82 / statements 92) playwright.config.ts # Mock + live test modes, serial execution (login state is shared) eslint.config.js # Flat config: @typescript-eslint (strict), react-hooks, no-floating-promises -package.json # @gameplane/web v0.3.0; dev: vite, npm scripts for build/test/lint +package.json # @gameplane/web v0.4.0; dev: vite, npm scripts for build/test/lint ``` ## Routing & Pages