soma.cell

Judicial recusal — a conflicted judge cannot sit, and cases aren't shopped

Caperton v. A.T. Massey Coal (2009): while a $50M verdict against Massey was heading to West Virginia's Supreme Court, Massey's CEO spent $3M electing Justice Brent Benjamin to that court. Benjamin refused to recuse himself — twice — and cast the deciding vote to overturn the verdict. The U.S. Supreme Court held the Due Process Clause itself required recusal. The lesson: recusal cannot be left to the conflicted judge's own discretion. Here the conflicts register is consulted by the assignment machinery, not by the judge's conscience. And the second classic abuse — judge shopping, reassigning a case until a friendly bench appears — is a memory invariant: one case, one assignment, ever. The second assignment is a write the docket refuses.

A Soma program from the governance part of the verified corpus: 121 lines, cells Docket, RecusalTests. It passes soma check with soma 3.2.4.

How it is built

The cell Docket declares 5 signals in its face: declare_conflict(judge: String, party: String) -> Map, assign_case(case_id: String, judge: String, party_a: String, party_b: String) -> Map, hear(case_id: String) -> Map, rule(case_id: String) -> Map and bench_of(case_id: String) -> String; keeps 3 memory slots: seatings (Map<String, Int>, persistent and consistent) under the invariant seatings >= 0 && seatings <= 1, conflicts (Map<String, Int>, persistent and consistent) under the invariant conflicts >= 1 && conflicts <= 1 and bench (Map<String, String>, persistent and consistent). Its state machine court_case starts in filed and allows 3 transitions: filed -> assigned, assigned -> heard and heard -> decided. decided is terminal. Handlers: declare_conflict (line 50), assign_case (line 55), hear (line 71), rule (line 77) and bench_of (line 83).

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

Generated from soma describe on this file.

The source

judicial_recusal.cell

// ============================================================================
// JUDICIAL RECUSAL — a conflicted judge cannot sit, and cases aren't shopped
// ============================================================================
//
// Caperton v. A.T. Massey Coal (2009): while a $50M verdict against
// Massey was heading to West Virginia's Supreme Court, Massey's CEO
// spent $3M electing Justice Brent Benjamin to that court. Benjamin
// refused to recuse himself — twice — and cast the deciding vote to
// overturn the verdict. The U.S. Supreme Court held the Due Process
// Clause itself required recusal. The lesson: recusal cannot be left to
// the conflicted judge's own discretion.
//
// Here the conflicts register is consulted by the assignment machinery,
// not by the judge's conscience. And the second classic abuse — judge
// shopping, reassigning a case until a friendly bench appears — is a
// memory invariant: one case, one assignment, ever. The second
// assignment is a write the docket refuses.
// ============================================================================

cell Docket {
    face {
        signal declare_conflict(judge: String, party: String) -> Map
        signal assign_case(case_id: String, judge: String, party_a: String, party_b: String) -> Map
        signal hear(case_id: String) -> Map
        signal rule(case_id: String) -> Map
        signal bench_of(case_id: String) -> String
    }

    memory {
        // case -> assignments made. ONE. Re-rolling the wheel until a
        // friendly judge appears is unrepresentable.
        seatings: Map<String, Int> [persistent, consistent]
        invariant seatings >= 0 && seatings <= 1

        conflicts: Map<String, Int> [persistent, consistent]
        invariant conflicts >= 1 && conflicts <= 1

        bench: Map<String, String> [persistent, consistent]
    }

    // filed -> assigned -> heard -> decided (TERMINAL: the ruling stands;
    // relief comes from appeal in a HIGHER court, not from re-running this one)
    state court_case {
        initial: filed
        filed -> assigned
        assigned -> heard
        heard -> decided
    }

    on declare_conflict(judge: String, party: String) {
        conflicts.set("{judge}:{party}", 1)
        return map("ok", true, "judge", judge, "party", party)
    }

    on assign_case(case_id: String, judge: String, party_a: String, party_b: String) {
        // the register, not the judge's discretion, decides
        if conflicts.get("{judge}:{party_a}") != () || conflicts.get("{judge}:{party_b}") != () {
            return map("ok", false, "reason",
                "due process: {judge} has a registered conflict in {case_id}")
        }
        // THE WALL: one seating per case — no judge shopping
        let w = try { seatings.set(case_id, (seatings.get(case_id) ?? 0) + 1) }
        if w.error != () {
            return map("ok", false, "reason", "{case_id} already has its judge; no reshuffling")
        }
        transition(case_id, "assigned")
        bench.set(case_id, judge)
        return map("ok", true, "case", case_id, "judge", judge)
    }

    on hear(case_id: String) {
        let r = try { transition(case_id, "heard") }
        if r.error != () { return map("ok", false, "reason", "{r.error}") }
        return map("ok", true, "state", "heard")
    }

    on rule(case_id: String) {
        let r = try { transition(case_id, "decided") }
        if r.error != () { return map("ok", false, "reason", "{r.error}") }
        return map("ok", true, "state", "decided", "judge", bench.get(case_id))
    }

    on bench_of(case_id: String) {
        return bench.get(case_id) ?? "[unassigned]"
    }
}

cell test RecusalTests {
    rules {
        // Massey's CEO funds Benjamin's seat; the register knows
        assert declare_conflict("benjamin", "massey").ok == true

        // the Caperton assignment: structurally refused
        assert assign_case("caperton-v-massey", "benjamin", "caperton", "massey").ok == false
        assert get_status("caperton-v-massey") == "filed"
        assert bench_of("caperton-v-massey") == "[unassigned]"

        // an unconflicted judge sits; the case proceeds
        assert assign_case("caperton-v-massey", "starcher", "caperton", "massey").ok == true

        // judge shopping: the docket can hold only one seating
        assert assign_case("caperton-v-massey", "benjamin", "caperton", "massey").ok == false
        assert assign_case("caperton-v-massey", "maynard", "caperton", "massey").ok == false
        assert_fails seatings.set("caperton-v-massey", 2)
        assert bench_of("caperton-v-massey") == "starcher"

        // no hearing before assignment, no ruling before hearing
        assert_fails transition("fresh-case", "heard")
        assert_fails transition("fresh-case", "decided")

        // the case runs to judgment; decided is terminal
        assert hear("caperton-v-massey").ok == true
        assert rule("caperton-v-massey").judge == "starcher"
        assert_fails transition("caperton-v-massey", "heard")
        assert_fails transition("caperton-v-massey", "filed")

        // a conflict entry is a fact, not a dial: only 1 is representable
        assert_fails conflicts.set("benjamin:massey", 0)
    }
}

What the toolchain says

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

$ soma check judicial_recusal.cell
✓ All checks passed.
$ soma test judicial_recusal.cell
test RecusalTests ...
  ✓ assert declare_conflict("benjamin", "massey").ok == true
  ✓ assert assign_case("caperton-v-massey", "benjamin", "caperton", "massey").ok == false
  ✓ assert get_status("caperton-v-massey") == "filed"
  ✓ assert bench_of("caperton-v-massey") == "[unassigned]"
  ✓ assert assign_case("caperton-v-massey", "starcher", "caperton", "massey").ok == true
  ✓ assert assign_case("caperton-v-massey", "benjamin", "caperton", "massey").ok == false
  ✓ assert assign_case("caperton-v-massey", "maynard", "caperton", "massey").ok == false
  ✓ assert_fails seatings.set("caperton-v-massey", 2) — raised memory invariant violated on 'seatings': seatings >= 0 && seatings <= 1 — rejected write of 2 (key "caperton-v-massey"); the slot is unchanged
  ✓ assert bench_of("caperton-v-massey") == "starcher"
  ✓ assert_fails transition("fresh-case", "heard") — raised invalid transition: filed → heard. Current state: 'filed'. Valid targets: [assigned]
  ✓ assert_fails transition("fresh-case", "decided") — raised invalid transition: filed → decided. Current state: 'filed'. Valid targets: [assigned]
  ✓ assert hear("caperton-v-massey").ok == true
  ✓ assert rule("caperton-v-massey").judge == "starcher"
  ✓ assert_fails transition("caperton-v-massey", "heard") — raised invalid transition: decided → heard. Current state: 'decided'. Valid targets: []
  ✓ assert_fails transition("caperton-v-massey", "filed") — raised invalid transition: decided → filed. Current state: 'decided'. Valid targets: []
  ✓ assert_fails conflicts.set("benjamin:massey", 0) — raised memory invariant violated on 'conflicts': conflicts >= 1 && conflicts <= 1 — rejected write of 0 (key "benjamin:massey"); the slot is unchanged

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

State machine 'court_case': 4 states, initial 'filed'
  States: [assigned, decided, filed, heard]

  ✓ 4 states, 3 transitions
  ✓ all states reachable from 'filed'
  ✓ terminal states: [decided]
  ✓ no deadlocks
  ✓ liveness: every state can eventually reach a terminal state
  ✓ think-isolated: CTL safety properties hold regardless of LLM output (3 handlers, 3 literal transitions, 0 dynamic)
  ✓ termination: all 5 handlers structurally terminate
  ✓ refinement: handler `assign_case` ⟶ {assigned}
  ✓ refinement: handler `hear` ⟶ {heard}
  ✓ refinement: handler `rule` ⟶ {decided}
  · transition sources: `assign_case`, `hear`, `rule` 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)

Docket/invariants:

  ✓ invariant seatings >= 0 — writer 'assign_case' proven by induction (writes (seatings.get(case_id) ?? 0) + 1)
  ⚠ invariant seatings >= 0 && seatings <= 1 — runtime-checked (computed values): assign_case → seatings [seatings <= 1] because `seatings` has no known range
  ✓ invariant conflicts >= 1 && conflicts <= 1 — writer 'declare_conflict' proven (writes 1)

12 passed, 1 warnings, 0 failures

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

Builtins used

get_status, map, transition

Source file: /corpus/governance/judicial_recusal.cell · examples/corpus/governance/judicial_recusal.cell