# Set up compute.md in one pass

For an AI agent setting up compute.md in the repo of the person it works for. Follow the steps in order. Nothing here is decided for the person: every number and every yes comes from them, and the numbers below are placeholders or labeled examples. Needs Node 18+ for the gate and the meter; the gate and the meter's install step are for Claude Code. Use at your own risk; provided as is (https://www.compute.md/terms).


## 1. Say what you'll set up (two lines)

Tell the person, in about these words:

> compute.md is a skill that makes me size and price compute work with your own quotes, and stay inside a budget, an approval threshold and a hard stop you set. Optionally: a local gate that stops provisioning commands until a plan is checked against your settings, and a local meter that refuses my model calls past a spend cap you set.

## 2. Ask five things, in one message

Ask all five at once and wait for the answers. Don't suggest values as defaults; if you give examples, label them as examples.

1. **Budget**: the most one run (task) may spend, in dollars. If they'd rather set a monthly cap, use `monthly_usd` for it instead of `budget_usd`.
2. **Approval threshold**: ask them before any spend over how many dollars (`approval_usd`).
3. **Hard stop**: nothing temporary runs longer than how many hours (`stop_hours`).
4. **Model-spend cap**: the most your own model calls may cost, in dollars (`model_budget_usd`). If their plan isn't billed per token (a subscription login), a cap in millions of tokens instead (`model_tokens_m`). Both are fine.
5. **Install**: the gate (yes or no) and the meter (yes or no).

## 3. Build their link and save the skill

Their settings link (the person's answers in place of the placeholders; leave out any they skipped):

```
https://www.compute.md/compute.md?budget_usd=<B>&approval_usd=<A>&stop_hours=<H>&model_budget_usd=<M>
```

Or call the MCP tool build_limits with the same settings: it returns the link and Markdown. The link also writes compute.md's defaults for the other core settings (most per hour, idle shutdown, spot, checkpoints, approver, regions...). Show the person the "Your rules" section of the saved file and change anything they want (add it to the link, for example `&idle_minutes=15`).

Save the customized skill where the agent reads skills. Claude Code, in this project:

```bash
mkdir -p .claude/skills/compute && curl -fsS -D - -o .claude/skills/compute/SKILL.md "<their link>" | grep -iE '^x-(skill-limits|limits-notes)'
```

`X-Skill-Limits: custom` means their settings were written in. `X-Limits-Notes` means a value was clamped or ignored: tell the person. For every project, use `~/.claude/skills/compute/SKILL.md` instead. Another agent: save the same file wherever it loads skills or instructions.

## 4. Install the gate and the meter (only after the person says yes)

Skip anything they said no to. First keep a copy of the project's Claude Code settings, so the change can be shown and undone:

```bash
mkdir -p .claude && { [ -f .claude/settings.json ] && cp .claude/settings.json .claude/settings.json.before-compute || echo '{}' > .claude/settings.json.before-compute; }
```

**The gate** (a PreToolUse hook: provisioning commands need a plan in `.compute/plan.json` checked against `.compute/settings.json`; it runs locally and sends nothing):

```bash
mkdir -p .claude/hooks && curl -fsSL https://www.compute.md/hook/compute-gate.mjs -o .claude/hooks/compute-gate.mjs
node .claude/hooks/compute-gate.mjs init "<their link>"
```

init saves the settings to `.compute/settings.json` and adds the hook to `.claude/settings.json`. The hook entry blocks shell commands if the gate itself can't run (`"onFailure": "block"`, Claude Code 2.1.295+).

**The meter** (a proxy on 127.0.0.1 that refuses model calls past the cap; keys pass through and are never stored):

```bash
mkdir -p .compute && curl -fsSL https://www.compute.md/meter/compute-meter.mjs -o .compute/compute-meter.mjs && node .compute/compute-meter.mjs init
node .compute/compute-meter.mjs start --budget-usd <M> --detach
node .compute/compute-meter.mjs install
printf '%s\n' .compute/meter-ledger.json .compute/meter-ledger.json.lock .compute/meter.log >> .gitignore
```

- Cap flags: `--budget-usd` is their model-spend cap in dollars, `--max-tokens-m` their token cap in millions; pass the ones they gave. Add `--period month` (or `day`) if the cap is per month (or day); the default, `run`, counts since the last reset. The caps are saved in `.compute/meter.json`. `--detach` runs it in the background; without it, start runs in the foreground and doesn't return.
- install adds `ANTHROPIC_BASE_URL=http://127.0.0.1:8787/anthropic` and a SessionStart hook to `.claude/settings.json`.
- **Prices**: init writes `.compute/prices.json` as a template with no numbers. The person fills it in with their own per-million prices from their provider's price page or contract. Never fill in, guess or look up a price for them. With an API key, every call to a model with no price is refused, so after the restart in step 5 Claude Code's own calls are refused until the prices are in. (On a subscription login the meter counts tokens and calls, not dollars.)

## 5. Show every change and get a yes

Show the diff of every file you wrote: `git diff` and `git status --short` in a git repo (new files show as untracked: print them), or else the list of files with their contents. For the Claude Code settings:

```bash
diff -u .claude/settings.json.before-compute .claude/settings.json
```

(diff exits 1 when it finds changes; that's expected.) Hooks and the base URL take effect only when a Claude Code session starts. Ask the person for a yes on the `.claude/settings.json` change. On a no, put it back: `mv .claude/settings.json.before-compute .claude/settings.json`. On a yes, delete the copy (`rm .claude/settings.json.before-compute`) and tell them to restart the session for the hooks to load (with the meter and an API key, after they fill in their prices).

## 6. Verify and report

```bash
node .compute/compute-meter.mjs doctor
node .claude/hooks/compute-gate.mjs test "terraform apply"
echo '{"resources":[{"kind":"machine","count":1,"hours":1,"stop_after_hours":1,"idle_stop_minutes":30}]}' > "${TMPDIR:-/tmp}/compute-setup-check.json"
node .claude/hooks/compute-gate.mjs check "${TMPDIR:-/tmp}/compute-setup-check.json"
```

- doctor: lines marked `FAIL` need fixing (exit 1); a `warn` about `.compute/prices.json` means the prices aren't filled in yet.
- test should say `gated`. check reads their settings and, for this test plan with no prices, says `needs_approval` (exit 10): expected, and it shows the gate works. It never approves anything.

Report in a few lines: where the skill was saved, their settings (from `.compute/settings.json` or the skill's "Your rules"), what was installed, what is still the person's to do (prices, the restart), and how to undo it: delete `.claude/hooks/compute-gate.mjs`, `.compute/` and `.claude/skills/compute/`, run `node .compute/compute-meter.mjs stop` first if the meter is running, and remove the gate's, the meter's and the `ANTHROPIC_BASE_URL` entries from `.claude/settings.json`.

## Never

- Never pick their numbers or answer for them, and never treat an example as their choice.
- Never invent, guess or look up prices.
- Never raise the meter's cap, reset it, or unset its base URL yourself; only the person does that.
- Never change settings outside this project unless the person asks.
