دسکتاپ، Worker و محاسبات محلی · فصل ۱ — Device Identity، Tauri، Tray و Admin CLI · 177
Sentinel Tray و Degraded Desktop Behavior
اپ یا worker محلی را اجرا میکند اما device identity، privilege، offline state و fleet behavior را طراحی نکرده است. موضوع جاری: «Sentinel Tray و Degraded Desktop Behavior». میتواند «Sentinel Tray و Degraded Desktop Behavior» را برای یک node محلی با identity، state، privilege و recovery boundary مناسب طراحی کند.
خلاصهٔ درس
اپ یا worker محلی را اجرا میکند اما device identity، privilege، offline state و fleet behavior را طراحی نکرده است. موضوع جاری: «Sentinel Tray و Degraded Desktop Behavior».
میتواند «Sentinel Tray و Degraded Desktop Behavior» را برای یک node محلی با identity، state، privilege و recovery boundary مناسب طراحی کند.
خروجی این درس
میتواند «Sentinel Tray و Degraded Desktop Behavior» را برای یک node محلی با identity، state، privilege و recovery boundary مناسب طراحی کند.
1. مسئله: آیکن سبز نباید نقش Oracle سلامت را بازی کند
فرض کنید پنجرهی اصلی بسته شده، پردازش Desktop هنوز زنده است، Worker در پسزمینه کار میکند، Coordinator برای چند دقیقه در دسترس نیست و Credential هم در همین فاصله منقضی میشود. اگر Tray فقط زندهبودن Process را بسنجد، ممکن است همچنان سبز بماند و یک وضعیت خطرناک و گمراهکننده بسازد. هدف این درس این است که Tray را از «منبع حقیقت» به «نمایشدهندهی Evidence صریح» تبدیل کنیم.
2. مرز مالکیت: LOC-004 چه چیزی را میگیرد و چه چیزی را نمیگیرد
این درس فقط Sentinel Tray و رفتار Desktop در حالت Degraded/Offline را مالک است: مدل Evidence، Freshness، Reducer وضعیت، Render state، Action gate، Reconnect و Recovery. مجوز Native Command متعلق به LOC-002 است؛ Capability و CSP متعلق به LOC-003 است؛ و Headless Admin/Break-glass در LOC-005 میآید. اینجا نباید هیچکدام دوباره اختراع شوند.
3. پنج سیگنال را از هم جدا نگه دارید
حداقل باید window_state، worker_state، coordinator_state، network_state و credential_state مستقل باشند. بستهبودن Window به معنی توقف Worker نیست؛ Online بودن Network به معنی Reachable بودن Coordinator نیست؛ Reachable بودن Coordinator هم Credential معتبر نمیسازد. هر تصمیم باید از همین تفکیک شروع شود.
4. Freshness قبل از رنگ آیکن بررسی میشود
Heartbeat فقط وقتی Evidence سلامت است که در پنجرهی Freshness معتبر باشد. اگر سن Heartbeat از freshness_window عبور کند، نتیجه نباید «آخرین وضعیت خوب» باقی بماند. State باید STALE یا UNKNOWN شود و Actionهای حساس تا Evidence تازه برگردد Fail-closed بمانند.
5. Health Reducer باید Deterministic و تایپشده باشد
بهجای چند if پراکنده در UI، یک Reducer مشخص بسازید که Evidence را به Stateهایی مثل ONLINE، DEGRADED، OFFLINE، STALE، UNKNOWN و CREDENTIAL_BLOCKED نگاشت کند. این Stateها باید دلیل (degraded_reason) داشته باشند تا UI و Log دقیقاً از یک تصمیم مشترک استفاده کنند.
6. Desktop Process، Window و Worker سه چیز متفاوتاند
Desktop Process ممکن است بالا باشد ولی Window بسته باشد؛ Worker ممکن است حتی بعد از بستهشدن Window ادامه دهد؛ یا برعکس، Tray بالا باشد ولی Worker واقعاً متوقف شده باشد. بنابراین «Tray وجود دارد» و «Worker سالم است» دو ادعای مستقلاند و نباید با هم Collapse شوند.
7. Worker سالم + Coordinator قطع = Worker مرده نیست
اگر Heartbeat Worker تازه است ولی Coordinator یا Network قطع شده، وضعیت محلی Worker میتواند سالم بماند؛ در عین حال Remote control path در دسترس نیست. Render درست معمولاً یک حالت DEGRADED/OFFLINE است، نه FAILED_WORKER. این تفاوت برای Recovery اشتباه بسیار مهم است.
8. Credential منقضی با Network failure فرق دارد
ممکن است Network و Coordinator کاملاً در دسترس باشند اما Credential منقضی شده باشد. در این حالت Remote-required یا Privileged action باید CREDENTIAL_BLOCKED شود؛ نباید برای کاربر پیام «اینترنت قطع است» نشان داد. Reason درست باعث Recovery درست میشود.
9. Action Gate از Status جداست
Status فقط شرایط را توصیف میکند. action_gate تعیین میکند چه کاری اکنون مجاز است. در Degraded mode ممکن است view_local_logs یا export_diagnostics محلی قابل اجرا باشد، در حالی که remote_sync یا عملیات Privileged به Evidence تازه، Credential معتبر یا مسیر مجوز جداگانه نیاز دارند.
10. Offline mode مجوز اضطراری تولید نمیکند
Offline بودن نباید یک Shortcut برای Privilege باشد. اگر یک Action در حالت عادی به Remote authority، Credential معتبر یا مجوز دیگری نیاز دارد، قطع شبکه آن پیشنیاز را حذف نمیکند. Degraded UX باید قابلیتهای واقعاً محلی و امن را نگه دارد و باقی موارد را صریح Block/Defer کند.
11. Reconnect و Recovery باید علتمحور باشند
برای Coordinator unreachable، Recovery مناسب ممکن است Retry/Reconnect باشد؛ برای Worker stopped، Restart worker؛ برای Credential expired، Re-authentication؛ و برای Evidence stale، Refresh observation. یک دکمهی عمومی «Fix» بدون Reason، خطر اجرای Recovery اشتباه را بالا میبرد.
12. Tauri Tray API: رفتار Platform را فرض نگیرید
در مستندات رسمی Tauri v2، Tray API و Tray events وجود دارند، اما یک تفاوت مهم Platform-specific ثبت شده است: روی Linux رویدادهای Tray icon emit نمیشوند، هرچند آیکن میتواند نمایش داده شود و Context menu روی Right-click قابل استفاده است. بنابراین UX ویندوزی مبتنی بر Click event را نباید عیناً به Linux منتقل کرد.
13. Managed State ابزار هماهنگی است، نه اثبات صحت مدل
Tauri اجازه میدهد State مدیریتشده از طریق Manager و AppHandle در handlerهایی مثل window event خوانده شود. این ابزار برای هماهنگکردن UI با Reducer مفید است؛ اما بهخودیخود ثابت نمیکند مدل Health درست است یا Concurrency شما بیخطر است. مدل Evidence و Locking همچنان مسئولیت طراحی شماست.
14. Lab: Sentinel Tray Degraded-State Contract v1
هشت Fixture مصنوعی دارید. باید برای هر مورد health_evidence_state، degraded_reason، status_render_state، action_gate، reconnect_state، recovery_action، decision و reason را بسازید. Expected labelها در Learner package نیستند. هیچ Tray واقعی، شبکه، Credential یا تغییر OS لازم نیست.
15. Transfer: Linux بدون ضعیفکردن Gateها
در Transfer فرض کنید Prototype ویندوزی برای بازکردن Recovery UI به Click روی Tray وابسته بوده، اما این event روی Linux در دسترس نیست. مسیر تعامل را با Context menu یا رفتار پشتیبانیشده بازطراحی کنید، ولی Runtime state و Action gate را دست نزنید. تفاوت Platform باید Interaction را تغییر دهد، نه Truth model را.
ارزیابی
پاسخنامهی این درس در بستهی آموزش وجود ندارد؛ خودت جواب بده و صادقانه علامت بزن. «نیاز به مرور» درس را به صف تکرار میفرستد.
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.
ملاکهای ارزیابی (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.
منابع و تازگی
مطالعهٔ موارد (case studies)
فایلهای آزمایشگاه
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.