R-12 · 12 min · Design Note
Conserved-State Constraints: An Open Design Question
Published Sep 13, 2026 · last revised Sep 15, 2026
Abstract
Every authority artifact today expresses static constraints — an amount, a role, a date range. Some real authority is not static: 'up to $20,000 cumulatively during this window' is a claim about a running total, not a threshold checked once per call. This note names that gap precisely, explains why it cannot be closed by simply adding a mutable counter without breaking the deterministic-execution and offline-verification guarantees the rest of the model depends on, and converges on an architectural direction: authority stays immutable, an external state layer (reserve/settle/release) holds what changes, and can() stays pure — evaluating authority against an explicit state fact rather than owning the state itself. A vertical slice of this direction has since been built and tested — see R-13.
R-13 · Engineering Case Study
Conserved-State Authority, Built →
The vertical slice this design converges on has been built and tested against a real database under real concurrent load — six of seven proof points verified, one open question below resolved. What's still open is still open.
Concept
Draft — pre-specification. Not part of any published NOMOS-SPEC. Surfaced by external critique of nomos.can(), published as an open question rather than answered reactively. A vertical slice of the direction this note converges on has since been built — see R-13: Conserved-State Authority, Built.
1. The problem
Every governance artifact today expresses static constraints: an amount, a role, a jurisdiction, a date range. can() evaluates one call against the facts supplied with it, and nothing else.
Some real authority is not static. 'Agent X may spend up to $20,000 cumulatively during this window' is a claim about a running total, not a threshold checked once per call. If the evaluator only ever asks whether one request is under the limit, an agent can call it any number of times and pass every time — nothing anywhere decrements what is left. The artifact can express the limit. Nothing today expresses, or conserves, the remaining amount.
This is a real, currently unsolved gap. It deserves a real answer — but not a rushed one.
2. Authority, facts, evaluation, state
The clearest way to state the architecture is four parts, not two. An authority artifact expresses a constraint. Facts describe the world at the moment evaluation happens. can() evaluates the artifact against those facts. State records what changes over time — and state is not the artifact.
.nomos | v authority rule | v can() ^ | facts <- ledger
ledger ≠ authority
The external critique initially reads as 'your authority object needs state.' The more precise answer is that the authority object needs to be able to express a constraint over state — the state itself does not need to become part of the authority object. That distinction, not a mutable field, is the actual fix.
3. Why this is not simply 'add a counter'
An authority artifact is sealed and immutable everywhere else in this model. The offline verifier, the permanent sealed transcript, and the deterministic-execution claim (same artifact, same facts, same outcome, today and in five years) all rest on the evaluator needing nothing but the artifact and the facts it was given. A live counter the evaluator reaches out and fetches mid-evaluation breaks exactly that: the same artifact, called with what looks like the same facts, could produce a different verdict depending on unrecorded history. Re-running the evaluation later, from the transcript alone, would no longer reproduce the original result.
Authority can be immutable while the state against which authority is exercised is mutable.
The way out: the consumed amount is an input fact, not hidden state. The artifact declares the rule — a constraint over an amount and a named field such as consumed-so-far, with a limit and a scope. An external ledger, outside the sealed artifact, mutable, supplies that consumed amount as an ordinary fact at call time, the same way any other fact is supplied today. The transcript records the exact fact it used, alongside the artifact version and seal hash it already records.
Re-execution from the recorded transcript remains deterministic because the transcript contains the exact state fact used at evaluation time: the same artifact, evaluated against those same recorded facts, reproduces the same verdict. Nothing mutable ever enters the sealed artifact.
4. The offline-verification problem
A chain-of-trust rail that verifies entirely offline — no lookup, no server call, by design — cannot reach a live ledger. A budget-bearing artifact presented that way cannot have its conserved constraint checked by a verifier with no ledger of its own. This is not a NOMOS-specific weakness; it is a fundamental property of offline verification: a verifier cannot establish a fact it cannot access.
That property also separates two verification problems this note has otherwise treated together: verifying that an authority artifact is genuine — its seal, its issuer, its chain of trust — and verifying that the current state against which that authority is being exercised is accurate. Offline verification can fully answer the first without ever being able to answer the second.
This is the same shape of problem artifact revocation already answers for freshness, and the honest solution reuses that pattern rather than inventing a new one: either refuse to answer a conserved constraint when no ledger is reachable, or disclose the weakest confidence honestly — the same discipline that reports revocation confidence as a tri-state and always reports the weakest state found, never the best.
5. The state layer: reserve, settle, release
There is a clean test for which mechanism is correct: does asking consume?
If can() atomically decrements the ledger the moment it is called, an agent considering ten possible purchases and acting on only one has exhausted its authority without doing anything. can(A), can(B), can(C) — each one AUTHORIZED, each one silently spending capacity the agent never used. That is wrong for a general-purpose primitive whose value depends on asking being cheap and side-effect-free, the same way calling fetch() to check whether a resource exists must not itself consume the resource.
can() → AUTHORIZED (no state change) | | (only once the agent actually commits) v reserve() → Reservation | v execute action | +-- success → settle() → settlement receipt +-- failure → release() → release receipt
The reservation is where state actually changes, and only there. can() answers a question; reserve() holds capacity; execute performs the real-world action; settle() or release() resolves the hold depending on what actually happened.
Left unresolved, this still permits a second failure: a reservation created against one authorization decision, redeemed after that decision no longer holds. Evaluate under authority A, have authority A change, execute under authority B. The fix is binding the reservation cryptographically to the exact decision it came from, not only to the artifact:
{
"reservation_id": "rsv_7821",
"authority_seal": "sha256:abc...",
"decision_digest": "sha256:def...",
"agent": "agent:123",
"action": "payments.transfer",
"scope": "supplier:acme",
"amount": 5000,
"state_digest": "sha256:ghi...",
"expires_at": "2026-09-13T12:00:00Z"
}state_digest also gives the ledger a compare-and-reject check at reserve time — optimistic concurrency control applied to authority: reserve only succeeds if the ledger's current state still matches what the caller expected, so two concurrent reservations against the same $8,000 remaining cannot both silently succeed and overspend the artifact's $20,000 limit.
No standalone receipt() call. Requiring a caller to remember a fifth invocation reintroduces exactly the reliability problem this layer exists to remove — what happens if someone forgets to call it? settle() and release() each produce their own tamper-evident record as a normal return value, the same way can() already produces its evaluation record without a separate call.
Reserve and settle appears to be the right shape for the general case. This is a design hypothesis, not a conclusion; a better transactional model would not weaken anything else in this note.
Atomic decrement-at-evaluation may still be correct for a narrower case — a caller that only ever asks immediately before acting, never speculatively — but that is a property of the caller, not something a general primitive can assume.
6. Scope must be declared, not inferred
'$20k per supplier per year', '$20k per agent per year', and '$20k total' are different ledgers. Whatever a conserved constraint is scoped to needs to be an explicit, declared field on the artifact — the same discipline already required of delegation scope elsewhere in this model, where an issuer that scopes a delegation forces every artifact under it to declare that scope or fail closed. Inferring scope from context is exactly the kind of implicit behaviour this discipline exists to make explicit instead.
7. The current architectural direction
The thesis this whole discipline rests on is that authority should be a first-class primitive in the software stack — one call, one answer shape, the way identity has authenticate() and the network has fetch(), regardless of what actually backs the answer. A stateless call was never going to be the whole story for a depleting constraint, and the direction above is what keeping that primitive pure requires: the state that changes lives beside can(), not inside it.
Four layers, not two: an authority layer (the sealed artifact, expressing what may be done), an evaluation layer (can(), pure and non-mutating, answering whether an action is authorized against the facts it is given), a state layer (reserve, settle, release, managing what remains possible), and an evidence layer (a tamper-evident record produced by every transition, not assembled after the fact).
Conserved state does not belong inside the authority artifact or inside can(). It belongs in an external state layer, with can() evaluating the authority against an explicit state fact, and reserve()/settle()/release() providing the transactional semantics required when authority is actually exercised.
This is the current architectural direction that a future vertical slice would test — not a claim that the protocol semantics are settled. The distinction matters: a design converging across independent review is a reason to commit to testing it, not a reason to skip testing it.
8. What this note is not
This is not a proposal to build a conserved-state feature reactively. It is the opposite: writing down, precisely, why the honest answer to 'how do we fix this' right now is 'not yet' — naming an open question rather than quietly assuming an answer to it. If this becomes real work, one vertical slice comes first: a single delegated monetary budget, proving that concurrent reservations cannot overspend, repeated can() calls consume nothing, reservations expire, failed execution releases capacity, successful execution settles, a reservation is bound to the exact decision that created it, the transcript reproduces the original can() decision, and offline verification correctly reports that it cannot establish current conserved state rather than guessing. Generalizing beyond one budget type comes after that, not before it.
Open question
This is an open question, not a settled answer. If you have a counter-argument, prior art, or a different approach, the discussion is public and cumulative on purpose — so a response is visible to everyone, not a private one-to-one email.
Respond on GitHub →Cite this
This is a field in formation; this page will be revised. Cite the version date below, not the day you happen to be reading this.
Suggested citation
SafeHaven (2026). Conserved-State Constraints: An Open Design Question. Computable Authority Research Library, version of 2026-09-15. https://www.computableauthority.com/research/conserved-state-authority
BibTeX
@misc{computableauthority-conserved-state-authority,
author = {SafeHaven},
title = {Conserved-State Constraints: An Open Design Question},
howpublished = {Computable Authority Research Library},
year = {2026},
note = {Version of 2026-09-15},
url = {https://www.computableauthority.com/research/conserved-state-authority},
}Next entry
Conserved-State Authority, Built →