Build on it
A dregg app is a set of cells minted from a factory you publish, plus client code that sends turns and reads receipts. The part you are used to writing — the enforcement code, the "check the balance before transferring" bookkeeping — does not exist. Your rules live in the factory descriptor as guard constraints, and the executor refuses any turn that would violate them. Your app cannot have an enforcement bug it never enforces anything.
That is why building here is worth the new vocabulary: the substrate's theorems — conservation, no amplification, whole-state receipts — are inherited by every cell your factory mints, for free, forever.
Three ways in
Rules you can mint
A factory's rules are generic constraints from one small vocabulary — there is no
Effect::CastVote or Effect::ClaimBounty anywhere in the
system. A ballot that cannot be voted twice is a WriteOnce slot; a budget
that cannot exceed its ceiling is a FieldLteField pair; a workflow that
cannot rewind is a StrictMonotonic counter. The full constraint grammar,
generated from the canonical source:
What factories dissolve into
Recurring shapes — escrow, obligation, council, constitution — are factory patterns with in-tree proof modules. These worked descriptors are generated by running the real constructors; open one in the Studio composer and edit it:
site/tools/gen-factory-samples.sh). Open one in the
Studio composer to edit it, or inspect the machine it
builds (the composer mounts the matching polis inspector on recognizable machines).Eight real apps, no enforcement code
Each is a real Rust crate with factory descriptors, signed turn-builders, and a passing test suite, running end-to-end against the canonical executor. The live devnet seeds one of each at genesis. To walk any of them — slots, constraints, turns, and a live try-it against a node — open the worked-examples walker.
tail ≤ head always holds; publish and consume advance monotone sequences.
Privacy voting
One vote per ballot — the vote slot is WriteOnce, and a second attempt is rejected by the executor, not by app code. Tallies can never shrink.
Bounty board
A substrate-enforced state machine: OPEN → CLAIMED → SUBMITTED → PAID, StrictMonotonic (no rewind), first claimer wins via a WriteOnce claimant slot.
Governed namespace
A council-controlled route table: propose → threshold vote → commit. The committee root and threshold are Immutable; the table version only advances.
Workflow mandate
A DAG workflow under a bounded mandate: the step cursor may never pass the charter terminal. Maps Lean mandate theorems to slot constraints.
Storage gateway mandate
GET / PUT / LIST under a volume ceiling with prefix authorization — spent is Monotonic and may never exceed the ceiling.
One image, four surfaces
While you build, everything is inspectable as a dregg:// URI rendered by
the same platform inspectors everywhere: the explorer for live
objects, the playground for driving the wasm executor, the
Studio for authoring, and
Starbridge — the shell you boot into your polis: one frame
holding your identity, your cells, the live receipt stream, and the app places (its
inspector IDE lives at workbench).
Drive an app from the CLI
A rejected second claim or a tally that refuses to shrink is the constraint biting on the verified commit path — not a string compare in the app:
# Privacy voting, live against a node
dregg voting open --question "ship the gallery port?"
dregg voting tally --poll <id> --choice yes
dregg voting close --poll <id>
# Bounty board lifecycle (first-claimer-wins)
dregg bounty post --title "port gallery" --reward 500
dregg bounty claim --bounty <id>
dregg bounty submit --bounty <id> --uri ipfs://...
dregg bounty payout --bounty <id>
Each app's source and tests live under starbridge-apps/<name>/ in
the repo. The deeper grounding — how apps inherit theorems by consuming receipts
against descriptors — is rung 6 of the
protocol docs.