دسکتاپ، Worker و محاسبات محلی · فصل ۱ — Device Identity، Tauri، Tray و Admin CLI · 177
Sentinel Tray and Degraded Desktop Behavior
Design a sentinel tray contract that maps independently observed runtime states to explicit tray/menu behavior, distinguishes UI/window state from worker health, preserves safe degraded/offline operation, prevents privileged actions when evidence is stale, and exposes recovery/reconnect paths without turning an icon into a health oracle. میتواند «Sentinel Tray و Degraded Desktop Behavior» را برای یک node محلی با identity، state، privilege و recovery boundary مناسب طراحی کند.
Lesson summary
Design a sentinel tray contract that maps independently observed runtime states to explicit tray/menu behavior, distinguishes UI/window state from worker health, preserves safe degraded/offline operation, prevents privileged actions when evidence is stale, and exposes recovery/reconnect paths without turning an icon into a health oracle.
میتواند «Sentinel Tray و Degraded Desktop Behavior» را برای یک node محلی با identity، state، privilege و recovery boundary مناسب طراحی کند.
This lesson produces
میتواند «Sentinel Tray و Degraded Desktop Behavior» را برای یک node محلی با identity، state، privilege و recovery boundary مناسب طراحی کند.
Who it is for
Foundation
Use a guided lesson-specific evidence matrix and one worked negative case.
Repair
Re-run only the failed owned dimension with a smaller deterministic synthetic fixture.
Experienced
Start from mixed authority/policy/evidence records; require explicit trade-offs and provenance.
Prerequisites
1. The problem: a green icon must not become a health oracle
Assume the main window is closed, the desktop process is still alive, the background worker continues running, the coordinator becomes unreachable for several minutes, and a credential expires during the outage. A tray that checks only process existence may remain green and present a dangerously false success state. This lesson turns the tray from a source of truth into a projection of explicit runtime evidence.
2. Owned boundary: what LOC-004 owns and what it does not
This lesson owns the sentinel tray and degraded/offline desktop contract: evidence fields, freshness, state reduction, rendering, action gates, reconnect, and recovery. Native command authorization belongs to LOC-002, Tauri capability/CSP exposure belongs to LOC-003, and headless break-glass administration belongs to LOC-005. Do not absorb those outcomes here.
3. Keep five runtime signals independent
At minimum, keep window_state, worker_state, coordinator_state, network_state, and credential_state separate. A closed window does not imply a stopped worker. An online network does not prove coordinator reachability. A reachable coordinator does not make an expired credential valid. Every later decision depends on preserving these distinctions.
4. Evaluate freshness before choosing an icon
A heartbeat is health evidence only while it is inside its declared freshness window. Once its age exceeds freshness_window, the UI must not continue displaying the last known good result as current truth. Preserve a typed STALE or UNKNOWN state and fail closed for sensitive actions until fresh evidence returns.
5. Use a deterministic, typed health reducer
Instead of scattering ad-hoc conditions across UI handlers, create one reducer that maps evidence into states such as ONLINE, DEGRADED, OFFLINE, STALE, UNKNOWN, and CREDENTIAL_BLOCKED. Attach an explicit degraded_reason so rendering, logging, and action gating all consume the same decision.
6. Desktop process, window, and worker are different things
The desktop process may be alive while its window is hidden or closed. A worker may continue after the window closes. Conversely, the tray may still exist while the worker has stopped. Therefore tray presence and worker health are independent claims and must never be collapsed.
7. Fresh worker plus unreachable coordinator is not a dead worker
When the worker heartbeat is fresh but the coordinator or network is unavailable, local worker evidence may still be healthy even though the remote control path is down. The truthful render is a degraded/offline state, not a fabricated worker failure. This distinction prevents the wrong recovery action.
8. Expired credentials are not network failures
The network and coordinator can both be healthy while the credential has expired. In that case remote-required or privileged actions should enter CREDENTIAL_BLOCKED; the UI should not claim the network is down. Accurate reasons produce accurate recovery paths.
9. Action gating is separate from status rendering
Status describes conditions. action_gate decides what can run now. In degraded mode, local-safe actions such as viewing local logs or exporting diagnostics may remain available while remote synchronization or privileged actions stay blocked until their own prerequisites are restored.
10. Offline mode does not manufacture emergency authority
Going offline must not create a privilege shortcut. If an action normally requires remote authority, a valid credential, or another authorization boundary, loss of connectivity does not erase that requirement. Degraded UX should preserve only genuinely local-safe functions and explicitly block or defer the rest.
11. Reconnect and recovery should follow the cause
Coordinator unreachability may call for reconnect. A stopped worker may call for worker restart. An expired credential requires re-authentication. Stale evidence requires observation refresh. A generic “Fix” button without a typed reason invites the wrong recovery action.
12. Tauri tray APIs: do not assume platform parity
Official Tauri v2 documentation provides tray APIs and tray events, but documents an important platform-specific boundary: tray icon events are not emitted on Linux even though the icon can still be shown and a context menu can be displayed on right click. A Windows interaction that relies on a tray click therefore needs a supported Linux alternative.
13. Managed state is coordination machinery, not health-model proof
Tauri managed state can be retrieved through Manager/AppHandle from handlers such as window events. That is useful for connecting UI code to a shared reducer, but it does not prove that the health model is correct or that every concurrency strategy is safe. Evidence semantics and synchronization remain design responsibilities.
14. Lab: Sentinel Tray Degraded-State Contract v1
Eight synthetic fixtures require you to derive health_evidence_state, degraded_reason, status_render_state, action_gate, reconnect_state, recovery_action, decision, and reason. Expected labels are not included in learner-visible files. No real tray, network, credential, privileged action, or operating-system change is required.
15. Transfer: Linux without weakening the gates
Assume the Windows prototype opens recovery UI from a tray click, but that tray event is unavailable on Linux. Rebuild the interaction around the supported context menu or another supported path while keeping the runtime reducer and action prerequisites unchanged. Platform variance should change interaction mechanics, not the truth model.
Assessment
There is no answer key in this lesson pack; answer it yourself and mark honestly. "Needs review" sends the lesson to your review queue.
LOC-004-AS1 application
Build a Sentinel Tray Degraded-State Contract from the supplied fixture without using tray/window presence as worker-health proof.
LOC-004-AS2 diagnosis
Diagnose the case where the network is online but the credential is expired. Name the status, blocked action class, and recovery path.
LOC-004-AS3 decision
State which local-safe and remote-required actions downstream UI may expose for a fresh local worker with an unreachable coordinator.
LOC-004-AS4 transfer
Rebuild the interaction for Linux when tray icon events are unavailable, without changing the health reducer or action prerequisites.
LOC-004-AS5 reflection
State the strongest claim supported by a green tray render and one stronger claim that remains unsupported.
Assessment rubric
A sufficient submission must keep the owned LOC-004 boundary explicit, bind every decisive state to exact runtime evidence, preserve stale/unknown/blocked states, and keep tray/window presence separate from worker/coordinator/network/credential truth.
Critical dimensions:
- identity and contract — no absorption of LOC-002/003/005 outcomes;
- exact evidence binding — status follows explicit evidence plus freshness;
- negative/unknown states — stale, unknown, offline and credential-blocked are not coerced into success;
- bounded decision — action gates are no stronger than prerequisites;
- transfer — Linux interaction is rebuilt from supported behavior without weakening gates.
References & freshness
Case studies
Lab files
Implement an evaluator for the eight synthetic fixtures. Keep UI visibility separate from worker/coordinator/network/credential evidence, apply heartbeat freshness before rendering success, and keep local-safe actions distinct from remote-required or privileged actions.
The lab performs no real tray integration, network call, credential operation, OS setting change, or privileged action. The Linux transfer fixture intentionally removes tray-icon event support while keeping a context-menu fallback available.