mirror of
https://github.com/runbear-io/beardrive.git
synced 2026-08-25 08:08:08 +02:00
fix(sync): a refused push stays refused, and says why (BEA-403) (#146)
A device whose journal push the hub 403s reported healthy sync between every pair of remote passes, and never showed the hub's reason for the refusal — so a user whose device was not registered to their account re-ran `bdrive login` (which the message told them to), re-checked their project permissions (write), and had nowhere left to look. Two causes, both local to the client: - Cycle recomputed st.Access from scratch at the end of every pass, including the daemon's cheap local-only ticks that never reach the hub. Three of those run between remote passes, so the daemon alternated "read-only on this project" / "access restored; syncing normally" every few seconds and `bdrive status` reported OK moments after a refused push. Now each leg records its own verdict — pull clears no-access, push records read-only or clears it — and a cycle that asked nothing leaves the last answer standing. - The hub's own sentence was summarized into "read-only (pull only)", which describes the STATUS CODE. It is the only thing that tells a device-registration refusal from a project the user really is a reader on. It now rides in SyncState.AccessReason and Result.Reason(), printed by `bdrive sync`, `bdrive status` and the daemon log, and dropped unless it passes journal.SafeText — hub text reaching a terminal. The hub's refusal also now names the upgrade: the binding is made by the login request naming its device, which a CLI older than the gate does not do, so "run `bdrive login`" alone sent that user in a circle. Hub and CLI deploy separately, so the skew is the expected state right after the gate ships. Claude-Session: https://claude.ai/code/session_01GSHsQU4pBCzKkPyPeXSwTm Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
709c40e76c
commit
922886b949
@@ -246,6 +246,12 @@ type SyncState struct {
|
||||
Lamport int64 `json:"lamport"`
|
||||
PushedOps int64 `json:"pushed_ops"` // how many of our own ops the remote has
|
||||
Access string `json:"access,omitempty"` // "", "read-only", or "no-access"
|
||||
// AccessReason is the hub's own words for the last refusal. Without it every
|
||||
// 403 renders as the same "read-only (pull only)" line, and the hub's most
|
||||
// actionable answer — "this device is not registered to your account on this
|
||||
// hub; run `bdrive login`" — reached nobody: the one state a user cannot
|
||||
// diagnose from the outside was the one the CLI summarized away.
|
||||
AccessReason string `json:"access_reason,omitempty"`
|
||||
|
||||
// IgnoreAccepted is the .bdriveignore text whose scan scope THIS device has
|
||||
// accepted, and IgnorePulled is the text a peer's version last wrote here.
|
||||
|
||||
Reference in New Issue
Block a user