Worked examples · 07 of 07
The hospital master
A standard hospital staffing template is instantiated through a chain of binding stages - the organization binds its own parties once, then each engagement binds the rest - instead of being copy-pasted and forked.
- SIZE
- small, structural
- PROFILE
- any
- STRESSES
- Genesis as a chain of binding stages, party slots bound late under declared constraints, and upgrade-by-transform instead of fork-and-drift.
Staged binding is the whole feature. Today an organization adapts a standard contract by copy-pasting the Word file and editing - a fork: it never receives upstream fixes, cannot be diffed against the standard, and drifts silently. Staged binding replaces the fork with a reference plus bound variables: the hospital’s “our contract” is a partially-applied artifact, still hash-linked to the governed template it came from.
The formulation
A contract is an expression over declared parameters. A template has free variables; a fully-ground instance has none. Genesis generalizes from one event to a chain of binding stages, each signing a subset of the remaining free variables, each hash-referencing the previous stage. (Technically partial application rather than currying - stages bind arbitrary subsets in any order, which is what contracts need. Schönfinkel, 1924, got there first.)
Law got there before software did:
| The ladder | Stages |
|---|---|
| ISDA Master → per-trade confirmations | parties bound once, economics bound per trade |
| Adda ramavtal → kommun call-off → avrop | supplier signs a quantified buyer slot (“any eligible member”); the kommun binds itself later; quantities bind last |
| Kollektivavtal → hängavtal → anställningsavtal | the same ladder in labor law |
| LOU förnyad konkurrensutsättning | a multi-supplier framework where each call-off’s mini-competition binds which supplier fills the party slot - runtime party binding, competitive, already Swedish law |
| A webshop template awaiting a buyer | a standing offer IS a signed partial application (example 01 was one all along) |
The contract chain
# ── STAGE 0: the governed template (a §5 artifact; e.g. profile- or SKR-published)
mechanical-contract v0 TEMPLATE
id: tpl-se-health-staffing @ v4
parameters: # each slot declares: type/domain,
vardgivare party<org> bound-by stage org-master
attest artifact<attestordning> bound-by stage org-master
calendar artifact<calendar> bound-by stage org-master
supplier party<org> in {vardgivare's approved-supplier register}
bound-by stage engagement
rates lookupOf<role, money/h> bound-by stage engagement
volume quantity<h> bound-by stage engagement
# ports, pools, cadences, escalation: written ONCE, here, over the slots
# ── STAGE 1: the hospital master - the org binds ITS variables, once
binding-stage region-skane-staffing-master:
of tpl-se-health-staffing @ v4 sha256:...
bind vardgivare org 232100-0255 "Region Skåne"
bind attest art:skane-attestordning track latest-approved
bind calendar art:se-working-days track latest
signed: Region Skåne (eIDAS-qualified-seal) # ONE party signs: this is a
# standing offer / internal
# remaining free: supplier, rates, volume # standard, not yet an agreement
# ── STAGE 2: each engagement - thin, confirmation-shaped
genesis mk-se-health-2027-0142:
of region-skane-staffing-master sha256:...
bind supplier org 556677-8899 "Bemanning AB" # constraint CHECKED at binding:
bind rates art:bemanning-rates-2027 pin v1 # not in the approved register ->
bind volume 5000 h # binding REJECTED, never a stage
signed: both # (§5.2's illegal-update rule,
# applied to binding)
Every staffing, equipment, and cleaning contract the region signs afterwards starts from stage 1 - identity, attestordning, calendar, profile inherited by reference. When the template ships v5, the master adopts it via one §6.4 transform (adherence, receipted); every future engagement inherits automatically, every existing one stays pinned per §6.3. The forked Word document can do none of this.
The rules that keep it boring
- Each stage signs the constraint, not the value. The Adda supplier never met Lunds kommun; they signed
buyer in eligible-members. A slot’s domain is a contract term of the earlier stage; violating it at bind time is a rejected event, never a stage. - A one-signature stage is an offer; a both-signature ground contract is an agreement. The signature set per stage is declared per slot (
signs:), so what the artifact legally IS at each rung is readable off the manifest. - Depth terminates structurally. The parameter list is finite and every stage must bind at least one variable, so chain depth ≤ parameter count. Once ground, nothing remains to bind - no recursion possible.
- Width is a pool draw. The other reading of “instances creating instances” - a contract whose rules spawn siblings (
on order.accept: instantiate ...) - is leashed by the existing machinery: instantiation-as-effect consumes declared capacity from the parent (the avrop draws the takvolym; a merchant master draws a max-active-orders pool). Unbounded self-replication is a §3.1 boundedness question the linter refuses. Daml’s create-in-choice proves the mechanism; Solidity’s factory sprawl is the graveyard we route around. - Stages do not freeze the environment. A closure captures its environment; a binding stage must NOT silently snapshot artifact versions - effective-dating (§5.1) keeps ruling, and pins are explicit per binding. A stage that quietly froze the rate table would be a new species of silent term.
What this example stresses
| Edge | Spec section |
|---|---|
| Genesis as a chain of binding events | §6.3 (extended) |
| Party slots bound late, under declared constraints | absorbs the besiktningsman appointment and the party-role questions |
| Standing offers as one-signature partial applications | §6.3, avtalsrätt |
| Instantiation-as-effect bounded by pool draws | §3.1, §7.1 |
| Upgrade-by-transform instead of fork-and-drift | §6.4 |
Questions this example forced
- Staged binding as THE instantiation model. As above: parameters declare domain + binder + signer per slot; stages chain by hash; constraint-violating bindings are rejected; depth terminates by arity; width draws pools. Absorbs the appointed besiktningsman (a party slot bound mid-contract) and gives the role classes their mechanism. Resolved in the working draft as the instantiation model; spec text pending (§6.3 extension).
- Derived values are views, and “reactive” needs a guard rail. Surfaced by the aggregate discussion: since ports, payloads, and bindings are immutable, every computed value (subtotal, consumed %, vite accrued) is a pure function of a log prefix - so computed things are never stored, never signed alone, and may be declared as named, typed derived values (the expectation register was the prototype; the invoice-as-projection is one rendered to a document). Reactivity split: as evaluation strategy (memoization, incremental maintenance - materialized views, Jane Street Incremental, Adapton/Salsa; purity makes caching undetectable, hence legal) always allowed; as semantics (derived-value changes triggering behavior spontaneously) forbidden - predicates evaluate AT events and heartbeats only, or replay dies. Division/percentages inherit declared rounding always, and must go through
splitthe moment results move money.