Most formats answer no by construction. Markdown puts a link inside a string and forgets it; RDF keeps the graph and loses the document. BendScript attaches the edge to the span — this exact phrase cites that exact phrase — so the prose and the graph are one object with one identity. Whether that survives contact with a language model is the interesting half, and it is the half nobody here has measured.
A typed inline link facet is a mark on a span of text that carries a predicate and a target. It is not metadata about the document and it is not a footnote — it is part of the sentence, and it expands deterministically into an edge in the document's graph.
The underlined run of text is a span. The pill is the predicate. The tail is a bend: URI that resolves to a span inside another document. On parse, that mark expands into an edge — deterministically and idempotently, so expanding twice adds nothing. A link mark with no predicate expands into no edge at all, which is how an ordinary hyperlink stays an ordinary hyperlink.
A single status for this domain would be a lie in one direction or the other. One artifact answers on the deployed domain, one is a package with a test suite, and one is a draft document.
Paste a .bend.json document; it parses, validates against §2/§3, expands link marks into edges and computes the content address. All of it client-side — no request leaves the browser and there is nothing to sign in to.
The reference parser, validator, canonicaliser, link-mark expander and content-address function, plus the §8 drift harness. TypeScript, two runtime dependencies, Node 20+.
v0.1 draft. Six primitives, one strict round-trip guarantee (§8.1.1), one measured round-trip property (§8.1.2), five reserved vocabularies and a gating adoption section (§14).
The spec distinguishes two round-trips sharply, and only one of them is a guarantee. §8.1.1 — that a parser returns the same structure it was handed — is deterministic, testable, and checked below. §8.1.2 — that a frontier model can edit a document and leave the graph intact — is measured, and the measurement has not happened.
The claim the whole format is built for: that a frontier model can modify a .bend document and leave the graph intact. The harness, the drift metric and the thresholds are written and tested; what has never happened is a run against a real model.
The spec says an Elixir, Rust or plain-HTML implementation MUST produce the same id for the same document. One TypeScript implementation cannot demonstrate that; it can only fail to contradict it.
§14 is gating: v0.1 is not final until at least one product has committed to bend: URIs and shipped a vocabulary implementation. Graphonomous is the named first adopter and has not started.
There is no .bend text syntax. The canonical form is JSON and it is meant to be produced by editors, not typed. A projection is deferred to v0.2 and the spec does not pretend otherwise.
The corpus files are checked into this repository. This build imports the published package, parses each one, expands its link marks and computes its content address — and refuses to emit the page if any value disagrees with the frozen record beside it. A number cannot be hand-written onto this site. The ids are the fixture a second implementation has to reproduce.
| Corpus document | Structure | Graph | Vocabulary | Document id (CIDv1, json multicodec, sha2-256) |
|---|---|---|---|---|
| plain prose | 1 blocks | 0 edges | core | bagaaiera2r4gqoyqnoqmwdlsu6xnjvi5ney5wywtliyqy6r73zi6il244uca |
| heading paragraph | 2 blocks | 0 edges | core | bagaaieraiim2khmj2cwp2ksuapfi2ir3cgg75aybu7q2ihtd64jwpkpqyzvq |
| marks | 1 blocks | 0 edges | core | bagaaierafmp7ebm2svksve3jjn5oj6ygcbyiyutvnmjdmlkxbz6gkjv26umq |
| typed link | 1 blocks | 1 edges | core | bagaaiera32ml6rat5sqdaxkcn7xgtxgko4v7jl4jjxaw4jghevtk76wmux6q |
| document edges | 1 blocks | 1 edges | core | bagaaieraqap4kuslufcrm6pes65oklewm3dl6oyeetdka7r6td2u4ks4pkba |
| list quote code | 4 blocks | 0 edges | core | bagaaieratq54d4wuiz2ln2sowdiyttudxqc5z72wrww6buixf3vngq6w6h5a |
| memory vocab | 1 blocks | 1 edges | bendscript.memory.v1 | bagaaierac2zyr2473k7eaiyzgbdqayjygkpw367gogbteeo3rya6bm5bfqgq |
| nested lists | 1 blocks | 0 edges | core | bagaaiera6tbxyy25nl4vvniqdjkvaqywevdrxlsnav2f6qpqgbehexaccd2q |
| embed divider | 5 blocks | 0 edges | core | bagaaierawepfijfqdskngazha4zlcqljat6wbeivxy5h2mo5jqckx5z5w42a |
| multi mark span | 1 blocks | 0 edges | core | bagaaierapwrgybul23z2fcdyacwsreuv7mvmv5vzpaifjijiko7oonkob74a |
| untyped link | 1 blocks | 0 edges | core | bagaaiera4v4pqmr6hft3rqsxjme73f3hig6ydydagj4ye2vxlp5mv2hgrvcq |
| all core predicates | 1 blocks | 9 edges | core | bagaaierao57xbtz5sftwdjbebqwibr2mvyphfoqgitzgg7u2zapybq2rxasa |
| edge meta | 2 blocks | 2 edges | core | bagaaieraedf5g6fxovfcu7tntj6luaogdsnxfgkn3wtp7736cwvnreh4nr4q |
| supersedes tombstone | 1 blocks | 1 edges | core | bagaaieraioih54rw6lslw3tlbnjdm3peaubgc6doksablcftbvnufhfqefea |
| argument vocab | 3 blocks | 2 edges | bendscript.argument.v1 | bagaaierazgxlyz2ny6qeqx7lgydflsfcx5uaxygc4k4frhgpssqzrd553pwa |
| spec vocab | 4 blocks | 2 edges | bendscript.spec.v1 | bagaaieraxh4hhtg7fgb6k6mm46avsc6waesgcd5uke7nlur6bg5jl6zffx3a |
| cross doc edges | 3 blocks | 6 edges | core | bagaaieravie4fk37o5wsudcy3vy7op66cymiekcr4nxavrnm3gariwayhana |
| unicode emoji | 3 blocks | 0 edges | core | bagaaieraqb3y54k6ciew5idcbsq2buloipstw3nw2z45usgzv2brwsl7vcba |
| large document | 10 blocks | 3 edges | core | bagaaieraqryv6avv3c66ygpweuo2dqlicpukim4earoq5m3its7mlqeztfsq |
| adversarial | 3 blocks | 1 edges | core | bagaaierayubxtbbx5tvt43x52ov6yni4ww7kvddzyf4ao2z7dsxa742xuqga |
Each row was produced by importing the compiled library, parsing the file at ./test-corpus/v0.1/, expanding its link marks into edges per §2.5.1, validating it against §2/§3, and hashing the JCS-canonical { blocks, edges } with sha2-256 wrapped as a CIDv1. Then the document was re-serialised, re-parsed and re-hashed, and the two ids compared — §8.1.1 exercised at build time rather than cited. id and meta are excluded from the hash, so editing metadata does not invalidate the address (§5.1).
Until this revision the subtitle of this site read deterministic JSON · LLM-round-trippable, and the comparison against Markdown ended with the sentence Round-trip a doc through an LLM and the graph survives. Both state §8.1.2 as an established property. It has never been run against a language model.
What exists is the machinery: the drift metric with its five components, the median and P95 aggregation, the threshold verdict, and four mock models named identity, small-edit, lossy and garbage that exercise each failure mode. The mocks prove the harness measures something. They cannot prove what it would measure. The spec itself is careful here — §8.1.1 is a hard MUST and §8.1.2 is explicitly “a measured property, not a guarantee” — and the landing page had quietly collapsed the two into one.
The fix is structural rather than careful. Those two strings are now in the publication gate's blocklist and any page that reinstates one is refused, except inside this paragraph, because naming the wrong claim is what a retraction is. The claim comes back when a run comes back, and not before.
Every number here is a measurement with a date on it, and measurements go stale. The form below is a real form with a real action: it posts to formspree.io when you press the button, and it works with JavaScript off. The script that upgrades it to an inline reply prints “sent” only when the endpoint actually answers 2xx — a form that says thank-you on submit and drops the message is the exact failure this page argues against. If you would rather leave a public trail, open an issue instead.