Project · State policy

State policy — states gallery

The rulebook for token memory: what may change about a token after it is claimed, who may change it, and under what limits. A project-level resource, versioned, attached to many token definitions by batch, snapshot-copied at attach and locked when the token goes Live.

Only the variant machine ships in this step. General fields, apps and crafting are later steps of the same model — the endpoint and the policy shape do not change to accommodate them, which is why this can ship without anticipating them.

Spec: Phase2/Composition Template System/state-policy-design.md. Consumed by token-variant-actions-spec.md (`TVA8`, `TVA9`). Chrome follows build-mocks/style-guide/page-shell.md.
01Policy library · project levelSits in the project library beside asset specs and attribute templates. Each policy is versioned; the list shows how many token definitions hold a snapshot of each version, and how many of those are locked because their token is Live.
Studio/Neon District/Templates/State policies
Project · State policies

State policies.

Author once, attach to many token definitions. Editing a policy never changes a token that already holds a snapshot.

PolicyVersionFieldsAttachedState
Reveal only
variant transitions, nothing else writable
v2variant18 definitions · 12 lockedPublished
Garden pet
variant + xp + hunger
v1variant · xp · hunger0 definitionsDraft
Showing 2 of 2 policiesA version with a locked attachment cannot be deleted
02Policy editor · fields and their write rulesEach field carries a type, default, visibility, mutable_by, write rules, transfer behaviour and marketplace display. Rolling limits are measured in hours — rolling N hours from each write, never calendar days, so there is no midnight reset and no timezone question. Cooldowns are per field only; there is no shared per-holding pool.
State policies/Garden pet
Draft
Project · State policy

Garden pet.

Three fields. Only variant is required — the rest are this policy's own.

Fields
variantenum · system-definedsystem
xpnumber · default 0 · increase-only · max 999 · rolling limit 50 / 24hpublic
hungernumber · default 100 · cooldown 6h · marketplace-visible below 20public
Field · xp

Maps and lists come later. No unlimited blobs, ever.

Measured from each write, not from midnight.

"Creator" means the project's administrative roles.

Field · xp · continued

Owner-scoped app grants always clear on transfer, whatever this is set to.

03The variant field · three things the author cannot changevariant is a system-defined enum, not a policy invention. The policy decides whether it is transitionable, its cooldown, its rolling limit, its mutable_by, and which per-instance fields a transition may write. It does not get to decide the three rules below, and topology is not here at all — from_variant indexes that token's own list, so it lives on the token.
Garden pet/Field · variant
Project · State policy · field

Variant.

Transitionable, with a cooldown and a one-way setting. Everything else about it is fixed.

What this policy sets

Set to No and a token declaring transitions cannot go Live.

One-way rejects a declared return path at authoring time.

One-time writes — immutable after the first success.

Fixed for this field
On transfernever resets — a revealed token stays what it became when soldfixed
Stack classsame-variant copies stack, whichever variantfixed
Rarity & scorenever affected — both are definition-levelfixed
i
Declare which variant reaches which on the token's Variants tab. This page sets what is allowed to happen, not what does.
04Batch attach · with a diff before anything commitsNever configure one token at a time. The batch tool is also where the diff lives, so an author sees exactly what will change and what will be skipped. Live definitions are skipped, not failed — their snapshot is locked, and re-apply is Draft/Review only.

Attach Reveal only · v2

✕

Attaching to 6 selected token definitions in Paper Trail.

#014 Relicno policy → v2will attach
#022 Walletv1 → v2will replace
#031 Walletv2 alreadyno change
#042 SlabLive — snapshot lockedskipped
#051 SlabLive — snapshot lockedskipped
#063 Relicno policy → v2will attach
!
Replacing v1 on #022 changes what holders may do once it goes Live. It has no minted copies yet, so nothing existing is affected.
05Snapshot and lock · the three states a token's policy can be inA snapshot is an independent copy. The policy in the library and the snapshot on the token are separate objects from the moment of attach, which is what makes a library edit structurally unable to reach an already-sold copy.
Token Draft · editable
SnapshotReveal only v2Draft
Token Review · editable, reverts to Draft
SnapshotReveal only v2Review
i
Changing the policy here returns the token to Draft first.
Token Live · locked
SnapshotReveal only v2 — frozen at go-liveLive
!
Locked. Library edits cannot reach this token, and it cannot be re-applied or detached. Holders keep exactly the rules this copy was sold under.
06Go-Live gates · every failure is namedThree of the gates come from this system. None reports a generic invalid flag, and the authoring UI disables transition controls when the attached policy forbids variant writes rather than letting an author build something that cannot ship.
Token · go-Live readiness
✓
Policy attached
Reveal only v2 · snapshotted, ready to lock
✕
Variant writes permitted
Token #014 declares transitions, but its policy sets variant to not transitionable. Attach a policy that permits it, or clear the transitions
✕
Policy endpoints in range
A transition names variant index 7; this token has 4. Rejected at authoring, surfaced here as a reminder
✕
Declared outcome fields exist
Target opened declares reveal_seed, which is not defined on this token. Writing the variant without its payload is an invalid end state, not a partial success
✓
Listed holdings
None — a listed holding rejects all state writes
07One endpoint, six ordered checksNot a screen — the reference for the write path. Every state change goes through the same call, variant transitions included. Do not build a bespoke transition endpoint.
The update path · state-policy-design.md §5
update_token_state(
  holding_id,
  actor,                 // owner principal | app_id | system
  changes: [ { field, op, value } ],
  reason,               // lands in the audit event
  operation_id         // idempotency key
)
1Actor allowed on every touched field
2Ops allowed for those fields
3Limits, cooldowns and rolling windows respected
4Holding eligible — owned, unlocked, not listed, Active — via the shared eligibility function
5Apply atomically
6Emit one audit event: copy identity, quantity, every field delta, actor, reason

actor is a static principal — the Internet Identity principal, or a wallet principal such as Oisy. Never a delegation principal, so a holding's owner stays stable across sessions. App authorisation reuses Canic delegated-signature auth: an approved app is a delegated token whose scopes name the project, definitions, fields, ops and limits it may write. Do not build a new ACL store.

08Outcome selection and build orderNot a screen — the two reference tables a developer needs beside this. Only the first selection mode is in scope, and only step 1 of the build order ships now.
Outcome selection · §6
ModeMeaningStatus
Deterministic mappingThe target fixes the outcome; no choice, no rollV1
Owner-selected pathThe holder picks from a creator-declared setDeferred
Rule-based selectionAn automation rule resolves it from project stateDeferred
Oracle / randomnessResolved server-side at executionDeferred

Owner-selected is not owner-executed. Every V1 transition is executed by the holder, but the outcome is fixed by the policy. Whichever mode: the selection is recorded in state, the outcome is immutable after first success, and variant plus outcome plus audit event land atomically.

Build order · §12
StepScopeStatus
1 · The variant machinevariant as an enum field, per-field cooldowns and rolling limits, policy presets and batch attach, owner-executed transitions, the shared endpoint and its audit eventsThis ship
2 · General fieldsnumber · text · boolean · timestamp · enum, with write rules, transfer behaviours, marketplace visibility, freeze-while-listedNext
3 · Apps and consumablesDelegated-auth app writers, charges, same-canister cross-token actions, derived triggersLater
4 · Crafting and beyondBurn-create recipes, cross-canister sagas, maps and lists, randomnessLater

Steps 2–4 only extend the field and action models. Neither the endpoint nor the policy shape changes for them, which is why step 1 ships without anticipating them. Progressive reveal is not a separate step — it is the narrowest policy step 1 can already express.