mirror of
https://github.com/hanzoai/chat.git
synced 2026-09-30 20:51:17 +00:00
The credits row was missing for a funded account. The balance is real --
Commerce holds $149,863.17 for the hanzo org -- and chat could never read it:
CommerceClient scoped its service-token call with `X-Hanzo-Org`, which
Commerce does not read on that path. Every call answered 401 "sign in to view
billing", byte-identical to sending no credential at all. The header is
`X-Org-Id`, as `api/billing/me.go` documents and as the LLM gate in
hanzoai/ai has always sent.
Proven against the live service from inside the pod, same token, same URL:
X-Hanzo-Org -> 401, X-Org-Id -> 200 {"available":14986317}.
Nothing caught this because three deliberate fallbacks sit behind it, each
doing exactly what it was written to do: checkBalance fails CLOSED and throws,
the balance controller falls through to the local tokenCredits ledger,
production does not fund that ledger (balance.enabled=false), the read 404s,
and the client renders no balance rather than a wrong one. A wrong header name
came out the far end as silence.
So the header is pinned where it is written, including the spelling that
failed, and the refusal case asserts a THROW rather than a zero -- a 401 must
never read as "this account has no money". Reverting the header turns 3 of the
5 red.
`ask.js` and CloudAgentsClient already sent `X-Org-Id`; this was the one
caller that did not.
Co-authored-by: Hanzo Dev <[email protected]>