You should detach the merge hook from any coding agent before you cancel the paid workspace, because that hook can still apply a diff after the vendor relationship ends. The paid product often treated proposal, review, and apply as one trusted gesture, and a free replacement does not inherit that trust. A free model can still write a useful patch, yet the runner must not receive the credential that pushes it. Rebind approval to a place you control, and leave the old key in place until that bind is tested.
The leftover is the merge, not the prompt
The dangerous leftover is rarely the prompt, and it is usually a script, workflow, or webhook that still knows how to merge. That automation trusted a vendor identity, a stable workspace, and a review click that lived in the old interface. After the cutover, the same automation trusts any process that can drop a diff into the watched path. If your free server can write that path, you have rebuilt the old privilege without the old review.
You are migrating three different things, and only one of them should move onto the cheaper host. The proposal channel can move, because a draft diff is not yet a change to the default branch. The approval record should stay with reviewers, in a pull request or a protected file that the model cannot edit. The apply credential should stay on protected CI, or with a person, until you have compared real tasks.
Write those three owners into the diary before you change a single environment variable or webhook. A cutover without named owners becomes a chat log, and that chat log vanishes when the paid workspace closes. You will want those names during the first bad patch, not during the cheerful launch note.
Step 1: Inventory every path that can apply a diff
Start from a clean checkout, and search for the verbs that turn generated text into a commit or a deploy. You are not judging model quality yet, and you are only finding the side effect that can outlive the vendor. Include local scripts and editor tasks, because a laptop hook survives cancellation as easily as a hosted workflow does.
- Search workflows and scripts for apply, merge, and push behavior, and save the file list into the diary. Paste the matching paths under a diary heading called apply paths, so the later table has evidence rather than memory. Ignore documentation hits unless the command in that file can change your branch or your deploy target.
git grep -nE 'git apply|gh pr merge|git push|patch -p' -- .github scripts || true
- List every secret name that an agent process could read, and mark any name that can push, deploy, or open a firewall change. A secret that only reads logs can stay for now, but a secret that pushes must be called out in bold in the diary. Do not copy those values into the diary, and record only names, owners, and the workflow files that reference them.
git grep -nE 'GITHUB_TOKEN|DEPLOY_KEY|SSH_KEY|API_KEY' -- .github scripts .env.example || true
Open recent agent runs and check whether a human review identifier appears before the merge event in the log. A jump from "diff written" to "pushed" means the gate is already missing on the old path. Do not assume the paid interface still sits in front of that jump after you remove the integration.
Name the rollback owner in the same note as the secret owner, including the channel where that person can be reached. A free server with no rollback owner is not a substitute for a paid agent your on-call already understood. If either name is blank, stop the migration and repair the runbook before you repoint anything.
Step 2: Freeze a proposal contract the new host must honor
A valid proposal carries a task id, a base revision, a unified diff, and a risk label from a list your team already uses. A valid apply cites the same task id, a hash of that diff, and a human actor tied to review. The model may write the proposal, and the model may not write the approval, even when the patch looks small or obvious.
Keep the checker boring, and fail closed when any required field is empty or when the actor is the agent itself. The following program is an example you should run locally and adapt, not a policy engine this diary claims to have executed. It reads two JSON files, rejects a model-written approval, and allows apply only when the hashes match.
# Example checker. Label: unexecuted until you run it on your own files.
import hashlib
import json
import pathlib
import sys
REQUIRED = ("task_id", "base_rev", "diff", "risk")
def load(path: str) -> dict:
return json.loads(pathlib.Path(path).read_text())
def proposal_digest(proposal: dict) -> str:
missing = [key for key in REQUIRED if not proposal.get(key)]
if missing:
raise SystemExit(f"proposal missing {missing}")
if proposal.get("approved_by"):
raise SystemExit("model must not set approved_by")
payload = proposal["diff"].encode()
return hashlib.sha256(payload).hexdigest()
def main() -> None:
proposal = load(sys.argv[1])
approval = load(sys.argv[2])
digest = proposal_digest(proposal)
if approval.get("task_id") != proposal["task_id"]:
raise SystemExit("task_id mismatch")
if approval.get("diff_sha256") != digest:
raise SystemExit("diff hash mismatch")
actor = approval.get("actor", "")
if not actor or actor == "agent":
raise SystemExit("human actor required")
print("apply allowed")
if __name__ == "__main__":
main()
Create two sample files so the command is reproducible on your laptop before any network call exists. The proposal file must not contain an approval field, and the approval file must carry the hash you compute yourself. A deliberate mismatch is a useful first test, because you want to see the gate fail before you trust a pass.
{
"task_id": "task-184",
"base_rev": "a1b2c3d4",
"risk": "low",
"diff": "diff --git a/README.md b/README.md\n"
}
python -c 'import hashlib,json,pathlib,sys; p=json.loads(pathlib.Path(sys.argv[1]).read_text()); print(hashlib.sha256(p["diff"].encode()).hexdigest())' proposals/task-184.json
python check_apply.py proposals/task-184.json approvals/task-184.json
Store proposals where the runner can write, and store approvals on a path that runner cannot push. A single shared directory with loose permissions collapses the split, even when the checker function looks strict on your laptop. Use code owners or a separate approvals repository, and confirm the agent token is rejected when it tries to write there.
proposals/<task_id>.json
approvals/<task_id>.json
Step 3: Point only the proposal writer at the free option
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
The operator describes MonkeyCode as an open-source project with free model access and a free server option for a proposal writer. That writer should hold no push credential, and you should confirm current terms in the project documentation before you rely on them. If the project page lists a free token allowance, copy that live figure into the diary yourself. Do not reuse a token number from an old chat, because allowances change and this draft did not verify one.
An availability note is not a quality result, and it is not a promise about how long logs will remain. Treat the free option as a place to run the proposal writer, not as proof that review can be skipped. Your repository rules stay in force on the free host, even when that host stops sending you an invoice.
Keep the paid workspace readable while you move the writer, and do not move the apply job in the same change. The free server should emit a proposal file and then exit, without a token that can update the default branch. Protected CI should run the checker, and only a separate job should apply the diff after apply allowed is printed. If the free server image still contains the old deploy key, remove that key before the first remote task.
- Choose three tasks you have already accepted: one low-risk edit, one dependency bump, and one change that touches auth, billing, or data migrations.
- Save the paid run's file list, base revision, and diff hash, and do not invent a fresh task during cutover week.
- Run the same task through the free model, and allow the process to write a proposal file only.
- Compare paths and the pinned base revision, not the surrounding explanation, because wording can drift while scope must not.
- Apply nothing from a laptop while you wait, and let CI refuse the job until a reviewer writes the matching approval.
A file outside the saved list is a stop, even when tests on the expected files are green. Scope drift is how an unreviewed edit passes a badge that never looked at the extra path. Record the stop in the diary, and do not apply the extra file from a personal checkout just this once.
Also pin the base revision before you compare, or a moving default branch will make both hosts look wrong. This command records the tip you intend both runs to start from, and you should paste that value into the proposal. If the free run reports a different parent, reject the proposal and rerun it against the pinned revision.
git rev-parse origin/main
Do not rebase the generated diff by hand during the comparison week, because that hides whether the new host respected the contract. Hand cleanup can return after the gate is proven, and it should not be part of the evidence you use to cut over. A hand-edited diff can look cleaner while hiding a host that ignored the base revision you pinned.
Step 4: Read the decision table before you delete the paid key
Treat the table as a gate rather than a summary you skim after the migration is already done. An unknown cell means apply traffic stays on the old path, even when proposal generation already looks cheaper or more convenient. Judge each row from the inventory in step 1, not from a feature list you have not rechecked this week.
| Check | Paid side today | Free side requirement | Move apply? |
|---|---|---|---|
| Diff writer | Vendor agent identity | Proposal path only | Propose only |
| Approval writer | Human in the old UI | Path the agent cannot push | No, until enforced |
| Base revision | Workspace snapshot |
base_rev pinned and checked |
No, if tip can drift |
| Push secret | Vendor scope or protected CI | Absent from the free server | No, if the key was copied |
| Rollback owner | Named in the old runbook | Same owner, updated link | No, if the name is blank |
| Three-task hash compare | Often skipped historically | Recorded before cutover | No, until the diary has it |
Move the proposal writer only when the diff-writer row and the push-secret row are both satisfied. Move the apply job only when every other row is satisfied on the three tasks you saved. Another week with the paid key still present is cheaper than reversing a merge that no reviewer saw.
Limitations that remain after a green check
A matching hash proves the approved bytes are the proposed bytes, and it does not prove those bytes are safe to ship. The free model can edit the expected files and still break a caller, a migration, or a permission check you forgot to name. Keep executable tests on the task, and keep a trusted path available until those tests are green on the new writer.
The sample checker trusts your repository permissions to protect the approvals path from the agent token. If that token can push the path, the gate is theater, and you should not migrate the apply job at all. Free model access and a free server option can also change latency, context, and retention without a new contract. Copy proposal files into storage you control before the paid workspace closes and takes the old run history with it.
This diary does not rank products and does not report a benchmark, a token price, or a hardware shape. Your three saved tasks are the only evidence that should decide whether the apply job moves. If those tasks never touch production risk, do not generalize from a documentation edit to an auth change.
Who should not use this cutover yet
Do not use this plan when the current agent can deploy to production without a pull request or an equivalent change record. You need a stronger control than a JSON file, and you should install that control before you change hosts. Do not use the plan when no named reviewer will read high-risk diffs, because an empty queue recreates the leftover.
Skip the free server when the task includes secrets, customer data, or details of an unreleased vulnerability. A smaller bill does not relax a data rule you already accepted for the paid agent. If the team still applies patches from laptops and has no protected CI, inventory those machines before you add another writer.
Leave the apply key until the table is true
After the checker prints apply allowed on three real tasks, remove the push credential from the agent environment and leave proposal writing in place. Keep the paid workspace readable until you copy the retention you need, including older diffs and the review notes beside them. If a free server should host that writer, read MonkeyCode's current project notes and keep only what the table marks safe.
Top comments (0)