A service change sat in review: about one hundred eighty lines of auth middleware, plus a fixture that still mentioned a staging host. The shortcut looked small. Paste the diff into a hosted coding model, accept the summary if the prose sounded calm, and clear the review. The senior in the pairing hour stopped that shortcut before a prompt existed.
The scene is a reconstructed pairing workflow, not a measured outage, a customer story, or a personal benchmark. File names are illustrative. Commands stay local proposals until someone runs them on a real tree.
What the hour was actually deciding
The junior engineer wanted a faster comment. The senior wanted a boundary that would still exist after the chat scrollback died. Those goals were written on the note as separate lines, because mixing them is how a convenience becomes a gate.
The questions asked were operational, not philosophical.
- Which changed paths may leave the workstation at all?
- Which evidence remains if the model summary is deleted, wrong, or never returned?
- Is the pass allowed to suggest a comment, or is a merge about to hide behind it?
- What is known about retention, and what is only a hope about a free box?
A free-model offer did not answer the list. Low price is not a data-handling policy. A short sentence carried the point. The longer one was the list itself.
Dead ends that looked efficient
The first dead end was the full paste. The diff included tests/fixtures/staging_notes.env.example, and a comment in it sketched a staging DSN. The senior blocked the paste. Calling a file an example does not make the path allowable. A redacted feeling is not an allowlist.
The second dead end was the calm paragraph. A model can call middleware safe while missing a refresh branch that skips token binding. The unit file already named that branch. The summary cited nothing. Commentary stayed commentary. Test output stayed the result.
The third dead end was afternoon automation. A free review server sounded easy to hang on the pipeline. The senior parked that idea. A server that receives every diff would only accelerate the bad paste. Automation waited on a local reject path.
The fourth dead end was fake precision. Free model access can be true without a model name, a token quota, a machine size, or a promise that the offer remains next month. The hour refused to invent those fields. Invented numbers would have made the note look current and made it false.
The decision that stayed
The decision kept was a review contract on the laptop. Allowed globs, forbidden globs, and a byte cap live in one file. A script checks diff names against that file and writes a hash manifest. Only a passing bundle may be copied into an excerpt. The excerpt is what a hosted reader is allowed to see, and only after a person looks at it.
MonkeyCode showed up after that rule, not before it. Disclosure: This article was prepared as part of MonkeyCode's product outreach. The operator-supplied claim is narrow. Free model access and a free server option may be a convenient place to read an excerpt that already passed the contract. This article does not state model names, quotas, hardware, retention windows, or permanence. Those details change, and they belong to current documentation.
Remove the product name and the hour still holds. The hosted box is optional. The forbidden-path list is the decision.
A contract the laptop can enforce
The JSON below is a proposal for the auth review, not a file taken from a private repository.
{
"base": "origin/main",
"max_bundle_bytes": 200000,
"allow": ["src/auth/**", "tests/auth/**"],
"forbid": ["**/.env", "**/*.pem", "**/*secret*", "tests/fixtures/**", "infra/**"],
"require_present": ["tests/auth/test_refresh_binding.py"]
}
Both lists are mandatory. An allowlist alone drifts toward extra folders. A denylist alone invites a clever rename. The required test path stops a review that edits middleware and forgets the binding check. Presence is not proof. It is only the first bar.
Path rules the checker actually implements
The helper is deliberately smaller than gitignore. It is labeled example code. Readers should run the self-test and then try real names before trusting a reject.
- A pattern ending in
/**matches that directory and everything under it. - A pattern starting with
**/matches the remainder against the file name, or a suffix when the remainder has no wildcard. - Any other pattern uses
fnmatchon the full relative path. - Forbid wins over allow. A path outside allow is also a reject.
- The matcher is case sensitive and does not understand negation rules.
That narrowness is a feature for a pairing hour. A mysterious ignore engine would have started a second debate.
Checker
#!/usr/bin/env python3
"""Local review-contract check. Unexecuted proposal until the self-test is run."""
from __future__ import annotations
import argparse
import hashlib
import json
import sys
from fnmatch import fnmatch
from pathlib import Path
def matches(path: str, pattern: str) -> bool:
path = path.replace("\\", "/")
pattern = pattern.replace("\\", "/")
if pattern.endswith("/**"):
prefix = pattern[:-3]
return path == prefix or path.startswith(prefix + "/")
if pattern.startswith("**/"):
rest = pattern[3:]
name = path.rsplit("/", 1)[-1]
if any(ch in rest for ch in "*?["):
return fnmatch(name, rest) or fnmatch(path, rest)
return path == rest or path.endswith("/" + rest)
return fnmatch(path, pattern)
def classify(names: list[str], contract: dict) -> tuple[list[str], list[str], list[str]]:
accepted, rejected = [], []
for name in names:
blocked = any(matches(name, pat) for pat in contract["forbid"])
allowed = any(matches(name, pat) for pat in contract["allow"])
if blocked or not allowed:
rejected.append(name)
else:
accepted.append(name)
missing = [item for item in contract.get("require_present", []) if item not in names]
return accepted, rejected, missing
def sha256(path: Path) -> str:
digest = hashlib.sha256()
digest.update(path.read_bytes())
return digest.hexdigest()
def self_test() -> None:
contract = {
"allow": ["src/auth/**", "tests/auth/**"],
"forbid": ["**/.env", "**/*.pem", "**/*secret*", "tests/fixtures/**", "infra/**"],
"require_present": ["tests/auth/test_refresh_binding.py"],
}
names = [
"src/auth/middleware.py",
"tests/auth/test_refresh_binding.py",
"tests/fixtures/staging_notes.env.example",
"src/auth/.env",
"src/auth/token_secret.py",
"infra/main.tf",
"README.md",
]
accepted, rejected, missing = classify(names, contract)
assert accepted == ["src/auth/middleware.py", "tests/auth/test_refresh_binding.py"]
assert "tests/fixtures/staging_notes.env.example" in rejected
assert "src/auth/.env" in rejected
assert "src/auth/token_secret.py" in rejected
assert "infra/main.tf" in rejected
assert "README.md" in rejected
assert missing == []
print("self-test ok")
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--self-test", action="store_true")
parser.add_argument("--contract", type=Path)
parser.add_argument("--names", type=Path)
parser.add_argument("--manifest", type=Path)
args = parser.parse_args()
if args.self_test:
self_test()
return 0
if not (args.contract and args.names and args.manifest):
parser.error("contract, names, and manifest are required")
contract = json.loads(args.contract.read_text())
names = [line.strip() for line in args.names.read_text().splitlines() if line.strip()]
accepted, rejected, missing = classify(names, contract)
if rejected or missing:
for item in rejected:
print(f"reject {item}", file=sys.stderr)
for item in missing:
print(f"missing {item}", file=sys.stderr)
return 2
files, total = [], 0
for name in accepted:
path = Path(name)
size = path.stat().st_size
total += size
files.append({"path": name, "bytes": size, "sha256": sha256(path)})
if total > int(contract["max_bundle_bytes"]):
print(f"bundle too large: {total}", file=sys.stderr)
return 3
payload = json.dumps({"files": files, "total_bytes": total}, indent=2) + "\n"
args.manifest.write_text(payload)
print(f"wrote {args.manifest} ({total} bytes)")
return 0
if __name__ == "__main__":
raise SystemExit(main())
The self-test does not touch the network and does not prove glob taste on a real repository. It proves the helper agrees with the cases the pairing hour cared about. Run it before editing the patterns. A failed assert is a stop, not a prompt to weaken the test.
Commands
python3 review_contract.py --self-test
git fetch origin main
git diff --name-only origin/main...HEAD > /tmp/diff-names.txt
python3 review_contract.py \
--contract review_contract.json \
--names /tmp/diff-names.txt \
--manifest /tmp/review-manifest.json
echo "contract_exit=$?"
A non-zero status ends the hosted idea for that hour. No excerpt is copied. The manifest, when written, records path, size, and hash so a later note can point at bytes.
Preparing the excerpt stays manual:
git diff origin/main...HEAD -- src/auth tests/auth > /tmp/review.patch
wc -c /tmp/review.patch
The script never opens a socket. That omission is the design. Upload belongs in a later change with a written retention answer, not in a convenience patch.
How a free server option sits beside the contract
A free server option is a possible second reader for a scrubbed excerpt. Free model access is a reason a pair might try that reader. Neither fact selects the paths. The table the senior kept is local and boring, which is why it survived the hour.
| Local question | If yes | If no or unknown |
|---|---|---|
| Every diff path is allowed and not forbidden | An excerpt may be prepared | Stop |
| The required test path is in the diff | Continue | Add the test before any hosted read |
| The bundle is under the byte cap | The manifest stands | Split the review |
| Retention for this run is documented | A hosted read is optional | Stay on the laptop |
| A human still merges | Model notes stay advisory | Do not use this workflow |
Unknown remains a stop. The table has no column named hope.
Failures the note refused to sand down
Three failures were written so the next pair would not treat the script as magic.
- A fixture was renamed into
src/auth/notes.txtto dodgetests/fixtures/**. The denylist missed it. The allowlist accepted the directory. A person still had to open the excerpt. The checker is a gate, not a reader. -
tests/auth/test_refresh_binding.pyexisted and asserted nothing new. Presence passed. The senior opened the file anyway. A required path cannot see an empty test. - The manifest hash matched a file that changed before the hosted read. The pair re-ran the checker and voided the stale manifest. A hash is a snapshot. It is not a lease on the branch.
A smoother model summary fixes none of those. It can hide them behind tone.
Who should not use this approach
Teams that cannot send source to a third party should stop at the manifest and review inside the existing code host. Customer payloads, private keys, live environment files, and regulated text do not belong in the excerpt, even when a glob fails to catch them. Repositories where the file names themselves are sensitive need a stricter process than this sketch.
People hunting a score, a quota, or a hardware comparison will not find one here. No latency was measured. No model was ranked. A write-up that invents those figures to sound timely is the failure this hour was built to avoid.
The checker should not become a mandatory CI job on the first day. Globs false-reject, and renames false-accept. Run it beside review, collect the rejects, and only then talk about automation. Teams without a human merger should not adopt the table at all. The last row is the product boundary, not a slogan.
What the hour refused to conclude
Public developer posts lately mix portfolio showcases with broad claims about model behavior. The pairing hour did not let a headline pick the tool, and it did not treat a trend title as evidence about this diff. The middleware change was local. The evidence had to be local too.
The conclusion that stayed is small enough to audit. Freeze the paths. Hash the bundle. Keep any model note advisory. A free server can be a second reader for an excerpt that already survived that freeze. It does not own the merge because the tab was open or the price was low.
Readers comparing options can hold this contract next to the current MonkeyCode documentation for free model access and the free server option. If those pages do not answer retention, the honest outcome is a local review. The forbidden-path list still earns its place on the branch.
Top comments (0)