soma.cell

Soma 2.5.0 — 2026-09-18

This page describes Soma as of release 2.5.0. Some of it may have changed since: the current release is 3.2.4, and the current language is in the guide.

The agent-experience release. Nine cycles of fresh AI agents (none had seen Soma) built services, ported Python/Java/TypeScript/Go/Ruby programs, ran data jobs and LLM pipelines, and attacked the prover, the runtime and the parser — learning only from the website. Every finding below was reproduced, fixed, and pinned by a regression test; the whole repository (1,405 .cell files) was re-run through check / verify / test after every batch.

Soundness and atomicity

  • A handler with persistent slots is one SQLite transaction: a process killed mid-handler (kill -9) leaves nothing of it on disk (writes used to commit one statement at a time). every / after ticks are rolled back when they raise, like handlers.

  • Slots give back exactly what they stored: an Int beyond 64 bits stayed a String; records keep their field order; .keys / .values are sorted.

  • Slot value types are enforced on every write (Map<String, Int> refuses a String, 1.5 or 1.0; Map<String, Pay> refuses a plain map).

  • List slots: rows[i] = v, rows[i].f = v, rows.delete(i) used to be silently dropped.

  • The prover no longer issues false ✓: a require in a loop that may run zero times, bindings that shadow a narrowed name, interval overflow past 2^53, termination without a lower-bound base case, cost bounds that skipped every blocks and delegate, liveness that assumed guards pass (now said).

  • The prover proves more: a require counts for the writes of its own block, early exits (if n >= 1 { return … }), require a + b <= K on the written expression, one slot's invariant chained through a local, size / len(slot) invariants, deletes against value invariants. Every ⚠ says why.

  • request is never an HTTP endpoint (a GET could run a POST route); path segments are percent-decoded; CORS on every response.

  • A bare call to a name two cells define is a check error (it resolved at random); * edges no longer fire from states a program stopped declaring.

Language and builtins

Toolchain

  • soma check catches what used to fail at run time: native-only primitives outside [native], what the native codegen refuses (buffer re-binding, list returns, stepped ranges, literal / 0), break outside a loop, transition() arity, values thrown away (let j = 1 2), rules outside a test cell, empty test cells, writes to a loop copy (warning), emit with no listener (warning). 10 000 nested blocks no longer crash it.

  • soma verify --strict repeats the ⚠ lines by the verdict and always ends with one verdict line; orphan [verify] properties fail.

  • soma test --json records carry rule, message, left/right, raised; assert_fails … matching matches the kind too; mock works for any handler, Cell.handler, now, and builtins such as http_post.

  • soma serve: --no-schedule, an llm: start-up line, endpoints listed, whitespace-padded JSON bodies accepted, stored-data audit at start-up (undeclared states, invariant violations, re-typed values, renamed slots) — also under soma run.

  • soma run --fresh; .soma_data/ lives beside the program; exact big-Int CLI arguments. soma fix repairs ;, => arms, -> T on handlers, null/True. soma describe --json lists sum types.

Site and docs

  • New docs/operations.md (failure modes, statuses, exit codes, migration guide, environment variables); serving/guarantees/reference corrected against the binary; builtins regenerated from the compiler; the landing page links status, guarantees and serving, and states what verify proves.

  • The soma init starter and the corpus exemplars pass --strict.