원본 저장소의 제목, 예시, 코드, 표, 링크, 이미지를 유지해 표시합니다.
Bounded backend
The server side of a Bounded app: the policy that governs documented supported mutation surfaces, the proof-backed and runtime-enforced invariants, the functions that run trusted code, and the actor model that decides who is acting. The proof loop is bounded verify; treat PROVED differently from a non-blocking runtime advisory with proof status UNKNOWN. bounded deploy compiles and pushes; runtime rule and invariant checks reject violations before commit on their documented supported mutation surfaces. Do not generalize that coverage to an unsupported plane, undocumented storage path, or inherited corpus. For CLI/deploy see the bounded-deploy skill; for the client SDK and auth UI see bounded-frontend; to route across the family, see the root bounded skill.
Write the actor model in mind from the start: know who @user is, which principal a function acts as (runAs/actAs), and where authorization comes from (@origin) before you write a rule.
Reference Router
Building one of the five most common app shapes? Take the quick path - one target page per build - instead of scanning this table. Otherwise read only the row matching the current task or term.
| Task or term | Read |
|---|---|
| One-screen syntax: field types, tiers, variables, operators, where logic goes | policy cheat sheet |
| Generate or repair a policy from an app description | policy generation |
| Complete policy examples by intent (marketplace, escrow, vaults, staking, tokens, ...) | examples index |
| Worked multi-collection policies (team SaaS, marketplace, realtime game) | examples |
| Rule recipes: owner-only, admin-or-owner, membership, time windows, validation, immutable fields, atomic batches | access patterns |
Rules, fields, expressions, @user, @data, @newData, @time, get(), getAfter(), transferAuthority | policy reference |
Caps, balances, supply, tenant isolation, hard bounds; rollingSum, windowSum, flowBound, conserve, tenantTag, tenantEdge, bound | invariants |
Trending feeds, leaderboards, ranked windowSum reads | trending feeds |
| Browser CSP / restrict what app pages may reach | browser boundary |
Constants, reusable rules, @const, @def | constants and defs |
| Choose rule vs invariant vs hook vs function | when to use functions |
Functions; declare, auth, entry, secrets, actAs, ctx.user, ctx.bounded, ctx.env, ctx.secrets, invoke, deploy | functions |
Public functions: HTTP routes without a Bounded session at <slug>-api.bounded.page, public, methods, cors, public JWKS, machine callers, webhook and browser-public modes | public functions |
ctx.ai.run, ctx.ai.generateImage, ctx.ai.generateVideo, getJob, AI without API keys | ctx.ai |
ctx.services, managed third-party APIs, bounded services | ctx.services |
ctx.browser, headless browser from a function, driving your own app signed in, @const.AGENT, agent identity | ctx.browser |
ctx.enqueue, background jobs, queues, replay identity | ctx.enqueue |
ctx.build, functions that originate governed app builds | ctx.build |
| Start simple and graduate to functions | function graduation |
| User-owned provider API keys | secrets |
Schedules, dueRows, hooks, webhooks, verifyWebhook | scheduled hooks and webhooks |
| Recurring fleet sweeps without full scans | scheduled sweeps |
| Anti-cheat proof limits | hooks and anti-cheat |
Atomic writes, subset attacks, requiresInBatch, incomplete_batch | data plane |
Queries, pagination, queryAggregate, count, filters, sort, cursor | queries |
Files, setFile, storage, full-text search | files and search |
Realtime rooms; session.tick, settleTo, settleFrom, fog-of-war views | realtime and games |
Native live modules; session.live, tick, views, @effect, live.intent | live runtime |
| Input cadence, interpolation, prediction | realtime netcode |
| AI NPCs / AI players | AI NPCs |
| Long-running backend runtime or managed services | backend runtime |
| Multi-step Flue agents | Flue agents |
| Owners, collaborators, scoped admins | admin and ownership |
Top-level roles, members, read:"*", read/write scopes | roles |
access, custom/external roles, __owners__, __admins__, __developers__, __viewers__ | access control · identity and logs |
Service keys, payout bots, backend identities, runAs, actAs, @origin, ctx.origin | service keys · principals and origins |
Proof coverage, PROVED / DISPROVED, counterexamples | proof coverage · verify and counterexamples |
Concrete allow/deny tests; policy-tests/*.json, bounded tests run/push/list/pull | policy tests |
| End-to-end tests for authenticated apps | testing authed apps |
| Completion review | quality checklist |
| Agent-facing or backend-only app | building for agents · building a backend |
Error Router
| Error/status | Meaning |
|---|---|
403 | A write or function invoke failed a rule. Check auth, ownership, roles, or function auth. Denied reads are hidden as 200 with empty data, not 403. |
500 rule_evaluation_failed | The rule was reached and could NOT be evaluated - no rule denied you, and nothing was read or written. Not a denial, not a retryable conflict. Read bounded decisions for the cause; the row is recorded with decision: error. |
409 + invariant name | The transaction would violate an invariant. Fix state or policy. |
403 incomplete_batch | A collection's requiresInBatch declaration names companion paths missing from the atomic batch. Submit the complete setMany. |
DISPROVED + counterexample | The proof found a breaking assignment. Fix every blocking result and verify again; only non-blocking advisories are reviewable. |
| Static validation error | Fix policy syntax, field types, tier/invariant pairing, constants, or expression use. |
Rules Of Thumb
- Use
@user.idfor normal ownership and membership checks;@user.addressonly for wallet/onchain semantics. - Denied reads return empty
200responses. Test read denial with a different permitted identity, not by waiting for a read403. - Use
conservefor fixed totals,rollingSumfor caps over time, andflowBoundfor cumulative per-partition outflow ≤ inflow; use one atomicset-manywhen correctness spans multiple writes. - When one write is invalid without companion writes, declare
requiresInBatchso a hostile client cannot submit only the individually valid subset. - Put provider API keys in Bounded secrets, not frontend code.
- Know the acting principal before writing a rule: a function's
runAs/actAsand@origindecide who@useris and whether the call is authorized.

