DEV Community

Emery Chen
Emery Chen

Posted on

Do Not Cite an Agent Run You Cannot Price

You should reject an agent run that cannot name its cost. A free server does not waive that recording rule. Zero dollars is still a number you must store.

Stop praising unlabeled results

Clean prompts are not the same as clear evidence. A short instruction can hide a messy execution path. You need the bill, the placement, and the model id.

This piece argues for a hard gate, not a soft tip. Incomplete manifests should fail before anyone reads the answer. A clever result without placement is not evidence.

Free access creates a new lie

Free model access feels harmless during the first hour. You try another prompt and skip the usage log. No invoice arrives, so the missing fields feel harmless.

That habit damages an eval set within days. Later you cannot separate a local fluke from a hosted fluke. You also cannot separate a free host from a paid host.

A missing amount should fail the test immediately. A missing server class should fail the test immediately. A missing model id should fail the test too.

Placement belongs in the artifact

The same prompt can shift when the server changes. Timeouts, tool reach, and rate limits all move. Your notes should name the placement beside the output.

A screenshot cannot support a serious merge decision. A pasted chat log is not an audit record either. Write the placement into the file you actually keep.

Stick to three labels and refuse extras mid-week. Use local for a machine you control yourself. Use free_hosted or paid_hosted for a vendor machine.

Extra labels quickly become excuses for lucky runs. Your reviewer cannot compare runs that invent names. Pick the three labels and keep them stable.

How to read the table

Use the table before you store any agent run. Every class still needs a model id and token counts. Only free_hosted may store an amount of zero.

Question local free_hosted paid_hosted
Record model id? Yes Yes Yes
Record token counts? Yes Yes Yes
Amount field Measured or estimated Must be 0 Must be above 0
Merge evidence? Only after the checker Only after the checker Only after the checker
Blank cost allowed? No No No

Local runs must show a measured or estimated amount. Paid hosted runs must show an amount above zero. None of these rows prove the answer itself is right.

Fields that earn trust

Keep one JSON manifest beside each saved output. Do not bury those fields inside a chat scrollback. A pretty trace without required fields is only a story.

Require these fields on every cited run:

  • Require a run id so retries do not overwrite evidence.
  • Require the model id exactly as the provider named it.
  • Require a server class from the three labels above.
  • Require input tokens and output tokens as integers.
  • Require a currency code and a numeric amount.
  • Require a UTC timestamp and a prompt hash.

Optional notes can wait until the next revision. Required fields cannot wait for a cleanup pass. If a host omits usage, the run is not evidence.

Sample manifest

The sample below is illustrative, not a captured run. Replace every value before you treat it as proof. Do not commit a toy hash and call it evidence.

{
  "run_id": "run-2041",
  "model_id": "provider-model-id",
  "server_class": "free_hosted",
  "input_tokens": 812,
  "output_tokens": 146,
  "currency": "USD",
  "amount": 0,
  "started_at": "2026-09-25T09:00:00Z",
  "prompt_sha256": "replace-with-real-hash"
}
Enter fullscreen mode Exit fullscreen mode

Run the proposed checker

The following script is a proposal, not a lab result. It was not executed while this article was written. Put it in your repo and run it on real files.

import hashlib
import json
import sys

REQUIRED = (
    'run_id',
    'model_id',
    'server_class',
    'input_tokens',
    'output_tokens',
    'currency',
    'amount',
    'started_at',
    'prompt_sha256',
)
CLASSES = {'local', 'free_hosted', 'paid_hosted'}

def fail(message):
    raise SystemExit(message)

def validate(manifest_path, prompt_path):
    data = json.load(open(manifest_path, encoding='utf-8'))
    missing = [key for key in REQUIRED if key not in data]
    if missing:
        fail('missing fields: ' + ', '.join(missing))
    if data['server_class'] not in CLASSES:
        fail('unknown server_class')
    if data['input_tokens'] < 0 or data['output_tokens'] < 0:
        fail('token counts cannot be negative')
    amount = data['amount']
    if amount < 0:
        fail('amount cannot be negative')
    if data['server_class'] == 'free_hosted' and amount != 0:
        fail('free_hosted must record zero')
    if data['server_class'] != 'free_hosted' and amount == 0:
        fail('zero amount requires free_hosted')
    digest = hashlib.sha256(open(prompt_path, 'rb').read()).hexdigest()
    if digest != data['prompt_sha256']:
        fail('prompt hash mismatch')
    print('manifest ok')

if __name__ == '__main__':
    validate(sys.argv[1], sys.argv[2])
Enter fullscreen mode Exit fullscreen mode

CI command

Run the checker before you comment on any result. Pass the manifest path and the prompt file path. A non-zero exit must fail the job in CI.

python check_manifest.py runs/run-2041.json prompts/run-2041.txt
Enter fullscreen mode Exit fullscreen mode

A green chat reply is not a green CI job. Keep the command in the same repo as the prompt. Reviewers should rerun it instead of trusting a screenshot.

A workflow you can repeat

Use this order for every run you might cite:

  1. Save the prompt bytes to a file before the call.
  2. Call the model on local or on the free server.
  3. Write the manifest with class, ids, tokens, and amount.
  4. Hash the prompt file and store that digest.
  5. Run the checker and keep the exit code.
  6. Share the answer only after the checker passes.

Stop at the first missing field. Do not patch the file after the review starts. A late edit is a new run, so give it a new id.

Limits you should say out loud

A valid manifest does not make the answer correct. It only shows that you recorded the run honestly. You still need assertions on the output text.

Vendor token counts can disagree with your own estimate. Do not write a guess into the token fields. Unknown usage means the run fails this gate.

Prices move, and free offers move as well. Record what was true for that specific run. Do not describe a free offer as a permanent promise.

This gate will reject casual exploratory notes on purpose. Keep scratch notes outside the evidence folder entirely. Mixing scratch files with evidence creates false confidence.

Use a free server without self-deception

A free hosted server can still teach you something. It helps when your laptop is a weak stand-in. It helps nothing if you delete the manifest afterward.

Disclosure: This article was prepared as part of MonkeyCode's product outreach.

MonkeyCode is an open-source project with free model access. It also offers a free server option for hosted runs. Those availability claims are the only product facts used here.

This article does not claim quotas, hardware, or fixed model lists. Check current project docs before you depend on either offer. Terms can change, so your manifest must stay specific.

Label that path as free_hosted and keep the amount at zero. Copy the model id from the response, not from memory. Then run the checker before you share the output.

If the free path omits token counts, do not backfill them. Mark that run unusable for any merge evidence. Measure on a host that returns usage, or stay local.

Put the checker in the repo before you chase clever prompts. Point one non-production prompt at the free server. See whether the manifest can pass without hand edits.

Who should skip the gate

Skip this gate if your tests never call a model. Fixture checks do not need a cost field at all. Adding a fake cost field would be theater, not engineering.

Skip it when a platform already signs usage exports. Import those exports instead of typing amounts by hand. Hand-typed bills are easy to fake under deadline pressure.

Skip it when you want a demo with no audit trail. This method will slow that kind of demo down. The slowdown is intentional, so pick another format.

Do not use the checker as a safety filter. It does not judge quality or policy risk. It judges whether the run can be priced and placed.

Four questions before you share

Ask these questions before you share a result.

  1. Can you name the model id without opening a chat log?
  2. Can you name the server class in a single word?
  3. Is the amount zero only because the class is free_hosted?
  4. Does the prompt hash match the file you sent?

If any answer is no, withhold the conclusion. Run the prompt again with the manifest in place. Let the checker speak before you write the conclusion.

Exploration can stay fast inside a scratch folder. Evidence stays in the checked folder, separate from scratch. Do not mix those folders when you ask for a merge.

Free access is useful for iteration and dangerous for memory. Write the zero down, or do not cite the run. That is the whole position, and it is not optional.

Top comments (0)