Dns change control — no record goes live without passing validation
On October 4, 2021, a routine maintenance command at Facebook withdrew every BGP route to its DNS servers. An audit tool existed precisely to block commands like that — but a bug let the command bypass it. With DNS gone, facebook.com vanished for six hours, internal tools died, and engineers couldn't badge into the datacenter to fix it. The lesson is not "audit harder", it is: the bypass must not be a path. In this change pipeline `live` is only reachable through `validated` and `staged` — there is no drafted -> live edge for a buggy tool to take, and `soma verify` proves it. A reverted change is TERMINAL: you draft a new change with a new review, you never re-push the one that broke the internet. TTLs sit behind a memory invariant so no change can ship a record the resolvers would cache for a year.
A Soma program from the devops part of the verified corpus: 102 lines, cells DnsChanges, ChangeGateTests. It passes soma check with soma 3.2.4.
How it is built
The cell DnsChanges declares 5 signals in its face: validate_change(chg: String, ttl: Int) -> Map, stage_change(chg: String) -> Map, push_live(chg: String) -> Map, revert(chg: String) -> Map and change_state(chg: String) -> String; keeps 1 memory slot: ttl (Map<String, Int>, persistent and consistent) under the invariant ttl >= 30 && ttl <= 86400. Its state machine change starts in drafted and allows 5 transitions: drafted -> validated, validated -> staged, staged -> live, live -> reverted and staged -> reverted. reverted is terminal. Handlers: validate_change (line 46), stage_change (line 56), push_live (line 62), revert (line 68) and change_state (line 74).
The file also holds 1 test cell (ChangeGateTests) with 11 assertions, run by soma test.
The source
dns_change_control.cell
// ============================================================================
// DNS CHANGE CONTROL — no record goes live without passing validation
// ============================================================================
//
// On October 4, 2021, a routine maintenance command at Facebook withdrew
// every BGP route to its DNS servers. An audit tool existed precisely to
// block commands like that — but a bug let the command bypass it. With
// DNS gone, facebook.com vanished for six hours, internal tools died,
// and engineers couldn't badge into the datacenter to fix it.
//
// The lesson is not "audit harder", it is: the bypass must not be a
// path. In this change pipeline `live` is only reachable through
// `validated` and `staged` — there is no drafted -> live edge for a
// buggy tool to take, and `soma verify` proves it. A reverted change is
// TERMINAL: you draft a new change with a new review, you never re-push
// the one that broke the internet. TTLs sit behind a memory invariant
// so no change can ship a record the resolvers would cache for a year.
// ============================================================================
cell DnsChanges {
face {
signal validate_change(chg: String, ttl: Int) -> Map
signal stage_change(chg: String) -> Map
signal push_live(chg: String) -> Map
signal revert(chg: String) -> Map
signal change_state(chg: String) -> String
}
memory {
// seconds. 30 is the emergency floor, 86400 the cache ceiling.
ttl: Map<String, Int> [persistent, consistent]
invariant ttl >= 30 && ttl <= 86400
}
// The audit gate is the topology: every path to `live` passes
// through `validated`. `reverted` has no exit.
state change {
initial: drafted
drafted -> validated
validated -> staged
staged -> live
live -> reverted
staged -> reverted
}
on validate_change(chg: String, ttl_secs: Int) {
let w = try { ttl.set(chg, ttl_secs) }
if w.error != () {
return map("ok", false, "reason", "TTL out of bounds: {w.error}")
}
let r = try { transition(chg, "validated") }
if r.error != () { return map("ok", false, "reason", "{r.error}") }
return map("ok", true, "state", "validated")
}
on stage_change(chg: String) {
let r = try { transition(chg, "staged") }
if r.error != () { return map("ok", false, "reason", "{r.error}") }
return map("ok", true, "state", "staged")
}
on push_live(chg: String) {
let r = try { transition(chg, "live") }
if r.error != () { return map("ok", false, "reason", "{r.error}") }
return map("ok", true, "state", "live")
}
on revert(chg: String) {
let r = try { transition(chg, "reverted") }
if r.error != () { return map("ok", false, "reason", "{r.error}") }
return map("ok", true, "state", "reverted")
}
on change_state(chg: String) {
return get_status(chg)
}
}
cell test ChangeGateTests {
rules {
// THE FACEBOOK MOVE: push a drafted change straight to prod.
// The bypass is not an edge. It cannot be taken, buggy tool or not.
assert_fails transition("chg-bgp-77", "live")
assert_fails transition("chg-bgp-77", "staged")
// the only road: validate, stage, then live
assert validate_change("chg-bgp-77", 300).ok == true
assert stage_change("chg-bgp-77").ok == true
assert push_live("chg-bgp-77").ok == true
// the change that broke things is reverted — and stays dead
assert revert("chg-bgp-77").ok == true
assert_fails transition("chg-bgp-77", "live")
assert_fails transition("chg-bgp-77", "drafted")
// a poisonous TTL never validates: memory refuses the record
assert validate_change("chg-ttl-1yr", 31536000).ok == false
assert change_state("chg-ttl-1yr") == "drafted"
assert_fails ttl.set("chg-ttl-1yr", 5)
}
}What the toolchain says
$ soma check dns_change_control.cell
warning: parameter 2 of `validate_change`: the face calls it `ttl`, the handler `ttl_secs` — an HTTP JSON body is matched by NAME (the handler's), and `soma describe` publishes the face's: use one name
--> dns_change_control.cell:22:9
|
22 | signal validate_change(chg: String, ttl: Int) -> Map
| ^
✓ 1 warning(s), no errors.$ soma test dns_change_control.cell
test ChangeGateTests ...
✓ assert_fails transition("chg-bgp-77", "live") — raised invalid transition: drafted → live. Current state: 'drafted'. Valid targets: [validated]
✓ assert_fails transition("chg-bgp-77", "staged") — raised invalid transition: drafted → staged. Current state: 'drafted'. Valid targets: [validated]
✓ assert validate_change("chg-bgp-77", 300).ok == true
✓ assert stage_change("chg-bgp-77").ok == true
✓ assert push_live("chg-bgp-77").ok == true
✓ assert revert("chg-bgp-77").ok == true
✓ assert_fails transition("chg-bgp-77", "live") — raised invalid transition: reverted → live. Current state: 'reverted'. Valid targets: []
✓ assert_fails transition("chg-bgp-77", "drafted") — raised invalid transition: reverted → drafted. Current state: 'reverted'. Valid targets: []
✓ assert validate_change("chg-ttl-1yr", 31536000).ok == false
✓ assert change_state("chg-ttl-1yr") == "drafted"
✓ assert_fails ttl.set("chg-ttl-1yr", 5) — raised memory invariant violated on 'ttl': ttl >= 30 && ttl <= 86400 — rejected write of 5 (key "chg-ttl-1yr"); the slot is unchanged
11 tests: 11 passed, 0 failed$ soma verify dns_change_control.cell
Verifying dns_change_control.cell...
State machine 'change': 5 states, initial 'drafted'
States: [drafted, live, reverted, staged, validated]
✓ 5 states, 5 transitions
✓ all states reachable from 'drafted'
✓ terminal states: [reverted]
✓ 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 `validate_change` ⟶ {validated}
✓ refinement: handler `stage_change` ⟶ {staged}
✓ refinement: handler `push_live` ⟶ {live}
✓ refinement: handler `revert` ⟶ {reverted}
· transition sources: `validate_change`, `stage_change`, `push_live`, `revert` 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)
DnsChanges/invariants:
⚠ invariant ttl >= 30 && ttl <= 86400 — runtime-checked (computed values): validate_change → ttl because `ttl_secs` is a parameter (narrow it: `require ttl_secs >= 30 && ttl_secs <= 86400 else …`)
11 passed, 1 warnings, 0 failures
Temporal properties for 'change':
✓ deadlock_free — no deadlocks in any reachable state
Temporal: 1 passed, 0 failed
VERIFY OK