Unit 16 · lesson

Build in Verified Slices, Not Explosions

Once the specification exists, the next danger is scale.

A tool can generate hundreds of lines faster than you can review fifty. If you accept all of it at once, your project may grow while your understanding shrinks.

That is not acceleration. It is review debt.

Break the specification into observable slices

Suppose the project specification is a Robot Fleet Console with these requirements:

R1  represent a robot with name and battery level
R2  identify low-battery robots at <= 20
R3  save robots to JSON
R4  reload robots at startup
R5  print a summary report

Do not request:

Build the whole application.

A safer sequence might be:

SLICE A  model + low-battery rule
SLICE B  persistence
SLICE C  report
SLICE D  command workflow

Each slice should end with evidence before the next begins.

SPECIFICATION

SLICE

SMALL CHANGE

TEST / RUN / DIFF

KNOWN CHECKPOINT

NEXT SLICE
Interactive model

Build the system in verified slices

Specification sets the target. Each bounded slice is implemented, tested, and committed before the next layer is allowed to grow.

Drag nodes to inspect the relationships. Motion shows the active path; the plain background keeps attention on the relationships instead of graph-paper decoration.

View static diagramStatic specification to implementation slices workflow

A slice is not just “one file”

A meaningful slice delivers one bounded behavior that can be verified.

For R2:

behavior:
robot at battery 20 is LOW

likely files:
robot.py
tests/test_robot.py

verification:
normal + exact-boundary tests

That may touch two files. It is still one conceptual slice.

By contrast, splitting one coherent behavior into five tiny prompts merely to make the changes look small can create unnecessary churn.

The slice boundary should follow the requirement and its evidence.

Predict a change budget before generation

Before a candidate change is created, write an expectation.

TASK: add low-battery classification
EXPECTED FILES: robot.py, tests/test_robot.py
NEW DEPENDENCIES: 0
NEW PUBLIC FUNCTIONS/METHODS: 1
PROTECTED BEHAVIOR: existing name/battery storage
EXPECTED TESTS: exact threshold + normal cases

That is a change budget.

It is not a hard law that no extra line may change. It is an early-warning system.

If the candidate suddenly includes:

robot.py
storage.py
main.py
settings.py
requirements.txt
new database package

stop.

Ask why the blast radius expanded before accepting the architecture.

Compare a reasonable slice with over-generation

Requirement:

Save fleet records to JSON.

Reasonable candidate plan:

1. Add save_fleet(path, robots) in storage.py.
2. Serialize the defined robot fields.
3. Add tests for normal list and empty list.

Over-generated plan:

1. Add repository abstraction.
2. Introduce SQLite.
3. Add ORM models.
4. Add migration framework.
5. Add configuration layer.
6. Rewrite Robot as database entity.

The second architecture might belong in a different system.

It does not belong in this task merely because the generator knows how to build it.

Architecture drift can happen one “helpful” change at a time

Not all drift arrives as a huge rewrite.

Imagine this sequence:

Slice 1 adds utils.py for one helper.
Slice 2 adds two unrelated helpers to utils.py.
Slice 3 moves validation there.
Slice 4 moves persistence formatting there.

No single step looks catastrophic.

After four slices, utils.py has become a junk drawer with no coherent responsibility.

At each checkpoint, ask:

Did this slice preserve or improve responsibility boundaries?
Did it create a new dependency direction?
Did a generic file start collecting unrelated behavior?

Fast generation makes these questions more important because architectural clutter can accumulate quickly.

Keep a clean baseline without erasing your own work

Before a generated or agent-assisted slice, inspect the repository:

git status
git diff

If you have your own uncommitted work, do not blindly stage everything just to create a checkpoint.

First decide what belongs to that checkpoint.

A safe workflow is:

  1. inspect current changes;
  2. finish, commit, stash, or otherwise deliberately preserve your own work according to your workspace rules;
  3. confirm the baseline you intend to compare against;
  4. run the relevant tests;
  5. begin the bounded slice.

The principle is not “always commit before AI.”

The principle is:

Know which changes existed before the generated work begins.

Without that, you cannot reliably attribute the diff.

Verification belongs inside every slice

Do not save all testing for the end.

After the model slice:

python -m pytest tests/test_robot.py

After persistence:

python -m pytest tests/test_storage.py

Then run the growing suite:

python -m pytest

Use the most relevant checks available in your project.

If Slice B breaks Slice A, you want to know while the causal window is small.

Stop conditions are part of the plan

Before generation, define reasons to stop:

STOP if a new dependency is proposed.
STOP if files outside the allowed set change.
STOP if an existing test is deleted or weakened.
STOP if the diff becomes too large to explain.
STOP if architecture changes before the requirement demands it.
STOP if generated code uses a pattern you cannot review confidently.

A stop is not failure.

It is a control mechanism.

A smaller accepted slice can beat a larger rejected one

Suppose a candidate implements R3 and R4 together but the load path is confusing.

You can keep only the clearly verified save behavior and postpone load behavior.

Development does not require accepting the candidate as one indivisible block.

This is another reason Git/diff literacy matters. You need to understand what you are accepting.

Build the slice ledger

For your Unit project, keep a small ledger:

SliceRequirementExpected filesActual filesEvidenceDecision
AR2 low-batteryrobot.py, testsame3 tests passaccept
BR3 save JSONstorage.py, test+ utils.pyunclear helperrevise

That ledger exposes drift before it becomes invisible history.

The real speed metric

Do not measure progress by generated lines per minute.

Measure:

verified requirements completed
without losing explainability

Lesson 3 builds the review process for a fast-generated slice after it lands in the repository.

Vocabulary lab

Flip the idea, not just the card

Explain the term before you reveal the back. Then compare your explanation with the definition, example, and warning.

1 / 5
Read all terms without animation
Implementation Slice
A bounded portion of a specification that delivers one coherent behavior and its verification evidence. Example: Implementing and testing low-battery classification before persistence. Do not confuse it with: An arbitrary number of generated lines or one file regardless of responsibility.
Change Budget
A pre-change expectation for likely files, dependencies, interfaces, complexity, and protected behavior. Example: Two files, zero dependencies, one new function. Do not confuse it with: A guarantee that the implementation may never need another justified change.
Review Debt
Changed or generated code that has accumulated faster than developers can inspect, understand, and verify it. Example: Accepting several large generated slices without reading their diffs. Do not confuse it with: Simply having many lines of code.
Architecture Drift
Gradual movement away from intended system responsibilities or boundaries through unplanned changes. Example: A generic utils.py collecting unrelated project behavior. Do not confuse it with: A deliberate architecture change justified by a new requirement.
Stop Condition
A predefined signal that pauses generation or integration so scope, evidence, or architecture can be reviewed. Example: Stop when an unauthorized dependency appears. Do not confuse it with: Giving up on the project.