{"doc":"app-manifest","title":"App Manifest reference","markdown":"# App Manifest reference\n\nThe App Manifest is `gamestage.yaml`: one file describing the whole game. It is\nnot an App Spec and it is not a general configuration file.\n\nFetch the machine-readable contract:\n\n```sh\ncurl https://gamestage.ai/schemas/app-manifest/1.0\n```\n\nValidate a local file:\n\n```sh\ngamestage manifest validate gamestage.yaml\ngamestage manifest validate gamestage.yaml --level L2\n```\n\n## Metadata\n\n`manifest` holds metadata about the file rather than a reviewable product\nsection.\n\n| Field | Type | Meaning |\n| --- | --- | --- |\n| `schema_version` | string | Manifest language version, currently `1.0` |\n| `revision` | non-negative integer | Creator-controlled revision |\n| `conformance` | `L0` to `L5` | The level the author claims; validation computes the evidenced level and refuses a claim above it |\n\n## Sections\n\nThe ten sections below carry their own `status` and `provenance`.\n\n### `app`\n\nIdentity and ownership of the game.\n\n* **`id`**: stable game id, also used as the Engine tenant and URL key.\n\n* **`title` and `summary`**: creator-facing name and optional description.\n\n* **`source`**: canonical repository URL and branch. This is distinct from repository evidence attached to one value.\n\n* **`owners`**: optional IP, delivery and platform owners.\n\n### `experience`\n\nThe fan-facing shape.\n\n* **`surfaces`**: places the game renders, such as `web-embed`.\n\n* **`container_label`**: what this game calls one go, such as Round, Voting window or Tournament. Defaults to Round.\n\n* **`screen_graph`**: optional path to the experience's screen graph.\n\n* **`design`**: optional Figma file, version, token reference and design build stage.\n\n### `backend`\n\nThe authority model.\n\n* **`route`**: `managed_runtime`. Every game runs on our Engine, so this is the\n  only value a manifest can carry. The schema still names three others,\n  `bring_your_own`, `manifest_driven` and `dedicated_engine`, because `inspect`\n  uses them to describe a game it found before you migrate it. A manifest that\n  declares one is refused, and the refusal says which value to use.\n\n* **`archetype`**: the declared rule set.\n\n* **`component`, `version` and `variant`**: the pinned Proxima implementation where known.\n\n* **`configuration`**: additional component configuration.\n\n* **`round`**: the current Preview container specification. See [Game formats](/docs/game-formats).\n\n### `studio_app`\n\nThe registered [Monterosa](https://www.monterosa.co/) Studio App Spec:\n`spec_url` and `version`.\n\n### `studio_surface`\n\nThe operator surface: `family`, `version` and `configuration_schema`.\nGamestage has no content editor. Paid content operations belong in Monterosa\nStudio.\n\n### `interaction_cloud`\n\nThe platform mapping: `project_template`, `project_id`, `events` and `elements`.\nA game maps to a\n[project](https://products.monterosa.co/mic/creator-guide/projects), an edition\nmaps to an\n[event](https://products.monterosa.co/mic/core-concepts/schedule-and-events) and\na container maps to an\n[element](https://products.monterosa.co/mic/reference/core-platform/elements).\n\nThe pairing ids are stored end to end: a deploy writes `platformProject`,\n`platformEvent` and `platformElement` back onto the game record, and the next\ndeploy reads them rather than searching by name (GS-259). Do not mark this\nsection verified because provisioning returned ids once: verify that a second\ndeploy found the same project rather than creating another.\n\n### `identity`\n\nPlayer identity and consent policy.\n\n* **`provider`**: `anonymous`, `jwt`, `identify` or `custom`.\n\n* **`jwt`**: `issuer`, `jwks_uri` and optional `audience` when provider is `jwt`.\n\n* **`require_authenticated_writes`**: whether production writes require an identified player.\n\n* **`age_gate`**: `required`, `minimum_age`, `method` and an optional named verifier.\n\n* **`consent`**: whether analytics needs consent and which provider owns the choice.\n\nGamestage issues signed anonymous sessions. It does not provide a login system\nfor identified fans at any plan. A game that needs identity names its own JWT\nissuer and public key set.\n\nThe JWT validator and `gamestage dev --as` harness exercise that contract. The\ndeployed Engine validates a presented token against the issuer and JWKS\nconfigured on that deployment; a deployment with neither set still refuses\nevery token rather than trusting one. `create` and `inspect` also still propose\n`identity.provider: identify`; review that generated value rather than treating\nit as a product default. Use `jwt` only after a person has confirmed the\nexternal issuer and keys.\n\n### `measurement`\n\nDeclared event routing.\n\n* **`destinations`**: ordered declarations for `monterosa`, `posthog`, `ga4` or `webhook`.\n\n* **`trusted_events`**: events emitted after an Engine commit.\n\n* **`signal`**: optional Fantenna Signal declaration and public identifiers.\n\nKeys and tokens never belong in the manifest. The schema accepting a\ndestination is not evidence that a production service has provisioned it. The\nlaunch plan records that production ingestion and Studio visibility are still\ndependencies, so a declared destination alone is not proof that analytics is\nflowing.\n\n### `deployment`\n\nHosting and environments.\n\n* **`hosting`**: named host or strategy.\n\n* **`space_spec`**: Proxima space specification when one exists.\n\n* **`environments`**: any of `local`, `playground`, `staging`, `production`.\n\n### `operations`\n\nSupport and promotion controls.\n\n* **`support_tier`**: stored plan key, one of `runtime`, `live` or `enterprise`.\n\n* **`runbook`**: operator runbook reference.\n\n* **`promotion`**: whether the game offers a prize, its terms, jurisdictions, free entry route and skill position.\n\nThe stored plan keys are not creator-facing labels. Surfaces show Starter,\nPublisher and Enterprise.\n\n### `assurance`\n\nRecord the accessibility, security, secrets and privacy checks you ran on your\ngame. Gamestage suggests a check for each and shows your record on the game's\npage in Stage. It does not run them, and it does not certify the result: the\nrecord is yours. Nothing here affects `verify`, `deploy` or the build stage.\n\n```yaml\nassurance:\n  accessibility:\n    tool: addyosmani/web-quality-skills@accessibility\n    ran_at: 2026-09-28\n    result: issues_fixed\n    owner: Jo Bloggs\n    evidence: reports/accessibility-2026-09-28.md\n  secrets:\n    tool: gitleaks\n    ran_at: 2026-09-28\n    result: passed\n```\n\n| Check | Suggested | Run it with |\n| --- | --- | --- |\n| `accessibility` | A WCAG 2.2 audit skill | `npx skills add addyosmani/web-quality-skills@accessibility` |\n| `security` | Sentry's security review skill | `npx skills add getsentry/skills@security-review` |\n| `secrets` | The gitleaks scanner | `gitleaks detect --source .` |\n| `privacy` | A GDPR skill | `npx skills add wshobson/agents@gdpr-data-handling` |\n\nEach check you record takes these fields:\n\n| Field | Type | Required | What it holds |\n| --- | --- | --- | --- |\n| `tool` | string | yes | The skill or tool that ran |\n| `ran_at` | date, `YYYY-MM-DD` | yes | The day it ran |\n| `result` | `passed`, `issues_fixed` or `issues_open` | yes | What it found, after any fixes |\n| `owner` | string | no | The person answerable for the result |\n| `evidence` | string | no | A link or repo path to the report |\n| `note` | string | no | Anything a reviewer should know |\n\nA check with no `ran_at`, a date in another format or an unknown `result` is\nnot counted: `verify` names the field to fix and Stage shows it as not\ncounted. It never makes the manifest invalid, so a typo here cannot stop a\ndeploy. A check you have not run is left out, and `verify` suggests it after\nits verdict.\n\n## Beside the manifest: `gamestage.settings.json`\n\nThe manifest describes the game and carries no content. The words and colours\na fan sees by default go in `gamestage.settings.json` next to it, keyed by the\nStudio field keys: `display_name`, `strapline`, `how_to_play`, the button\nlabels, `primary_colour` and the `css_variables_*` palette.\n\n```json\n{\n  \"display_name\": \"Wages\",\n  \"how_to_play\": \"Pick one player from each line. Stay under the cap.\",\n  \"play_button_label\": \"Select Player\"\n}\n```\n\nA deploy writes each value into the game's Studio project where that field is\nempty, and never over a producer's edit. `manifest validate` and `deploy` refuse\na key Studio does not have and list the ones it does. The file is never\npublished with the game.\n\n## Status\n\n| Status | Meaning |\n| --- | --- |\n| `missing` | The section does not exist yet. This is normal until it is needed. |\n| `proposed` | An agent wrote it and nothing has tested it. |\n| `confirmed` | Checked and it holds. |\n| `verified` | Proved by evidence rather than inspection. |\n| `approved` | A person signed it off. |\n\nAn inferred value is `proposed`. An agent must not turn its own inference into a\nhuman decision.\n\n## Provenance\n\nEach section carries a list showing where its values came from.\n\n| Kind | Required fields | Use |\n| --- | --- | --- |\n| `human_decision` | `owner`, `date` | A person made the decision |\n| `generated_proposal` | `tool` | An agent or tool proposed it |\n| `repository_evidence` | `file` | Source code or repository state supports it |\n| `platform_evidence` | `system`, `id` | A platform record exists |\n| `external_evidence` | `supplier` | A supplier, licence or dataset supports it |\n\nOptional detail includes notes, commits, packages, model names, source context,\nlicences and dataset versions.\n\n## Build stages\n\nThe CLI works out the highest stage supported by the evidence. Setting\n`conformance` above that stage is a validation error.\n\n| Level | Build stage |\n| --- | --- |\n| L0 | Concept |\n| L1 | Experience built |\n| L2 | Wired to the platform |\n| L3 | Ready to deploy |\n| L4 | Production ready |\n| L5 | Operating live |\n\nNever use the L number alone in creator-facing output.\n\n## Cross-section rules\n\nStructural JSON Schema validation is necessary but does not cover every rule.\nThe CLI also checks:\n\n* **Signal and consent**: Signal cannot be enabled while analytics consent is disabled.\n\n* **Prize declarations**: a prize needs terms, jurisdictions and either a free entry route or a declared skill basis.\n\n* **JWT identity**: `provider: jwt` needs an issuer and JWKS URI. Deployed URLs must use HTTPS and cannot point at loopback.\n\n* **Age gates**: a required gate needs a minimum age, and a verified method needs a named verifier.\n\n* **Container integrity**: each built game format has reachability, uniqueness and ordering checks described in the game formats guide.\n\n## Where a round's content comes from\n\nToday both the local path and a deploy read `backend.round` from the manifest.\nKeep the manifest as the source for `dev`, `verify` and deploy.\n"}