Open Standard · Working Draft
mekaniskt·kontrakt

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 split the moment results move money.