Commits as signed envelopes on the resource: Tree::Envelopes, retention, attributable History - #1313
Conversation
|
Decision (accepted 2026-09-01, |
Add RFC-style decision documents, each with a "Decision needed by maintainer" box and consequences for open PRs: - runtime-boundary-decision.md: Rust decides, TS displays; twins only for pure fixtured functions; first AtomicNode slice. - authority-unit-decision.md: drive stays the identity/replication unit; additive zone chain is the rights unit; what #1254 must change. - commit-retention-floor-decision.md: envelope-on-resource floor; sequence #1274 -> #1313 -> #1254. - trust-model-decision.md: the node that owns the URL is trusted with plaintext; anything that only stores is blind. - schema-routes-decision.md: did:ad:frozen is the on-ramp; optional schema is policy; defaults fingerprint closes the repopulate gap. Index them under "Decisions pending" in planning/README.md. Claude-Session: https://claude.ai/code/session_019asLKBrBWY5ovyeCgtmdSd
* docs(planning): five architecture decision documents Add RFC-style decision documents, each with a "Decision needed by maintainer" box and consequences for open PRs: - runtime-boundary-decision.md: Rust decides, TS displays; twins only for pure fixtured functions; first AtomicNode slice. - authority-unit-decision.md: drive stays the identity/replication unit; additive zone chain is the rights unit; what #1254 must change. - commit-retention-floor-decision.md: envelope-on-resource floor; sequence #1274 -> #1313 -> #1254. - trust-model-decision.md: the node that owns the URL is trusted with plaintext; anything that only stores is blind. - schema-routes-decision.md: did:ad:frozen is the on-ramp; optional schema is policy; defaults fingerprint closes the repopulate gap. Index them under "Decisions pending" in planning/README.md. Claude-Session: https://claude.ai/code/session_019asLKBrBWY5ovyeCgtmdSd * docs(planning): match the decisions index to the documents Claude-Session: https://claude.ai/code/session_019asLKBrBWY5ovyeCgtmdSd * docs(planning): record the five architecture decisions as accepted All five RFCs accepted 2026-09-01. Status boxes record the outcome, the README table is renamed to "Decisions", and encryption.md is closed to "at-rest + vault" with an explicit reopen test. Claude-Session: https://claude.ai/code/session_019asLKBrBWY5ovyeCgtmdSd
️✅ There are no secrets present in this pull request anymore.If these secrets were true positive and are still valid, we highly recommend you to revoke them. 🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request. |
Ordinary content commits are applied and then discarded. Genesis, rights, parent, and destroy stay, including unflagged creations. Drop previous-commit validation, stop indexing Loro binaries as KV keys, and stop creating the /commits collection. Co-authored-by: joepmeindertsma <joepmeindertsma@gmail.com>
UI reads author and dates from the resource. History no longer offers Show Commit, the Sync page does not link commit ids, and sequential saves no longer set previousCommit. Co-authored-by: joepmeindertsma <joepmeindertsma@gmail.com>
Align public docs, README, changelogs, and test-coverage notes with apply-and-discard for ordinary content commits. Co-authored-by: joepmeindertsma <joepmeindertsma@gmail.com>
Proofs have to replicate with the resource. Preferred path is a sibling Loro envelopes container so snapshot and SYNC_PUSH carry the signed log. Co-authored-by: joepmeindertsma <joepmeindertsma@gmail.com>
3fa4336 to
27da3e1
Compare
CI failed on @tomic/lib format-check: the multi-line import of CommitBuilder / commitIdOf / Commit is a single-line import. Co-authored-by: joepmeindertsma <joepmeindertsma@gmail.com>
… History Every applied signed commit leaves its JSON-AD on the resource it changed, keyed pure_id || createdAt || signature, written in the apply transaction. Not a resource, not indexed. Retention per node: latest (default, the envelope that produced the current state) or all (a signed audit log), via --envelope-retention / ATOMIC_ENVELOPE_RETENTION. Every commit's Loro change carries a token (browser drain token; Rust builder and create_did now tag too), so an envelope maps to the History version it produced. envelopes::attribute_history verifies signatures with the apply code, credits each token to one envelope (the genesis carrier only to a genesis envelope), and reports completeness. Read paths: GET /history-attribution (read-gated), WASM ClientDb.historyAttribution, Store.getHistoryAttribution merging both. History shows by <agent> Verified / Unverified / Unattributed. The destroy envelope on the tombstone value (#1370) is now the subject's latest row in this tree; the tombstone is a marker again. Tests: lib envelopes (8), server it history_attribution, browser lib history-attribution (5), e2e history assertions. Planning: decision doc amended (no #1274 gating, retention knob), auditability doc now Building.
…fe VersionTitle - attribute_history read each envelope's tokens by importing its update into an empty doc; a browser delta has dependencies, sits pending there and lists no changes, so every browser edit came back with no tokens. Tokens are now read from the stored doc over the update's [start, end) range (AtomicLoroDoc::change_messages_in / update_range). Regression test with a real delta. - getLoroHistory strips the drain token from Version.message for display; expose it as Version.token so attributionForVersion can match it. - VersionTitle is split into flat pieces: the i18n extractor turned the element-spanning ternary into one placeholder message that rendered as [i18n-404:…] (the CI failure). Catalogues re-extracted.
Related Issues
Implements option C of
planning/completed/commit-retention-floor-decision.md(amended 2026-09-05 in this PR): commits are signed envelopes, kept per resource, not a queryable event log. Follows #1370 (signedSYNC_DIFF.removeCommits). #1274 and #1254 rebase after this.What
Commits are not resources. Ordinary content commits are not stored as
Tree::Resourcesrows after apply; genesis, rights/parent and destroy commits still are (AuthImpact::is_critical, and any commit that brings a resource into being).Value::LoroDocis not a KV index key. The/commitscollection is not created.CommitDetailreads author and date from the resource; History has no "Show Commit" link; the Sync page no longer links commit ids. Clients no longer setpreviousCommit;validate_previous_commitis gone.Signed envelopes live on the resource (
Tree::Envelopes). Every signed commit's JSON-AD is written in the apply transaction, keyedpure_id ‖ createdAt ‖ signature. Not a resource, not indexed. Retention per node:--envelope-retention latest(default: the envelope that produced the current state, the audit floor) orall(every envelope: a signed audit log). The destroy envelope #1370 put on the tombstone value is now the subject's latest row here.History is attributable. Every commit's Loro change carries a token (browser drain token; the Rust builder path and
create_didnow tag too).envelopes::attribute_historyverifies each envelope's signature with the apply code, credits each token to one envelope (the genesis carrier only to a genesis envelope, since the inline certificate is that proof), and reportscomplete. Read viaGET /history-attribution?subject=(read-gated), WASMClientDb.historyAttribution, andStore.getHistoryAttribution. History's version title showsby <agent> Verified,Unverified, orby peer … Unattributed. Never a guessed signer.Not in this PR: envelopes travelling in bulk sync and the vault pack (next, as a
removeCommits-style side map), secondary indexes over envelopes, session certificates (#1310). Seeplanning/auditability-loro-history.md→ Next.Checklist
lib/src/envelopes.rs,server/tests/it/history_attribution.rs,browser/lib/src/history-attribution.test.ts, e2e history assertions)docs/src/commits/versioning.md,docs/src/atomicserver/installation.md, planning docs,TESTING_COVERAGE.md)