Skip to content

Phase 2.5: multi-master write safety - bucket-root CAS (FM-1) + EIP-712 portable identity (FM-4) #32

@ehsan6sha

Description

@ehsan6sha

Phase 2.5 of the decentralization roadmap — make CONCURRENT masters safe where Stage A (functionland/pinning-service#46) made fenced failover possible. Gate for Stage B (vetted third-party storage-only operators).

Ships

  • FM-1 — bucket-root CAS: the per-bucket root pointer is currently guarded only by IN-PROCESS locks (fula-core/src/bucket.rs:428 per-bucket DashMap mutex, :432 registry persist lock) — two concurrent gateways writing one bucket = silent lost updates. Add compare-and-swap on the expected root CID (reject + bounded retry on mismatch) with pre-commit pinning of the new root blocks BEFORE the pointer flips, over a registry store readable by all masters. Flag-gated, default OFF (single-master behavior byte-identical when dark).
  • FM-4 — portable identity: EIP-712 wallet-signature auth as an ADDITIVE auth path (existing JWT/session auth untouched) so one identity works on any master without master-local secrets.
  • Auto-failover graduation: with CAS live, a wrongly-presumed-dead master becomes harmless — the Stage A runbook's fenced manual flip can graduate to health-based automatic failover.
  • join-as-master.sh storage-only profile (cross-repo, pinning-service): follower + ingest, no cluster write authority, no DB.

Verify (e2e, test infra)

Two gateways against the same stack: concurrent same-bucket writes -> both commit or one cleanly rejects+retries, NEVER silently lost (CAS race drill); unfenced failover during live writes loses nothing; EIP-712 login works against both masters with the same wallet; storage-only profile runs end-to-end on a third box/container.

Data-safety

CAS behind a flag; no auth removal; no migration rewrites; mixed-fleet invariant holds.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions