DEV Community

Taylor Lin
Taylor Lin

Posted on

Pin the Fixture Hash Before an Agent Score Leaves the Machine

Thursday's pagination card looked done. The agent summary said the tests passed, and the diff touched only list_users.py plus one fixture. Monday's clean worktree failed the same card. The prompt was identical; the sample payload was not.

That gap is what this workflow classifies. A free model call cannot repair a fixture that was never pinned. A free server cannot make two runs comparable when they saw different files.

The walkthrough is a constructed example, not a measured incident. No pass rates are claimed. Use the branch logic locally before any hosted seat is involved.

Glossary

Use these terms as written on the task card. If a field cannot be filled, the tree treats it as missing, and missing is a result rather than a prompt to guess.

Task card. One agent job with a goal, inputs, and the files it may read. A chat transcript is not a task card.

Fixture bundle. Pinned inputs plus the oracle that judges the result. A folder of whatever happened to be in the repo this morning is not a bundle.

Oracle kind. How correctness is judged. This workflow allows pytest, schema, or human. An empty value means there is no oracle.

Mutation scope. What the run may change. Allowed values are read_only, workspace, network, and secrets.

Writable root. The single directory a workspace run may write. If it is unset, the write surface is unnamed.

Leak flag. True when the bundle holds credentials, customer rows, or anything you would not paste into a shared runner.

Stale window. Hours after which a fixture hash is no longer accepted for scoring. You pick the number for your suite. This text does not set a vendor default.

Runner seat. Where the model call and the tool host execute. Store an operator-filled label. Do not infer the seat from a price tier.

Score receipt. A small JSON record of leaf, hash, oracle kind, mutation scope, and runner seat. A model summary is not a receipt.

The four-leaf decision tree

Evaluate the checks in order. Stop at the first match. Later checks do not rescue an earlier failure.

  1. If oracle_kind is missing, or leak_flag is true, the leaf is refuse.
  2. Else if scope is network or secrets, or scope is workspace without a writable root, the leaf is quarantine.
  3. Else if fixture_sha256 is missing, or age_hours exceeds stale_after_hours, the leaf is refresh.
  4. Else the leaf is score.
Order Condition Leaf Next action
1 No oracle, or leak flag set refuse Do not call a model
2 Network, secrets, or unnamed writes quarantine Do not upload the bundle
3 Missing hash, or past the stale window refresh Rebuild locally; do not score
4 Pinned, fresh, and bounded score Bind a runner seat, then run

A free seat does not reorder the table. It is only a candidate after row 4.

Numbered workflow

  1. Write the task card in one file. Name the oracle kind before you open a model session.
  2. Hash the fixture bundle on your machine. Store the digest beside the card, not inside the prompt.
  3. Set mutation scope. If scope is workspace, set exactly one writable root. Reject a card that says "edit the repo" and names no path.
  4. Run the classifier. Branch on the leaf. Do not override refuse or quarantine because a hosted seat is idle.
  5. On score only, bind a runner seat. Keep that model call off any host that can read production credentials.
  6. Write the score receipt in the same commit as the hash. If the seat label is unknown, leave it blank. Do not invent one.

Artifact: classify_fixture.py

Save the following as classify_fixture.py. It is proposal code: run it yourself. It does not contact a network API, and the asserts only lock the branch order.

"""Classify an agent fixture before any runner seat is bound."""

from __future__ import annotations

from dataclasses import dataclass
from enum import Enum
import hashlib
import json
from pathlib import Path


class Leaf(str, Enum):
    REFUSE = "refuse"
    QUARANTINE = "quarantine"
    REFRESH = "refresh"
    SCORE = "score"


@dataclass(frozen=True)
class FixtureCard:
    oracle_kind: str | None
    mutation_scope: str
    writable_root: str | None
    fixture_sha256: str | None
    age_hours: float
    stale_after_hours: float
    leak_flag: bool


def classify(card: FixtureCard) -> Leaf:
    if not card.oracle_kind or card.leak_flag:
        return Leaf.REFUSE
    unsafe_scope = card.mutation_scope in {"network", "secrets"}
    unnamed_write = card.mutation_scope == "workspace" and not card.writable_root
    if unsafe_scope or unnamed_write:
        return Leaf.QUARANTINE
    if not card.fixture_sha256 or card.age_hours > card.stale_after_hours:
        return Leaf.REFRESH
    return Leaf.SCORE


def bundle_sha256(paths: list[Path]) -> str:
    digest = hashlib.sha256()
    for path in sorted(paths, key=lambda item: item.as_posix()):
        digest.update(path.as_posix().encode())
        digest.update(b"\0")
        digest.update(path.read_bytes())
        digest.update(b"\0")
    return digest.hexdigest()


def receipt(card: FixtureCard, seat: str | None) -> dict:
    leaf = classify(card)
    return {
        "leaf": leaf.value,
        "oracle_kind": card.oracle_kind,
        "mutation_scope": card.mutation_scope,
        "fixture_sha256": card.fixture_sha256,
        "runner_seat": seat if leaf is Leaf.SCORE else None,
    }


if __name__ == "__main__":
    refuse = FixtureCard(None, "read_only", None, "abc", 1, 24, False)
    leak = FixtureCard("pytest", "read_only", None, "abc", 1, 24, True)
    quarantine = FixtureCard("pytest", "secrets", None, "abc", 1, 24, False)
    unnamed = FixtureCard("pytest", "workspace", None, "abc", 1, 24, False)
    refresh = FixtureCard(
        "pytest", "workspace", "/tmp/eval/pagination", None, 3, 24, False
    )
    stale = FixtureCard("pytest", "read_only", None, "abc", 48, 24, False)
    score = FixtureCard(
        "pytest", "workspace", "/tmp/eval/pagination", "abc", 3, 24, False
    )
    assert classify(refuse) is Leaf.REFUSE
    assert classify(leak) is Leaf.REFUSE
    assert classify(quarantine) is Leaf.QUARANTINE
    assert classify(unnamed) is Leaf.QUARANTINE
    assert classify(refresh) is Leaf.REFRESH
    assert classify(stale) is Leaf.REFRESH
    assert classify(score) is Leaf.SCORE
    print(json.dumps(receipt(score, seat=None), indent=2))
Enter fullscreen mode Exit fullscreen mode

Run the classifier, then pin a real bundle with files you already have:

python3 classify_fixture.py
find fixtures/pagination -type f -print0 | sort -z | xargs -0 shasum -a 256
Enter fullscreen mode Exit fullscreen mode

The first command should print a score receipt with runner_seat set to null. The second prints digests you computed. Paste a digest into the card. Do not ask a model to invent it.

python3 - <<'PY'
import hashlib
import pathlib
path = pathlib.Path("fixtures/pagination/sample.json")
print(hashlib.sha256(path.read_bytes()).hexdigest())
PY
Enter fullscreen mode Exit fullscreen mode

Local test plan

Case Distinct input Expected leaf
empty oracle oracle_kind is null refuse
leak flag oracle set, leak_flag true refuse
secrets scope mutation_scope is secrets quarantine
unnamed write workspace and root null quarantine
missing hash hash null, age inside window refresh
stale hash hash set, age 48, window 24 refresh
ready card pinned, fresh, workspace root set score

All seven asserts in __main__ must pass before you bind a seat. If you reorder the leaves, change the asserts in the same edit. A green model demo does not replace that check.

Worked leaf: refuse

Card text: "make the users page feel faster." Oracle kind is empty. Leak flag is false. Scope is read_only. A hash may even be present. It does not matter.

The classifier returns refuse. Stop. There is no judgment to record, so a model paragraph would only look like a score. Write the receipt and close the card until an oracle exists.

{"leaf":"refuse","oracle_kind":null,"mutation_scope":"read_only","fixture_sha256":null,"runner_seat":null}
Enter fullscreen mode Exit fullscreen mode

A schema check on page size is enough to leave this leaf later. A summary that says the page looks faster is not an oracle kind.

Worked leaf: quarantine

Card text: "hit staging and confirm pagination." Oracle kind is pytest. Scope is secrets because .env holds a staging token. You might have left leak_flag false. Scope alone is enough to stop.

The leaf is quarantine. Do not upload the bundle to a shared server, free or otherwise. Do not paste the token into a prompt to save a step. Delete the secret and reclassify, or run tools only on a machine you already control, outside this tree.

Quarantine is a block, not a softer score. Idle capacity does not reclassify it.

Worked leaf: refresh

Card: pagination regression. Oracle kind is pytest. Scope is workspace. Writable root is /tmp/eval/pagination. The sample file is 90 hours old. The stale window on the card is 24. The hash field is empty.

The leaf is refresh. Rebuild the expected body from the spec you checked in, then hash the bundle. Do not record a model score against the old file. Two greens on different payloads are not a comparison.

After the digest is stored and age is reset by that rebuild, run classify again. Only a new score result continues. Keep the refresh receipt so the gap stays visible.

{"leaf":"refresh","oracle_kind":"pytest","mutation_scope":"workspace","fixture_sha256":null,"runner_seat":null}
Enter fullscreen mode Exit fullscreen mode

Worked leaf: score

Same pagination card, now pinned. Oracle kind is pytest. Scope is workspace. Writable root is set. Hash is present. Age is 3 hours. Stale window is 24. Leak flag is false.

The leaf is score. Bind a runner seat in the receipt before the call. Keep the model call off any host that can read production credentials.

Disclosure: This article was prepared as part of MonkeyCode's product outreach. One seat you may fill, if it matches your constraints, is MonkeyCode's free model access on its free server option. This article does not name models, token quotas, hardware, or how long that option remains available. Check the current product terms before you depend on them.

{
  "leaf": "score",
  "oracle_kind": "pytest",
  "mutation_scope": "workspace",
  "fixture_sha256": "<digest you computed>",
  "runner_seat": "operator-filled-label"
}
Enter fullscreen mode Exit fullscreen mode

If the seat label is still unknown, leave it null and do not start the run. A missing seat is an incomplete receipt. It is not a default to whichever seat happens to be free.

How to read a failed receipt

A failed receipt is still a result. Store it next to the card so the next run does not start from chat memory.

If leaf is refuse, the missing piece is the oracle or a raised leak flag. Fix the card. Do not tune the prompt to talk past the gap.

If leaf is quarantine, the bundle is not eligible for a shared seat. Removing a secret is a fixture edit. That edit needs a new hash and a new classification. Do not reuse the old digest.

If leaf is refresh, the score field stays empty. A model may be used only after the hash exists. Calling it during refresh mixes a draft file into the baseline.

If leaf is score and runner_seat is null, the run has not started. Fill the seat from documentation you checked the same day. A seat name copied from an old post is not evidence.

What this does not prove

A score leaf means the fixture is comparable enough to run. It does not mean the patch is correct, secure, or cheaper than a local model. The asserts only prove branch order in this script.

Free model access and a free server option are availability claims supplied for this draft. They are not a benchmark, a capacity promise, or a reason to skip refuse and quarantine. If the vendor page disagrees with this text, trust the vendor page.

Hashes catch file drift. They do not catch a wrong spec. If the pinned oracle expects the bug, every model can pass by preserving it. Review the oracle before you treat the receipt as a quality signal.

Who should skip this workflow

Skip it for regulated data, production secrets, or unbounded network writes. Quarantine is the ceiling of this tree, not a hosting guide for those cards.

Skip it if you need an uptime commitment. Nothing here selects a free seat for reliability, latency, or retention.

Skip it if people will edit refuse results into score to keep a demo moving. The receipt is useless once leaves are rewritten after the fact.

For a card that already classifies as score, bind the seat from the MonkeyCode documentation you checked today, and keep that receipt beside the diff. If those docs and this tree disagree, follow the docs and leave the seat blank until the card still lands on score.

Top comments (0)