soma.cell

Land registry — a parcel cannot be sold to two buyers at once

Deed-theft rings in Brooklyn and Detroit ran the same con for years: file a sale of the same house to two different buyers in the gap before the recorder's index catches up, collect both down payments, vanish. The con needs a registry that will hold two open sales on one parcel. This one will not: open escrows per parcel is a memory invariant capped at 1 — the second contract is refused at the write. Sales also only move title when the seller IS the recorded owner, and an escheated parcel (abandoned to the state) is terminal: soma verify proves it never re-enters commerce.

A Soma program from the civic part of the verified corpus: 110 lines, cells LandRegistry, RegistryTests. It passes soma check with soma 3.2.4.

How it is built

The cell LandRegistry declares 5 signals in its face: record_deed(parcel: String, owner: String) -> Map, open_escrow(parcel: String, seller: String, buyer: String) -> Map, close_escrow(parcel: String) -> Map, escheat(parcel: String) -> Map and owner_of(parcel: String) -> String; keeps 3 memory slots: pending (Map<String, Int>, persistent and consistent) under the invariant pending >= 0 && pending <= 1, owners (Map<String, String>, persistent and consistent) and buyers (Map<String, String>, persistent and consistent). Its state machine parcel starts in unrecorded and allows 4 transitions: unrecorded -> titled, titled -> in_escrow, in_escrow -> titled and titled -> escheated. escheated is terminal. Handlers: record_deed (line 42), open_escrow (line 49), close_escrow (line 68), escheat (line 77) and owner_of (line 84).

The file also holds 1 test cell (RegistryTests) with 16 assertions, run by soma test.

Generated from soma describe on this file.

The source

land_registry.cell

// ============================================================================
// LAND REGISTRY — a parcel cannot be sold to two buyers at once
// ============================================================================
// Deed-theft rings in Brooklyn and Detroit ran the same con for years: file
// a sale of the same house to two different buyers in the gap before the
// recorder's index catches up, collect both down payments, vanish. The con
// needs a registry that will hold two open sales on one parcel. This one
// will not: open escrows per parcel is a memory invariant capped at 1 — the
// second contract is refused at the write. Sales also only move title when
// the seller IS the recorded owner, and an escheated parcel (abandoned to
// the state) is terminal: soma verify proves it never re-enters commerce.
// ============================================================================

cell LandRegistry {
    face {
        signal record_deed(parcel: String, owner: String) -> Map
        signal open_escrow(parcel: String, seller: String, buyer: String) -> Map
        signal close_escrow(parcel: String) -> Map
        signal escheat(parcel: String) -> Map
        signal owner_of(parcel: String) -> String
    }

    memory {
        // parcel -> open sales. TWO open escrows on one parcel — the
        // double-sale — is unrepresentable.
        pending: Map<String, Int> [persistent, consistent]
        invariant pending >= 0 && pending <= 1

        owners: Map<String, String> [persistent, consistent]
        buyers: Map<String, String> [persistent, consistent]
    }

    // Per-parcel lifecycle. escheated has no exit.
    state parcel {
        initial: unrecorded
        unrecorded -> titled
        titled -> in_escrow
        in_escrow -> titled
        titled -> escheated
    }

    on record_deed(parcel: String, owner: String) {
        let r = try { transition(parcel, "titled") }
        if r.error != () { return map("ok", false, "reason", "{r.error}") }
        owners.set(parcel, owner)
        return map("ok", true, "parcel", parcel, "owner", owner)
    }

    on open_escrow(parcel: String, seller: String, buyer: String) {
        if owner_of(parcel) != seller {
            return map("ok", false, "reason", "{seller} does not hold title to {parcel}")
        }
        let open_sales = pending.get(parcel) ?? 0
        // THE WALL: a second simultaneous sale refuses at the write.
        let w = try { pending.set(parcel, open_sales + 1) }
        if w.error != () {
            return map("ok", false, "reason", "{parcel} already under contract")
        }
        let r = try { transition(parcel, "in_escrow") }
        if r.error != () {
            pending.set(parcel, open_sales)               // roll the contract back
            return map("ok", false, "reason", "{r.error}")
        }
        buyers.set(parcel, buyer)
        return map("ok", true, "parcel", parcel, "buyer", buyer)
    }

    on close_escrow(parcel: String) {
        let r = try { transition(parcel, "titled") }
        if r.error != () { return map("ok", false, "reason", "{r.error}") }
        let buyer = buyers.get(parcel)
        owners.set(parcel, buyer)
        pending.set(parcel, 0)
        return map("ok", true, "parcel", parcel, "new_owner", buyer)
    }

    on escheat(parcel: String) {
        let r = try { transition(parcel, "escheated") }
        if r.error != () { return map("ok", false, "reason", "{r.error}") }
        owners.set(parcel, "STATE")
        return map("ok", true, "parcel", parcel)
    }

    on owner_of(parcel: String) { return owners.get(parcel) ?? "none" }
}

cell test RegistryTests {
    rules {
        assert record_deed("lot-7", "ada").ok == true
        assert open_escrow("lot-7", "eve", "bob").ok == false   // eve holds no title
        assert open_escrow("lot-7", "ada", "bob").ok == true
        // THE DOUBLE SALE: same parcel, second buyer, while escrow is open
        assert open_escrow("lot-7", "ada", "mallory").ok == false
        assert_fails pending.set("lot-7", 2)                    // unrepresentable
        assert close_escrow("lot-7").ok == true
        assert owner_of("lot-7") == "bob"
        // bob can sell; ada no longer can
        assert open_escrow("lot-7", "ada", "eve").ok == false
        assert open_escrow("lot-7", "bob", "eve").ok == true
        assert close_escrow("lot-7").ok == true
        assert owner_of("lot-7") == "eve"
        // an abandoned parcel leaves commerce forever
        assert record_deed("lot-9", "ada").ok == true
        assert escheat("lot-9").ok == true
        assert_fails transition("lot-9", "titled")
        assert_fails transition("lot-9", "in_escrow")
        assert open_escrow("lot-9", "STATE", "bob").ok == false
    }
}

What the toolchain says

Run on a fresh copy of the program at build time; the outputs are pasted unedited.

$ soma check land_registry.cell
✓ All checks passed.
$ soma test land_registry.cell
test RegistryTests ...
  ✓ assert record_deed("lot-7", "ada").ok == true
  ✓ assert open_escrow("lot-7", "eve", "bob").ok == false
  ✓ assert open_escrow("lot-7", "ada", "bob").ok == true
  ✓ assert open_escrow("lot-7", "ada", "mallory").ok == false
  ✓ assert_fails pending.set("lot-7", 2) — raised memory invariant violated on 'pending': pending >= 0 && pending <= 1 — rejected write of 2 (key "lot-7"); the slot is unchanged
  ✓ assert close_escrow("lot-7").ok == true
  ✓ assert owner_of("lot-7") == "bob"
  ✓ assert open_escrow("lot-7", "ada", "eve").ok == false
  ✓ assert open_escrow("lot-7", "bob", "eve").ok == true
  ✓ assert close_escrow("lot-7").ok == true
  ✓ assert owner_of("lot-7") == "eve"
  ✓ assert record_deed("lot-9", "ada").ok == true
  ✓ assert escheat("lot-9").ok == true
  ✓ assert_fails transition("lot-9", "titled") — raised invalid transition: escheated → titled. Current state: 'escheated'. Valid targets: []
  ✓ assert_fails transition("lot-9", "in_escrow") — raised invalid transition: escheated → in_escrow. Current state: 'escheated'. Valid targets: []
  ✓ assert open_escrow("lot-9", "STATE", "bob").ok == false

16 tests: 16 passed, 0 failed
$ soma verify land_registry.cell
Verifying land_registry.cell...

State machine 'parcel': 4 states, initial 'unrecorded'
  States: [escheated, in_escrow, titled, unrecorded]

  ✓ 4 states, 4 transitions
  ✓ all states reachable from 'unrecorded'
  ✓ terminal states: [escheated]
  ✓ no deadlocks
  ✓ liveness: every state can eventually reach a terminal state
  ✓ think-isolated: CTL safety properties hold regardless of LLM output (4 handlers, 4 literal transitions, 0 dynamic)
  ✓ termination: all 5 handlers structurally terminate
  ✓ refinement: handler `record_deed` ⟶ {titled}
  ✓ refinement: handler `open_escrow` ⟶ {in_escrow}
  ✓ refinement: handler `close_escrow` ⟶ {titled}
  ✓ refinement: handler `escheat` ⟶ {escheated}
  · transition sources: `record_deed`, `open_escrow`, `close_escrow`, `escheat` call transition(id, target) without declaring the source — the runtime refuses a move the graph forbids, but the proof does not see where the handler starts; `transition(id, from, to)` names the edge (checked by `soma check`, refused at run time from any other state)

LandRegistry/invariants:

  ✓ invariant pending >= 0 && pending <= 1 — writer 'close_escrow' proven (writes 0)
  ✓ invariant pending >= 0 — writer 'open_escrow' proven by induction (writes open_sales + 1)
  ✓ invariant pending >= 0 && pending <= 1 — writer 'open_escrow' proven by induction (writes open_sales)
  ⚠ invariant pending >= 0 && pending <= 1 — runtime-checked (computed values): open_escrow → pending [pending <= 1] because `open_sales + 1` is only known to lie in [1, 2] — narrow it: `require (open_sales + 1) <= 1 else …`

14 passed, 1 warnings, 0 failures

  Temporal properties for 'parcel':
  ✓ deadlock_free — no deadlocks in any reachable state
Temporal: 1 passed, 0 failed
VERIFY OK

Builtins used

map, transition

Source file: /corpus/civic/land_registry.cell · examples/corpus/civic/land_registry.cell