soma.cell

A simplified TCP connection state machine (active-open path)

closed -> syn_sent -> established -> fin_wait -> closed. This is a classic protocol automaton; the model checker proves that from any state the connection can return to `closed` (no half-open leaks) and that the handshake order cannot be skipped.

A Soma program from the state_machines part of the verified corpus: 58 lines, cells TcpState, TcpConnection, TcpTests. It passes soma check with soma 3.2.4.

How it is built

The cell TcpConnection declares 6 signals in its face: open_conn(id: String) -> String, syn_ack(id: String) -> String, close_conn(id: String) -> String, timeout(id: String) -> String, reset(id: String) -> String and phase(id: String) -> String. Its state machine conn starts in Closed and allows 6 transitions: Closed -> SynSent, SynSent -> Established, Established -> FinWait, FinWait -> TimeWait, TimeWait -> Closed and * -> Closed. Handlers: open_conn (line 31), syn_ack (line 32), close_conn (line 33), timeout (line 34), reset (line 35) and phase (line 36).

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

Generated from soma describe on this file.

The source

tcp_connection.cell

// A simplified TCP connection state machine (active-open path).
// closed -> syn_sent -> established -> fin_wait -> closed. This is a
// classic protocol automaton; the model checker proves that from any
// state the connection can return to `closed` (no half-open leaks) and
// that the handshake order cannot be skipped.

cell type TcpState {
    variants { Closed  SynSent  Established  FinWait  TimeWait }
}

cell TcpConnection {
    face {
        signal open_conn(id: String) -> String
        signal syn_ack(id: String) -> String
        signal close_conn(id: String) -> String
        signal timeout(id: String) -> String
        signal reset(id: String) -> String
        signal phase(id: String) -> String
    }

    state conn: TcpState {
        initial: Closed
        Closed      -> SynSent
        SynSent     -> Established
        Established -> FinWait
        FinWait     -> TimeWait
        TimeWait    -> Closed
        *           -> Closed
    }

    on open_conn(id: String)    { transition(id, SynSent)     return get_status(id) }
    on syn_ack(id: String)    { transition(id, Established) return get_status(id) }
    on close_conn(id: String) { transition(id, FinWait)     return get_status(id) }
    on timeout(id: String)    { transition(id, TimeWait)    return get_status(id) }
    on reset(id: String)      { transition(id, Closed)      return get_status(id) }
    on phase(id: String)      { return get_status(id) }
}

cell test TcpTests {
    rules {
        // full lifecycle
        assert open_conn("c1") == "SynSent"
        assert syn_ack("c1") == "Established"
        assert close_conn("c1") == "FinWait"
        assert timeout("c1") == "TimeWait"
        assert reset("c1") == "Closed"

        // a RST from any state returns to Closed (the * arrow)
        assert open_conn("c2") == "SynSent"
        assert reset("c2") == "Closed"

        // illegal: cannot reach Established without sending SYN first
        assert_fails syn_ack("c3")
        // illegal: cannot close a connection that was never established
        assert_fails close_conn("c4")
    }
}

What the toolchain says

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

$ soma check tcp_connection.cell
✓ All checks passed.
$ soma test tcp_connection.cell
test TcpTests ...
  ✓ assert open_conn("c1") == "SynSent"
  ✓ assert syn_ack("c1") == "Established"
  ✓ assert close_conn("c1") == "FinWait"
  ✓ assert timeout("c1") == "TimeWait"
  ✓ assert reset("c1") == "Closed"
  ✓ assert open_conn("c2") == "SynSent"
  ✓ assert reset("c2") == "Closed"
  ✓ assert_fails syn_ack("c3") — raised invalid transition: Closed → Established. Current state: 'Closed'. Valid targets: [SynSent]
  ✓ assert_fails close_conn("c4") — raised invalid transition: Closed → FinWait. Current state: 'Closed'. Valid targets: [SynSent]

9 tests: 9 passed, 0 failed
$ soma verify tcp_connection.cell
Verifying tcp_connection.cell...

State machine 'conn': 5 states, initial 'Closed'
  States: [Closed, Established, FinWait, SynSent, TimeWait]

  ✓ 5 states, 9 transitions
  ✓ all states reachable from 'Closed'
  ✓ reactive machine: no terminal state, and every reachable state can return to 'Closed'
  ✓ no deadlocks
  ✓ liveness: every reachable state can return to 'Closed' (reactive machine)
  ✓ wildcard transitions: * -> [Closed]
  ✓ think-isolated: CTL safety properties hold regardless of LLM output (5 handlers, 5 literal transitions, 0 dynamic)
  ✓ termination: all 6 handlers structurally terminate
  ✓ refinement: handler `open_conn` ⟶ {SynSent}
  ✓ refinement: handler `syn_ack` ⟶ {Established}
  ✓ refinement: handler `close_conn` ⟶ {FinWait}
  ✓ refinement: handler `timeout` ⟶ {TimeWait}
  ✓ refinement: handler `reset` ⟶ {Closed}
  · transition sources: `open_conn`, `syn_ack`, `close_conn`, `timeout`, `reset` 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)

13 passed, 0 warnings, 0 failures

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

Builtins used

get_status, transition

Source file: /corpus/state_machines/tcp_connection.cell · examples/corpus/state_machines/tcp_connection.cell