heph-tui sync health: last-sync age, pending conflicts, auth-failure indicator #11

Merged
eblume merged 1 commit from feature/tui-sync-health into main 2026-06-06 11:03:01 -07:00
Owner

Summary

A spoke (e.g. gilbert) could silently stop syncing — an expired token → 401, or the hub asleep/unreachable — with the only evidence buried in hephd.log. This adds the visibility, and documents the auth-longevity fix.

  • Daemon (hephd): tracks SyncHealth (last attempt/success time, last error, auth-failure flag) from the background sync loop and sync.now, classifying an HTTP 401 as an auth failure. The sync.status RPC now returns that health plus the pending merge-conflict count (so heph sync --status shows it too).
  • heph-tui: a live status-line indicator (spoke only) — ⟳ <age> since the last good sync, red ⚠ auth when re-login is needed, ⚠ offline when the hub is unreachable, and ⚠ N conflicts when conflicts are pending. The event loop polls on a 2s tick so the age advances and failures appear even while idle. Standalone instances show nothing.
  • Docs: recommended Authentik access + refresh token validity values to stop frequent re-logins (root cause of "I re-auth constantly"), with the iOS PWA localStorage-eviction caveat. host-heph-pwa points at it.

Read-side only — no schema, no op-log, no wire change. Closes the backlog items "Add hub connection status to heph-tui" and "Spoke sync health: surface unhealthy state instead of silent 401 spam".

Testing

  • cargo test --workspace (incl. new sync_indicator/fmt_age unit tests + a standalone-no-indicator assertion that round-trips the sync.status RPC)
  • prek run --all-files
  • manual: run heph-tui on gilbert (a real spoke) and confirm the ⟳ <age> chip; pull the plug on indri and watch it flip to ⚠ offline

🤖 Generated with Claude Code

## Summary A spoke (e.g. gilbert) could silently stop syncing — an expired token → 401, or the hub asleep/unreachable — with the only evidence buried in `hephd.log`. This adds the visibility, and documents the auth-longevity fix. - **Daemon** (`hephd`): tracks `SyncHealth` (last attempt/success time, last error, auth-failure flag) from the background sync loop **and** `sync.now`, classifying an HTTP 401 as an auth failure. The `sync.status` RPC now returns that health plus the pending merge-conflict count (so `heph sync --status` shows it too). - **heph-tui**: a live status-line indicator (spoke only) — `⟳ <age>` since the last good sync, red `⚠ auth` when re-login is needed, `⚠ offline` when the hub is unreachable, and `⚠ N conflicts` when conflicts are pending. The event loop polls on a 2s tick so the age advances and failures appear even while idle. Standalone instances show nothing. - **Docs**: recommended Authentik **access + refresh token validity** values to stop frequent re-logins (root cause of "I re-auth constantly"), with the iOS PWA `localStorage`-eviction caveat. `host-heph-pwa` points at it. Read-side only — no schema, no op-log, no wire change. Closes the backlog items *"Add hub connection status to heph-tui"* and *"Spoke sync health: surface unhealthy state instead of silent 401 spam"*. ## Testing - [ ] `cargo test --workspace` (incl. new `sync_indicator`/`fmt_age` unit tests + a standalone-no-indicator assertion that round-trips the `sync.status` RPC) - [ ] `prek run --all-files` - [ ] manual: run `heph-tui` on gilbert (a real spoke) and confirm the `⟳ <age>` chip; pull the plug on indri and watch it flip to `⚠ offline` 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(heph-tui,hephd): surface sync health (last-sync age, conflicts, auth failure)
All checks were successful
Build / validate (pull_request) Successful in 6m11s
11aa25c9f4
A spoke could be silently failing to sync (expired token → 401, or hub
unreachable) with the only signal buried in the daemon log. Now:

- hephd tracks SyncHealth (last attempt/success time, last error, auth-failure
  flag) from the background sync loop and sync.now, classifying a 401 as an auth
  failure. sync.status returns it plus the pending merge-conflict count.
- heph-tui shows a live status-line indicator (spoke only): '⟳ <age>' since the
  last good sync, red '⚠ auth' when re-login is needed, '⚠ offline' when the hub
  is unreachable, and '⚠ N conflicts' when conflicts are pending. The event loop
  polls on a 2s tick so the age advances and failures appear while idle.
- docs: recommended Authentik access/refresh token validity to stop frequent
  re-logins (with the iOS PWA localStorage-eviction caveat).

Closes the 'Add hub connection status to heph-tui' and 'Spoke sync health:
surface unhealthy state instead of silent 401 spam' backlog items.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
eblume merged commit 02a8dd5180 into main 2026-06-06 11:03:01 -07:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
eblume/hephaestus!11
No description provided.