games.cavu.defs

chris.pardy.family

{
  "$type": "com.atproto.lexicon.schema",
  "defs": {
    "attestation": {
      "description": "badge.blue CID-first attestation over the grant: DAG-CBOR(grant) -> SHA-256 -> CIDv1(dag-cbor), signed with low-S ECDSA by the key `key` (a DID URL resolving to a verification method in the launch service's DID document).",
      "properties": {
        "cid": {
          "format": "cid",
          "type": "string"
        },
        "key": {
          "maxLength": 512,
          "type": "string"
        },
        "signature": {
          "maxLength": 128,
          "type": "bytes"
        }
      },
      "required": [
        "key",
        "cid",
        "signature"
      ],
      "type": "object"
    },
    "capability": {
      "closed": false,
      "description": "What a game may do through the host. Games declare these on their games.cavu.game record; the host enforces them per bound session. Unknown members are refused (and, later, will require step-up consent).",
      "refs": [
        "#standard",
        "#repoWrite",
        "#repoDelete"
      ],
      "type": "union"
    },
    "gameRecords": {
      "description": "This game's own records in the shared collections: games.cavu.score and games.cavu.save at rkey '<slug>' or '<slug>:...'. Plain language: 'Save your <game> scores and progress to your account.'",
      "type": "token"
    },
    "grant": {
      "description": "What a launch service attests to. A client that verifies the attestation against the launch service's published key opens `url`, wherever it points (it encodes room and instance placement). If `hostService` is present, the game presents this grant plus a DPoP proof made with the key whose thumbprint is `jkt` to the host's games.cavu.bindSession; nothing else is needed from the launch service. Grants are short-lived: they bound the time to bind, not the play session.",
      "properties": {
        "expiresAt": {
          "format": "datetime",
          "type": "string"
        },
        "game": {
          "description": "The games.cavu.game record being launched.",
          "format": "at-uri",
          "type": "string"
        },
        "hostService": {
          "ref": "#hostService",
          "type": "ref"
        },
        "issuedAt": {
          "format": "datetime",
          "type": "string"
        },
        "jkt": {
          "description": "RFC 7638 JWK thumbprint of the game server key allowed to bind this grant at the host. Required when hostService is present.",
          "maxLength": 64,
          "type": "string"
        },
        "joinCode": {
          "maxLength": 64,
          "type": "string"
        },
        "player": {
          "description": "The player. Absent for a guest grant (only allowed when the game declares `guests`).",
          "format": "did",
          "type": "string"
        },
        "room": {
          "description": "The room the launch service placed this player in.",
          "maxLength": 128,
          "type": "string"
        },
        "url": {
          "description": "Launch URL to open. Need not be on the launch service's host.",
          "format": "uri",
          "type": "string"
        }
      },
      "required": [
        "url",
        "game",
        "issuedAt",
        "expiresAt"
      ],
      "type": "object"
    },
    "hostService": {
      "description": "The player's game host (the service holding their PDS session), echoed from the intent.",
      "properties": {
        "nonce": {
          "description": "Single-use, minted by the host for this player; consumed at bindSession.",
          "maxLength": 128,
          "type": "string"
        },
        "service": {
          "description": "Base URL of the host's XRPC service. The game must present the grant nowhere else.",
          "format": "uri",
          "type": "string"
        }
      },
      "required": [
        "service",
        "nonce"
      ],
      "type": "object"
    },
    "repoDelete": {
      "description": "Delete records in one collection. Destructive: always step-up (confirmation or pre-approval on the host), never part of a standard set.",
      "properties": {
        "collection": {
          "format": "nsid",
          "type": "string"
        },
        "reason": {
          "maxLength": 300,
          "type": "string"
        },
        "rkey": {
          "maxLength": 128,
          "type": "string"
        }
      },
      "required": [
        "collection"
      ],
      "type": "object"
    },
    "repoWrite": {
      "description": "Create/update records in one collection, optionally limited to an rkey shape. Anything not covered by a standard set needs this explicit form (and, outside first-party games, step-up consent).",
      "properties": {
        "collection": {
          "format": "nsid",
          "type": "string"
        },
        "reason": {
          "description": "Plain-language explanation shown to the player.",
          "maxLength": 300,
          "type": "string"
        },
        "rkey": {
          "description": "'*' (any), 'date' (YYYY-MM-DD), or a literal rkey. Default '*'.",
          "maxLength": 128,
          "type": "string"
        }
      },
      "required": [
        "collection"
      ],
      "type": "object"
    },
    "rpgActorSheet": {
      "description": "The player's rpg.actor character sheet for this game only: actor.rpg.stats at rkey = the game's slug. Plain language: 'Keep your <game> sheet on rpg.actor up to date.'",
      "type": "token"
    },
    "signature": {
      "description": "badge.blue CID-first inline attestation by the issuing game service (e.g. did:web:play.cavu.games#score-20261006-1730). Signs the record minus `signatures`, plus $sig {$type, key, issuedAt, repository}; readers must also check the record's `game`/`period` against its rkey (the rkey is not signed).",
      "properties": {
        "cid": {
          "maxLength": 128,
          "type": "string"
        },
        "issuedAt": {
          "format": "datetime",
          "type": "string"
        },
        "key": {
          "maxLength": 512,
          "type": "string"
        },
        "signature": {
          "maxLength": 128,
          "type": "bytes"
        }
      },
      "required": [
        "key",
        "issuedAt",
        "signature"
      ],
      "type": "object"
    },
    "slug": {
      "description": "A game's slug: [a-z0-9-], the rkey of its games.cavu.game catalog record. Records a game writes are keyed '<slug>' or '<slug>:<...>'; slugs never contain ':'.",
      "maxLength": 64,
      "type": "string"
    },
    "standard": {
      "description": "A named capability set defined and reviewed by the host. Players see one plain-language line per set.",
      "properties": {
        "set": {
          "knownValues": [
            "games.cavu.defs#gameRecords",
            "games.cavu.defs#rpgActorSheet"
          ],
          "type": "string"
        }
      },
      "required": [
        "set"
      ],
      "type": "object"
    }
  },
  "id": "games.cavu.defs",
  "lexicon": 1
}

Validate Record

Validate a record against games.cavu.defs

Validation Options
Treat any remaining unresolved references as valid

Metadata

DID
did:plc:dp7v5b5kejmmzzpwmqyf5wj6
CID
bafyreib5azizaprxlq2p23evvoy3yukedcolab3ovpiyqy5lnao5oh2sqe
Indexed At
2026-10-07 02:02 UTC
AT-URI
at://did:plc:dp7v5b5kejmmzzpwmqyf5wj6/com.atproto.lexicon.schema/games.cavu.defs

Similar Lexicons

Lexicons whose schemas describe something close to this one. Check them before publishing a new one that overlaps.

  • Cavu's sidecar to a game's games.atmosphere.define record: how the game launches and what it may do with a player's account. Same rkey as the define record: the game's slug (e.g. 'haiku-day'), which scopes everything th…

  • A record indicating the actor owns a game on a specific platform. May include attestation signatures proving ownership was verified by an external service.

Lexicon Garden

@