soma.cell

Container weight — the misdeclared box that breaks the ship

When the MSC Napoli was beached off Devon in 2007, investigators weighed the containers coming off her deck: 137 of 660 were more than 3 tonnes heavier than their declared weight — one was 20 tonnes over. Misdeclared container weights overload stacks, snap lashings, and capsize feeder ships. The IMO's answer was SOLAS VGM (2016): no verified gross mass, no loading. Period. Here the rule is structural. A container's gross mass lives behind a memory invariant capped at the ISO max for a 40-foot box (30,480 kg): the write that would overload it is REFUSED by the memory itself, and a container only reaches the `laden_aboard` state through `vgm_certified` — there is no path from packing straight onto the ship.

A Soma program from the logistics part of the verified corpus: 97 lines, cells ContainerYard, SolasVgm. It passes soma check with soma 3.2.4.

How it is built

The cell ContainerYard declares 4 signals in its face: stuff_cargo(box_id: String, kg: Int) -> Map, certify_vgm(box_id: String) -> Map, load_aboard(box_id: String) -> Map and gross_kg(box_id: String) -> Int; keeps 1 memory slot: gross (Map<String, Int>, persistent and consistent) under the invariant gross >= 0 && gross <= 30480. Its state machine container starts in packing and allows 3 transitions: packing -> vgm_certified, vgm_certified -> packing and vgm_certified -> laden_aboard. laden_aboard is terminal. Handlers: stuff_cargo (line 41), certify_vgm (line 54), load_aboard (line 63) and gross_kg (line 69).

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

Generated from soma describe on this file.

The source

container_weight.cell

// ============================================================================
// CONTAINER WEIGHT — the misdeclared box that breaks the ship
// ============================================================================
//
// When the MSC Napoli was beached off Devon in 2007, investigators weighed
// the containers coming off her deck: 137 of 660 were more than 3 tonnes
// heavier than their declared weight — one was 20 tonnes over. Misdeclared
// container weights overload stacks, snap lashings, and capsize feeder
// ships. The IMO's answer was SOLAS VGM (2016): no verified gross mass,
// no loading. Period.
//
// Here the rule is structural. A container's gross mass lives behind a
// memory invariant capped at the ISO max for a 40-foot box (30,480 kg):
// the write that would overload it is REFUSED by the memory itself, and
// a container only reaches the `laden_aboard` state through `vgm_certified`
// — there is no path from packing straight onto the ship.
// ============================================================================

cell ContainerYard {
    face {
        signal stuff_cargo(box_id: String, kg: Int) -> Map
        signal certify_vgm(box_id: String) -> Map
        signal load_aboard(box_id: String) -> Map
        signal gross_kg(box_id: String) -> Int
    }

    memory {
        // tare (3,800 kg) + cargo. ISO 40ft max gross: 30,480 kg.
        gross: Map<String, Int> [persistent, consistent]
        invariant gross >= 0 && gross <= 30480
    }

    // No edge from `packing` to `laden_aboard`: VGM first, always.
    state container {
        initial: packing
        packing       -> vgm_certified
        vgm_certified -> packing          // re-opened: certificate void
        vgm_certified -> laden_aboard
    }

    on stuff_cargo(box_id: String, kg: Int) {
        if get_status(box_id) != "packing" {
            return map("ok", false, "reason", "container is sealed for VGM")
        }
        if kg <= 0 { return map("ok", false, "reason", "cargo weight must be positive") }
        let current = gross.get(box_id) ?? 3800     // empty box = tare weight
        let w = try { gross.set(box_id, current + kg) }
        if w.error != () {
            return map("ok", false, "reason", "REFUSED: {current} + {kg} kg exceeds 30480 kg max gross")
        }
        return map("ok", true, "gross_kg", current + kg)
    }

    on certify_vgm(box_id: String) {
        if gross.get(box_id) == () {
            return map("ok", false, "reason", "nothing stuffed — no mass to verify")
        }
        let r = try { transition(box_id, "vgm_certified") }
        if r.error != () { return map("ok", false, "reason", "{r.error}") }
        return map("ok", true, "vgm_kg", gross.get(box_id))
    }

    on load_aboard(box_id: String) {
        let r = try { transition(box_id, "laden_aboard") }
        if r.error != () { return map("ok", false, "reason", "no VGM on file: {r.error}") }
        return map("ok", true, "state", get_status(box_id))
    }

    on gross_kg(box_id: String) { return gross.get(box_id) ?? 0 }
}

cell test SolasVgm {
    rules {
        // legal stuffing accumulates from tare weight
        assert stuff_cargo("MSCU100", 20000).ok == true
        assert gross_kg("MSCU100") == 23800

        // the Napoli box: 20 tonnes over — memory refuses the write
        assert stuff_cargo("MSCU100", 20000).ok == false
        assert gross_kg("MSCU100") == 23800
        assert_fails gross.set("MSCU100", 43800)
        assert_fails gross.set("MSCU100", -1)

        // NO VGM, NO LOAD: packing -> laden_aboard does not exist
        assert_fails transition("MSCU100", "laden_aboard")
        assert certify_vgm("MSCU100").ok == true
        assert load_aboard("MSCU100").ok == true

        // aboard, the box is sealed: no more cargo, no re-certification
        assert stuff_cargo("MSCU100", 100).ok == false
        assert_fails transition("MSCU100", "packing")

        // an empty box cannot be VGM-certified
        assert certify_vgm("GHOST01").ok == false
    }
}

What the toolchain says

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

$ soma check container_weight.cell
✓ All checks passed.
$ soma test container_weight.cell
test SolasVgm ...
  ✓ assert stuff_cargo("MSCU100", 20000).ok == true
  ✓ assert gross_kg("MSCU100") == 23800
  ✓ assert stuff_cargo("MSCU100", 20000).ok == false
  ✓ assert gross_kg("MSCU100") == 23800
  ✓ assert_fails gross.set("MSCU100", 43800) — raised memory invariant violated on 'gross': gross >= 0 && gross <= 30480 — rejected write of 43800 (key "MSCU100"); the slot is unchanged
  ✓ assert_fails gross.set("MSCU100", -1) — raised memory invariant violated on 'gross': gross >= 0 && gross <= 30480 — rejected write of -1 (key "MSCU100"); the slot is unchanged
  ✓ assert_fails transition("MSCU100", "laden_aboard") — raised invalid transition: packing → laden_aboard. Current state: 'packing'. Valid targets: [vgm_certified]
  ✓ assert certify_vgm("MSCU100").ok == true
  ✓ assert load_aboard("MSCU100").ok == true
  ✓ assert stuff_cargo("MSCU100", 100).ok == false
  ✓ assert_fails transition("MSCU100", "packing") — raised invalid transition: laden_aboard → packing. Current state: 'laden_aboard'. Valid targets: []
  ✓ assert certify_vgm("GHOST01").ok == false

12 tests: 12 passed, 0 failed
$ soma verify container_weight.cell
Verifying container_weight.cell...

State machine 'container': 3 states, initial 'packing'
  States: [laden_aboard, packing, vgm_certified]

  ✓ 3 states, 3 transitions
  ✓ all states reachable from 'packing'
  ✓ terminal states: [laden_aboard]
  ✓ no deadlocks
  ✓ liveness: every state can eventually reach a terminal state
  ✓ think-isolated: CTL safety properties hold regardless of LLM output (2 handlers, 2 literal transitions, 0 dynamic)
  ✓ termination: all 4 handlers structurally terminate
  ⚠ refinement: declared transition `vgm_certified → packing` is never reached by any handler — spec may be aspirational or stale
  ✓ refinement: handler `certify_vgm` ⟶ {vgm_certified}
  ✓ refinement: handler `load_aboard` ⟶ {laden_aboard}
  · transition sources: `certify_vgm`, `load_aboard` 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)

ContainerYard/invariants:

  ✓ invariant gross >= 0 — writer 'stuff_cargo' proven by induction (writes current + kg)
  ⚠ invariant gross >= 0 && gross <= 30480 — runtime-checked (computed values): stuff_cargo → gross [gross <= 30480] because `current + kg` is only known to lie in [1, ∞) — narrow it: `require (current + kg) <= 30480 else …`

10 passed, 2 warnings, 0 failures

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

Builtins used

get_status, map, transition

Source file: /corpus/logistics/container_weight.cell · examples/corpus/logistics/container_weight.cell