STATE CONTRACTS
Bags, observation and hold
Keep actual supply, available information and currently usable pieces as different state dimensions.
Standard bags and custom sources
seven_bag() declares a uniform bag containing each standard kind once. With r kinds remaining, each has base next-draw probability 1/r. Initial leftovers can be declared separately as remainder("SZ", epoch=2).
config {
rule = seven_bag();
start = remainder("SZ", epoch=2);
}Do not infer physical bag boundaries from braces or pattern segments. Fixed queues and P3P3 are not silently edited to fit a standard bag. A host can validate actual bag legality against rule; validating the document alone does not prove game supply legality.
For multiplicities or weights, declare a custom bag/pool. Each positive integer weight corresponds to an individual listed token. bag draws from remaining tokens proportionally to their weights; pool draws with replacement. Omitted weights are one per token. Sampling and conditional probabilities belong to the consumer.
see-n is an explicit information contract
config {
see = view(active=true, next=5, hold=true,
memory=history, reveal=supply, bag=known);
}| Field | Meaning / document-v1 default |
|---|---|
| active | Reveal current piece / true |
| next | Directly revealed next-piece count / 5 |
| hold | Reveal hold content / true |
| memory | history or current / history |
| reveal | supply, lock or host / supply |
| bag | known or hidden bag knowledge / known |
supply advances observation when actual supply is consumed; lock updates it at post-lock decision boundaries; host uses consumer-defined reveal events. all() exposes actual supply within the declared horizon. An ambiguous see-7 label alone is not stored.
Independent hold-state dimensions
config {
hold = slot(initial=empty, used=false, allowed=true, deny=["T"]);
active = token("I", origin=10);
queue = [token("O", origin=11)];
cursor = 0;
tail = end;
}| Expression | State |
|---|---|
| hold=none() | No hold feature or slot |
| hold=slot(initial=empty) | An available empty slot |
| initial=token("T",origin=9) | A held T with explicit origin |
| used=true | Hold already used this turn; re-hold locked |
| allowed=false | Default hold-action policy denies use |
| deny=["T"] | Deny hold while the pre-action active kind is T |
deny exists only in advanced declarations. It is not a D/U shortcut or a proposed Clearra UI feature. The held kind does not trigger it, and it does not forbid moving or placing T. Equal kinds may still have different origins.
Swapping occupied hold consumes no future queue entry. Empty hold consumes one actual next piece. Both lock re-hold for the turn; host-confirmed lock and spawn unlock it. A failed swap leaves state unchanged.
Missing information and unsupported states
tail=pending means further supply information is needed; tail=end means supply has ended. Neither is a proof of zero solutions. Missing settings also do not become EMPTY or NONE implicitly.
If a dataset supports only occupied hold, EMPTY is UNSUPPORTED_STATE. Never invent a held piece for lookup. A consumer may provide a verified mapping preserving active/held, queue consumption, bag leftovers, revealed information and corresponding legal actions.