Skip to main content

Crate blockworx_doc

Crate blockworx_doc 

Source
Expand description

The commit log: the document’s only authoritative representation.

A document is an append-only history of typed ops. Everything else — the editor’s document state, routed geometry, spatial indexes — is derived from it and can be thrown away and rebuilt. That inversion is what makes undo and an audit trail cheap: the log holds every edit that ever landed, so a step back is another commit rather than an erasure.

The layering is strictly one-way:

commit log  ──fold──▶  document  ──solve──▶  derived  ──▶  caches

Order comes from a process, not a protocol: the Repo assigns each accepted commit the next Rev, so the total order on writes is submission order and nothing else participates in establishing it. That is why there are no clocks, no actor ids, no content-addressed history, and no merge pass here.

Five rules keep it honest, and every one of them is load-bearing:

  1. All state is writes, creates, and deletes. An op names one entity and one field of it, and the last write to land stands, so the document is a function of the ops in log order. An op that does not reduce to those three breaks it.
  2. The fold is pure, and it is the only writer. try_apply folds into a new document, so a refused commit cannot leave a partial write behind and consumes no rev. No I/O, no clock, no randomness, and no re-running of the logic that produced an op — ids are minted before an op is recorded, never during replay.
  3. Nothing derived is ever stored in the log. Solver output is a function of the whole document rather than of any one op, so it has no write order to merge under and must be recomputed instead.
  4. Unknown encodings are refused, never skipped. Half-loading a log written by a newer build forks the document silently. The decode boundary is a trust boundary — a log is a file the user’s tools can reach — so values arriving through it are range-checked and refused, never clamped.
  5. Global invariants are ingress preconditions, not repairs. One apply point means a cycle or a dangling reference can be refused before it is sequenced, rather than voided after the fact.

Per-kind structure is generated, not transcribed: one field list per entity in block_model expands through the entity! macro to the struct, its update vocabulary, and the Entity impl — so a field cannot exist without a way to write it, and neither can drift from the other.

See docs/single-author-playbook.md for the design and docs/doc-ng-design-notes.md for why each piece is shaped as it is.

Modules§

block_model
The block model: entities and namespaces of the document. Rationale: docs/doc-ng-design-notes.md.
commit
The commit — the sealed unit of edit, undo, and review: a labeled batch of ops. The Rev and wall time are assigned as the commit is applied and live outside the payload. Rationale: docs/doc-ng-design-notes.md.
document
The document root and the index derived from it. Rationale: docs/doc-ng-design-notes.md.
entity
The Entity trait and the entity! macro that implements it: one field list per kind (block_model.rs) expands to the struct, its update vocabulary, and the trait impl — the mirror guard is generation, not transcription.
fixtures
Test builders shared across the module’s suites.
geometry
Geometry value types for the document model.
hash
A simple wrapper for the blake3 hasher
id
opcode
The opcode: one primitive edit, its target id bundled in. A commit’s payload is a Vec<OpCodes>; an op’s index in it is its Seq in the total write order. Rationale: docs/doc-ng-design-notes.md.
repo
The document, in one type: the folded Document and the commit log it folds. Rationale: docs/single-author-playbook.md.
rev
The commit sequence number — the first component of the total write order. Totality is structural: the head rev lives in the document and is minted only by a successful try_apply, so a refused commit consumes nothing and the log cannot gap. A Rev outside the fold is inert (try_apply takes no rev), so next stays public while minting stays module-private.
trail
The undo trail: which revs a session can step back to, and which forward.
values
Shared value enums: the closed vocabularies entity registers draw from. Serde variant names are wire tags — never rename or repurpose a variant; deprecate and add instead. Rationale: docs/doc-ng-design-notes.md.