Skip to content

Build1 publisher3 min readPublished

Spec Kit plus gh stack splits a 135-file agent feature into three capped diffs

Enforcement is a bash script that counts files against the merge-base with the parent branch, so it bounds one diff at a time, and only if the agent chooses to run it. The 100 is an environment variable's default.

The Engineer · Build desk

Illustration accompanying Spec Kit plus gh stack splits a 135-file agent feature into three capped diffs

What happened

  • A dev.to tutorial pairs GitHub's Spec Kit with the gh stack extension so that a feature an agent implements arrives as a stack of small pull requests instead of one large one.
  • Its premise is that an agent can hand back a 180-file pull request in ten minutes, which nobody reviews, so it sits, goes stale, and gets merged on a LGTM.
  • The worked example is a payments feature estimated at about 135 files, planned as three stacked units: domain at around 25 files, API at around 40, and webhooks plus UI at around 70.
  • A constitution addendum makes the loop project law: implement, pass unit tests, commit, run the cap check, push, run gh stack submit, then branch the next unit.
  • Merges run bottom-up with gh stack sync after each one, and no unit is allowed to depend on a unit above it in the stack.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • constraint The cap bounds a diff, not a change: three compliant units can put 300 files into main without the script ever failing, so reviewers get smaller reads rather than a smaller feature.
  • exposure With the limit sitting behind an environment variable default and the check being a script the agent is told to invoke, a stack can look compliant while never having been measured at all.
  • decision Banning forward dependencies moves the hard call to plan time: someone has to decide whether domain code can merge and be tested before the API that calls it exists.
  • cost Fixed bottom-up merge order with a sync after every merge means whoever owns the top of the stack absorbs every rebase caused by review churn below.

Read check-stack-cap.sh before trusting the word hard. The cap line is CAP="${STACK_FILE_CAP:-100}" [4]. One hundred is the default value of an environment variable, and the process running the implement loop is also a process that can export environment variables.

What the script measures is narrow, and deliberately so. BASE is the merge-base of the parent branch and HEAD, COUNT is git diff --name-only from BASE to HEAD piped through wc -l, and above the cap it prints FILE CAP EXCEEDED and exits 1 [5]. For the third unit the parent is the second unit, so files the first two units already touched fall outside the count. The example's three units add to 135 files, which is the scope it started from [3][14]. The largest of them, webhooks plus UI, is planned at 70 files, 70 percent of the cap, leaving 30 files of slack in the unit most likely to grow [3][16].

The part I would keep is where the split gets decided. /speckit.plan is handed the stack layout as a mandatory constraint instead of being asked for prose [12], and the branch Spec Kit creates for the spec, 001-payments, is unit one of the stack, with the spec documents shipping in PR #1 [11]. Cutting the seams before any code exists is cheaper than carving them out of a finished diff, and it gives the reviewer of the bottom PR a spec to read the code against.

Enforcement is thinner than the label. The addendum is headed non-negotiable, and rule 4 says never run gh stack with failing tests or a failed cap check [13][7]. The stated design is that the gate runs before anything touches GitHub, with the instruction to bake it into the agent's rules file [6]. That is a prompt, not a hook. Nothing described here fails a push or blocks a merge on its own, whereas a required status check running the same script on every stack branch does not care whether the agent remembered to call it.

For a file count to carry the weight it is given here, review cost per file has to be roughly flat across your repo. A hundred generated adapters read faster than twelve files of a state machine. The 180-file pull request that opens the argument and the estimated 135-file payments scope are illustrations from a worked example [2][3], and the outcomes the tutorial promises are a setup, a plan that is a stack layout, three open PRs and a merge workflow [17]; measured review time is not among them. The defensible claim is the modest one, that diffs of 25, 40 and 70 files get read while a 135-file diff gets a LGTM [2][3].

What to watch

  • Whether anyone moves the cap check into a pre-push hook or a required status check, so it stops depending on the agent's own compliance.
  • A published run that reports review time per unit rather than file counts, since that is the number the argument rests on.
  • Whether /speckit.plan reliably produces a first unit that builds and tests without the units above it, because the whole split rests on that.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories