Quickstart
Set up the workspace, then scaffold a hub — a markdown file whose frontmatter anchors sentences to code:
surf init # writes surf.toml + creates hubs/surf new auth # creates hubs/auth.mdEdit it: write a claim and point at: at the symbol it describes.
---summary: How auth refresh rotation works.anchors: - claim: refresh rotation is single-use; reuse triggers global logout at: src/auth/refresh.ts > rotateRefreshToken---
# Auth
Prose a human (or agent) reads to understand this domain.Then drive the loop:
surf lint # does every anchor resolve to exactly one symbol?surf check # the gate — a brand-new claim is "unverified" until you seal itUNVERIFIED hubs/auth.md :: src/auth/refresh.ts > rotateRefreshToken run `surf verify`You’ve read the prose and confirmed it’s true, so seal it — this writes the hash back into the
frontmatter (verify only touches that one line):
surf verifysurf check # surf check: all anchored spans match their stored hashes.Now change the logic of rotateRefreshToken and run the gate again:
$ surf checkDIVERGED hubs/auth.md :: src/auth/refresh.ts > rotateRefreshToken stored 9b1c33ade8f1 → now 4d5e6f2a0b7c (magnitude: Small) claim: refresh rotation is single-use; reuse triggers global logoutsurf check: 1 divergence(s).The merge is blocked (non-zero exit) until someone re-reads the sentence. If it still holds,
surf verify re-seals; if it’s now false, fix the prose first. Reformatting, comments, or renaming
a local variable do not trip it — only logic does.
Machine-readable output for tooling and the optional reviewer plugin:
surf check --format json{ "version": 1, "divergences": [ { "hub": "hubs/auth.md", "claim": "refresh rotation is single-use; reuse triggers global logout", "at": "src/auth/refresh.ts > rotateRefreshToken", "kind": "changed", "old_hash": "9b1c33ade8f1", "new_hash": "4d5e6f2a0b7c", "new_code": "function rotateRefreshToken(...) { ... }", "prose": "refresh rotation is single-use; reuse triggers global logout", "magnitude": "small" } ]}Next: Authoring hubs for writing good claims and choosing granularity, or the Command reference.