Keep custom chrome on non-mac platforms while restoring native traffic lights on macOS. Also remove the extra outer mac shell radius/border to avoid double-rounded corners.
Constraint: macOS must show native traffic lights for issue #183
Constraint: Windows/Linux should keep custom titlebar behavior
Rejected: set decorations=true in tauri.conf globally | enables native chrome on Linux
Confidence: high
Scope-risk: narrow
Directive: Platform-specific window decoration behavior should be controlled at runtime, not by global config
Tested: npm run build (openless-all/app)
Not-tested: manual visual verification on real macOS/Linux/Windows runtimes
Content flows now allow empty Ark API keys only when a custom Ark endpoint is configured. If both key and endpoint are empty, we fail locally instead of falling back to the public Ark endpoint, preserving the privacy guard while restoring ticket #192 keyless self-hosted behavior.
Constraint: Keep no-key self-hosted OpenAI-compatible LLM support from issue #192
Constraint: Prevent transcript content from being sent to default public Ark endpoint when key is empty
Rejected: unconditional API-key requirement in coordinator | breaks keyless self-hosted usage
Rejected: unconditional default-endpoint fallback | risks accidental data egress on fresh installs
Confidence: high
Scope-risk: narrow
Directive: Any future endpoint fallback change must preserve the blank-key + blank-endpoint local guard for content-sending flows
Tested: rustfmt --edition 2021 --check src/coordinator.rs; cargo test --lib resolve_ark_endpoint_
Not-tested: end-to-end UI interaction for keyless custom endpoint polish/translate/chat
Polish, translate, and QA chat now fail locally when ArkApiKey is blank, so fresh installs and keyless LLM setups do not leak transcript content to the default public Ark endpoint. Model discovery remains keyless because it is a separate non-content path.
Constraint: LLM model discovery must stay keyless
Rejected: rely on downstream provider auth failures | leaks user content over the network
Confidence: high
Scope-risk: narrow
Directive: Keep the blank-key guard ahead of any Ark endpoint fallback in content-sending flows
Tested: cargo test --lib require_ark_api_key_rejects_blank_key; rustfmt --edition 2021 --check src/coordinator.rs
Not-tested: full UI settings flow
Model discovery now matches the keyless LLM path by omitting Authorization when the stored API key is blank. This keeps Fetch models usable for endpoints that reject empty Bearer credentials while preserving authenticated discovery for configured providers.
Constraint: ASR still requires an API key
Rejected: send a fake or empty Bearer header | breaks keyless endpoints
Confidence: high
Scope-risk: narrow
Directive: Do not reintroduce auth headers for blank LLM keys without a provider-specific requirement
Tested: cargo test --lib fetch_provider_models_omits_authorization_when_api_key_is_empty; rustfmt --edition 2021 --check src/commands.rs
Not-tested: full frontend integration flow
Some OpenAI-compatible LLM endpoints do not require an API key, so the LLM validation and runtime polish paths should not invent one or fail early when the key field is blank. The client now omits the Authorization header when the key is empty, the coordinator stops treating a blank LLM key as a hard error, and the settings validation continues to distinguish a missing model from a genuinely failed connection.
Constraint: Keep the change minimal and preserve the existing HTTP-status error mapping.
Rejected: Keep key-required behavior for all LLM endpoints | it mislabels keyless endpoints such as local 11443-style servers as invalid.
Confidence: high
Scope-risk: moderate
Directive: Empty LLM API keys are allowed only for the OpenAI-compatible path; ASR remains key-required.
Tested: npm run build; cargo test --lib
Not-tested: Live behavior against a real keyless endpoint outside the test harness
The LLM connection check no longer falls back to an Ark-specific default model when the user has not configured one. Instead, it returns a dedicated marker and the settings UI surfaces the empty-state copy, which keeps the validation result aligned with the actual configuration state.
Constraint: Preserve the existing provider-status parsing and keep the change minimal.
Rejected: Keep the deepseek-v3-2 fallback | it creates a false positive for unconfigured non-Ark providers.
Confidence: high
Scope-risk: narrow
Directive: Validation should never invent a model when the user has not saved one.
Tested: npm run build; cargo test --lib
Not-tested: Live provider behavior with a truly empty model field on a real endpoint
LLM validation now maps non-2xx completion responses back to the same providerHttpStatus:<code> marker used by the model-listing path. That keeps the settings page on its existing error-copy branch so real API-key, endpoint, and model failures stay diagnosable instead of collapsing into a generic message.
Constraint: Keep the change minimal and preserve the existing settings error-message parser.
Rejected: Teach the frontend to parse LLMError::InvalidResponse text | this would duplicate provider-status semantics and broaden the UI change.
Confidence: high
Scope-risk: narrow
Directive: Validation error strings for provider status should stay normalized at the command boundary.
Tested: cargo test --lib
Not-tested: Live provider error text against a real non-2xx endpoint