diff --git a/specs/109-ux-navigation-consistency/contracts/health-vocabulary.md b/specs/109-ux-navigation-consistency/contracts/health-vocabulary.md index d638f1e2e..05984bdd8 100644 --- a/specs/109-ux-navigation-consistency/contracts/health-vocabulary.md +++ b/specs/109-ux-navigation-consistency/contracts/health-vocabulary.md @@ -55,7 +55,7 @@ Priority order for `actions`: `login` > `set_secret` > `configure` > `edit_url` | `error` | Error | "" | Restart | | `disabled` | Disabled | "Disabled" | Enable (a disabled server is never an attention item, FR-002, but its card still offers the one step that brings it back) | -The macOS Servers row, the tray server submenu's first line and the Server Detail header all render `ServerStatusLinePresentation.line(for:)` (`native/macos/MCPProxy/MCPProxy/Menu/TrayPresentation.swift`): the label, then ` · ` when `admin_state` is `enabled` and the summary adds information beyond the label (the same rule as the Web card's status detail). Only a core that sends no `status` falls back to the legacy words (`Needs review`, `Disabled`, `Connecting`, `Connected`, `Disconnected`). +The macOS Servers row, the tray server submenu's first line and the Server Detail header all render `ServerStatusLinePresentation.line(for:)` (`native/macos/MCPProxy/MCPProxy/Menu/TrayPresentation.swift`). On macOS that helper takes three branches, in order. A present, non-empty `health.status` uses the shared status label (an unknown non-empty status stays on this branch and renders its raw value), then ` · ` when `admin_state` is `enabled` and the summary adds information beyond the label (the same rule as the Web card's status detail). Otherwise a present `health` object with a non-empty `summary` uses that summary as the label and appends no detail; a missing `status` and an empty `status` both reach this branch before any legacy wording. `testOldCoreHealthWithoutStatusUsesItsSummary` (`native/macos/MCPProxy/MCPProxyTests/ServerStatusLineTests.swift`) is the compatibility reference: the old-core error summary `Connection refused` remains the label, with no appended detail. Only when neither branch applies, including absent `health` or a missing or empty `status` with an empty `summary`, does the renderer derive legacy words from server state, in order: quarantined (`Needs review`), disabled (`Disabled`), connecting (`Connecting`), connected (`Connected`, or `Unavailable` when `health.usable` is `false`, so a server the core reported as not usable never reads `Connected`, SC-003), disconnected (`Disconnected`), with quarantine taking precedence over disabled state. `testOldCoreFallbacksUseLegacyWordsOnlyWithoutHealth` covers absent `health`. Button labels per action: `login` Sign in · `set_secret` Add secret · `configure` Fix config · `edit_url` Edit URL · `approve` Review (opens the review screen; never approves directly, FR-005) · `restart` Restart · `view_logs` View logs · `enable` Enable.