The last rung of the chain is a token the user pastes into Settings, and an
enterprise personal access token pasted there was still sent to
api.github.com. Settings now takes the host beside the token, defaulting to
github.com, and saves both in the same provider Keychain record so the host a
request is addressed to always comes from the entry that carried the token.
A host no endpoint can be derived from is refused at the field instead of
being stored and reported later as a terminal fetch failure, and the crafted
values #1286 guarded against are refused there too. Clearing the token clears
the host with it, so a stale tenant can never be paired with the next token.
The record's decoding moves into an extension and reads every key with
decodeIfPresent: Swift's synthesized init(from:) ignores a property's default
and throws on a missing key, so adding a field would otherwise make every
credential saved before it unreadable — for every provider, not just Copilot.
The dormant connection row no longer promises api.github.com before anything
has been fetched; it names a host only once one has answered.
Tests cover the three new host sources with a hostile value each, the rung
wiring for all five rungs, the gh hosts.yml key scan, and that a record
written before the host field still decodes.
The lock no longer covers the defaults write, so the main-queue hop is
what keeps the read-modify-write atomic; say so where the next reader
would be tempted to make it async. The regression test now cleans up its
observer and defaults domain on every exit and waits up to 5 seconds, so
a loaded runner cannot fake a deadlock.
A background credential read held the provider-presence lock while UserDefaults synchronously notified SwiftUI. SwiftUI could re-read presence while holding its own update lock, leaving each thread waiting on the other. Serialize presence writes on the main queue and release the presence lock before publishing defaults changes.
* feat(menubar): add native capacity dock
* fix(menubar): harden dock interaction boundaries
* feat(menubar): polish native Capacity Dock for launch
- Flush top-edge docking via NSHostingView safe-area opt-out; shielding
window level so the rail necks into the physical top like the system notch
- Liquid Glass legibility scrim so labels stay readable on light wallpapers
- Weekly-else-monthly headline window; unified severity colour bands
(green <50 / yellow / orange / red) across rings and detail bars
- Squircle gauge + graphite theme defaults; auto-show connected
subscriptions (up to 5) until the user edits the set, then respect it
- Capacity Dock Settings menu item; re-centre the settings window; info
glyph for the About row
- Trim dead provider-credential override fields down to apiKey only
- Reconcile and extend tests for all of the above
---------
Co-authored-by: iamtoruk <hello@agentseal.org>