Your starting point
A reviewed shipping-label function, generated execution records, passing checks and a short handoff explaining the remaining limits.
Before you begin. Git, a running Docker installation with permission to build containers, and make on the host; familiarity with JavaScript and reviewing a Git diff. The container workspace requires Node.js 22 or later and declares Claude Code ^2.1.304. Claude access and its usage costs or subscription limits apply. Use a disposable clone with fictional inputs.
Product details and verification
The repository documents impact analysis, execution planning, schema validation, worker execution, checks and resumable progress. Source ↗
Its regulator uses ordered, first-matching rules for tool calls. Commands inside a make recipe are not individually inspected by that top-level rule check. Source ↗
The workspace package declares Node.js >=22 and Claude Code ^2.1.304. Dependency ranges can resolve differently across installations. Source ↗
Container tooling mounts the workspace and persists Claude state. Node dependencies should be installed inside the container to match its platform. Source ↗
Repository documentation checked October 20, 2026 UTC. The original exercise below has not been run through the factory. No external project, container or coding agent was executed in this review.
The lights-on software factory is Gojko Adzic’s open-source boilerplate for splitting a coding change into planned steps, running agents through those steps, and stopping at checks. Its documentation exposes the plan, progress records and permission rules so a developer can inspect how work proceeds.
This exercise asks for one JavaScript function. A small boundary makes mistakes visible: the output is either FREE or $4.99, and invalid inputs have specified errors. The procedure follows the repository documentation. The exercise and its expected results are original; the complete workflow has not been executed here.
Prepare the workspace
Read the repository’s setup and container documents first. The MIT-licensed boilerplate still needs Claude access, container resources and model usage. Set an affordable session limit in your provider account and use a project without customer data. The mount and agent permission rules require review; a container alone does not establish a security boundary for the host files it exposes.
Run the following in a host terminal. The dry run shows the initialization commands before you run them. Record the commit printed by Git with your results, since the default branch can change. Review any initialization script and dependency changes before proceeding.
git clone https://github.com/gojko/lights-on-software-factory.git
cd lights-on-software-factory
git rev-parse HEAD
make -n init
make init
make claudeUse the documented Claude sign-in when prompted, or the existing API-key mechanism if you already have one configured. Keep credentials out of the plan and Git history. The project persists Claude configuration/history separately from application files. Installation and login are required setup; they do not show that the example works.
Write the task and its answer key
In the cloned repository, create workspace/plans/shipping-label.md with the complete text below. The paths inside the task are relative to the container workspace. Keep a second copy of the examples outside the generated test file, so an agent cannot make the only answer key agree with its implementation.
The input amount is an integer number of cents. The result is a display label for a fictional shipping charge. This keeps currency rounding, checkout integration and network activity outside the exercise.
# Shipping label exercise
Create src/parcel-label.js with a named export shippingLabel(totalCents).
Create tests/parcel-label.test.js using the existing Jest setup.
Accept a number that is an integer from 0 through 100000, inclusive.
Return the string "FREE" when totalCents is at least 5000.
Return the string "$4.99" for smaller valid amounts.
Throw TypeError for non-number input.
Throw RangeError for NaN, Infinity, fractions and out-of-range numbers.
Examples:
0 -> "$4.99"
4999 -> "$4.99"
5000 -> "FREE"
100000 -> "FREE"
"5000" -> TypeError
-1, 1.5, NaN, Infinity, 100001 -> RangeError
Use JavaScript ES modules and the repository's existing test/lint tools.
The implementation and its tests are the only application files to change.
Do not add dependencies, network calls, UI, payment processing or storage.
Keep the normal generated plan/progress records.
Ask for approval if the existing configuration requires a wider change.
Done means: the cases above pass, the existing suite and lint pass,
and a reviewer confirms the diff contains only this small feature,
its tests and the expected planning/progress records.Review the proposed work
In the Claude session opened by make claude, run the first command below. Read the impact analysis and confirm the work stays within the function and test requested. Then run the planning command. Inspect the proposed steps, dependency order and plan sidecar before approving execution.
/impact-analysis shipping-label
/plan-execution shipping-labelThe planner produces plans/shipping-label.plan.json alongside the Markdown task. Let the planner create that schema. Check that success means the actual boundary and error cases pass, and that a failed check stops progress. Decline a plan that adds packages, changes unrelated application code or weakens the test configuration without explaining why.
Open a second host terminal at the repository root and run make shell. That enters the container workspace. Run this validator there after the sidecar exists. The documented successful output is plans/shipping-label.md: no fault, with exit status zero. Fix any validation errors before execution.
node .claude/workflow/bin/validate-plan.js plans/shipping-label.mdRun once and inspect the evidence
Return to the Claude session and run the execution command. The documented orchestrator validates the plan, generates its execution files, runs workers through dependent groups, and invokes checks. It records completion and deviations rather than requiring you to infer progress from a long chat.
/execute shipping-labelRead any deviation before accepting it. The regulator applies the first matching rule to a top-level tool call. A permitted make command can run a recipe containing other commands; inspect the recipe and mounted paths when evaluating its scope. Give the session only the files and credentials needed for this exercise.
The documented repair loop is bounded. Failed gates can lead to rework and eventually a halt; a halted plan needs inspection. A final checker attempts to find faults in the result. These mechanisms provide evidence for a human review, and their success still depends on the quality of the requirements and checks.
Check the result independently
From the repository root on the host, run make test and make lint. Both must exit successfully. Then use make shell and run the following in the container workspace. It imports the requested function and checks thirteen cases independently of the generated Jest file. Success prints exactly PASS: all 13 independent checks. Any assertion error is a failed exercise.
node --input-type=module <<'JS'
import assert from 'node:assert/strict';
import { shippingLabel } from './src/parcel-label.js';
for (const [input, expected] of [[0, '$4.99'], [4999, '$4.99'], [5000, 'FREE'], [100000, 'FREE']]) {
assert.equal(shippingLabel(input), expected);
}
for (const input of ['5000', null, undefined, {}]) {
assert.throws(() => shippingLabel(input), TypeError);
}
for (const input of [-1, 1.5, NaN, Infinity, 100001]) {
assert.throws(() => shippingLabel(input), RangeError);
}
console.log('PASS: all 13 independent checks');
JSInspect git diff and git status --short from the host repository. Confirm that source code changes are limited to src/parcel-label.js and tests/parcel-label.test.js inside workspace, with the expected planning and progress records. Read the function: hidden network calls, extra side effects or changed tests elsewhere fail the scope check even when the command above passes.
Keep the task Markdown, generated plan JSON, progress JSONL, final diff and command results. Record the source commit, resolved tool versions, time spent reviewing and model usage. Leave generated orchestration files and credential/history directories subject to the repository’s ignore rules. Review each file before staging it.
Recover without losing the record
| Problem | Check | Recovery |
|---|---|---|
| Initialization fails | Docker is running; make is available; inspect the failing command. | Resolve that setup error before opening an agent session. Install workspace dependencies inside the container. |
| Planning commands are unavailable | The correct workspace and its project configuration were loaded. | Restart the documented Claude session after checking setup and workflow enablement. |
| Validator reports a fault | The Markdown task and generated plan sidecar agree. | Return to planning, repair the reported schema/dependency problem and validate again. |
| Execution stops at a gate | Read the failing test, worker deviation and progress record. | Correct the specific cause; approve any material plan change before resuming. |
| A partial run needs resuming | The append-only progress record is present and refers to this plan. | Run /execute shipping-label again after reviewing state. Completed work is skipped only when its recorded prerequisites are satisfied. |
| Independent check fails | Compare the failing case with the original task. | Repair the implementation and rerun both the ordinary suite and the independent check. Do not relax the answer key. |
Generated orchestration files can be regenerated. Losing the progress record is more consequential: the workflow may repeat work instead of recognizing completed steps. Keep that record with the plan and inspect it before restarting. If a task repeatedly fails, stop and reduce or clarify it; repeated agent retries can consume time and paid usage.
This small exercise establishes only the behavior you inspect locally. It cannot establish the creator’s broader productivity claims, safe operation on a private repository, or reliability across large applications. A useful handoff states the commit tested, passed and failed cases, review effort and any unexecuted steps.
Sources & next steps
GitHub · implementation
Lights-on software factory ↗
Rendered repository documentation checked for setup, approval points, execution roles and limitations.
Gojko Adzic · page checked 2026-10-20
GitHub · implementation
Factory container setup ↗
Rendered repository documentation checked for setup, approval points, execution roles and limitations.
Gojko Adzic · page checked 2026-10-20
More sources reviewed (5)
GitHub · implementation
Factory getting started ↗
Rendered repository documentation checked for setup, approval points, execution roles and limitations.
Gojko Adzic · page checked 2026-10-20
GitHub · implementation
Factory orchestrator and recovery ↗
Rendered repository documentation checked for setup, approval points, execution roles and limitations.
Gojko Adzic · page checked 2026-10-20
GitHub · implementation
Factory command regulator ↗
Rendered repository documentation checked for setup, approval points, execution roles and limitations.
Gojko Adzic · page checked 2026-10-20
GitHub · implementation
Factory planning and execution ↗
Guide history
Revisions preserve the original instructions. A source recheck alone does not create a new revision.
Revision 1 · New source-checked walkthrough with a bounded JavaScript task, complete input fixture, independent acceptance checks, plan review and recovery procedure; full workflow remains unexecuted.