Background
The boot barrier added in #3752 closes the stale-store revert vector: a coordinate whose local store has no publish history but whose relay head is present gets its pending row withheld (publish_blocked = 1). This is the correct polarity for dev-build collisions.
The parked state is a stable fixed point: retain_event's upsert never touches publish_blocked, and each subsequent boot re-parks the same coordinate so long as no baseline exists. A user who edits an agent on a second legitimate install (no prior publish history on that machine) gets a save that never syncs, with no UI explaining why.
This issue tracks the Step 6 / V3.6 resolution surface that unblocks parked coordinates.
Required surface
Backend (Rust / Tauri)
get_blocked_coordinates — query the retention DB for all rows where publish_blocked = 1 and pending_sync = 1, return coordinate + local projection + reason (ParkReason)
force_publish_local — clear publish_blocked = 0 for the coordinate, then stamp the baseline from the local row's event_id/content atomically; the next flush loop tick picks it up as a normal pending publish
accept_remote_head — write the relay head's content to the local disk record (same path as ApplyHead), clear publish_blocked, stamp baseline from the head
- Both operations must be atomic per coordinate — clear gate + stamp baseline in one transaction; no partial state where the row is unblocked but has no baseline (which would cause the next boot to re-park it again)
Frontend
- Surface the blocked-coordinate list in agent settings or a dedicated conflict indicator
- For each parked coordinate: show local vs. relay content diff (or at minimum local content + "relay has a different version"), and offer Keep mine / Use relay's actions
- Parked state is transient relative to the user's intent — surface it promptly, not buried under a deep settings link
Schema notes
The resolution path is reachable today without schema changes:
set_publish_blocked(conn, kind, pubkey, d_tag, false) already exists (retention.rs)
stamp_baseline already exists (config_sync.rs)
- The atomicity requirement means these two calls must be wrapped in a single SQLite transaction per coordinate
Diagnosing parked rows today
is_publish_blocked is #[cfg(test)] and not available in production. The barrier's per-decision tracing line (buzz::config_sync) logs every Park decision with coordinate, kind, and reason — that trace line and direct SQL against the retention DB are the current support path.
Related
Background
The boot barrier added in #3752 closes the stale-store revert vector: a coordinate whose local store has no publish history but whose relay head is present gets its pending row withheld (
publish_blocked = 1). This is the correct polarity for dev-build collisions.The parked state is a stable fixed point:
retain_event's upsert never touchespublish_blocked, and each subsequent boot re-parks the same coordinate so long as no baseline exists. A user who edits an agent on a second legitimate install (no prior publish history on that machine) gets a save that never syncs, with no UI explaining why.This issue tracks the Step 6 / V3.6 resolution surface that unblocks parked coordinates.
Required surface
Backend (Rust / Tauri)
get_blocked_coordinates— query the retention DB for all rows wherepublish_blocked = 1andpending_sync = 1, return coordinate + local projection + reason (ParkReason)force_publish_local— clearpublish_blocked = 0for the coordinate, then stamp the baseline from the local row'sevent_id/contentatomically; the next flush loop tick picks it up as a normal pending publishaccept_remote_head— write the relay head's content to the local disk record (same path asApplyHead), clearpublish_blocked, stamp baseline from the headFrontend
Schema notes
The resolution path is reachable today without schema changes:
set_publish_blocked(conn, kind, pubkey, d_tag, false)already exists (retention.rs)stamp_baselinealready exists (config_sync.rs)Diagnosing parked rows today
is_publish_blockedis#[cfg(test)]and not available in production. The barrier's per-decision tracing line (buzz::config_sync) logs everyParkdecision with coordinate, kind, and reason — that trace line and direct SQL against the retention DB are the current support path.Related