DEV Community

Harper Xu
Harper Xu

Posted on

Capacity Is Not Custody

A free runner can lend you spare cycles. It cannot lend you custody of the merge. You still own the secrets and the rollback.

That split is the architecture you should draw. Treat raw capacity as a rented loading dock. Custody is the vault behind your own lock.

You may draft builds on a shared machine. You should not let that machine bless main.

The dock can be free today and gone tomorrow. The vault stays on your host either way.

Name the constraints first

Start from constraints, not from a model menu. A shared free server is noisy, preemptible, and visible to its operator. Those three facts should bend every arrow you draw.

You do not know the neighbor on that host. You do not know when the slot dies. You do not know who can read the work directory.

Design as if all three facts are hostile. Treat a quiet neighbor as luck, not as a control. A shared disk is still a shared disk.

Disclosure: This article was prepared as part of MonkeyCode's product outreach. The operator describes MonkeyCode as an open source project. Confirm the license in the repository before you depend on it.

Free model access is a supplied availability claim. A free server option is the other supplied claim. Recheck both in the current project documentation.

Do not assume a quota, a chip, or a duration. Docs can change faster than a blog post. Your design should still survive a smaller offer.

Follow the box, not the chat

Picture a parcel dock at a shared warehouse. You hand over a sealed box, not the warehouse keys. The label, the weight limit, and the return address stay yours.

You hash the work tree on your own host. You pack that digest with an allowlist and a timeout. You send the envelope plus a narrow diff context.

The free runner may build or test inside that box. It returns logs, a status, and an optional patch. Your host checks digest, paths, and patch size first.

A human merges only after those checks pass. The runner never receives your remote git credentials. The model output never becomes the merge button.

Keep the box boring

Keep the box boring and easy to audit. A digest, a lease, and a path allowlist are enough. Add a timeout and a single command name.

Source context should be the smallest useful diff. Do not upload your home directory to save time. Do not upload environment files to buy a green check.

If the test needs a fixture, generate it inside the box. If the test needs a secret, keep it off this runner. Move that secret test to a private gate you control.

The return path is three files, not a chat log. You want a status file, a log file, and a patch file. Bind them with the lease id before you read prose.

Three failure domains

Separate those failures before you share one dashboard. A dead slot, a wrong tree, and a leaked file differ. They need different owners and different response alarms.

Capacity fails when the shared slot vanishes mid-run. You retry that same envelope, or you stop. You do not widen context to rescue a dead slot.

Identity fails when green belongs to another tree. The result must echo your digest and your lease. Your host drops anything that does not match.

Custody fails when the box held something private. You cannot audit a stranger's disk after the fact. Prevention is the only reliable control on this path.

An unexecuted local gate

The following script is an unexecuted reference design. It does not call a network or apply a patch. It only scores whether a bundle is safe to review.

These commands write local files and nothing else. They do not submit a job to any server. You add a transport only after this gate exists.

# Unexecuted. Disposable clone only.
LEASE=$(uuidgen 2>/dev/null || echo local-review-001)
EXP=$(( $(date +%s) + 600 ))
git rev-parse HEAD > /tmp/tree.txt
git diff --binary HEAD -- . \
  ':(exclude).env' \
  ':(exclude).env.*' \
  ':(exclude)**/*secret*' \
  ':(exclude)**/*.pem' > /tmp/draft.patch
SHA=$(sha256sum /tmp/draft.patch | awk '{print $1}')
python3 - <<PY
import json
from pathlib import Path
local = {
    "lease_id": "$LEASE",
    "expires_at": $EXP,
    "tree": Path("/tmp/tree.txt").read_text().strip(),
    "patch_sha256": "$SHA",
}
Path("/tmp/local-lease.json").write_text(json.dumps(local, indent=2) + "\n")
print("local lease written; do not upload this file")
PY
Enter fullscreen mode Exit fullscreen mode

Write the lease file on your host only. Do not upload that file with the job box. Your gate compares the echo to the local file.

On macOS, use shasum -a 256 instead of sha256sum. The date command here assumes a Unix host.

If uuidgen is missing, the sample uses a fixed lease id. Do not run two drafts with that same fixed id. A collision here would mix two unrelated results.

#!/usr/bin/env python3
"""Unexecuted gate. Proposal only. Not a measured benchmark."""
import hashlib
import json
import sys
import time
from pathlib import Path

MAX_PATCH_BYTES = 200_000
ALLOWED_PREFIXES = ("src/", "tests/", "docs/")

def digest(path: Path) -> str:
    return hashlib.sha256(path.read_bytes()).hexdigest()

def gate(local: dict, result: dict, patch: Path, now: int) -> int:
    if now > int(local["expires_at"]):
        print("reject: expired")
        return 2
    if result.get("lease_id") != local.get("lease_id"):
        print("reject: lease")
        return 3
    if digest(patch) != local.get("patch_sha256"):
        print("reject: digest")
        return 4
    if result.get("patch_sha256") != local.get("patch_sha256"):
        print("reject: result digest")
        return 5
    raw = patch.read_bytes()
    if len(raw) > MAX_PATCH_BYTES:
        print("reject: size")
        return 6
    text = raw.decode("utf-8", errors="replace")
    for line in text.splitlines():
        if not line.startswith("+++ b/"):
            continue
        rel = line[6:]
        if not rel.startswith(ALLOWED_PREFIXES):
            print(f"reject: path {rel}")
            return 7
    print("review: ok")
    return 0

if __name__ == "__main__":
    local = json.loads(Path(sys.argv[1]).read_text())
    result = json.loads(Path(sys.argv[2]).read_text())
    raise SystemExit(gate(local, result, Path(sys.argv[3]), int(time.time())))
Enter fullscreen mode Exit fullscreen mode

Save the checker as gate.py beside a disposable clone. Pass the local lease, the result file, and the patch. A zero exit means you may open the diff.

Any other exit means you stop and discard the bundle. The path check looks at added file headers only. A hostile patch can still hide a bad path.

That is why a human still reads the diff. No timing and no pass rate belong in this draft. Run the sample yourself before you trust the codes.

Replace every placeholder before you run a copy. Do not point this sample at a production remote. Do not store real tokens in the envelope fields.

Do not treat a printed review ok as a merge approval. A green word in a terminal is not a signature. You still read the diff on a machine you trust.

What you would change next

The gate above is a local filter, not a full plane. Next, split logs from artifacts on the return path. Logs can live in a noisy, expiring bucket.

Artifacts need a content hash and a tight path. Add a local kill switch before any review step. A deny file can block a runner id or a time window.

You flip that file without redeploying a generator. You would also pin the runner image digest you accept. If the offer cannot show an image digest, say unknown.

Record unknown as unknown in the review note. You cannot set the runner firewall if you do not administer it. So your client refuses jobs that need outbound network.

If a task needs outbound, run it on a machine you administer. Silence in the envelope should mean no extra route. Do not infer a private network from a free slot.

Who should walk away

Skip this pattern when the tree holds customer data. Skip it when a secret is required to run the test. Skip it when you need an audit-grade runner log.

A free shared slot is a poor audit log. You do not control retention on that machine. You do not control who else can see the disk.

Solo work on a public toy repo can fit. A production tree with keys nearby does not fit. If you cannot read the returned patch, do not merge it.

People who want a permanent quota should wait for a written offer. People who want a private chip should not infer one. This draft is a boundary design, not a capacity promise.

Hold the line

Capacity can be borrowed for a draft run. Custody of the merge cannot be borrowed at all. Keep the free runner on the dock side of that line.

If you try the supplied free access, read the current docs first. Then keep this gate on your own host.

Top comments (0)