Cost feature fixes: /stats scope, burst breakdown, table overflow, strip persistence, admin landing - #51
Merged
Merged
Conversation
(1) /stats leaked other users' jobs to admins.
`principal.can_view()` returns True for admins regardless of owner,
so the recent-counts dashboard included every user's job. Switched
to strict `_job_owner(data) != principal.name`, matching what
/jobs and /usage/cost already do. New test pins the behavior.
(2) Burst breakdown was blank when expanded.
pollBurstAggregate set breakdown to {} on purpose. Sum each job's
breakdown fields (compute / memory / request / network) so the
expanded view shows real numbers for the whole burst.
(3) Top-5 most expensive table overflowed horizontally.
Wrapped it (and by-language and by-status) in .tablewrap so the
existing overflow-x: auto kicks in and content can scroll within
the card instead of pushing it wide.
(4) Cost strip used a different surface token than .card.
.card uses var(--card); strip used var(--surface). Same shadow,
same border, but a slightly off shade. Matched to var(--card) so
the strip blends in visually with the cards next to it.
(5) Strip metrics changed between page refreshes.
Hydration picked "most recent terminal job" — which can shift
between refreshes if jobs completed in the background, so the
Estimated max and Actual cells could read different values
second-to-second. Fix: persist what the user last saw to
localStorage (LAST_ESTIMATE_STORAGE / LAST_ACTUAL_STORAGE) and
restore on boot before any refreshAll runs. Hydration now stands
down whenever persisted state exists. Clear-finished resets the
persisted state too.
(6) Admin sidebar: moved Admin to the top of the list, and admins
landing fresh (no explicit hash) now go straight to #admin instead
of #invoke.
Cost-calculation audit (single / burst / files / codebase): verified
the math against the formula end-to-end. All four paths produce
cost = compute + memory + request + network with values matching
duration × vcpu × per_vcpu_second + duration × gb × per_gb_second
+ attempts × per_request to 1e-9 USD precision.
Bumped app.js?v=22 + styles.css?v=16.
aakri0
added a commit
that referenced
this pull request
May 3, 2026
The previous PR (#51) added an admin-default branch in showTabFromHash, but it never fired: hideAuthGate() rewrites the URL hash from #login to #invoke right before showTabFromHash() reads it, so the admin saw 'invoke' and went there. (And then auto-redirected to invocations because that's where the URL took them on a follow-up nav.) hideAuthGate now picks the landing hash by role: #admin for admins, #invoke for everyone else. state.principal is set in bootstrapPrincipal before hideAuthGate runs, so the role check is reliable. Bumped app.js?v=23.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Six bugs in one pass — most are cost-related, plus the Admin tab UX you asked for.
(1) /stats leaked other users' jobs to admins
principal.can_view()returns True for admins regardless of owner, so the recent-counts on the dashboard included every user's job. /jobs and /usage/cost are already strict — /stats now matches:_job_owner(data) != principal.name. New test pins the behavior.(2) Burst breakdown was blank when expanded
pollBurstAggregatesetbreakdown: {}. Now sums each job's breakdown fields (compute / memory / request / network) so the expanded view shows real per-component numbers across the burst.(3) Top-5 (and by-language / by-status) overflowed horizontally
Wrapped each table in
.tablewrap. The existingoverflow-x: autoon that class now lets the table scroll inside the card instead of pushing it wide.(4) Cost strip used a different surface token than
.card.cardusesvar(--card); strip usedvar(--surface). Same shadow / border / radius, but a slightly off shade. Matched tovar(--card)so the strip blends visually with the cards next to it.(5) Strip metrics changed between page refreshes
Hydration was picking "most recent terminal job", which shifted as background jobs completed. Estimated max and Actual could read different values second-to-second. Fix:
localStorage.refreshAll, so the strip shows the last-seen values immediately on first paint.(6) Admin tab landing + sidebar order
#admininstead of#invoke.Cost-calculation audit (single, burst, files, codebase)
Verified live, end-to-end, that every path produces the formula's math to 1e-9 precision:
Test plan
pytest -q— 179 passed (1 new test for /stats scope).app.js?v=22,styles.css?v=16.