docs(architecture): version-history design ADR + codebase inventory (#362)#212
Merged
Conversation
…#362) Design + codebase-inventory ADR gating the version-history build (C2-C5, #363-#366) for initiative #321. Docs only; no feature code. Chosen model: field-level change-event log (record_field_changes), one row per changed field per write, each badged by source (human/agent/automation/ mcp) via the #330 AgentPrincipal; debounced whole-content rich-text snapshots (document_versions); whole-record restore first with per-field revert as a documented fast-follow. Retention is plan-gated and tiny (Free none, Pro 1d, Business 7d, Enterprise 30d), Free = capture off. Structural undelete extends the #229 trash to databases/views/spaces. Scope is history/restore, NOT point-in-time workspace backup (#320/#322). Inventory: MN-231/PR #115 already shipped whole-record record_versions + list/restore API (RecordVersionsController) and the transactional capture hook in RecordsService.update() — C2-C5 EXTEND this, they do not replace it. The field-level log, source attribution, rich-text history, structural undelete, and the (MN-231-deferred) pruning job are additive. Indexed from CLAUDE.md per the repo ADR convention. Signed-off-by: ikrasovytskyi <i.krasovytskyi@owox.com>
ikrasovytskyi
enabled auto-merge
July 25, 2026 20:55
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
storyos-docs | a27f706 | Commit Preview URL Branch Preview URL |
Jul 25 2026, 08:55 PM |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Design + codebase-inventory ADR for the version-history initiative (#321), gating the C2–C5 build (#363–#366). Docs only — no feature code. Adds
docs/architecture/version-history.mdand indexes it fromCLAUDE.mdper the repo ADR convention.Chosen model
Field-level change-event log (
record_field_changes) — one row per changed field per write — each badged by source (human/agent/automation/mcp) via the #330 AgentPrincipal. Debounced whole-content rich-text snapshots (document_versions, snapshots over patches). Whole-record restore first, per-field revert a documented fast-follow off the same log. Structural undelete extends the #229 trash todatabases/views/spaces. Scope is history/restore, not point-in-time workspace backup (that's #320 export / #322 backup).Locked founder decisions the ADR is built around
Key inventory findings (what already exists)
record_versionstable (full priorvalues+titleper write), transactional capture inRecordsService.update(), andRecordVersionsController(GET …/versions,POST …/versions/:id/restore, reversible). C2–C5 EXTEND this, they do not replace it — it's the whole-record restore substrate and C3's backend.activity_eventsalready holds a display-shapeddiffper update but no queryable per-field rows and no source label.actorId(a user id); agent/automation/human writes are today indistinguishable.auth.via,AgentPrincipal, and the automation/MCP call sites exist, butsourceis net-new plumbing throughRecordsService.update/create.records/fields/space_documents/commentshavedeleted_at;databases/views/spacesdo not — structural undelete (C5) closes that. No hard-"Erase" endpoint or trash purge cron for records today.BillingService.getStatus+EntitlementsService(self-host short-circuits to unlimited); retention windows belong onPlanDefinplans.ts.documents/space_documentscarry only an optimistic-concurrencyversionint; C4 is fully net-new.Recommended build order
C2 (#363) field-level capture +
sourceplumbing + pruning job (extends MN-231; land with a write-path benchmark) → C3 (#364) whole-record restore UX + source badges (backend already exists) → C4 (#365) rich-textdocument_versions(debounced snapshots) → C5 (#366) structural undelete (deleted_aton databases/views/spaces). One migration in flight at a time (hard rule #1) — these serialize.Risks / open decisions flagged for the founder
Write amplification (mitigated by short retention + Free=off + batched inserts), rich-text snapshot size, relation revert semantics (relations live in
record_links, notvalues— a whole-record restore leaves relations untouched), avoiding double-counting agent writes, andactivity_eventsretention (separate from the paid history feature — product call).Verification:
pnpm docs:check(0 broken links) andpnpm lintboth pass locally. Docs-only; no SDK/migration surface touched.Workers Builds: storyos-docsis informational.Refs #321. Part of #362.