Coding harness built specifically for AMD Strix Halo
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Simon Harms 1f61a03431
mclass golden: regenerate from the retrained model
The mclass model was retrained with general-question negatives, so its logits
and labels changed. Regenerate the Go golden from the new model so the parity
test matches. The token ids do not change; the tokenizer is the same.
2026-10-05 14:45:10 -04:00
.commandcode/taste replace the harness, TUI and CLI with the new runtime 2026-10-01 19:37:33 -04:00
cmd/mcode native Go mverify and mclass, and the verification contract 2026-10-05 14:36:32 -04:00
docs native Go mverify and mclass, and the verification contract 2026-10-05 14:36:32 -04:00
internal mclass golden: regenerate from the retrained model 2026-10-05 14:45:10 -04:00
.gitignore Import the Go port of mcode 2026-09-29 19:24:59 -04:00
CHANGELOG.md native Go mverify and mclass, and the verification contract 2026-10-05 14:36:32 -04:00
go.mod native Go mverify and mclass, and the verification contract 2026-10-05 14:36:32 -04:00
go.sum TUI: colour it, move the status bar down, make waiting visible, fix scrolling 2026-09-30 07:52:33 -04:00
README.md native Go mverify and mclass, and the verification contract 2026-10-05 14:36:32 -04:00

mcode

A coding agent for local models, served by malaikat. It starts the model server for you, keeps a small local model on track, and checks its work.

cd your-repo
mcode

Bare mcode opens the TUI and starts the default profile (glm47-flash) plus the Laya sidecar. Run one task and exit:

mcode -p "fix the failing test" --yes

Build

go build -o bin/mcode ./cmd/mcode

mcode then needs malaikat on PATH, or MCODE_MALAIKAT set. It builds the managed binary from ~/Projects/malaikat when that tree is newer.

A release build sets the version:

go build -ldflags "-X main.version=0.3.0" -o bin/mcode ./cmd/mcode

Test

go test ./...

The unit and integration tests use a fake model server, so they need no GPU. The live test drives the real stack: it starts malaikat, runs real turns, captures a preference with mclass, and judges the output with mverify. It is behind a build tag and uses the tiny profile unless MCODE_LIVE_PROFILE says otherwise:

go test -tags live -run TestLiveEndToEnd -timeout 6m ./internal/runtime/

Commands

Command Action
mcode the TUI in the current directory
mcode -p "..." [--yes] run one task, print the answer, exit
mcode approve not yet: approvals happen in the TUI
mcode model [name] list malaikat profiles
mcode goal [text|complete] show or set the durable goal
mcode log [--session X] [--type T] [--limit N] search the session log
mcode install [mclass|all] [--status] install the mclass companion
mcode version print the version

Flags: --cwd DIR, --model NAME, --mode lean|full|plan|minimal, --url URL, --yes.

Slash commands

Command Action
/plan [task] plan mode; /plan <task> plans it, /plan execute runs the plan
/mode lean|full|plan|minimal change the tool surface
/model [name] list or switch the malaikat profile
/goal <text> / /goal complete set or verify-and-close the goal
/verify run the acceptance checks now
/accept list proposed and active checks; /accept <text> accepts one
/accept reject <text> drop a proposal
/accept undo <text> un-accept a check
/compact compact the session now
/undo restore the files the last turn changed
/resume [id] resume a saved session
/yes / /ask allow every command this session, or ask again
/stop stop the current turn (Esc also stops)
/help, /quit

What makes it work on a local model

  • A frozen prefix. The first system message does not change inside a session, so llama.cpp keeps its KV cache. Volatile state (goal, plan, todos, checks) rides on the newest request.
  • A lean tool surface. read, write, edit, bash, grep, glob, find, todo, criteria, and skill or ask_user when the session has them. mode plan is read-only.
  • A valid history, always. One message type for the whole program, and the history is validated before every request. Tool calls are committed with their results, so the model always sees what it did.
  • The project's own checks. go test ./..., npm test, make test, and the rest are detected at start and run after any turn that changed files. A failure goes back to the model as the next turn. A check the model suggests is a proposal: you accept it with /accept before it runs.
  • Progress guards. The loop stops a model that only talks, repeats the same action, writes an essay, or fills the context.
  • Laya. The System-1 sidecar reads intent, command risk, and stalls. When it is not running, the harness continues without it.

Preference model

mclass classifies coding preferences. It is a native Go MiniLM encoder plus two heads: it reads the user text and writes a typed label. A durable preference in a user turn is saved during the turn. A question is never saved. mcode install mclass downloads the model files (about 90 MB) from Hugging Face into ~/.mcode/opt/mclass/artifacts. No Python, no uv. Check the state with mcode install --status. Without the model, a built-in Bayes classifier runs.

Set MCODE_MCLASS=0 to force the Bayes classifier, or MCODE_MCLASS_ARTIFACTS to a directory to use different model files.

Verification model

mverify judges fuzzy acceptance checks. It is a small TF-IDF plus logistic regression classifier that asks: does this output satisfy this prompt? The model is embedded in the binary, so it always runs. No install, no subprocess, no Python.

On a verify pass the harness judges the output against the prompt once, then judges each fuzzy check the model wrote. A pass needs the verifier to say pass and a confidence at or above verify.confidence_threshold (default 0.7). /goal complete hands failures back to the model and retries, up to verify.max_retries (default 3). The automatic pass after an edit runs the deterministic command checks only.

Set MCODE_MVERIFY to a path to use an external verifier instead.

Permissions

Every command is rated allow, ask, or deny. rm -rf /, curl | sh, a force-push to main, and writes to system paths are denied. Installs, inline interpreters, and network downloads ask. The prompt offers allow, allow for this session, allow all this session, and deny. --yes allows the ask class. A deny is never weakened.

The project's own detected checks are pre-approved, because you already agreed to run them by launching mcode in the project.

Files

mcode keeps state in .mcode/ in the workspace: sessions/ (JSONL log and snapshots), criteria.json, history, and goals/. It writes .mcode/.gitignore so a wildcard git add never picks it up. Global state lives in ~/.local/share/mcode and ~/.config/mcode.

Configuration

~/.config/mcode/config.json and .mcode/config.json merge over the defaults. Environment variables win over both.

Variable Effect
MCODE_PROFILE malaikat profile
MCODE_MODEL model id sent to the server
MCODE_MODE tool surface
MCODE_URL attach to a running server
MCODE_MALAIKAT path to the malaikat binary
MCODE_MAX_TOKENS output cap for one reply
MCODE_MAX_STEPS step fuse for one turn
MCODE_LLAMA_ARGS extra malaikat serve arguments
MCODE_LAYA=0 turn the sidecar off; a URL pins it
MCODE_VERIFY=0 skip the acceptance pass
MCODE_VERIFY_AUTORUN=0 skip the automatic pass after an edit
MCODE_VERIFY_CONFIDENCE minimum confidence for a fuzzy check to pass
MCODE_MVERIFY path to the fuzzy verifier
MCODE_MCLASS=0 force the built-in Bayes preference classifier
MCODE_MCLASS_ARTIFACTS directory that holds the mclass model files

Not finished

  • mcode update does not upgrade; build from source.
  • There is no command palette, mouse selection, or diff colouring in the TUI.
  • plan mode saves the plan text, and /plan execute runs it, but the plan is not yet shown as a first-class panel.