The April inversion said constraints are free for machines. It never said which constraints. This release commits to an answer, and committing was uncomfortable. Every cap is a number someone can argue with.
The shape: vertical slices (one feature, one folder), no cross-feature imports, file and method line caps, command/query separation, and a spec of at most 500 words per feature. That spec is what an agent loads instead of the whole repository. Five structural checks enforce the rules: cross-feature imports, scattered features, oversized files, oversized methods, mixed command/query capabilities. Each check is a decidable fact about the code. No model in the loop. True or false, nothing in between.
The 500-word spec is the piece I keep turning over. It works as a loading contract. If a change can’t be made inside one slice plus its spec, the slice is shaped wrong. Split it, don’t widen the context.
I made it all opt-in. Brownfield never auto-converts. I’ve seen what forced architecture migrations do to teams, and I’m not shipping one.
Doubt for the record: 150-line files, 25-line methods, 500 words. Defensible defaults or numerology? Time will tell.