Skip to content

feat(sidecar): cross-process locking + atomic writes, and wire provenance/history CLI (V-L2-F4, #150)#151

Merged
hyperpolymath merged 1 commit into
mainfrom
claude/gracious-curie-HS03A
May 30, 2026
Merged

feat(sidecar): cross-process locking + atomic writes, and wire provenance/history CLI (V-L2-F4, #150)#151
hyperpolymath merged 1 commit into
mainfrom
claude/gracious-curie-HS03A

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Hardening + CLI follow-up to the JSON sidecar (#146). Closes #150.

Harden the JSON store

  • Cross-process write locking (src/sidecar/lock.rs): dependency-free advisory <path>.lock (O_EXCL via create_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; gc apply now runs through it (dry-run stays lock-free/read-only).
  • Atomic writes: documents and keeps the temp-file + same-dir rename durability already in save() — 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_chain 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.adoc [0.2.0] entry.
  • ⚠️ The requested .claude/settings.json permission 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

  • 145 lib unit tests (incl. lock acquire/release, contention timeout, stale-steal) + integration tests, incl. a new end-to-end tests/sidecar_cli_test.rs that seeds via the locked write path (real hashes) and drives provenance/history through the built binary.
  • cargo clippy --all-targets -- -D warnings and cargo fmt --check clean; MSRV-conservative (edition 2024 / 1.85).

Acceptance (#150)

  • JSON writes guarded by a cross-process lock; crash-safe atomic rename.
  • provenance/history work on sqlite + json (tests cover json end-to-end).
  • Docs, example, version/CHANGELOG updated. (settings.json blocked — flagged.)
  • fmt/clippy/test green at source.

https://claude.ai/code/session_01S2xDQQU5o85N3xTpeFUSfN


Generated by Claude Code

)

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
@hyperpolymath hyperpolymath marked this pull request as ready for review May 30, 2026 23:24
@hyperpolymath hyperpolymath merged commit 00fd80f into main May 30, 2026
11 of 20 checks passed
@hyperpolymath hyperpolymath deleted the claude/gracious-curie-HS03A branch May 30, 2026 23:24
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
Comment thread src/sidecar/lock.rs
@@ -0,0 +1,168 @@
// SPDX-License-Identifier: PMPL-1.0-or-later
@github-actions
Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 82 issues detected

Severity Count
🔴 Critical 3
🟠 High 7
🟡 Medium 72

⚠️ Action Required: Critical security issues found!

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

V-L2-F4: harden JSON sidecar (cross-process locking + atomic writes) and wire provenance/history CLI

3 participants