Skip to content

v1.8.0

Choose a tag to compare

@github-actions github-actions released this 08 Oct 09:06
· 272 commits to main since this release
8023010

TokenFuse 1.8.0

Who a refused call is filed under, and what a call was charged at, made
visible everywhere a person reads them.

  • The Cloud files a call refused for identity under the credential that made
    it, as the FOCUS export has since 1.7.0, and counts every Breaker reason as
    evidence.
  • The dashboard shows a refused run as refused, with its reason, and draws the
    refused calls.
  • A call charged at the fallback rate is visible in the Cloud and on the
    dashboard, per run, per model and across the fleet.
  • A gateway says which price book it charges with, at GET /v1/price-book.
  • A call forwarded under TOKENFUSE_IDENTITY_STRICT=warn is marked as such in
    the trace, the FOCUS export, the Cloud and the dashboard.

This is a minor release because it adds a gateway route, GET /v1/price-book
(behind the admin keys, like the other observability routes), a trace column,
identity_reason, and a FOCUS export column, x_identity_reason, both
appended after the existing ones. The Cloud's
/v1/runs and /v1/summary gain fields and its ingest reads two more keys a
gateway sends; nothing is renamed or removed, and nothing frozen in
compat/1.0.json moves. The umbrella crate and both client SDKs move to
1.8.0 with no client behavior change.

Fixed

  • The Cloud trusted 7 of the 9 Breaker reasons as evidence (#373, invariant
    83).
    • The defect. unit_budget_exceeded and identity_mismatch were never
      added to the Cloud's list of decisions it trusts. /v1/compliance counted
      no refusal for identity and no unit's cap, and a caller refused on every
      call went quiet and was reported run_stalled, naming the agent it
      claimed.
    • The fix. All nine are trusted, and the test that holds the list reads
      the reasons from contracts/tokenfuse-constants.json, so a tenth cannot
      be left out again.
  • The Cloud filed a refusal for identity under the agent it claimed (#373,
    invariant 84).
    • The defect. The gateway has always sent the credential (key_id) with
      every record, and the Cloud dropped it. An impersonation's refusals
      landed on its victim:
      • /v1/agents gave the victim the impersonation's run;
      • /v1/spend counted the refusals as the victim's blocked calls;
      • the dashboard's Owners card counted the victim among the key owner's
        agents;
      • fanout_explosion could raise an incident naming the victim.
    • The fix. Such a call is filed under key:<key_id>, as the FOCUS
      export files it, or under nobody when client keys are off. It never takes
      over a run an admitted call named, a credential is never counted as an
      owner's agent, and no incident names an agent for it.

Added

  • A call forwarded under identity warn mode is marked (#377, invariant 87).

    • The defect. With TOKENFUSE_IDENTITY_STRICT=warn the gateway forwards
      a call whose credential may not speak as the agent id it named. Only the
      answer's x-fuse-identity header said so; its trace row, its FOCUS row and
      the Cloud's figures read like an honest call under the claimed id.
    • The marker.
      • A trace column, identity_reason, holds the identity check's own word,
        such as agent_id_not_allowed. It is set on every row of a forwarded
        call, and also on a refusal for identity, whose finer reason was
        previously only in the 403.
      • The FOCUS export appends x_identity_reason after x_block_reason.
    • Where the marker reaches.
      • The Cloud counts these calls per run (identity_warned) and for the
        fleet (identity_warned_calls), and keeps the latest reason when it is
        one of the gateway's own words.
      • The dashboard shows identity · warn beside the run's status.
    • What did not change. A forwarded call is still an admitted, spent row
      filed under the id it claimed. Warn mode records what it would do; enforce
      is what refiles it.
  • A refused run reads as refused (#375, invariant 86).

    • Each run on /v1/runs now carries blocked (its refused calls) and
      last_decision (its latest call's decision, by the call's own time).
    • The dashboard's Runs table shows refused · <reason> where it showed
      live, and N refused under the call count.
    • The refused calls per minute that /v1/series always served are now
      drawn under the burn-rate line.
  • A fallback price is visible across the fleet (#375, invariant 86).

    • The gateway tells the Cloud the basis it charged each admitted call at,
      known or fallback, the same word as x-fuse-price. The trace's
      columns do not change.
    • /v1/runs carries fallback_calls and basis_unreported_calls per run.
      /v1/summary carries the same two for the fleet, plus fallback_models
      (calls per model id, bounded at 256 ids).
    • The dashboard marks a model charged at the fallback, and a Fallback-priced
      tile counts those calls across the fleet. It also counts the calls from
      gateways older than 1.8.0, which name no basis.
  • GET /v1/price-book on the gateway (#374, invariant 85).

    • It reports the rows in the book and in the built-in book, and whether a
      TOKENFUSE_PRICE_BOOK file is in effect.
    • It names the model ids that file replaced and added, and gives the
      fallback rates.
    • It names the model ids charged at the fallback since the process started:
      at most 100, each cut at 256 bytes.
    • It sits behind TOKENFUSE_ADMIN_KEYS, like /v1/runs and
      /v1/policy-plane.
  • Documentation (#372).

    • The README says x-fuse-price: known covers rows from
      TOKENFUSE_PRICE_BOOK too.
    • docs/02-architecture.md describes the price book that ships. It is not
      versioned, the fallback is fixed, and an unknown model is never blocked.

Upgrade

  • Upgrade the Cloud and the gateways together for the new figures.
    • A 1.8.0 Cloud reads a 1.7.x gateway's records as before. It counts their
      admitted calls as "no basis reported", and the dashboard's tile says how
      many there were.
    • A 1.7.x Cloud ignores the two keys a 1.8.0 gateway adds.
  • A FOCUS consumer that reads columns by name needs nothing. One that
    checks the exact header sees x_identity_reason at the end. Trace segments
    written before 1.8.0 export the column empty.
  • A Cloud snapshot from before 1.8.0 loads. Its runs and totals read the
    new counts as zero, and its existing figures keep the attribution they were
    folded with. Only records ingested after the upgrade are filed under the
    credential.
  • Nothing to configure. GET /v1/price-book is behind the admin keys you
    already set, open on a loopback bind with none, as the other observability
    routes are.

Not proven

  • No live call to any provider, and no live Cloud, for this release. The
    Cloud figures are held by tests through /v1/ingest and the read routes.
    The gateway's price_basis is held by a test that runs the real binary
    against a capturing control plane.
  • The dashboard was checked by eye against a mock Cloud serving these
    shapes, not by a test, and not against a live Cloud.
  • The Cloud's list of identity reasons is a copy of the gateway's. A reason
    the gateway adds later is counted but not shown until the Cloud learns it.
  • tokenfuse top (the terminal view) does not show the price basis.
  • The fallback list on GET /v1/price-book is process-local, and its
    memory is emptied past 8,192 model ids.