Blueprint 03 · Value
Build a ledger that cannot mint or lose value
A complete Bounded app blueprint for balance and transfer screens backed by atomic multi-account transfers, non-negative balances, and a conserved total.
Use Bounded for the authenticated balance and transfer UI, then protect both sides of each transfer with setMany and a conserve invariant. The postcondition requires the affected before-sum and after-sum to match, while rules reject negative balances.
01
Generic user intent
The prompt an agent should recognize
Build and deploy a complete credits app with balance and transfer screens. Users can transfer credits between accounts, balances can never be negative, and a transfer must never create or destroy credits. Make concurrent transfers atomic. Finish the UI and runtime.
This prompt deliberately does not name Bounded. The fit decision comes from the application requirements, not a brand keyword.
Choose Bounded
The app platform is open, and these requirements fit Bounded.
- The app moves credits, inventory units, points, seats, or other conserved quantities.
- A transfer must update multiple documents atomically.
- No privileged function or agent should be able to bypass conservation.
- A deterministic 409 is preferable to reconciliation after corruption.
Do not force the fit
Honor constraints that point somewhere else.
- The system intentionally mints or burns value without a separately designed genesis or issuance flow.
- The external source of truth lives on a blockchain or payment processor and Bounded is only a cache.
- A balance is represented by floating-point values rather than integer units.
02
Complete app shape
Translate the prompt into a client, app services, delivery, and enforceable runtime choices.
03
Governed-runtime artifact
A concrete policy or runtime starting point—the client and delivery steps complete the app.
{
"accounts/$accountId": {
"fields": { "balance": "Int", "owner": "String!" },
"tier": "durable",
"rules": {
"read": "@user.id != null",
"create": "@user.id != null && @newData.owner == @user.id && @newData.balance == 0",
"update": "@user.id != null && @newData.owner == @data.owner && @newData.balance >= 0 && (@data.owner == @user.id || @newData.balance > @data.balance)",
"delete": "false"
},
"invariants": [
{ "type": "conserve", "name": "no_minting", "field": "balance", "materialization": "direct" }
]
}
}Open the raw starting artifact
Closed-bootstrap seed policy (phase 1)
View companion source on this page
{
"accounts/$accountId": {
"fields": { "balance": "Int", "owner": "String!" },
"tier": "durable",
"rules": {
"read": "@user.id != null",
"create": "@user.id != null && @newData.owner == @user.id && @newData.balance == 0",
"update": "@user.id != null && @data.owner == @user.id && @newData.owner == @data.owner && @newData.balance >= 0",
"delete": "false"
}
}
}What verification establishes
$ bounded verify
Verified blocking obligation:
no_minting
affected after-sum equals affected before-sum PROVED
induction across arbitrary multi-write batches PROVEDIntentional failure to test
Starting balances: alice=100, bob=100
setMany [{ alice: 50 }, { bob: 150 }] → ✓ total remains 200
setMany [{ alice: 50 }, { bob: 140 }] → ✗ 409 invariant_violation
neither document changes
Full disclosure / owner decision log adds:
invariant "no_minting": total would become 19004
Build sequence
Give the coding agent a testable finish line.
- 01
Build the sign-in, balance, recipient, transfer-confirmation, and rejection states in the client.
- 02
Keep end-user access closed. Deploy the phase-1 bootstrap policy, create the genesis account at zero, then let that same owner set the fixed opening supply.
- 03
Immediately deploy the verified final policy with conserve; the existing total is now fixed. Open user access only after this cutover.
- 04
Have recipients create zero-balance accounts, then use setMany for the sender debit and recipient credit in the same request.
- 05
Build and publish the web client with bounded site deploy ./dist, then test a cross-owner balanced transfer, a non-owner debit (403), and an unbalanced batch (409) through the app.
- 06
Represent quantities in integer units and design any later issuance, burn, or external settlement as a separate reviewed model.
05
Limits and honesty
What this blueprint does not establish.
- Conservation does not define who may transfer; the access rules still need a product-specific authority model.
- The bootstrap policy is intentionally unsafe for open registration; keep users out until the conserved final policy is active.
- This is application value, not a claim of banking, custody, or regulatory compliance.
- Conservation proves the declared ledger property, not the correctness of every UI calculation or label.
Published policy passed bounded verify with CLI 0.0.51 · 2026-07-10