Skip to content

fix: make repository metadata updates conflict-safe - #7090

Open
mo0ooo wants to merge 1 commit into
block:mainfrom
mo0ooo:codex/repo-protection-cas
Open

fix: make repository metadata updates conflict-safe#7090
mo0ooo wants to merge 1 commit into
block:mainfrom
mo0ooo:codex/repo-protection-cas

Conversation

@mo0ooo

@mo0ooo mo0ooo commented Aug 31, 2026

Copy link
Copy Markdown

Summary

Repository metadata updates currently stamp created_at as the observed
announcement plus one second. Once that announcement is more than 15 minutes
old, the relay's timestamp-drift gate permanently rejects repos protect set,
repos protect remove, and repos bind.

This change:

  • stamps read-modify-write updates with max(now, observed + 1);
  • adds one buzz-expected-revision tag naming the announcement the CLI read;
  • validates that revision atomically with the NIP-33 replacement under the
    existing Postgres coordinate lock;
  • keeps exact replay idempotent and suppresses duplicate/conflict side effects;
  • reports stale repository updates as the existing CLI conflict class (exit 5);
  • preserves tagless standard NIP-34 latest-wins behavior; and
  • documents the opt-in CAS semantics and relay-before-CLI rollout order.

The revision precondition closes the lost-update hole left by a timestamp-only
max(now, head + 1) fix: a delayed Buzz writer cannot use the fresh timestamp
to overwrite metadata that changed after its read.

Related issue

Fixes #2876
Fixes #4431
Fixes #4432

This supersedes the timestamp-only approaches in #2901, #4363, #4509, and
#6282 by pairing wall-clock freshness with an atomic revision check.

Testing

  • Rebased and re-verified at origin/main@c3132c3; exact PR tip
    5af1be774ffc22722eb6c48c89c38b551987bacb
  • cargo fmt --all -- --check (Rust 1.95.0): passed
  • CI-default (Redis unset) RUST_TEST_THREADS=2 cargo test --locked -p buzz-core -p buzz-cli -p buzz-db -p buzz-relay: passed; relay library 997
    passed, relay binary 13 passed, all doc tests passed
  • cargo test --locked -p buzz-db conditional_parameterized_replacement_allows_one_concurrent_writer_and_replay -- --ignored: 1 passed
  • cargo clippy --locked -p buzz-core -p buzz-cli -p buzz-db -p buzz-relay --all-targets -- -D warnings: passed
  • Independent fresh-frame review: blocker 0, major 0 after adding the missing
    conformance trace for conditional exact replay
  • Isolated Postgres/Redis/relay + real CLI:
    • moved a signed test announcement's stored timestamp from 2026-08-31 to
      2026-08-28; repos protect set succeeded and stored a current timestamp,
      the original metadata, one protection rule, and exactly one expected
      revision tag;
    • concurrent CLI writers produced accepted updates plus a deterministic stale
      conflict with process exit 5;
    • the final announcement retained all 24 accepted protection edits and
      exactly one expected-revision tag.

With Redis enabled, the full relay suite also exposed a pre-existing
demo_join_forwarded_arm_round_trips_echo cancellation bug on unmodified
origin/main: a 100ms drain tick can drop an in-progress framed receive. The
CAS files do not overlap that path; it is being fixed and reviewed separately
on codex/mesh-recv-cancel-safe instead of being folded into this PR.

No production relay deployment, PR merge, branch deletion, or external-account
call was performed.

Signed-off-by: GPT <9d2d69e45be446edf9645e5b4dd62801ce14ea9cd0ae43467cc48a663e6dae5f@buzz.local>
@mo0ooo
mo0ooo requested a review from a team as a code owner August 31, 2026 05:41
@github-actions

Copy link
Copy Markdown

🔐 Codex Security Review

Status: review required for the current range.

The current range is c3132c3ee982d194cd0198ad07b57ec8bd726e4e...5af1be774ffc22722eb6c48c89c38b551987bacb.
A new review must complete for this exact range. When manual authorization
is required, a Block organization member must comment exactly
@buzz-security-review 5af1be774ffc22722eb6c48c89c38b551987bacb to authorize a new review.
Any previous review applies only to its recorded range.

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