DEV Community

Alex Zhu
Alex Zhu

Posted on

Spend a Free Token Grant Like It's Production: A Ledger SOP With Three Roles and a Gate Script

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.

  1. Run one representative job and record the token count your tool reports for that single run.
  2. Multiply by the planned run count for the pilot window, then by 1.5 for retries and re-runs.
  3. Write the number into envelopes.json, one key per workload, and commit both files.
  4. Record every run as one JSON line with ts, workload, tokens, and run — the run id 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
Enter fullscreen mode Exit fullscreen mode

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))
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

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; jq is 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)