Skip to content

Repair provider usage and Hermes cost contracts - #1234

Merged
iamtoruk merged 10 commits into
getagentseal:mainfrom
avs-io:codex/provider-core-contract-repair
Sep 2, 2026
Merged

Repair provider usage and Hermes cost contracts#1234
iamtoruk merged 10 commits into
getagentseal:mainfrom
avs-io:codex/provider-core-contract-repair

Conversation

@avs-io

@avs-io avs-io commented Sep 2, 2026

Copy link
Copy Markdown
Member

Summary

  • make providerDetails.hasUsage authoritative and fail closed for legacy payloads
  • scope provider history/cache to active provider periods so stale providers and false zero totals do not leak into the menubar
  • preserve Hermes measured/estimated provenance with the v3 session ledger and migration handling
  • keep provider paging arrows navigational and surface only providers with current usage evidence
  • derive versioned Claude family labels so observed ids such as claude-fable-5-1 display as Fable 5.1 without another hand-maintained entry
  • make upgrade verification discover the newly derived daily-cache version instead of hard-coding a version that drifts at every accounting bump

Verification

  • 193 focused model/pricing tests, including Fable and Mythos future-minor regression coverage
  • live CLI proof: claude-fable-5-1 reports Fable 5.1
  • 120 focused TypeScript tests across menubar status, cache carry-forward, Hermes cost/ledger, payload encoding, and provider scoping
  • 56 Electron renderer tests
  • 28 focused Swift tests for provider visibility, reconnect presentation, strip paging, and refresh recovery
  • complete verify:upgrade path: migration, provider parity, stdio parity, worker determinism, warm-cache stability, partial source aging, and durable history
  • clean branch against upstream 41f44edc

This is draft pending maintainer review. The concurrency/reconciliation follow-up is intentionally separated into a dependent draft PR.

avs-io and others added 7 commits September 2, 2026 16:44
…#1132

Two open branches claim daily-cache version 30, so a v30 file on disk carries
unknown accounting. Bump this branch to 31 and move the Hermes
pending-rederive contract version with it, so a v30 file written under getagentseal#1132's
accounting is treated as a foreign prior version: carried forward per slice,
never adopted as the finalized base.

The getagentseal#946 copilot fixture seeded itself at DAILY_CACHE_VERSION - 5, a moving
target that crossed the copilot contract boundary (26) at this bump and
silently stopped granting the entitlement those tests exist to check. Pinned
to 25, which is the fixed historical version the fixture actually means.

Disclosure: the bump re-derives every day whose sources still survive, so
finalized history shifts. On the reviewer's machine Claude moved -0.78
percent. That is a corrected figure replacing a stale cached one, not a loss,
but it is a visible change to numbers users have already seen.
…s with shrunken parses

The provider-scoped overlay blind-set a fresh slice for every date it could
produce one. A settled day's sources age off disk continuously, so that fresh
slice is a lower bound, not a correction, and the overlay replaced finalized
cache days with whatever the surviving files still explained. It ran over the
whole period and over the whole history, so the scoped view could report a
fraction of the same day the all-provider view served off the same cache.

The overlay now routes through mergeDayEntries with guardPartialSurvival:
fresh may FILL a (date, provider) the cache lacks and still wins inside the
settle window, but it can no longer SHRINK a settled day the cache already
holds. Filling has to keep working, because on a cold cache the scoped parse
is the only source a historical day has.

Measured on this machine over 2026-08-03..2026-09-01, comparing scoped
--provider claude against the claude slice of the unscoped run:

  before  $16649.42 / 81812 calls   (short by $291.70 and 2507 calls)
  after   $16941.12 / 84319 calls   (exact match, both fields)
…pend

hasUsage is a new payload field, so every RELEASED CLI omits it. Both decoders
treated the absent case as "derive from cost", which is the strict reading of
a field that is not there: a provider with $0 spend in the period vanished
from the picker even though the user has it and is actively using it on an
included subscription.

Absent now means visible on both surfaces. The strict signal still applies
wherever the CLI actually emits the field, so an explicit false still hides an
idle discovery row. Settings.tsx carried the same fallback and is fixed with
it.
The loader reads only the v3 path, so a hermes-session-ledger.v1.json from an
earlier install sat in the cache dir unread and undeleted. It is dead weight
that can only mislead: the parse-version bump forces a cold re-parse that
rebuilds every cursor from source, so nothing in it is recoverable. Unlink it
when the v3 file is absent.

The v2 test this replaces was vacuous. It wrote a v2 file and asserted the
ledger was empty, but the loader never looks at a v2 path, so it passed
whatever the code did. The replacement uses a real v1 fixture and asserts both
halves: the ledger loads empty AND the v1 file is gone afterwards.
@iamtoruk
iamtoruk marked this pull request as ready for review September 2, 2026 18:50
@iamtoruk
iamtoruk merged commit 3376d76 into getagentseal:main Sep 2, 2026
18 of 19 checks passed
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.

2 participants