Skip to content

fix: secret ordering, dead-end opens, and stale response metrics - #10

Open
starvy wants to merge 3 commits into
mainfrom
ui-audit-fixes
Open

fix: secret ordering, dead-end opens, and stale response metrics#10
starvy wants to merge 3 commits into
mainfrom
ui-audit-fixes

Conversation

@starvy

@starvy starvy commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Three fixes that came out of a hands-on UI audit, each verified end-to-end in the running app on Linux (real sends against api.github.com and a local streaming server).

1. Secrets resolve only after the host allow-list decision — fix(engine)

Sending to an off-list host with inherited {{secret:…}} auth used to resolve the secret first: an unreachable keychain failed the whole send over a credential the policy would never let it carry, and every refused send cost a secret-backend read. The egress decision now comes first — refused destinations skip resolution entirely and go straight to the policy dialog; Send once / Allow host re-enter with the grant and only then resolve. The Auth-tab mismatch warning now uses the same policy::egress_allowed predicate as the send path, so the two can't drift.

New engine tests prove the ordering with a counting resolver double: off-list host → zero backend calls, no Authorization header, one strippable OffHostEgress; granted host → exactly one read, and a broken backend still errors as before.

2. Failed workspace opens no longer dead-end — fix(ui)

  • A recent whose folder is gone is marked missing in the Welcome list; opening it prunes it from the persisted recents and the toast says so. Only NotFound + path-actually-gone prunes — permission errors and malformed manifests keep the entry.
  • A path picker that can't open at all (Linux without xdg-desktop-portal) used to be a silent no-op; New/Open Workspace now toast the underlying cause.

3. History rows carry their numbers; elapsed ticks live — feat(ui)

  • History rows now show the recorded latency and size (200 · 10.21 s · 170 B) next to the age.
  • The in-flight elapsed only rendered before the first byte, so it read as a frozen counter that jumped to the final total. It now counts through the whole flight (1.9 s · 32 B received5.0 s · 89 B received), quantized so the low digits don't strobe at repaint rate; the settled total remains the engine-reported elapsed.

Gates

cargo test --workspace (413 passed) · cargo clippy --workspace --all-targets -- --deny warnings · cargo fmt --all --check

Review notes

  • History-row metadata is flex_shrink_0, so long ad-hoc URL names truncate hard in a narrow sidebar (saved-request names are fine). Shout if you'd rather the metadata yield instead.
  • The same picker-failure swallow still exists in the OpenAPI-import and multipart file pickers (interchange.rs, multipart.rs); the new picked_folder helper is liftable — left as a follow-up to keep this reviewable.
  • Screenshots live on the throwaway assets/ui-audit-fixes branch; delete it whenever this PR is closed out.

starvy added 3 commits July 28, 2026 14:25
An off-list destination used to resolve {{secret:…}} first, so an
unreachable keychain failed the whole send over a credential the
policy would never let it carry (and every refused send cost a
secret-backend read). The egress decision now comes first: refused
hosts skip credential resolution entirely and report what a granted
send would carry; granting the host re-resolves for real. The Auth
tab warning now shares the same predicate so the two can't drift.
Opening a recent whose folder is gone now prunes it from the recents
(the toast says so) instead of leaving a permanently broken row, and
the Welcome list marks still-missing entries. A path picker that
cannot open at all — no xdg-desktop-portal on Linux — used to be a
silent no-op; it now toasts the cause instead of looking like a dead
button.
History recorded latency and size but the rows only showed status and
age. The in-flight elapsed also only rendered before the first byte,
which read as a frozen counter that jumped to the final total; it now
counts through the whole flight (quantized — full precision would
strobe at repaint rate) and the settled total stays engine-reported.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant