Skip to content

docs(rfc): propose model checking protocols with TLA+ - #827

Draft
behinddwalls wants to merge 1 commit into
mainfrom
tla-exploration
Draft

behinddwalls wants to merge 1 commit into
mainfrom
tla-exploration

Conversation

@behinddwalls

@behinddwalls behinddwalls commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Why?

Nine of our last eleven serious bugs were protocol bugs between controllers or services: dead letters, lost acks, CAS races, dedup. Every one was found by a demo run, a hung test, or a reviewer, never by a test written to find it. More e2e coverage cannot fix that, because each run samples one ordering and each pinned ordering needs a hand-built lever.

What?

  • doc/rfc/tla-plus.md: proposal covering when a change needs a TLA+ spec, the spec/{domain}/{protocol}/ layout, CI, staged ties to the Go code, a rollout with a stop criterion, and why e2e and integration tests cannot close the gap.
  • spec/submitqueue/landoutcome/: a spec of a batch going from landing to terminal across orchestrator and Runway, plus a matrix of 24 DLQ and Runway design combinations with the expected verdict for each. It found Land and landsignal DLQs fail a landing batch that Runway goes on to merge #819 and Runway DLQ answers FAILED for a merge whose push already landed #820, and showed that both obvious fixes are wrong.
  • tool/tlc/: a Python runner and a tlc_matrix_test macro. The TLA+ tools JAR is pinned in MODULE.bazel and runs on a downloaded JDK (--java_runtime_version=remotejdk_21), so nobody installs Java or fetches a JAR, locally or in CI.

Test Plan

✅ bazel test //spec/submitqueue/landoutcome:matrix_test: all 24 verdicts match, in about 6s; --runs_per_test=10 stable
✅ a deliberately wrong expectation fails the test
✅ make tidy, make gazelle, and make fmt leave the tree unchanged; license linter; //tool/docsite:site_test

Issue

Part of #819, #820

🤖 Generated with Claude Code

## Summary

### Why?

Nine of our last eleven serious bugs were protocol bugs between controllers or services: dead letters, lost acks, CAS races, dedup. Every one was found by a demo run, a hung test, or a reviewer, never by a test written to find it. More e2e coverage cannot fix that, because each run samples one ordering and each pinned ordering needs a hand-built lever.

### What?

- `doc/rfc/tla-plus.md`: proposal covering when a change needs a TLA+ spec, the `spec/{domain}/{protocol}/` layout, CI, staged ties to the Go code, a rollout with a stop criterion, and why e2e and integration tests cannot close the gap.
- `spec/submitqueue/landoutcome/`: a spec of a batch going from `landing` to terminal across orchestrator and Runway, plus a matrix of 24 DLQ and Runway design combinations with the expected verdict for each. It found #819 and #820, and showed that both obvious fixes are wrong.
- `tool/tlc/`: a Python runner and a `tlc_matrix_test` macro. The TLA+ tools JAR is pinned in `MODULE.bazel` and runs on a downloaded JDK (`--java_runtime_version=remotejdk_21`), so nobody installs Java or fetches a JAR, locally or in CI.

## Test Plan

✅ `bazel test //spec/submitqueue/landoutcome:matrix_test`: all 24 verdicts match, in about 6s; `--runs_per_test=10` stable
✅ a deliberately wrong expectation fails the test
✅ `make tidy`, `make gazelle`, and `make fmt` leave the tree unchanged; license linter; `//tool/docsite:site_test`

## Issue

Part of #819, #820

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant