Skip to content

Specs-driven development

Alfred does not require a specific spec framework. It needs a durable source of intent that an agent can read before it acts: a GitHub issue, a spec file, a roadmap, an AGENTS.md or CLAUDE.md file, or a dedicated specs repo.

Specs-driven Alfred means the important context lives outside the chat transcript. Agents read the spec, turn it into scoped implementation tasks, execute in clean worktrees, and return PRs, reviews, tests, and Slack reports.

Full GitHub guide: docs/SPECS_DRIVEN_DEVELOPMENT.md.

One-off prompts are good for small tasks. Recurring engineering work needs stable inputs:

  • what user or system behavior should change
  • which repo owns the first implementation
  • which repos may need follow-up work
  • how a reviewer can verify the result
  • what is out of scope for the current PR

Without those inputs, autonomous agents tend to either guess or stop. Alfred uses specs to reduce both failure modes.

You can scaffold this shape with:

Terminal window
alfred spec new "Feature name" --repo my-org/api --out docs/specs/feature.md
alfred spec lint docs/specs/feature.md
# Feature: <name>
Status: draft | approved | shipped
Owner: <human owner>
Repos: api, web, mobile
## Goal
What user or system behavior changes?
## Current Behavior
What does the product do today?
## Target Behavior
What should be true after this ships?
## Acceptance Criteria
- [ ] A reviewer can verify this with <command, endpoint, screen, or file>.
- [ ] Tests cover <specific behavior>.
- [ ] The PR does not change <explicit out-of-scope area>.
## Rollout
1. <repo A first because...>
2. <repo B after...>
## Out Of Scope
- <what the agent must not include>
## Rollback
How to revert or disable the change if it breaks.
  1. Drake reads specs and roadmap context. It files scoped agent:implement issues only when the acceptance criteria are concrete and testable.
  2. Batman plans multi-repo work. A labelled agent:large-feature issue, optionally grouped with agent:bundle:<slug>, becomes a rollout plan across the configured repos. The plan is visible in Slack and in alfred serve under Plans.
  3. Lucius implements one repo at a time. It claims a single agent:implement issue, opens an isolated worktree, invokes Claude Code or Codex, pushes a branch, and opens a PR.
  4. Ra’s al Ghul, Bane, and Nightwing close the review path. Review, tests, and P0/P1 comment fixes happen as separate bounded jobs.
  5. Slack and shipped summaries show the outcome. You see what was planned, claimed, opened, merged, or blocked.

For one repo, keep specs inside that repo:

my-app/
AGENTS.md
docs/specs/
src/

For multi-repo products, keep the specs checkout beside the code repos:

~/code/product/
api/
web/
mobile/
specs/

Use code repos in the first write path:

Terminal window
./bin/alfred-init.py \
--non-interactive \
--agents starter \
--repos my-org/api,my-org/web,my-org/mobile \
--slack-webhook skip

Then edit the seeded prompts under ~/.alfred/prompts/ to mention the specs checkout. Do not include the specs repo in --repos unless you want Alfred to create labels there and pick issues or PRs from it.

For a cross-repo feature, create a GitHub issue in the repo that owns the first decision and label it:

agent:large-feature
agent:bundle:<short-slug> # optional when several issues belong together

Batman scans BATMAN_SCAN_REPOS, drafts the rollout plan, posts it to Slack or local logs, and saves the draft under $ALFRED_HOME/batman-plans. Treat the Slack thread as the place to change the plan before approval. Plain-English feedback is enough: “remove mobile”, “make this read-only”, “add an empty state”, or “split this into two PRs”. Alfred acknowledges newly captured plan replies in-thread with the execution scope if approved now, and when the configured approver approves with a reaction, Alfred passes those replies along as approval amendments. Trusted feedback users can amend the plan without approval authority. Repo add/remove replies update execution scope before implementation starts, and question: replies keep the plan paused until they are resolved.

The local Planning tab in alfred serve uses the same command vocabulary:

acceptance: reviewer can verify the new state on the settings page
test: run npm test for the settings components
add repo: my-org/web
remove repo: my-org/mobile
question: should this be behind a feature flag?

Use it to refine rough ideas into a GitHub issue draft and a spec draft before Drake, Batman, or Lucius sees the work. When promoted repo lessons exist, Alfred shows them as advisory planning memory and embeds them in saved specs. Saving a useful spec also queues a reviewable memory candidate, so future work can learn from the decision only after promotion.

Poorly scoped parent issues should not go straight to implementation. If the issue does not name repos, acceptance criteria, and done-when checks, keep it in planning and tighten the issue first.

  • Use stable file names and headings. Agents can link to SPECS/012-auth.md more reliably than “the auth doc.”
  • Name exact endpoints, tables, screens, commands, and test files when they are known.
  • Put “Out of scope” in every spec. It prevents scope creep inside a worktree.
  • Split cross-repo work into repo-sized implementation issues after the plan.
  • Keep specs current, but trust code when they disagree. File a docs or specs issue when drift is discovered.
  • Put repo-specific guidance in AGENTS.md or CLAUDE.md so the coding engine receives local rules every time.

These are useful references, not Alfred dependencies:

Alfred can consume outputs from any of these styles. The only hard requirement is that the work item given to an autonomous agent has clear scope, a repo boundary, and testable acceptance criteria.