feat(sidecar): cross-process locking + atomic writes, and wire provenance/history CLI (V-L2-F4, #150)#151
Merged
Conversation
) V-L2-F4 — hardening + CLI follow-up to the JSON sidecar (#146). Harden the JSON store: - Cross-process write locking (src/sidecar/lock.rs): dependency-free advisory `<path>.lock` (O_EXCL create_new) with retry/backoff and stale-lock steal, RAII release. `json::with_locked` holds it across the load→mutate→save cycle; `gc` apply now goes through it. Documents the existing atomic temp-file + rename durability (readers always see a complete file). Wire the stub CLI subcommands (both sqlite + json backends; postgres refuses): - `provenance <entity>`: prints the chain, verification status, and any fork points (ADR-0010). - `history <entity> [--at <RFC3339>]`: lists temporal versions, or the point-in-time snapshot per modality. Bad `--at` → clean error. Docs + config: - README: "Sidecar storage backends" section (storage/format + per-command backend matrix); rustdoc throughout. - examples/json-sidecar/ NDJSON example; blog-db notes the json option. - Version 0.1.0 -> 0.2.0; CHANGELOG [0.2.0] entry. Tests: lock acquire/release/contention/stale-steal; end-to-end CLI test (tests/sidecar_cli_test.rs) seeds via the locked write path (real hashes) and drives provenance/history through the built binary. Full suite green; clippy -D warnings and fmt clean. Refs #150. https://claude.ai/code/session_01S2xDQQU5o85N3xTpeFUSfN
This was referenced May 30, 2026
hyperpolymath
added a commit
that referenced
this pull request
May 30, 2026
) Document V-L2-F4 (#150, shipped in #151): add ADR-0013 (json sidecar cross-process locking + atomic writes + provenance/history CLI), refine ADR-0012's single-writer note to reference it, add the CHANGELOG.md entry, and extend the .claude read-only permission allowlist. Docs + config only. https://claude.ai/code/session_01Ux144vBDdySvLUqUrCgkT4
| @@ -0,0 +1,168 @@ | |||
| // SPDX-License-Identifier: PMPL-1.0-or-later | |||
🔍 Hypatia Security ScanFindings: 82 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.
Hardening + CLI follow-up to the JSON sidecar (#146). Closes #150.
Harden the JSON store
src/sidecar/lock.rs): dependency-free advisory<path>.lock(O_EXCLviacreate_new) with retry/backoff and stale-lock steal (a lock older than the staleness window is reclaimed, so a crashed writer can't wedge the sidecar), RAII release on drop.json::with_locked(path, fmt, |store| …)holds the lock across the whole load → mutate → save cycle;gcapply now runs through it (dry-run stays lock-free/read-only).renamedurability already insave()— a concurrent reader always sees a complete file, never a partial one. The one documented difference from SQLite (engine-serialised) is now closed for the single-host case.Wire the stub CLI subcommands (sqlite and json; postgres refuses)
provenance <entity>— prints the entity's chain,verify_chainstatus, and any fork points (ADR-0010).history <entity> [--at <RFC3339>]— lists temporal versions, or the point-in-time snapshot per modality; bad--at→ clean error.Docs + config
format+ per-command backend matrix) + rustdoc throughout.examples/json-sidecar/NDJSON example;blog-dbnotes the json option.CHANGELOG.adoc[0.2.0]entry..claude/settings.jsonpermission allowlist was blocked by the harness self-modification guardrail (an agent can't widen its own permissions). Left out — see the PR thread / my message; you can add it directly.Verification
tests/sidecar_cli_test.rsthat seeds via the locked write path (real hashes) and drivesprovenance/historythrough the built binary.cargo clippy --all-targets -- -D warningsandcargo fmt --checkclean; MSRV-conservative (edition 2024 / 1.85).Acceptance (#150)
provenance/historywork on sqlite + json (tests cover json end-to-end).fmt/clippy/testgreen at source.https://claude.ai/code/session_01S2xDQQU5o85N3xTpeFUSfN
Generated by Claude Code