well

Every paid call through one door.

one rope, one bucket at a time.

well is one door for every call that costs money or needs a key. A program reserves its estimate before it sends, and well refuses when everything spent and held would pass the budget. After the call the program settles what it was charged, and a call that may have been charged is never sent again blind.

well status --budget judge · its one line of JSON, pretty-printed
$ well status --budget judge
{
  "ok": true,
  "budget": "judge",
  "period": "2026-11",
  "spent_usd": 0.018,
  "held_usd": 0,
  "cap_usd": 20,
  "day": {
    "spent_usd": 0.018,
    "limit_usd": 4
  },
  "week": {
    "spent_usd": 0.018,
    "limit_usd": 10
  }
}

well 0.8.0, as it ships · commit ff8943b · 5 nov 2026

tests
82
invariants
8
network calls
0
runtime dependencies
0

why

Agents spend. The owner pays.

An agent that calls a paid service spends its owner's money, and a mistake costs the same as the work. Each tool keeps its own cap, so each stays under it while together they overspend. A call that timed out may already have been charged, and a plain retry pays twice. Keys sit in files and variables any agent can read. well puts every spender of a budget on one ledger, so one tool's call in flight counts against the next tool's reservation, and the cap holds across all of them.

what it refuses

  • a call with no budget
  • a month over its cap
  • a week or a day over its pace
  • a resend of a call still open
  • a budgets file it cannot read
  • a secret on the command line

the door

Reserve before send. Record the charge.

  1. well reserve

    holds the estimate before the call. It is refused when the month, the week or the day would pass its limit.

  2. well settle

    records what the call was charged, so the hold becomes spend.

  3. well release

    frees a hold whose call never left, was refused by the provider without charge, or was checked against the bill by a person.

  4. well run

    gives one paid call its key from the macOS Keychain, only once the reserve is allowed, and settles by what the call reports.

  5. well status

    shows the month's spent, held and cap, and the day's and week's spent and limit.

  6. well breaches

    lists every month whose settled spend passed its cap. It must stay empty.

A call that may have been charged is never sent again blind.

pacing

A month's cap, spent at a walking pace.

A reserve must fit the month, the week and the day. The day is the 1,440 minutes up to the reserve and the week the 10,080 minutes, so no midnight lets two days of spending through at once.

  • $20 a monththe cap the owner sets
  • $10 a weekits own limit, or the cap times 1.5/4
  • $4 a dayits own limit, or the cap times 3/30

Set in ~/.local/share/well/budgets.json

a refusal

A refusal is one line and exit 1.

The reason names the limit the reserve missed: cap, cap-week, cap-day, unsettled for a call still open, or no-budget.

$ well reserve --budget judge --tool my-tool --key "$key" --usd 0.02
{"ok":true}
$ well reserve --budget judge --tool my-tool --key "$key" --usd 0.02
{"ok":false,"reason":"unsettled"}
$ well reserve --budget judge --tool my-tool --key "$other" --usd 4.5
{"ok":false,"reason":"cap-day"}
$ well reserve --budget nightly --tool my-tool --key "$other" --usd 0.01
{"ok":false,"reason":"no-budget"}
  • exit 0allowed: send the call
  • exit 1refused, and the reason says why
  • exit 2a usage error
  • exit 3a fault: the ledger could not be read or written

A caller sends only on exit 0.

Install

well needs Node 24 or later and runs with no build step. Its keys live in the macOS Keychain. Clone it and link the command:

git clone https://github.com/jahala/well.git
cd well
npm install -g .

Then well status --budget judge

where it sits