Concepts
Keeping spec and code in sync
Every push Babbit didn't make is read, re-run and classified. Sync runs in both directions, and drift never changes a goal on its own.
Forward: spec to code
An approved change flows forward: the approved lines go to the spec branch, the Code Writing agent makes the code match, and the spec lands before the code. This is the normal path, covered in Changes.
Backward: code to spec
Anyone with write access can push to your code. A push that no change explains is drift. Babbit doesn't ignore it and doesn't undo it. It reads it:
- Babbit traces the changed code to the features and scenarios it belongs to.
- It re-runs the tests of every scenario the push touched.
- It classifies the push into one of four kinds and acts on it.
The four kinds of drift
| Kind | What it means | What Babbit does |
|---|---|---|
| Behavior changed | A scenario no longer describes what the code does. | Opens a change with the evidence first: which scenarios flipped. The proposals edit the spec to match the code. The other way out, this is a bug, opens a change that restores the old behavior. |
| New capability | Code that no feature claims. | Drafts a feature from the code and its tests, and asks where it goes, the same way it does for a feature you describe. |
| Removed | The code behind a scenario is gone. | Marks the scenario not implemented. The feature's light goes hollow, and archiving is offered rather than done. |
| Implementation only | A refactor, a dependency bump, a faster query. | Accepted without asking anyone, but only after every touched scenario re-ran and held. The feature's History shows it with where it came from, such as Repo · 3f9a1c2. |
A push that flips any scenario is behavior changed, whatever else it looks like. A touched scenario that couldn't re-run is never assumed to hold; Babbit asks instead of recording the push as implementation only.
The rules of sync
- The spec owns intent; the code owns implementation. Drift never changes a goal on its own, only scenarios and implementation facts. If a goal no longer holds, the drift change says it needs you.
- A label is not proof. Every commit Babbit makes carries a
NewDev-Changeline naming its change. A commit that names a change in its message but isn't in any of that change's pull requests is still drift. - Force-pushes are read in full. Babbit reads a forced push from before to after. Merged work the forced push dropped opens removed drift against the change it belonged to, and the scenarios that work proved re-run.
- A hand edit to the spec is a change. A push to the spec branch without a change opens a change whose proposals are that edit, for review like any other.
- Your own drift needs someone else. By default, an owner, not the builder who pushed, must approve a builder's drift change. See Roles and permissions.
What drift looks like on screen
A drift change shows the person who pushed as its writer, and its steps read Pushed, Described, Decide, Verified and Kept. Its proposals are approved the same way as any change's.
Related
- Changes: the forward path in detail.
- GitHub, branches and check runs: which branches Babbit writes and reads.