feat(sidecar): JSON-family storage backend — plain / JSON-LD / NDJSON (V-L2-F3, #146)#148
Merged
Merged
Conversation
V-L2-F3. Re-opens the JSON sidecar capability dropped in #112/#144, now as a deliberately-scoped family with full parity to the runtime operations the SQLite path implements today. Manifest: - `[sidecar].storage = "json"` is accepted again; new `[sidecar].format` selects the encoding: plain (default) | ld (JSON-LD) | ndjson. - New `sidecar::StorageKind::resolve(storage, format)` is the single source of truth (Sqlite | Postgres | Json(JsonFormat)); `SqlDialect::from_storage` is folded into it. `validate`/`doctor`, `generate`, `drift`, `gc` defer to it, so they agree on the accepted set and reject typos/bad formats. Store (src/sidecar/json.rs): - One `SidecarData` model mirrors the verisimdb_* tables; the format is purely a codec over it, so octad operations are written once and are format-independent. JSON-LD emits @context + @graph of typed (@type/@id) nodes; NDJSON emits one `{"_table":…}` record per line; plain is the model. - Provenance (linear append, fork, verify_chain, fork_points) reuses `abi::ProvenanceEntry::compute_hash`, so hashing is identical across backends. Temporal (append_version, read_current, read_at, rollback_to) enforces monotonicity + exactly-one-current in code. Temporal drift reuses the storage-agnostic `tier1::drift::temporal_drift_score`. GC purges provenance/temporal(superseded)/lineage by age. - Writes are crash-safe (temp file + atomic rename); logical append-only, single-writer model documented. Commands: - `generate` emits a format-appropriate scaffold (sidecar_schema.{json,jsonld, ndjson}) for SQL→DDL parity; `drift` and `gc` dispatch to the json store. Tests: provenance (incl. fork + tamper), temporal (monotonic/one-current/ read_at/rollback), drift (matches the SQLite worked example), and gc mirror the SQLite suite across all three formats; resolver + codec + scaffold round -trips covered. Full suite green; clippy -D warnings and fmt clean. Closes #146. https://claude.ai/code/session_01S2xDQQU5o85N3xTpeFUSfN
#147 (test-only postgres validate + gc fixture) landed on main after this branch was pushed. Incorporated by keeping #147's postgres-storage validate test and reconciling the gc rejection test with #148's dispatch (postgres gc now reports "not yet implemented"; the json family is supported). https://claude.ai/code/session_01S2xDQQU5o85N3xTpeFUSfN
hyperpolymath
added a commit
that referenced
this pull request
May 30, 2026
… (V-L2-F3) (#152) Reconcile the decision record with main after a merge race: V-L2-F3 (#146, #148) reversed the V-L2-F2 json drop and implemented a JSON-family sidecar backend. Adds ADR-0012 (supersedes ADR-0011), nets the CHANGELOG to "Added: JSON-family backend", and lists json in the README example. Docs only. https://claude.ai/code/session_01Ux144vBDdySvLUqUrCgkT4
| @@ -0,0 +1,1291 @@ | |||
| // SPDX-License-Identifier: PMPL-1.0-or-later | |||
🔍 Hypatia Security ScanFindings: 81 issues detected
View findings[
{
"reason": "Action perpolymath/standards/.github/workflows/governance-reusable.yml@main\n needs attention",
"type": "unpinned_action",
"file": "governance.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action actions/checkout@v4 needs attention",
"type": "unpinned_action",
"file": "rust-ci.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action dtolnay/rust-toolchain@stable needs attention",
"type": "unpinned_action",
"file": "rust-ci.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action Swatinem/rust-cache@v2 needs attention",
"type": "unpinned_action",
"file": "rust-ci.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action actions/checkout@v4 needs attention",
"type": "unpinned_action",
"file": "rust-ci.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action dtolnay/rust-toolchain@master needs attention",
"type": "unpinned_action",
"file": "rust-ci.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Action Swatinem/rust-cache@v2 needs attention",
"type": "unpinned_action",
"file": "rust-ci.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in boj-build.yml",
"type": "missing_timeout_minutes",
"file": "boj-build.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in casket-pages.yml",
"type": "missing_timeout_minutes",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in casket-pages.yml",
"type": "missing_timeout_minutes",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
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.
V-L2-F3: JSON-family sidecar storage backend (#146)
Implements a real
jsonsidecar store covering plain JSON, JSON-LD, and NDJSON, with full parity to the runtime operations the SQLite path implements today. Re-opens the capability that #112/#144 dropped — at the maintainer's request — now deliberately scoped and built rather than aspirational.Manifest
[sidecar].storage = "json"is accepted again; new[sidecar].format=plain(default) |ld|ndjson.sidecar::StorageKind::resolve(storage, format)is the single source of truth (Sqlite | Postgres | Json(JsonFormat)); the oldSqlDialect::from_storageis folded into it.validate/doctor,generate,drift, andgcall defer to it, so they agree on the accepted set and reject typos / bad formats consistently.Store (
src/sidecar/json.rs)SidecarDatamodel mirrors theverisimdb_*tables; the format is purely a codec, so every octad operation is written once and is format-independent:@context+@graphof typed (@type/@id) nodes (genuine linked data);{"_table": …}record per line.append,append_fork,verify_chain,fork_points— reusingabi::ProvenanceEntry::compute_hash, so hashing is byte-identical to the SQLite backend.append_version(monotonic, exactly-one-current enforced in code),read_current,read_at,rollback_to.tier1::drift::temporal_drift_score.Commands
generateemits a format-appropriate scaffoldsidecar_schema.{json,jsonld,ndjson}(DDL-parity for SQL);driftandgcdispatch to the JSON store;postgresdrift/gcremain explicit "not yet implemented".Verification
cargo clippy --all-targets -- -D warningsandcargo fmt --checkclean.validate(newsidecar-storage-supportedcheck),generate(plain/ld/ndjson scaffolds incl. JSON-LD@context/@graph),gc, anddriftall work against a json manifest, and that a badformatis rejected with a clear message.Acceptance (#146)
storage = "json"+format = plain|ld|ndjsonparse, validate, round-trip; bad format rejected clearly.StorageKind::resolveis the single resolver;validate/doctoraccept json, reject typos.generateemits a format-appropriate scaffold;driftandgchonour the json store.SidecarConfigdocs + manifest template documentjsonandformat.Closes #146.
https://claude.ai/code/session_01S2xDQQU5o85N3xTpeFUSfN
Generated by Claude Code