AURA

JSGG

AuraJS
DOCSEXAMPLESGITHUB
Game State CLI Contract
Exact CLI/state artifact behavior for session, state, inspect, and action flows.
docs/game-state-cli-contract-v1.md

AuraJS Game-State CLI Contract v1

Status: Draft (AS85-001)
Date: 2026-03-05
Canonical schemaVersion: aurajs.game-state.v1
Schema file: docs/schemas/game-state-v1.schema.json

This document defines the canonical game-state-v1 contract for:

  1. State export payloads (aura state export)
  2. Mutation request payloads (aura state patch / aura state apply)
  3. Mutation result payloads (aura state apply response artifact)

1) Snapshot Schema Contract

Top-level export payload is validated against the schema root object.

Field Type Required Notes
schemaVersion string yes Must be aurajs.game-state.v1.
export object yes Export metadata (mode, seed, frameIndex, fingerprint).
state object yes Canonical mutable state sections.

State sections:

Section Required Notes
state.globals yes Game-defined values; JSON-compatible.
state.camera no Canonical 2D camera state snapshot.
state.scene3d no Scene hierarchy and clip snapshots.
state.physics no Physics frame + body snapshots.
state.ecs no ECS entities/systems snapshot.
state.tilemap no Tilemap/layer snapshot.

Schema rejects unknown top-level/state-section keys to keep contract drift-sensitive.

2) Mutation Contract

Mutation payload and result payload are defined in schema defs:

  • Request: #/$defs/mutationRequest
  • Operation row: #/$defs/mutationOperation
  • Result: #/$defs/mutationResult

2.1 Mutation request envelope

{
  "schemaVersion": "aurajs.game-state.v1",
  "baseFingerprint": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
  "mutations": [
    {
      "order": 10,
      "op": "set",
      "path": "/state/globals/score",
      "value": 1200
    },
    {
      "order": 20,
      "op": "increment",
      "path": "/state/camera/zoom",
      "by": 0.1
    },
    {
      "order": 30,
      "op": "array_insert",
      "path": "/state/ecs/entities/0/tags",
      "index": 1,
      "value": "armed"
    }
  ],
  "options": {
    "dryRun": false,
    "verify": true,
    "rollbackOnFail": true,
    "maxMutations": 128,
    "timeoutMs": 200
  }
}

2.2 Supported mutation ops

op Required fields Semantics
set order, path, value Set/replace target value at JSON Pointer path.
delete order, path Remove target key/entry.
increment order, path, by Numeric increment; fails on non-number targets.
array_insert order, path, index, value Insert one array entry at index.
array_remove order, path, index (count optional) Remove one or more array entries from index.

2.3 Immutable paths

Mutations MUST reject writes to:

  • /schemaVersion
  • /export
  • /export/*

Mutations are allowed only under /state/*.

3) Deterministic Ordering Contract

  1. Canonical object key order on serialization:
    • top-level: schemaVersion, export, state
    • export: mode, seed, frameIndex, elapsedSeconds, fingerprint, capturedAt
    • state: globals, camera, scene3d, physics, ecs, tilemap
  2. Arrays must be deterministic:
    • scene3d.nodes: ascending id
    • scene3d.clips: ascending clipId
    • physics.bodies: ascending id
    • ecs.entities: ascending id
    • ecs.systems: ascending order, then name
    • tilemap.maps: ascending id
    • tilemap.layers: ascending order, then id
  3. Mutation apply order is deterministic by order ascending, then original array index.
  4. Runtime must process mutation rows sequentially, where each successful row updates the working state for the next row.
  5. If rollbackOnFail=true, any failed row must restore pre-apply state and return a rollback reason code.
  6. Non-finite numbers (NaN, Infinity, -Infinity) are invalid and must fail validation.

4) Reason Codes (Canonical)

Reason code Phase Trigger
state_export_ok export Export completed and payload matches schema.
state_dry_run_ok apply Dry-run succeeded; no mutation committed.
state_apply_ok apply Apply + optional verify succeeded.
schema_version_mismatch validate schemaVersion is not aurajs.game-state.v1.
invalid_schema_payload validate JSON shape/type mismatch vs schema.
missing_required_field validate Required key absent from contract payload.
unknown_top_level_key validate Unexpected root key present.
unknown_state_section validate Unexpected key under state.
invalid_json_pointer apply Mutation path is not valid JSON Pointer.
immutable_path apply Mutation targets immutable contract path (/schemaVersion, /export/*).
unsupported_mutation_op apply op is not one of canonical operations.
type_mismatch apply Target type incompatible with operation (for example increment on string).
entity_not_found apply Target ECS entity/path is absent.
tilemap_layer_not_found apply Target tilemap layer/path is absent.
mutation_conflict apply Mutations conflict under same base snapshot/fingerprint.
mutation_budget_exceeded apply Mutation row count exceeded options.maxMutations.
state_payload_too_large apply Payload exceeds deterministic size limit.
state_apply_timeout apply Apply exceeded deterministic runtime budget.
verify_failed apply Post-apply verification mismatch.
rollback_unavailable apply Rollback requested but runtime cannot rollback.
rollback_failed apply Rollback attempted but did not restore baseline.

reasonCode must be stable and machine-readable. Human-readable message text is additive and non-canonical.

5) Concrete JSON Examples

5.1 Pass fixture: minimal snapshot

{
  "schemaVersion": "aurajs.game-state.v1",
  "export": {
    "mode": "headless",
    "seed": 12345,
    "frameIndex": 0,
    "fingerprint": "0000000000000000000000000000000000000000000000000000000000000000"
  },
  "state": {
    "globals": {
      "level": "intro",
      "score": 0
    }
  }
}

5.2 Pass fixture: extended snapshot

{
  "schemaVersion": "aurajs.game-state.v1",
  "export": {
    "mode": "native",
    "seed": 777,
    "frameIndex": 1440,
    "elapsedSeconds": 24,
    "fingerprint": "1111111111111111111111111111111111111111111111111111111111111111",
    "capturedAt": null
  },
  "state": {
    "globals": {
      "level": "forest-03",
      "score": 1200,
      "flags": {
        "bossUnlocked": true
      }
    },
    "camera": {
      "x": 10,
      "y": -4,
      "zoom": 1.25,
      "rotation": 0,
      "following": true,
      "activeEffects": 0
    },
    "scene3d": {
      "nodes": [
        {
          "id": 1,
          "parentId": null,
          "position": { "x": 0, "y": 0, "z": 0 },
          "rotation": { "x": 0, "y": 0, "z": 0 },
          "scale": { "x": 1, "y": 1, "z": 1 },
          "visible": true,
          "layer": 0
        }
      ],
      "clips": [
        {
          "clipId": 5,
          "nodeId": 1,
          "time": 0.5,
          "playing": true,
          "weight": 1
        }
      ]
    },
    "physics": {
      "frameIndex": 1440,
      "snapshot": null,
      "bodies": [
        {
          "id": 1,
          "kind": "dynamic",
          "position": { "x": 3, "y": 2 },
          "velocity": { "x": 0, "y": -1 },
          "angle": 0,
          "angularVelocity": 0,
          "sleeping": false
        }
      ],
      "lastReasonCode": null
    },
    "ecs": {
      "entities": [
        {
          "id": 100,
          "components": {
            "transform": { "x": 3, "y": 2 },
            "health": 95
          },
          "tags": ["player", "armed"]
        }
      ],
      "systems": [
        {
          "name": "movement",
          "enabled": true,
          "order": 0
        }
      ]
    },
    "tilemap": {
      "maps": [
        {
          "id": "overworld",
          "layers": [
            {
              "id": 0,
              "name": "ground",
              "visible": true,
              "opacity": 1,
              "order": 0,
              "collisionEnabled": false
            }
          ]
        }
      ]
    }
  }
}

5.3 Pass fixture: mutation result

{
  "ok": true,
  "reasonCode": "state_apply_ok",
  "appliedMutations": 3,
  "failedMutationIndex": null,
  "fingerprint": "2222222222222222222222222222222222222222222222222222222222222222",
  "warnings": []
}

5.4 Fail fixture: schema version mismatch

{
  "schemaVersion": "aurajs.game-state.v0",
  "export": {
    "mode": "headless",
    "seed": 1,
    "frameIndex": 0,
    "fingerprint": "0000000000000000000000000000000000000000000000000000000000000000"
  },
  "state": {
    "globals": {}
  }
}

Expected reason code: schema_version_mismatch

5.5 Fail fixture: immutable mutation path

{
  "schemaVersion": "aurajs.game-state.v1",
  "baseFingerprint": "3333333333333333333333333333333333333333333333333333333333333333",
  "mutations": [
    {
      "order": 1,
      "op": "set",
      "path": "/export/seed",
      "value": 999
    }
  ],
  "options": {
    "dryRun": false,
    "verify": true,
    "rollbackOnFail": true
  }
}

Expected reason code: immutable_path

5.6 Fail fixture: invalid JSON Pointer

{
  "schemaVersion": "aurajs.game-state.v1",
  "baseFingerprint": "4444444444444444444444444444444444444444444444444444444444444444",
  "mutations": [
    {
      "order": 1,
      "op": "set",
      "path": "state/globals/score",
      "value": 7
    }
  ]
}

Expected reason code: invalid_json_pointer

DOCUMENT REFERENCE
docs/game-state-cli-contract-v1.md
AURAJS
Cmd/Ctrl+K
aurajsgg