Usage records for external meters — billed dollars, per-model tokens, aux spend (k0nnx, kq39p, kcajh)
Every dollar figure Cyberine keeps now travels with the model and the token counts behind it, so a meter outside Cyberine (tokenburn, a spreadsheet) can price it again or check it without guessing. There is nothing to switch on and no new environment variable.
Provider-billed cost on a loop worker (k0nnx): when an OpenAI-wire provider puts its own cost on the final usage chunk (OpenRouter's usage.cost), the loop worker stores it as usage.billedUsd on the workerRuns entry and usage.costUsd becomes that figure plus any delegate-subtask cost, so run cost, the fleet Cost column, the daily cap and cyberine cost all read the billed amount instead of the rate-table estimate. A run where any round of the worker lacked a cost keeps the table estimate and has no billedUsd. The chat planner already did the same through providerReportedCostUsd in src/chat/providerCost.ts.
Per-model usage in the global run index (kq39p): each ~/.cyberine/runs/<runId>.json entry carries a usage array with one object per source, provider, model and billing class: calls, inputTokens, cacheHitTokens, outputTokens, billedUsd (provider-reported) and estimatedUsd (rate-table or CLI-reported). source is worker or aux in a run record (a chat session adds chat entries under sessionTokens); costModel is subscription, metered, free-local or free, and subscription marks notional cost. The entry is rewritten with the rest of the record on every run write, so it still prices after the run directory, worktree or temp dir is gone.
Aux and chat records (kcajh): each paid judge, router, re-ranker or planner call appends model, token counts and a billed flag to ~/.cyberine/credits/aux-spend.jsonl next to its usd; inside a run the same detail folds into run.json as auxUsage (the dollar total stays in auxCostUsd). Worker spend rows in ~/.cyberine/credits/events.jsonl and credit-units.jsonl also name the model and tokens. A chat session keeps sessionTokens.auxUsage (compaction, handoff and run-report turns) next to auxUsd.
jq '.usage' ~/.cyberine/runs/<runId>.json
tail -n 3 ~/.cyberine/credits/aux-spend.jsonl
jq '.sessionTokens.auxUsage' ~/.cyberine/chat-sessions/<sessionId>.json
npm run selftest:run-usageKnown limitations and deferred work:
- Only providers that report a cost on the usage chunk get
billedUsd; DeepSeek, Moonshot and the rest stay on the rate table, andbilledUsdis never invented from tokens. ~/.cyberine/credits/spendcap-events.jsonlanddailycap-reservations.jsonlstay dollar-only: they are cap bookkeeping, not usage records.- Runs and ledger rows written before these changes are not backfilled; an old run with aux dollars but no detail shows one
unknownprovider aux entry in its new index record, and a pre-kq39p index record has nousagekey until its run is written again. - The non-streaming judge path reads
usage.costfrom the response body; the aux ledger prunes to the current UTC day past 64 KB, so an external meter must read it at least daily. - Not verified against a live OpenRouter response from this change: the fixtures are a local fake server, and no provider was called.
Task footprint estimator — history-driven budget planning (kx9rt, calibrated in k5m89)
planBudget() decides whether a step can spawn all its workers, must chunk into a handoff chain, should degrade, or has to abort. Its cost side comes from the credit ledger above; its SIZE side...
Hard spend cap — opt-in, race-free ceiling across ALL providers
CYBERINECREDITMINUSD above is a SOFT, per-provider gate: it reads the folded balance and down-ranks/skips a worker, but two concurrent dispatches can each read "balance ok" moments apart and,...