type: meta

slug: limit-warning-icon

topic: Tray icon warning state + notification when current default account nears usage limits (5h<15% remaining, 7d<5% remaining)

exec_mode: ship

scheduler: dag-parallel

land_mode: merge-to-main

base_branch: main

status_enum: BLOCKED PENDING WORKING WRITTEN REVIEWED COMMITTED

truth_rule: this file is ground truth for INTENT (goals/directions/task list); git is ground truth for DONE-NESS — reconcile statuses against git, never trust a COMMITTED line with no commit

refresh_how: native Read of THIS file — NEVER ctx_execute/ctx_search (the point is re-injecting intent into the main thread; a context-mode call keeps bytes OUT and silently kills the feature)

refresh_what: meta + every goal/methodology/intent/direction record + all WORKING and BLOCKED tasks (skip COMMITTED lines)

refresh_when:
wave/phase boundary
any task status change
after a compaction system-reminder
before calling advisor

update_rule: on status change, rewrite that task's single line in place; append new tasks/session_memory as new lines

report_rule: at session end emit brief: done / blocked / deferred / canceled — NO 'next action' (if you know it, do it)


type: goal

text: Warn the user (tray icon flip + OS notification) when the current default account (Codex and/or Claude) drops under 15% remaining on its 5h window or 5% remaining on its 7d window.


type: methodology

text: Contract-level spec -> plan -> subagent-per-task execution (ship). Notification is event-driven (per snapshot change); icon is state-driven (heartbeat + instant feedback on manual default switch), per the corrected data-flow design.


type: intent

text: User currently only discovers usage exhaustion after the fact by opening the dashboard. Proactive signal needed on the tray itself.


type: direction

verbatim: i want to have a warning on my systray icon and a notification when the current default account is reaching under 15% of the 5h limit, or under 5% of the 7d limit.


type: deferred

text: Claude default-account support

reason: ClaudeHealthClient does not exist on main yet (unmerged claude-account-parity spec); Claude snapshots are permanently HealthStatus.UNKNOWN, so this feature is a silent no-op for the Claude default until that lands. Feature is written generically so it activates automatically once parity merges — no code change needed here.


type: task

desc: limit_warning.py — pure breach-detection module (breached_windows against AccountSnapshot, 15%/5% thresholds) + tests/test_limit_warning.py

status: COMMITTED


desc: Add set_icon_full recorder to _FakeAppIndicatorInstance in tests/test_indicator.py


desc: Warning icon SVG asset + install.py wiring (copy/remove alongside existing icon)


desc: Wire limit_warning into Indicator: _check_limit_warning (notify, event-driven, called from _apply_snapshot) + _update_warning_icon (icon, state-driven, called from _refresh_all_timer heartbeat + on_activate instant feedback) + APPINDICATOR_ICON_WARNING constant + instance state + tests