Picture the third Tuesday of a pilot: the grant is gone, nobody can name the workload that ate it, and the one job that mattered is now being throttled by its own team. That is not a model problem and it is not a capacity problem — it is an accounting problem. Free tokens and a free server make the first experiment cheap, but they also remove the invoice that would normally tell you, painfully and on time, that a retry loop is spending your budget. This post is the playbook I would paste into a team wiki before anyone points a job at a grant: three roles, one gate script, and a stop rule that does not depend on somebody happening to notice.
The scenario above is a composite, not a customer story. The mechanics are ordinary, which is exactly why the fix can be a page of Markdown and forty lines of Python.
1. Why a grant without a ledger fails quietly
Three failure modes show up in almost every pilot that skips bookkeeping. First, unattributed spend: the usage dashboard shows one aggregate number per day, so no one can say whether the cost came from the ticket summarizer or the scraper. Second, retry amplification: an agent that retries three times looks like one job in your logs but bills like four, and the run count stays flat while tokens climb. Third, no stop authority: the person who owns the workload is also the person who decides to keep it running, so the halt never happens until the grant is empty.
None of these need a platform change to fix. You need per-run token counts in a file you control, an envelope per workload, and someone other than the spender holding the stop button.
Which workloads belong on a free grant at all
| Workload shape | Belongs on a grant? | Reason | Guard you must add |
|---|---|---|---|
| Bounded batch (summarize 200 tickets, one pass) | Yes | Finite and measurable per run | Per-run cap + retry ceiling |
| Interactive chat for a whole team | No, not yet | Unbounded, attribution is per-seat and invisible | Ship attribution before access |
| Nightly cron with automatic retries | Only with a ceiling | Classic amplification source |
max_attempts = 2, backoff, alert on 3rd |
| Extraction over a large corpus | Yes, behind an envelope | Cost is roughly linear, good pilot material | Sample 1%, extrapolate, then open |
| Anything you cannot count per run | No | Your ledger would be fiction | Add token counts to the logs first |
The last row is the one teams argue about. If your tooling cannot emit tokens per run, stop and instrument it; a ledger built from estimates will pass the gate and still leave you blind at the worst moment.
2. Three roles and two handoffs
| Role | Owns | Cadence | Never does |
|---|---|---|---|
| Workload Owner | The job, its acceptance test, and the envelope request | Writes the request once, reviews weekly | Halts their own workload |
| Meter Keeper |
ledger.jsonl, deduplication, the gate output |
Runs the gate twice a week | Approves new workloads |
| Stop Authority | The halt call at the stop threshold | On-call for the pilot window | Edits the ledger |
The handoffs are short enough to write on one line each. Owner to Meter Keeper: the envelope request plus the source of per-run token counts, delivered before the first production run. Meter Keeper to Stop Authority: the gate output whenever any workload reaches the warning band, with the offending workload named. Stop Authority to Owner: a written halt notice, and resumption requires a written fix — a retry ceiling, a smaller batch, or a new envelope.
Separating the spender from the stopper feels bureaucratic for a two-person team, and for a two-person team it probably is. Keep the split for any pilot where more than one person can trigger a run, because that is where attribution quietly dies.
3. Set envelopes in tokens, not money
Money is the wrong unit during a pilot, because the price can change while your grant cannot. Derive each envelope from one measured run, the expected run count, and a retry allowance: envelope = tokens_per_run × planned_runs × 1.5. Round up, write it down, and keep one envelope per workload per model — token counts from different tokenizers are not comparable, so mixing models in a single ledger column turns your percentages into noise.
- Run one representative job and record the token count your tool reports for that single run.
- Multiply by the planned run count for the pilot window, then by 1.5 for retries and re-runs.
- Write the number into
envelopes.json, one key per workload, and commit both files. - Record every run as one JSON line with
ts,workload,tokens, andrun— therunid is what makes amplification visible.
# Append one measured run. In practice your tool writes this line; here it is by hand.
python3 - <<'PY'
import json, pathlib
row = {"ts": "2026-10-20T09:00:00Z", "workload": "summarize-tickets",
"tokens": 18432, "run": "r-0413"}
with pathlib.Path("ledger.jsonl").open("a", encoding="utf-8") as fh:
fh.write(json.dumps(row) + "\n")
PY
With 18,432 tokens per run, 200 planned runs, and the 1.5 allowance, the envelope is 5,529,600 tokens; round it to 5,500,000 and you have a number a reviewer can check in ten seconds.
4. The gate script
This is the artifact. It reads the ledger, compares each workload to its envelope, and returns an exit code your scheduler or CI can act on. Standard library only, Python 3.9 or newer.
#!/usr/bin/env python3
"""token_gate.py — enforce per-workload token envelopes from a JSONL ledger.
Exit codes: 0 ok, 10 warning (>=60%), 20 stop (>=85%), 30 halt (>=100%),
10 if any workload appears with no envelope.
"""
import json
import pathlib
import sys
from collections import defaultdict
WARN, STOP, HALT = 0.60, 0.85, 1.00
STATE_CODE = {"ok": 0, "warn": 10, "stop": 20, "halt": 30, "unbudgeted": 10}
def load_ledger(path):
totals, runs = defaultdict(int), defaultdict(set)
with open(path, encoding="utf-8") as fh:
for lineno, line in enumerate(fh, 1):
line = line.strip()
if not line:
continue
try:
row = json.loads(line)
except json.JSONDecodeError as exc:
raise SystemExit(f"ledger line {lineno}: {exc}")
totals[row["workload"]] += int(row["tokens"])
runs[row["workload"]].add(row.get("run", "?"))
return totals, runs
def evaluate(totals, runs, envelopes):
report, worst = [], 0
for name, cap in sorted(envelopes.items()):
used = totals.get(name, 0)
pct = (used / cap) if cap else 1.0
state = ("halt" if pct >= HALT else "stop" if pct >= STOP
else "warn" if pct >= WARN else "ok")
worst = max(worst, STATE_CODE[state])
report.append({"workload": name, "used": used, "cap": cap,
"pct": round(pct * 100, 1),
"runs": len(runs.get(name, ())), "state": state})
for name in sorted(set(totals) - set(envelopes)):
worst = max(worst, STATE_CODE["unbudgeted"])
report.append({"workload": name, "used": totals[name], "cap": None,
"pct": None, "runs": len(runs[name]),
"state": "unbudgeted"})
return report, worst
def main(argv):
if len(argv) != 3:
print("usage: token_gate.py LEDGER.jsonl ENVELOPES.json", file=sys.stderr)
return 64
totals, runs = load_ledger(argv[1])
envelopes = json.loads(pathlib.Path(argv[2]).read_text(encoding="utf-8"))
report, code = evaluate(totals, runs, envelopes)
for row in report:
print(json.dumps(row, sort_keys=True))
return code
if __name__ == "__main__":
sys.exit(main(sys.argv))
Run it the same way every time so the output is comparable across weeks:
python3 token_gate.py ledger.jsonl envelopes.json; echo "exit=$?"
# {"cap": 5500000, "pct": 71.4, "runs": 186, "state": "warn", "used": 3927000, "workload": "summarize-tickets"}
# exit=10
One jq line catches retry amplification early, because a looping job owns the top of this list:
# Top five single runs by tokens — retry loops appear here before they appear in totals.
jq -r '[.workload, .run, .tokens] | @tsv' ledger.jsonl | sort -k3,3nr | head -5
5. A test that proves the gate fires
A gate nobody tested is a comment with a sys.exit in it. This stdlib-only test writes three small ledgers and asserts the exit codes you will actually act on.
# test_token_gate.py — run with: python3 test_token_gate.py
import json, pathlib, subprocess, sys, tempfile
def write(path, rows):
path.write_text("\n".join(json.dumps(r) for r in rows) + "\n", encoding="utf-8")
def main():
with tempfile.TemporaryDirectory() as tmp:
tmp = pathlib.Path(tmp)
(tmp / "envelopes.json").write_text(
json.dumps({"summarize-tickets": 1000}), encoding="utf-8")
write(tmp / "warn.jsonl", [{"workload": "summarize-tickets", "tokens": 600, "run": "r1"}])
write(tmp / "stop.jsonl", [{"workload": "summarize-tickets", "tokens": 500, "run": "r1"},
{"workload": "summarize-tickets", "tokens": 350, "run": "r2"}])
write(tmp / "unbudgeted.jsonl", [{"workload": "scraper", "tokens": 10, "run": "r1"}])
for ledger, expected in [("warn.jsonl", 10), ("stop.jsonl", 20), ("unbudgeted.jsonl", 10)]:
proc = subprocess.run(
[sys.executable, "token_gate.py", str(tmp / ledger),
str(tmp / "envelopes.json")], capture_output=True, text=True)
assert proc.returncode == expected, \
f"{ledger}: got {proc.returncode}, want {expected}\n{proc.stdout}{proc.stderr}"
print(f"ok {ledger} -> exit {proc.returncode}")
print("all gate cases pass")
if __name__ == "__main__":
main()
I have not run this against your tooling, only against the three synthetic ledgers above, so treat the numbers as structure rather than evidence. If your ledger has a different field name than tokens, change the one line in load_ledger and re-run the test before trusting the output.
6. The wiki page you paste
Keep it to one screen. If it does not fit, the pilot is too complicated to audit.
# Token Envelope Run — <pilot name>
## Scope
Workloads allowed on the grant: <list>. Everything else needs a new envelope.
Model(s) in this ledger: <one per ledger column>.
## Roles
- Workload Owner: <name> — writes the envelope request, reviews weekly.
- Meter Keeper: <name> — owns ledger.jsonl, runs the gate Tue/Fri.
- Stop Authority: <name> — halts workloads; resumes only after a written fix.
## Thresholds
60% of envelope -> warning posted in <channel>.
85% of envelope -> Stop Authority halts the workload; Owner gets a written notice.
100% -> no new runs until a new envelope is approved in writing.
Unbudgeted workload seen -> treated as a warning, never as free capacity.
## Cadence
Tue/Fri: gate output pasted in <channel> with the exit code.
Friday: reconcile run count vs token count; flag any workload above 1.5x tokens per run.
## Exit criteria for the pilot
Acceptance test passes, spend is inside envelope, and the ledger can name every run.
Two fields do the real work here: "Model(s) in this ledger" and "Unbudgeted workload seen". Skip them and you will eventually compare percentages across tokenizers that counted differently, which produces confident, wrong percentages.
7. Where a free tier fits, and what it cannot fix
A free tier changes the cost of running the exercise, not the discipline it requires. MonkeyCode's current offer includes free model access, a free server option, and a promotion advertised as 10 million free tokens — all of that is what the operator states, and quotas on any promotion change, so read the offer page on the day you plan around the number rather than trusting this paragraph.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
What the free tier removes is the procurement conversation before the pilot starts, which is often the whole reason the pilot never starts. What it does not remove is the need to know which workload spent what, and an offer of free tokens cannot tell you that — only your ledger can. Treat the grant as the budget you are auditing, not as a reason to skip the audit.
Who should not use this approach
- Solo builders on a weekend project. One envelope and one person is theatre; just log tokens and move on.
- Teams without per-run token export. If the numbers are estimates, the gate returns confident fiction — instrument first.
- Workloads where tokens are not the binding constraint. If latency, GPU minutes, or rate limits stop you first, build that meter instead.
- Anyone mixing models in one ledger column. Percentages across tokenizers are not comparable; split the ledger.
- Teams treating this as a security control. It is an accounting control; it will not stop a determined caller, only make spend visible.
If you want to run the exercise end to end, start from the current free-tier offer page, paste the wiki block above into your team space, and let the gate script fail a synthetic ledger before a real workload ever reaches 85%. The first week you catch an amplification loop at the warning band instead of in the post-mortem is the week this page pays for itself.
References and scope notes
- The script and test above target Python 3.9+ with the standard library only;
jqis required for the one-liner in section 4. - Threshold constants 0.60/0.85/1.00 are a starting convention, not a recommendation derived from benchmarks; change them in one place,
WARN/STOP/HALT. - Token counts are tokenizer-specific by definition, which is why the SOP keeps one model per ledger column and one envelope per workload.
- Free model access, the free server option, and the 10 million token promotion are operator-supplied availability claims; verify current terms on the offer page before planning capacity around them.
Top comments (0)