• Stefy Lanza (nextime / spora )'s avatar
    runpod: hours nobody ledgered, and a flag the ledger threw away (v0.3.63) · d8984250
    Stefy Lanza (nextime / spora ) authored
    Two gaps I left open last night, both about the ledger telling the truth.
    
    **A pod that went away without a pool noticing was never billed to anyone.** A
    pool closes its own pods' bills — `_terminate` for one it retires, `forget` for
    one RunPod says is gone — and neither runs for a pod only the REGISTRY knew
    about: one orphaned by a restart, or terminated from the console or straight
    through the RunPod API. Observed: pod lgdgfs749chkib, killed by hand, never
    appeared in the ledger while two pods that went through coderai did.
    `close_bill_from_registry()` now computes the hours from the registry's own
    `created` — the only record of when a pod started once no handle exists — and
    records them against the pool it belonged to. Both reaper paths use it, so the
    "terminated as stale" and "vanished from the account" cases cannot drift apart,
    and a pod a pool still holds is deliberately skipped: `forget` ledgers that one,
    and counting it here as well would double-count every pod RunPod reclaims.
    
    **`record_spend` dropped the `reaped` flag it was being handed.** It keeps a
    deliberate allow-list, which is right — the file is persisted and pruned for
    every pod — but the list has to carry what distinguishes one kind of charge from
    another. A pod the reaper killed looked in the file exactly like one a pool
    retired on purpose. `reaped` and `reason` are kept now.
    
    Writing the test for the first fix found a third thing, and it was mine: v0.3.56
    made a stale registry entry stop counting as "known" so the reaper could kill the
    pod it named — but the reconcile was only ever asked about known ids, so that
    same change stopped stale entries being RECONCILED. An entry for a pod that no
    longer exists was then never pruned and its hours never attributed. The reaper
    now reconciles against the whole registry; `known` keeps its one job, which is
    deciding what is shielded from reaping.
    
    9 tests in tests/test_ledger_out_of_band.py, including the double-count guard
    and the pruning regression. test_runpod_client_scale's source anchor moves with
    the change and says why.
    Co-Authored-By: 's avatarClaude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01PxYHWbCAjjjD7A1rhFKtaW
    d8984250
Name
Last commit
Last update
..
admin Loading commit data...
api Loading commit data...
backends Loading commit data...
broker Loading commit data...
cluster Loading commit data...
compose Loading commit data...
frontproxy Loading commit data...
models Loading commit data...
ocr Loading commit data...
openai Loading commit data...
pydantic Loading commit data...
queue Loading commit data...
tasks Loading commit data...
util Loading commit data...
__init__.py Loading commit data...
cli.py Loading commit data...
config.py Loading commit data...
main.py Loading commit data...
platform_paths.py Loading commit data...
system_app.py Loading commit data...