DEV Community

AI Dive
AI Dive

Posted on Originally published at aidive.dev

Your agent commits every spec. Nobody owns them.

In June, the maintainers of okama, a Python finance library, found their internal implementation plans published on Read the Docs. Eight markdown files an agent had written, committed exactly as the plugin intends, rendered as public web pages. They noticed after the release.

The plugin was Superpowers. By default every spec and every plan it writes lands in docs/superpowers/, and the brainstorming skill commits the design doc before you've even seen the plan.

So who owns those files, and when is one dead?

Every tool commits the files

This isn't a Superpowers quirk. spec-kit keeps one numbered folder per feature on that feature's branch. Kiro keeps .kiro/specs/, one folder per feature. Anthropic's playbook goes further and commits an artifact at every stage: intent, spec, plan, diff, review findings, incident record.

Whether to commit is settled. Ownership and lifecycle aren't.

Picture a front-end team of 10 people in four squads sharing one repo, with every developer generating these files. Three failures are already documented:

  • A docs generator renders every markdown file under docs/, listed in the table of contents or not. That's the okama leak.
  • Issue #1246: the brainstorm commits the plan straight to main. One user counts 10 to 15 commits per session.
  • Drift, the quiet one. Birgitta Böckeler at Thoughtworks separates spec-first (written, used once) from spec-anchored (maintained for the feature's life). Superpowers writes spec-first documents and keeps them forever, so you get anchored storage with first-draft maintenance. Nobody updates the file, and an agent reads it next quarter as truth.

Rule 1: the folder has an owner, and it's a squad

Since v5, Superpowers honors the instructions in your CLAUDE.md over its own defaults. A table of paths isn't enough though. In issue #939 a user wrote an output paths table and the model followed the concrete path in the skill instead. One bold imperative line, naming the default as the thing to avoid, fixed it on the first attempt:

IMPORTANT: specs MUST be saved under docs/superpowers/<squad>/specs/
and plans under docs/superpowers/<squad>/plans/, NOT docs/superpowers/specs/.
Enter fullscreen mode Exit fullscreen mode

In a monorepo, put that line in the package's own CLAUDE.md. Claude Code loads a subdirectory's file when it reads there. Then let the platform enforce the owner:

# CODEOWNERS
docs/superpowers/checkout/        @org/squad-checkout
docs/superpowers/search/          @org/squad-search
docs/superpowers/design-system/   @org/squad-design-system
Enter fullscreen mode Exit fullscreen mode

Every spec review now lands with the people who'll live with it. One caveat: the override is a prompt, not a setting. Check the first spec after every plugin release.

Rule 2: not every plan is a team artifact

Personal redirects go in CLAUDE.local.md, which loads after the shared file and which you git-ignore yourself. For the folder itself, .git/info/exclude ignores it per clone without touching the shared tree.

The shared side is whatever passed the review gate the brainstorm already runs. Approved by a second person, it moves into the squad folder. Not approved, it stays local. Both are written on a branch, never on main. Two lines in the shared CLAUDE.md do it:

Treat specs and plans as the start of a feature.
Create the worktree before writing them.
Enter fullscreen mode Exit fullscreen mode

There's a limit. The okama maintainers tried ignoring the folder first and reverted, because plans stopped syncing between machines and agents. Personal means personal.

Rule 3: a spec has a status, and a dead spec says so

Michael Nygard wrote this down for architecture decision records in 2011. A decision is proposed, then accepted, and when a later record changes it the old one is marked superseded instead of deleted.

So every shared spec opens with a short header, plus a review date if your team uses one:

---
status: accepted
superseded-by:
owner: @org/squad-checkout
touches: src/checkout/retry.ts, src/checkout/api.ts
---
Enter fullscreen mode Exit fullscreen mode

Never edit an accepted spec into a different decision. Write the next one and point it back. The one exception is in Anthropic's playbook: when implementation departs from the plan, update the plan in the same commit.

The weak spot is that a status is metadata a human sets. The agent won't mark its own spec superseded unless your CLAUDE.md tells it to.

Rule 4: a spec that lies about the tree fails the build

For every spec whose header says accepted, pull the paths it names (in backticks or on the touches line) and check that each one exists. Proposed and superseded specs are skipped, because only accepted specs make claims about the tree.

#!/usr/bin/env bash
# drift gate: accepted specs may only name paths that exist
shopt -s globstar
fail=0
for f in docs/superpowers/**/specs/*.md; do
  grep -q '^status: accepted' "$f" || continue
  paths=$( { grep -oE '`[^` ]+/[^` ]+`' "$f" | tr -d '`'
             grep -m1 '^touches:' "$f" | sed 's/^touches://' | tr ',' '\n'; } | tr -d ' ')
  for p in $paths; do
    if [ ! -e "$p" ]; then
      echo "drift: $f names $p, which no longer exists"
      fail=1
    fi
  done
done
exit $fail
Enter fullscreen mode Exit fullscreen mode

People already do the manual version. One commenter on r/ClaudeCode has Claude compare the spec files to the codebase and file tickets for what's missing. This does that on every pull request.

While you're in CI, add the guard okama shipped: exclude the folder from the docs build. In Sphinx that's one entry in exclude_patterns, and the files stay in git without reaching the HTML.

The check catches deleted files, not changed behavior. A spec can name files that all exist and still describe an API that's gone. That part is still review's job.

Rule 5: most work doesn't deserve a spec

Marmelab ran spec-kit on a feature that shows the current date and got 8 files and 1,300 lines of specification. The OpenSpec bake-off ran the same requirements twice, with the spec tool and with Claude Code alone. The spec run produced 50% more code with 50% more cyclomatic complexity, took twice as long and cost three times as much. It's one experiment, and the author says so. It also found three gaps the plain run missed.

A team that ran spec-driven development for months couldn't prove it improved the code: two to three times the tokens, about twice as long.

My rule: write a spec when the work crosses a squad boundary or will be read again in 90 days, and keep it near 300 lines. Everything else is a prompt. The spec buys coverage, not speed.

What this doesn't fix

None of these rules is enforced by a tool today. The override issue is open, the main branch issue is open, and the pull request that reordered the instruction was closed without merging. And if your team won't review a code owner request, it won't review a spec either. In that case git-ignoring the folder is the honest choice.

The full walkthrough

The video puts the issues, the ADR source and the okama config on screen. The written version with every source is at https://aidive.dev/videos/spec-plan-governance/.

Do you commit your agent's specs, and has a stale one misled an agent yet?

I used AI tools to help edit this piece.

Top comments (0)