A rider at a workbench fitting a harness to a copper dragon

Practice mission / Engineers

Ship a small code change

This 30–45 minute exercise gives a coding agent one broken function, six acceptance checks written before it starts, and permission to edit a single file. You run the checks yourself before and after, read the whole patch, add one case of your own, and log the prompt, output, time and cost. Six passing checks are evidence, not proof.

30–45 minutes · GUIDED EXERCISE · By · Published · Updated

The deliverable

A reviewed local patch, observed test output, and a record of what changed.

Practice material. Replace fictional inputs only when you have the right access and review process.

The mission

Fix one function that counts ticket statuses. Keep the input unchanged. Prove the behavior with checks written before the agent begins. Here, “ship” means hand over a reviewed local artifact; publishing a package or changing production is outside the exercise.

This is a practice fixture, not a report of a real flight. You need a local Node.js installation and an empty exercise folder. Use an agent that can edit that folder, or ask a chat-only agent to return a replacement function for you to paste. No network access, package installation, credentials, or customer data is needed.

If this is your first run, read Your first flight and copy the mission brief before starting.

Set up the fixture: one function, six acceptance checks

Create summarize.cjs with this intentionally incomplete implementation:

function summarize(statuses) {
  return {
    open: statuses.filter(s => s === 'open').length,
    closed: statuses.filter(s => s === 'closed').length,
    unknown: 0,
    total: statuses.length,
  };
}
module.exports = { summarize };

The contract: the argument is always an array. Count each entry exactly once. Normalize string entries by trimming surrounding whitespace and converting to lowercase. Recognize only open and closed. Everything else, including empty strings and non-string values, is unknown. Return exactly the four numeric fields shown. Do not mutate the supplied array.

Create check.cjs yourself. Keep it outside the agent’s permitted edit scope:

const assert = require('node:assert/strict');
const { summarize } = require('./summarize.cjs');

const cases = [
  [[], { open: 0, closed: 0, unknown: 0, total: 0 }],
  [['open', 'closed'],
    { open: 1, closed: 1, unknown: 0, total: 2 }],
  [[' OPEN ', 'Closed', 'pending'],
    { open: 1, closed: 1, unknown: 1, total: 3 }],
  [['', '   ', null, 7],
    { open: 0, closed: 0, unknown: 4, total: 4 }],
  [['reopened', 'open', 'open'],
    { open: 2, closed: 0, unknown: 1, total: 3 }],
];

let passed = 0;
for (const [input, expected] of cases) {
  try {
    assert.deepEqual(summarize(input), expected);
    passed++;
  } catch (error) {
    console.error('FAIL:', JSON.stringify(input), error.message);
  }
}
const input = [' OPEN ', 'closed', null];
const original = [...input];
try {
  summarize(input);
  assert.deepEqual(input, original);
  passed++;
} catch (error) {
  console.error('FAIL: input preservation', error.message);
}
console.log(`${passed}/6 checks passed`);
process.exitCode = passed === 6 ? 0 : 1;

Run node check.cjs once before editing. Save the actual output as your baseline. Do not replace that observation with an expected result copied from this page.

Give the coding agent a bounded brief

Paste the contract and both files, then use:

Fix summarize.cjs to satisfy the supplied contract.
Read both files; edit only summarize.cjs.
Do not alter the checks, add dependencies, access the network,
publish anything, or expand the function's public interface.
Keep the input unchanged. Prefer a small, readable patch.

First restate the behavior and edit boundary. Then implement.
Run node check.cjs if execution is available. Report the exact
command and observed result; otherwise say "not run".
Return the patch, a brief explanation, and any unresolved issue.
Stop after one implementation and one corrective attempt.

Restrict file and tool access in the environment where possible. A sentence in the prompt is not a filesystem permission. If your tool cannot enforce a narrow edit scope, use the chat-only path and apply the proposed replacement yourself.

Inspect the patch before accepting it

Run the checks yourself after the edit. Read the complete changed function: it should be short enough to understand without asking the agent to explain each line. Confirm that the original checks remain unchanged and that no new files, imports, or dependencies appeared.

Six passing checks are required for this fixture. They are evidence about these cases, not proof of correctness for every possible JavaScript value. Add one case of your own before accepting: for example, a mixed array with repeated unknown values. Write its expected counts manually. Check that the category counts sum to total.

If it goes wrong

If a non-string causes an exception, point to the failing input and the original contract. If the agent rewrites the test, restore the test and reject that attempt. If it proposes a package or architectural rewrite, return to the one-file boundary. If the runtime is unavailable, record “not run” and stop at a proposed patch; do not mark the mission complete.

After the corrective attempt, retain any failing output and stop. A small partial result is easier to diagnose than a broad rewrite.

Log the evidence: prompt, patch, test output, time, cost

Keep the starting function, final patch, exact prompt, runtime version, and before/after command output. Record elapsed work time and review time separately. Record visible cost, or “not observable” if your tool does not expose it.

Use the Flight Log template, labeling this a sandbox exercise. Note the added case and the human acceptance decision. Then read Evals to turn this one inspection into a repeatable check for your next real change.

Questions riders ask

How do I give a coding agent a bounded brief?

Tell the agent to edit only one file, leave the checks alone, add no dependencies, use no network and publish nothing. Ask it to restate the behavior and edit boundary before implementing, report the exact command and observed result or say “not run”, and stop after one corrective attempt. A prompt sentence is not a filesystem permission.

What acceptance checks does this coding agent exercise use?

Six checks in a file kept outside the agent’s edit scope: empty array, plain open and closed, whitespace and mixed case, empty strings and non-strings as unknown, an unrecognized status, and input not mutated. Run them before the edit for a baseline and again after. All six must pass, then add one case of your own.

How do I check a coding agent’s patch before accepting it?

Run the checks yourself; all six must pass. Read the complete changed function and confirm the original checks are untouched and no new files, imports or dependencies appeared. Add one case of your own, write its expected counts by hand, and check the categories sum to total. Without a runtime, record “not run” and do not mark it complete.

ONE MISSION. ONE HONEST RECORD.

Log what actually happened.

Include review time, failed checks, and what you changed. Do not fill gaps with estimates presented as measurements.

Open the flight log template ↗