P3-5: Status, activity and conflict UI #34
Labels
No labels
data-integrity
engine
platform
procurement
remote
scaffold
ui
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: Cordy/cairn-desktop#34
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Depends on P3-4.
Goal
Make the engine's state legible. Everything below already exists in
sync.Result— this task is about surfacing it, not computing it.Files
internal/app/status.go,frontend/status.*,frontend/conflicts.*Main window
Result.SkippedandResult.Conflicts. This is the important one and must never be a silent counter.Conflicts
For each conflict, show both files with size and modification time, and offer three actions:
Both files already exist locally, so no action here can destroy data — which is exactly why the conflict policy was designed that way in Task 12. Say so in the UI: "Both versions are saved. Choose which one keeps the original name."
Skipped items
Each skip carries a
Reasonfrom the engine (illegal filename, case collision, quota, partial write). Show the reason verbatim — those strings were written to be read by users, not developers. Where the fix is obvious, say it: a Windows-illegal name should suggest renaming, and offer to open the containing folder.Quota exhaustion
Give it a dedicated state, not a generic error: "Your Cairn is full. Nothing is being uploaded until space is available." Link to the web UI. Never present this as a transient failure the user should wait out.
Notifications
Native OS notifications, used sparingly: first successful sync, a new conflict, quota exhausted, auth expired. Never notify on routine success — that is how an app gets muted permanently.
Steps
Skip.Reasonrenders legibly for a non-technical reader.git commit -s -m "feat(app): status, activity and conflict resolution UI"Acceptance criteria
Amendment — 2026-09-11: an empty sync folder is its own state, never a delete (phase-2 final review X2)
Final review X2 found that a pass whose local folder lists nothing, while the state store holds
rows, deletes every server copy, and so every other device's copy. That happens, for instance, when
the sync folder is on a disk that is not mounted. The same holds the other way round: a server
folder that lists nothing deletes every local file. The fix adds an engine refusal. Such a pass
returns an error naming the empty side and applies nothing, unless the caller explicitly allows it.
This UI must surface that refusal as a distinct attention state, never as a generic or transient
error:
connected?" The default action is to wait, and the next pass checks again. The destructive action,
"Delete them from your Cairn and your other devices", needs an explicit confirmation that states
the number of files.
Offer "Upload them again from this device", which forgets the state rows so that the next pass
merges the two sides and uploads, and "Delete them here too", which needs the same explicit
confirmation.
automatically, and never retry into the deletion.
Acceptance: no path through this UI deletes files on the empty-side refusal without that explicit
confirmation.