← Research log
Report #7 · 2026-07-02

The algorithm scales: a six-package production backend from a 7B

Report #6 ended with 3–4 file specs and a thesis: with a small, fixed model, the loop and its data are the lever. This report pushes that thesis up the only axis that matters for the mission — project size. Same 7B specialist the whole way (go-dev-mixed-v2, at base parity on the unit benchmark, never retrained), same Builder loop, and a ladder of increasingly real backends. The question: where does it break, and is the break in the algorithm or the model?

The ladder

SpecFiles / packagesShapeAutonomous
usersapi7 / 1REST users API: repository, middleware chain, JSON handlers, graceful shutdown3/3
taskflow11 / 1Layered: errors→models→store→middleware→pagination→handlers→router→main3/3
taskapi13 / 5Real multi-package: cmd/server + internal/{config,models,store,api}, interface DI, slog, Go 1.22 routing3/3
taskapipro16 / 6+ service layer, pagination, /healthz + /readyz, config validation, context-aware store/service2/3 → 3/3

Score is score_backend as always: go build + go vet + go test, real toolchain, 0–3. The asterisk on taskapipro is the honest part; it gets its own section below.

What made multi-package work: the Builder learned what a package is

The jump from 11 files in one package to 13 files in five is where naive file-at-a-time generation dies: cross-package references need imports and qualifiers, same-named symbols in different packages are legal, and only exported identifiers cross the boundary. The Builder became package-aware — package = directory; same-directory files are shown in full while other packages appear as their exported API only (signatures, not bodies), exactly how a human reads a codebase. Redeclaration-stripping and sibling context were scoped to the directory so a legitimate New() in two packages isn't "repaired" away.

The result surprised us: on taskapi's first run the whole five-package architecture — every import path, every qualified reference, every package clause, the config→models→store→api→cmd dependency graph — compiled clean on the first try. The hard part of multi-package wasn't hard once the prompts carried the right context.

Every failure class became a deterministic gate

Ten runs up the ladder surfaced failure modes one at a time — and each became a permanent, model-free repair or prompt rule. The pattern that keeps repeating: a 7B's mistakes are not random noise, they're enumerable mechanical classes, and every class you close deterministically is closed forever, for free:

The honest gap: taskapipro stopped 20 human lines short

Three full autonomous runs of the six-package spec all landed at exactly 2/3 — all six packages build and vet clean every time, and the failures were the same two test-semantics bugs each run, down to the line. That reproducibility is the finding. The model wrote correct env-with-default helpers for five of six config fields and missed the same one every time; its table test correctly isolates state per subtest (the fix-time diagnosis landed) but keeps expected values that assume the old shared-store accumulation. The fix loop, even pointed at the right files with the right diagnosis, could not make those two semantic expected-value repairs — and a maintain pass asked to make both fixes dug a fresh hole in the service layer and was correctly rolled back by the non-regressing gate.

So we finished it by hand and counted: ~20 lines of human edits in 1,225 (one missing default helper; three corrected expected values plus the coverage the table shape couldn't express), documented line-by-line in the artifact's HUMAN_EDITS.md. go build, go vet, go test -race: green across all six packages, including the model's own router, service and config tests.

What we learned

All builds served and run locally on an M1 Max with Apple MLX — total cloud spend: $0 (the DAPT run uses a free Kaggle GPU). Specs, gates, the package-aware Builder and the green artifacts: github.com/guildlm/builder.