A teammate pasted a 400-line function. "AI can split this," they said. The model returned 200 lines of fresh code. The build broke. Nobody measured why.
This week's AI conversation repeats one claim: write less code. Another says constraints forge better work. Both are testable. Free tiers make the test cheap. Cheap is not the same as measured.
MonkeyCode is an open-source coding assistant. Its free tier currently includes 10 million tokens and a free hosted server. Terms change. Verify them in the repo before you depend on them. Disclosure: This article was prepared as part of MonkeyCode's product outreach.
This article is a hands-on evaluation. It designs a reproducible experiment. It quantifies where a free model and free server perform well. It shows where they break. The artifact is a 10-task gauntlet. Run it yourself. Publish your own scorecard.
The problem with vibes-based evaluation
Most model reviews quote one demo. One demo proves one thing. It proves nothing about your codebase. A single success hides variance. A single failure hides context.
The gauntlet fixes three gaps. First, it uses multiple tasks. Second, it repeats each task three times. Third, it scores behavior, not text.
The 10-task gauntlet
Ten tasks. Three classes. One pass criterion per task.
- Pick ten tasks from your real workload.
- Write one behavioral pass criterion per task.
- Run each task three times.
- Record verdict, wall time, and token usage.
- Apply the decision table below.
Task classes:
- Greenfield. Write a function. Write a test. Write a CLI script.
- Refactor. Rename and extract. Split a monolith. Migrate an API call.
- Debug. Fix a failing test. Fix a null bug. Fix a race condition. Optimize a slow query.
Each task ships with three files. A prompt. A seed workspace. An assertion script.
The assertion script is the judge. It checks behavior. It never checks wording. A model can pass with different code. A model can fail with pretty code.
The harness
The script below runs the gauntlet. It isolates the model call in one adapter function. Replace run_model with your client. CLI, API, or web. The rest stays the same.
#!/usr/bin/env bash
# gauntlet.sh — reproducible capability probe for a free coding model
# Usage: ./gauntlet.sh <task-dir> <runs>
set -euo pipefail
TASK_DIR="${1:-tasks}"
RUNS="${2:-3}"
REPORT="report.json"
# --- Adapter: plug in your client here -------------------------------
run_model() {
local prompt_file="$1" workspace="$2"
# Example (CLI): monkeycode run -p "$(cat "$prompt_file")" -w "$workspace"
# Example (API): curl -s "$ENDPOINT" -d @payload.json
# The adapter must write the final answer to "$workspace/ANSWER.md"
:
}
# ----------------------------------------------------------------------
pass=0; fail=0; results=()
for task in "$TASK_DIR"/*/; do
name=$(basename "$task")
for run in $(seq 1 "$RUNS"); do
ws=$(mktemp -d)
cp -r "$task/seed/." "$ws/"
start=$(date +%s.%N)
run_model "$task/prompt.md" "$ws"
end=$(date +%s.%N)
time_s=$(echo "$end - $start" | bc)
if "$task/assert.sh" "$ws"; then
verdict="pass"; pass=$((pass+1))
else
verdict="fail"; fail=$((fail+1))
fi
results+=("{\"task\":\"$name\",\"run\":$run,\"verdict\":\"$verdict\",\"time_s\":$time_s}")
done
done
printf '{"pass":%d,"fail":%d,"results":[%s]}\n' \
"$pass" "$fail" "$(IFS=,; echo "${results[*]}")" > "$REPORT"
echo "done: $pass pass, $fail fail -> $REPORT"
The output is a JSON report. One object per run. Parse it. Plot it. Keep it. Record token usage from your client's usage field. The free tier counts those tokens. The scorecard shows where they go.
The scorecard
Record every run in a table. Median time beats average. Three runs expose variance.
| Task | Class | Pass criteria | Run 1 | Run 2 | Run 3 | Median time |
|---|---|---|---|---|---|---|
| T01 | greenfield | unit test passes | ||||
| T02 | greenfield | test suite passes | ||||
| T03 | greenfield | CLI exits 0 | ||||
| T04 | refactor | behavior preserved | ||||
| T05 | refactor | tests pass after split | ||||
| T06 | refactor | API call migrated | ||||
| T07 | debug | failing test fixed | ||||
| T08 | debug | null bug fixed | ||||
| T09 | debug | race fixed under load | ||||
| T10 | debug | query under threshold |
How to read the results
Use the decision table. It turns raw counts into a verdict.
- Pass rate 8/10 or higher. The free tier fits your task mix. Review diffs as usual.
- Pass rate 5–7/10. Use it for greenfield. Review refactors line by line.
- Pass rate below 5/10. Keep it for explanation and chat. Do not let it edit code.
Where the free tier breaks
Three failure modes show up fast. The gauntlet turns each one into a number.
Nondeterminism. The same prompt produces different code. Three runs catch this. One run never will. Look for runs with different verdicts.
Context loss. Multi-file tasks degrade before single-file tasks. The gauntlet isolates both. Watch which class fails first. Refactor failures usually signal context limits.
Close-but-wrong output. The model produces plausible code. The assertion script rejects it. This is the most common failure. It is also the most dangerous one.
Limitations of this approach
The gauntlet measures ten tasks. It does not measure your codebase. It measures one model version. Model versions change. Free quotas change. Server performance changes.
The harness does not measure security. It does not measure maintainability. It does not measure license risk. Pass means behavior matches. Pass does not mean production-ready.
Who should not use this workflow
Teams shipping regulated code. The free tier cannot promise guarantees. Nobody should.
Teams with huge monorepos. Context windows shrink. Multi-file edits drift. Review costs explode.
Teams that skip review. The gauntlet proves nothing if humans skip the diff. Review every generated change. Always.
Run it
Clone the task set. Plug in your client. Run the gauntlet. Publish your scorecard. Try the free tier. Measure it.
The free tier is a real offer. Ten million tokens and a free server are real constraints. Constraints are testable. This week's hot takes will fade. Your scorecard will not.
Top comments (0)