This is Time's worker PR #167 for #82 (sonnet via Time), re-applied onto current main. The router (#169) landed beside it at the same spots in test_time.py and CHANGELOG.md, so #167 was mergeable: false. Time can't bring a branch up to date yet (#123), so the CEO re-cut it, as AGENTS.md says.
budget_check(route) paces each call to its pool's allowance.
Expiring credit: (balance − spent since as_of) / days to reset × TIME_PACE.
A window pool: window_usd per window.
No pool: TIME_DAILY_USD, as before.
The monthly cap stays global and hard, and TIME_CAP_SLACK applies to the pool's allowance.
Ledger rows carry pool. doctor prints each pool, and Astra's old-path log line shows spend per pool.
time/pools.json ships [], so nothing changes until it is filled in.
One change on top, a bug in #167:pools() read time/pools.json from the checkout. But every workflow here checks out only .github/time (sparse), so a filled-in pools.json would have been invisible to the heartbeat, venture and Astra alike, and the daily cap would have kept pacing everything silently. It now reads the file through the contents API once per run, like the ledger. Missing or unreachable means no pools. Malformed still fails loudly. Test 82 gains the API read and the 404 case.
Tests:test_time.py passes locally on this branch's tree (ALL OK 80, ALL OK 82).
Once this lands: filling time/pools.json with the Anthropic credit is the owner's or CEO's call. The suggested entry is {"name": "anthropic-credits", "kind": "expiring", "balance_usd": <balance>, "as_of": "<date read>", "resets_at": "2026-11-08", "routes": ["anthropic"]}.
This is Time's worker PR #167 for #82 (sonnet via Time), re-applied onto current main. The router (#169) landed beside it at the same spots in `test_time.py` and `CHANGELOG.md`, so #167 was `mergeable: false`. Time can't bring a branch up to date yet (#123), so the CEO re-cut it, as AGENTS.md says.
Closes #82
**The worker's change, as written:**
- `pools()` / `pool_for` / `window_bounds` / `pool_spend` / `pool_spent` / `allowance`.
- `budget_check(route)` paces each call to its pool's allowance.
- Expiring credit: (balance − spent since `as_of`) / days to reset × `TIME_PACE`.
- A window pool: `window_usd` per window.
- No pool: `TIME_DAILY_USD`, as before.
- The monthly cap stays global and hard, and `TIME_CAP_SLACK` applies to the pool's allowance.
- Ledger rows carry `pool`. `doctor` prints each pool, and Astra's old-path log line shows spend per pool.
- `time/pools.json` ships `[]`, so nothing changes until it is filled in.
**One change on top, a bug in #167:** `pools()` read `time/pools.json` from the checkout. But every workflow here checks out only `.github/time` (sparse), so a filled-in `pools.json` would have been invisible to the heartbeat, venture and Astra alike, and the daily cap would have kept pacing everything silently. It now reads the file through the contents API once per run, like the ledger. Missing or unreachable means no pools. Malformed still fails loudly. Test 82 gains the API read and the 404 case.
**Tests:** `test_time.py` passes locally on this branch's tree (`ALL OK 80`, `ALL OK 82`).
**Once this lands:** filling `time/pools.json` with the Anthropic credit is the owner's or CEO's call. The suggested entry is `{"name": "anthropic-credits", "kind": "expiring", "balance_usd": <balance>, "as_of": "<date read>", "resets_at": "2026-11-08", "routes": ["anthropic"]}`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_017K4vyY3yUD3GsvoZaAtKkD
The worker's change for #82 (PR #167, by sonnet via Time), re-applied onto main after the router (#169) landed
beside it. One change on top: pools.json is read through the contents API once per run, like the ledger, because
every workflow checks out only .github/time and a file on disk was invisible to all of them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017K4vyY3yUD3GsvoZaAtKkD
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
This is Time's worker PR #167 for #82 (sonnet via Time), re-applied onto current main. The router (#169) landed beside it at the same spots in
test_time.pyandCHANGELOG.md, so #167 wasmergeable: false. Time can't bring a branch up to date yet (#123), so the CEO re-cut it, as AGENTS.md says.Closes #82
The worker's change, as written:
pools()/pool_for/window_bounds/pool_spend/pool_spent/allowance.budget_check(route)paces each call to its pool's allowance.as_of) / days to reset ×TIME_PACE.window_usdper window.TIME_DAILY_USD, as before.TIME_CAP_SLACKapplies to the pool's allowance.pool.doctorprints each pool, and Astra's old-path log line shows spend per pool.time/pools.jsonships[], so nothing changes until it is filled in.One change on top, a bug in #167:
pools()readtime/pools.jsonfrom the checkout. But every workflow here checks out only.github/time(sparse), so a filled-inpools.jsonwould have been invisible to the heartbeat, venture and Astra alike, and the daily cap would have kept pacing everything silently. It now reads the file through the contents API once per run, like the ledger. Missing or unreachable means no pools. Malformed still fails loudly. Test 82 gains the API read and the 404 case.Tests:
test_time.pypasses locally on this branch's tree (ALL OK 80,ALL OK 82).Once this lands: filling
time/pools.jsonwith the Anthropic credit is the owner's or CEO's call. The suggested entry is{"name": "anthropic-credits", "kind": "expiring", "balance_usd": <balance>, "as_of": "<date read>", "resets_at": "2026-11-08", "routes": ["anthropic"]}.🤖 Generated with Claude Code
https://claude.ai/code/session_017K4vyY3yUD3GsvoZaAtKkD