DEV Community

Emery Yang
Emery Yang

Posted on

Buffer the Stream or Kill the Spike

A short model stream is a failed patch. Write nothing until the full sentinel arrives intact. A matching worktree hash is the only ship signal.

Partial model output is not a usable diff. Exit zero does not prove a complete file. This spike kills the apply when the stream stops early.

Hypothesis

One claim is under test in this spike. The client must buffer the full stream first. Four bad fixtures must leave every tracked byte unchanged.

The clock for this spike stops at ninety minutes. Run one checker against the five prepared local fixtures. Do not add a second hypothesis during the spike.

Stream contract

The accepted stream format is plain UTF-8 text. The final line of the stream must equal END_PATCH. The first line must start with the PATH prefix.

The declared path must stay relative and local. That path must remain inside the spike_wt directory. Forbidden names must fail closed before any write.

Use these stable exit codes so later rows stay comparable.

  • Exit 2 means the sentinel line is missing.
  • Exit 3 means the header line is unusable.
  • Exit 4 means the requested path is forbidden.
  • Exit 5 means the body exceeds forty lines.
  • Exit 6 means a failure dirtied the worktree.
  • Exit 0 means one allowed file was replaced.

A client timeout must use exit code 2. A hung read is never treated as success. No extra exit code counts as a pass.

Why the buffer comes first

Model token streams usually arrive in small pieces. A naive client appends each piece to the target. A dropped socket then leaves a half file on disk.

That half-written file can still look locally editable. Later tests may even import the broken module. The spike treats that state as data loss, not as progress.

The checker therefore reads all of stdin to completion. Classification happens only after the full string arrives. The worktree is hashed before that classification returns.

Ninety-minute plan

Minutes 0 to 15 lock the contract written above. Create spike_wt and the local fixture directory. Do not open any remote session during this block.

Minutes 15 to 40 type the checker and the five fixtures. Run only local pipes during this middle block. Record each exit code beside the matching hash.

Minutes 40 to 55 compare hashes on every failure row. Both before and after digests must match exactly. A single hash mismatch ends the spike early.

Minutes 55 to 75 allow one remote draft if local rows are green. Store that remote draft outside the hashed worktree. Pipe the saved draft file into the same checker.

Minutes 75 to 90 must mark ship or kill. Ship needs five matching local rows and one clean apply. Anything else is a kill, written in one line.

Checker proposal

The program below is only an unexecuted proposal. It is not a recorded benchmark from this draft. Run it on your machine before you trust an exit.

# UNEXECUTED PROPOSAL — not executed for this article.
import hashlib
import os
import sys
from pathlib import Path

SENTINEL = "END_PATCH\n"
MAX_LINES = 40
FORBIDDEN = {"secrets.env", ".git/config", "package-lock.json"}
ROOT = Path("spike_wt")
TMP = Path(".spike_tmp/patch.tmp")

def tree_hash(root: Path) -> str:
    digest = hashlib.sha256()
    files = sorted(p for p in root.rglob("*") if p.is_file())
    for path in files:
        rel = path.relative_to(root).as_posix()
        if rel.startswith(".git/"):
            continue
        digest.update(rel.encode())
        digest.update(b"\0")
        digest.update(path.read_bytes())
        digest.update(b"\0")
    return digest.hexdigest()

def line_count(text: str) -> int:
    if text == "":
        return 0
    extra = 0 if text.endswith("\n") else 1
    return text.count("\n") + extra

def classify(stream: str) -> tuple[int, str, str]:
    if not stream.endswith(SENTINEL):
        return 2, "", ""
    body = stream[: -len(SENTINEL)]
    header, sep, rest = body.partition("\n")
    if sep == "" or not header.startswith("PATH "):
        return 3, "", ""
    rel = header[5:].strip()
    parts = Path(rel).parts
    if (
        rel in FORBIDDEN
        or rel.startswith("/")
        or ".." in parts
        or rel == ""
    ):
        return 4, "", ""
    if line_count(rest) > MAX_LINES:
        return 5, "", ""
    return 0, rel, rest

def write_atomic(rel: str, text: str) -> None:
    target = ROOT / rel
    target.parent.mkdir(parents=True, exist_ok=True)
    TMP.parent.mkdir(parents=True, exist_ok=True)
    TMP.write_text(text, encoding="utf-8")
    os.replace(TMP, target)

def main() -> int:
    before = tree_hash(ROOT)
    code, rel, rest = classify(sys.stdin.read())
    if code != 0:
        after = tree_hash(ROOT)
        if before != after:
            print("dirty_failure", file=sys.stderr)
            return 6
        print(code)
        return code
    write_atomic(rel, rest)
    print(0)
    return 0

if __name__ == "__main__":
    raise SystemExit(main())
Enter fullscreen mode Exit fullscreen mode

The .spike_tmp directory sits outside spike_wt. A crash before os.replace must not change the hashed tree. Delete that temp directory after every finished row.

Local commands

Prepare a tiny tree before the first pipe. Keep every secret file outside that tiny tree. Then pipe the fixtures through in a fixed order.

mkdir -p spike_wt/notes fixtures .spike_tmp
printf 'seed\n' > spike_wt/notes/seed.txt
python3 check_stream.py < fixtures/trunc.txt; echo exit:$?
python3 check_stream.py < fixtures/bad_header.txt; echo exit:$?
python3 check_stream.py < fixtures/forbid.txt; echo exit:$?
python3 check_stream.py < fixtures/long.txt; echo exit:$?
python3 check_stream.py < fixtures/ok.txt; echo exit:$?
find spike_wt -type f -print0 | sort -z | xargs -0 sha256sum
Enter fullscreen mode Exit fullscreen mode

Every fixture file here is hand-written local text. None of it is sample output from a model. The expected fixture shapes look like the blocks below.

# fixtures/trunc.txt
PATH notes/seed.txt
seed

# fixtures/bad_header.txt
notes/seed.txt
seed
END_PATCH

# fixtures/forbid.txt
PATH package-lock.json
{}
END_PATCH

# fixtures/ok.txt
PATH notes/seed.txt
seed
plus one line
END_PATCH
Enter fullscreen mode Exit fullscreen mode

Build long.txt with a valid header and forty-one body lines. End that long fixture with the required sentinel. Expect exit 5 and a fully unchanged worktree hash.

Decision table

Fixture Exit Hash rule Next action
trunc.txt 2 unchanged discard buffer
bad_header.txt 3 unchanged discard buffer
forbid.txt 4 unchanged discard buffer
long.txt 5 unchanged discard buffer
any dirty failure 6 changed kill spike
ok.txt 0 one file changes inspect that file

Read the decision table from top to bottom. Do not skip ahead to the success row. A red row above it cancels the remote step.

How to read a red row

Match the exit before you match the story. Confirm the before hash equals the after hash. Only then discard the buffer and continue downward.

Timeout rule

Pick a twenty-second read limit for this spike. That limit is a local choice, not a vendor setting. Start that timer when the remote socket opens.

When the timer fires, close the open socket. Drop the partial buffer while it is still in memory. Return exit 2 without creating any new file.

Do not retry the draft inside the same ninety minutes. A retry can hide a short stream behind a later full one. The hypothesis allows one remote draft, not a loop.

Ship or kill

Ship the spike only when every table row matches. The success row may change notes/seed.txt only. Plain git status must show no other changed path.

Kill the spike if any failed row writes a file. Kill the spike if exit 6 appears even once. Kill it if the remote draft runs while a local row is red.

Record the ship decision as one single word. Add the five recorded exit codes under that word. A kill is valid evidence, not a failed author.

Where the optional draft runs

The local fixture rows are the actual proof. The remote draft step stays optional and late. That remote step starts only after the table is green.

MonkeyCode belongs only in that optional remote draft. Disclosure: This article was prepared as part of MonkeyCode's product outreach.

Operator-supplied notes say free model access and a free server option exist. This article does not name a model, a quota, hardware, or a rental period. Those product details were not provided as sources.

Treat the free server only as a stream source. Write its output to .spike_tmp/remote.txt, outside the hashed tree. Run the same checker against that saved file.

Delete that saved file if the exit is not 0. If your local table is already green, use that access for the single draft. If any local row is red, do not spend the remote step.

Limitations

The end sentinel is easy for a model to forge. A model can emit END_PATCH after a wrong edit. These shape checks will not catch that kind of lie.

The forty-line cap is an arbitrary spike limit. It blocks oversized accidents, not ordinary logic bugs. A wrong three-line file can still exit 0.

The hash skips .git and ignores every other root. Files outside spike_wt are invisible to the proof. Do not point the checker at a home directory.

Python os.replace is atomic only on one filesystem. A temp file on another device can fail the replace. Keep .spike_tmp on the same volume as spike_wt.

Free server availability is not a latency SLA. This checker proposal was not executed for this article. Publish your own table, not numbers copied from this page.

No permanence claim is implied by this note. Access described by the operator can change later. Re-read the current plan before the next spike.

Who should skip this

Skip the spike when the edit must touch a lockfile. That forbidden path set is intentional and closed. Bypassing that forbidden set voids the spike result.

Skip the spike when the tree holds live credentials. The worktree hash function reads raw file bytes. A secret in spike_wt would enter the digest inputs.

Skip the spike when you need a semantic review. This gate checks stream framing, not program behavior. Pair it with tests you already trust, or do not ship.

Skip it when the client flushes tokens straight to disk. Buffer the full stream, or do not run this plan. Incremental disk writers cannot satisfy the hash rule.

Skip it when you need a named quota or a model SLA. This note does not supply any of those figures. Find a primary source before you plan capacity.

Log lines to store

Keep the spike log both boring and complete. Four stored lines are enough for a later reader. Leave every vendor screenshot out of the log folder.

  1. Record the date, the hypothesis id, and the clock limit.
  2. Record all five exits, listed in fixture order.
  3. Record before and after hashes for every failure row.
  4. The single word ship, or the word kill.

Suggested hypothesis id is stream-sentinel-2026-10-10 for the log. The date marks the planned spike, not a product release. The recorded hash lines are the spike evidence.

What this spike does not prove

This spike does not prove the remote draft is correct. It proves the client refused a short or illegal stream. Behavioral correctness still needs your existing local tests.

This spike does not compare any model vendors. No quality score and no latency table appear here. Adding either metric would create a second hypothesis.

This plan does not authorize unattended production writes. A human still must read the one changed file. If that human read cannot happen, kill the apply.

Stop the work when the ninety-minute clock ends. Do not extend this spike just to fix the model. A red decision table is already a finished result.

Top comments (0)