Skip to content

refactor: one file per guarantee under laws/ and proofs/ - #17

Merged
ngngardner merged 2 commits into
mainfrom
refactor/split-laws
Nov 1, 2026
Merged

ngngardner merged 2 commits into
mainfrom
refactor/split-laws

Conversation

@ngngardner

@ngngardner ngngardner commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • One file per guarantee. Each guarantee is laws/<Name>.bend (its prose, then its quantified laws), proved by proofs/<Name>.bend. LAWS.bend and PROOF.bend only import them. That's 54 law files, no shared definition files and 4 lemma files (ArrayItemsRoundTrip, BoolCharStringFacts, CompareSelfEqual, InitializeResultShape), replacing the 2.4k-line LAWS.bend and 1.8k-line PROOF.bend.
    • All 54 are SPEC.md's guarantees, one per row.
    • Six laws that two guarantees cite sit in the guarantee that states them, and the other guarantee says so with an also rests on: line: line_blank and line_message in BlankLinesGetNothing, line_decoded in LinesDecodedAsUtf8, ran_id in RepliesCarryRequestId, took_status_200 in ClientReadsReplies, and web_post in RevisionFromVersionHeader.
  • No requirement IDs.
    • SPEC.md's source notes (the three revisions, how sections are cited, what differs between revisions, the pure modules, the departure from schema.json) now head LAWS.bend, which also names the first file of each family.
    • Each section's intro heads that family's first file. The OpenAPI citation notes are in laws/OperationsFromPaths.bend.
    • The "left to prove" note for UTF-8 decoding is in laws/LinesDecodedAsUtf8.bend, which says it is pending.
    • IDs cited in src/, main.bend and the README are now law paths or (trusted in src/io.bend).
    • The table itself is kept as docs/SPEC.md, along with its Not implemented list. LAWS.bend and the README point to it.
  • Trust boundary, now # Trusted, not proved: comments on the code, or cites of the dependency's law files:
    • MCP-TRUST-1 (IO sequencing) goes on the src/io.bend header.
    • MCP-TRUST-2 (ezhttp) goes on the src/io.bend header too. It cites ezhttp's laws/BadRequestAnswers400.bend, laws/WithServesGetOctetsAndContext.bend, laws/FieldLookupIgnoresCase.bend, laws/DeadlineIsTimeout.bend and laws/OctetsDecodeAsUtf8.bend. Forking and max are cited as trusted in ezhttp's src/server.bend.
    • MCP-TRUST-3 (ezjson) is cited in laws/MessagesWrittenAsLines.bend (ezjson's laws/QuoteEscapesExactly.bend and laws/PrintIsCompactAndStable.bend) and in laws/UnparsedTextIsParseError.bend (ezjson's laws/ParsesExactlyJsonTexts.bend). The old row claimed ezjson proves a compact print of every well-formed value. ezjson proves that only for the print of a parsed value, so for values ezmcp builds, "no newline" is now stated as trusted.
    • MCP-TRUST-4 (the runner validates its inputs) goes on main.bend's "what a runner answers" section.
    • MCP-TRUST-5 (the stdin effect, and Base's write and print_err) goes on ezmcp.stdin in src/io.bend.
  • Helpers: one proof helper no proof reached (eq.or_true) is dropped.
  • bolt.bend drops def trace().

Depends on

Test plan

  • bend PROOF.bend → ALL PROOFS CHECK
  • Lint with bolt from #257: 40 errors, 0 warnings. All 40 are S005 stale # noqa: L001 (all in examples/), which main also shows under that bolt. Main has 41 errors there; the extra one is the C011 for def trace().
  • Bump the bolt pin after the release, then nix flake check

🤖 Generated with Claude Code

ngngardner and others added 2 commits October 31, 2026 23:35
SPEC.md, a 2.4k-line LAWS.bend and a 1.8k-line PROOF.bend had to be read
side by side, matched up by ID tags. Each guarantee is now
laws/<Name>.bend, its prose on top and its quantified laws under it,
proved by proofs/<Name>.bend. LAWS.bend and PROOF.bend only import them.

Lemmas several proofs use are under proofs/lemmas/, each named for what it
holds. Requirement IDs are gone: a file's name is its guarantee's. A law
two guarantees rest on sits in the one that states it, and the other says
`also rests on:`. SPEC.md's source notes (the revisions, how sections are
cited, the pure modules, the departure from schema.json) head LAWS.bend,
each section's intro heads that family's first file, the UTF-8 "left to
prove" note is in laws/LinesDecodedAsUtf8.bend, and the table itself,
with its Not implemented list, is kept as docs/SPEC.md. One proof helper
no proof reached (eq.or_true) is gone.

The trust boundary moves onto the code: the IO sequencing, ezhttp and the
stdin effect on src/io.bend, and the runner's duty on main.bend. ezjson's
printer is cited where laws/MessagesWrittenAsLines.bend rests on it, and
its parser in laws/UnparsedTextIsParseError.bend.

This needs a bolt that reads law and proof files by what LAWS.bend and
PROOF.bend import, and no longer runs `trace`; bolt.bend drops `trace`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bolt v1.22.0 reads law and proof files by what LAWS.bend and PROOF.bend
import, which this layout needs. Rules changed since the old pin, so some
noqa comments no longer silence anything (S005); they are removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ngngardner
ngngardner marked this pull request as ready for review November 1, 2026 03:40
@ngngardner
ngngardner merged commit 222124b into main Nov 1, 2026
4 checks passed
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