How I turned fstack into a software factory

By

How I use fstack, Fable, bounded subagents, repository context, and review gates to build many software products without losing control.

~~~

I recently launched fstack, my collection of 13 simple agent skills.

At first I saw it as a better way to work with one coding agent.

Take an idea. Nail it down. Write a plan. Build it. Check the result. Push it.

Then I started using the same system across all the applications I am building under ~/www.

The projects are very different. I have small static sites, sites with hundreds of generated pages, applications with accounts and payments, and courses with dozens of lessons and practical templates.

One agent was no longer enough.

I did not want one enormous autonomous agent either.

I wanted a manager that understood the whole product, several workers that could build independent parts, and a strict review step before anything became part of the product.

This changed how I think about fstack.

It is becoming a software factory, by which I mean a repeatable production system. Work enters in one form, passes through clear stations, gets inspected, and leaves in a better-defined form.

This is not a magic machine that turns one sentence into a startup. Every agent has a bounded job, and I check every result.

What I mean by a software factory

The phrase can sound bigger than it is.

My software factory is a collection of plain files, agent skills, model roles, and review rules.

The input might be:

  • a product idea
  • a feature request
  • a set of course lessons
  • a large content migration
  • a framework port
  • a redesign
  • a bug that touches several systems

The output should be a working, verified, documented change that still matches the original product decision.

The full line looks like this:

idea or task
  -> challenge and clarify
  -> write the product context
  -> write the plan
  -> split the work
  -> run independent production cells
  -> review every return
  -> integrate
  -> verify the complete product
  -> document what matters
  -> commit, push, and log the outcome

There is still a human in this system. I choose the idea, answer product questions, approve the plan, and decide whether the result is good.

The factory removes repeated implementation work, but I still make the judgments.

More agents do not create a factory

It is easy to launch five agents.

That is not the difficult part.

Without structure, five agents can create five different interpretations of the same task.

You might get an agent changing the data model, another inventing a design system, and two editing the same shared file. Another adds a library, while the last one finishes early and says everything looks good.

You get more output, but you also get more uncertainty.

This is the difference between parallel work and a production system.

A production system needs:

  • one source of truth
  • one owner of the plan
  • clear dependencies
  • clear file ownership
  • repeatable briefs
  • visible progress
  • review before integration
  • proof before completion

I had parts of this before fstack. fstack gave me the small control points, the multi-agent setup added the production cells, and repository files made the state durable.

fstack is the control system

fstack still has 13 small skills.

I do not want to replace them with one giant /fstack-factory command.

That would recreate the problem I built fstack to avoid. One command would have to understand product strategy, planning, architecture, implementation, design, testing, documentation, and Git.

It would become difficult to inspect and difficult to stop.

Instead, each skill controls one station.

The main production loop is:

fstack-nail -> fstack-plan -> fstack-build -> fstack-check -> fstack-push

The other skills support the line:

  • /fstack-roast challenges the idea before I invest in it
  • /fstack-interview records the product context
  • /fstack-simplify removes unnecessary complexity
  • /fstack-design brings the interface back to the existing design system
  • /fstack-counselors asks three independent models about a difficult decision
  • /fstack-document writes and updates the project documentation
  • /fstack-learn saves one non-obvious lesson for the next session

The /fstack skill is the front door. It picks one of the other 12 skills, runs it, and stops. I can inspect what happened before sending the work to the next station.

The factory starts before code

A fast factory can manufacture the wrong thing very efficiently, so the first stations do not write code.

If the product idea is weak, I can run /fstack-roast.

It asks questions about the customer, the status quo, demand, distribution, and the smallest version worth building. It ends with one of three verdicts:

  • build the wedge
  • shrink it
  • do not build it

I use it to avoid putting a vague idea on an efficient production line.

For a new project, /fstack-interview records the business context in AGENTS.md.

The result is short:

## Product context

- **Product:** what this is
- **Customer:** who it is for
- **Demand:** what evidence exists
- **Business model:** how it makes money
- **Status quo:** what it replaces
- **Distribution:** how people find it
- **Not doing:** what stays outside the product
- **Open questions:** what we still do not know

This file becomes part of the repository.

Every future agent starts with the same product definition. It does not have to reconstruct the business from old chat messages.

This is the first factory rule:

Long-lived project state belongs in the repository, not in chat memory.

The plan is the production order

When a task is unclear, /fstack-nail asks up to five questions.

Then it reduces the answers to three lines:

  • what we are building
  • the constraint that matters most
  • what success looks like

Once I confirm those lines, /fstack-plan writes PLAN.md.

Every plan has the same four sections:

### What we're doing

The outcome and why it matters.

### Steps

1. A small step that can be completed and verified.
2. Another small step.

### What we're NOT doing

- A tempting extra that is outside this task.
- A future feature we are not building now.

### How we'll know it works

- A concrete behavior we can test.
- A build, test, or browser check that must pass.

The most valuable section is often What we’re NOT doing.

Agents are good at expanding an idea.

They see possible abstractions, settings, fallbacks, dashboards, and future features. Many sound reasonable. Most are not needed for the current result.

The exclusion list gives the factory a physical boundary.

Work outside that boundary does not enter the line.

Fable is the factory manager

I currently use Fable as the planner, coordinator, and reviewer.

Opus 5 is also great in this role.

This is where I want the strongest reasoning model I have available.

The manager owns the complete picture.

It reads the request, the codebase, AGENTS.md, PLAN.md, the design rules, the existing architecture, and the files that define shared contracts.

It decides how to split the work.

It also decides what must not be split.

I put the coordination rules directly in my repositories:

Use Fable as the planner, coordinator, and reviewer.

Use Composer 2.5 subagents only for bounded execution or
investigation tasks with clear inputs, constraints, and output format.

Subagents may inspect, report, test, or implement narrow changes.
They may not redefine the plan, change architecture, expand scope,
or touch shared contracts unless explicitly instructed.

I can replace Fable with another strong reasoning model and keep the same system.

The model names will change again, but I will keep these roles. One agent owns the plan, and worker agents do not make product-wide decisions independently.

Using the strongest model as the manager is worth it. A weak plan multiplied across several fast workers creates expensive rework.

The manager usually writes less code than the workers. It makes the decisions, writes the briefs, and rejects bad returns.

If every worker can change the architecture, there is no architecture.

Composer subagents are production cells

I use Composer 2.5 subagents for bounded work.

A bounded task has clear inputs and outputs.

It should also be independently verifiable.

Good worker tasks include:

  • inspect a set of routes and return a migration inventory
  • write three lesson files from an approved curriculum outline
  • implement one calculator in its own folder
  • port one isolated application using an existing parity contract
  • test a group of pages and report every failure
  • research one narrow technical decision without changing files

Bad worker tasks include:

  • make the product better
  • redesign the architecture
  • finish whatever is missing
  • clean up the codebase
  • build the backend while another worker builds against an undefined API

The manager resolves the important questions before delegating execution.

Every worker gets a real brief

A vague prompt creates vague work.

Every production cell receives a self-contained brief with five parts:

## Goal

One sentence describing the exact outcome.

## Context

The product decisions, relevant files, and constraints the worker
cannot safely infer.

## Deliverables

The exact files to create or change and what each must contain.

## Constraints and boundaries

Files the worker must not touch, decisions it must not make,
and work that stays outside this task.

## Bring back

Files inspected, files changed, tests run, decisions made,
uncertainties, and review points.

I end every brief with:

Flag uncertainty; do not guess silently.

A worker that guesses can produce a polished implementation of the wrong decision. A worker that reports uncertainty gives the manager a useful decision point.

The brief also assumes the worker has no chat history.

Everything it needs must be in the repository or in the brief.

That makes the task reproducible. Another worker can receive the same production order and understand it.

File ownership makes parallel work possible

Parallel work is useful when tasks do not compete for the same files.

For example, imagine a course with six weeks of material.

The manager can define the curriculum, lesson format, shared layout, and metadata contract first. Then three workers can write weeks 1–2, 3–4, and 5–6 in separate content files.

They can run at the same time because their file sets do not overlap.

The manager integrates the shared course index later.

The same approach works for:

  • independent route groups
  • separate tools in isolated folders
  • content collections
  • test suites for unrelated modules
  • framework editions in separate package directories
  • research tasks that only return reports

I do not run two writing agents against the same shared abstraction.

Two workers editing the same router, schema, config file, or design token file are not parallel. They are a race condition.

The rule is simple:

Parallelize independent files. Sequence shared contracts.

The dependency graph comes before the workers

Some work looks independent but is not.

A user interface might depend on a data contract. Tests might depend on a finished migration. Product pages might depend on verified package metadata.

The manager maps those dependencies before launching a batch.

A simple project might look like this:

product contract
  -> data model
    -> API routes
      -> interface
        -> end-to-end tests

product contract
  -> independent content files
  -> independent documentation files

Only the branches that do not depend on each other run in parallel.

I also keep a live task list. Every subtask is pending, in progress, returned, accepted, patched, or re-briefed.

This sounds like project management because it is project management.

Agents make implementation faster. They do not make dependencies disappear.

The manager stays useful while workers run

The factory manager should not launch workers and wait.

While a batch runs, the manager can:

  • inspect shared files
  • prepare the next briefs
  • update the task list
  • review a return from an earlier batch
  • handle integration work that does not depend on the active workers
  • verify the product contract against the current implementation

This keeps the line moving without creating overlapping edits.

If a brief turns out to be wrong, I do not send several corrections while the worker is halfway through the task.

I let the return arrive, review it, then issue a corrected brief.

Mid-flight instructions create work that follows two different plans.

Every return is inspected

Worker self-reports help, but the manager still reads the actual files, checks the diff, and walks through the brief line by line.

Every return gets one of three verdicts:

  • ACCEPT means the work matches the brief
  • PATCH means the work has a trivial issue the manager can fix immediately
  • RE-BRIEF means the approach or deliverable is substantially wrong

The distinction between patching and re-briefing matters.

A missing import is a patch.

A wrong data model is not.

If the manager quietly repairs a large failed delegation, the production system learns nothing. The worker brief remains bad, the boundary remains unclear, and the same failure returns in the next batch.

A corrected brief explains what was wrong and sends the task through the cell again.

After individual reviews, the manager runs a cross-cutting pass.

It checks naming, tone, structure, imports, links, shared types, and duplicated logic across all returned work.

This is how several worker outputs become one product instead of a pile of parts.

The quality gate has three questions

When the implementation is complete, /fstack-check asks exactly three questions.

Does it work?

The agent proves it by running the checks that fit the product. That might mean tests, a site build, opening pages in a browser, submitting forms, checking responsive layouts, or testing a clean installation.

“It should work” is not evidence.

Does it match the plan?

The finished diff is compared with PLAN.md.

The check looks for planned work that is missing and extra work that was never approved.

It also checks the blast radius: routes, callers, styles, data, configuration, and anything else the change could affect.

Is it simple?

The final pass looks for unnecessary abstractions, unused code, speculative options, duplicated logic, and dependencies that replace a few lines.

If something smells wrong, the check reports it.

It reports the problem without fixing it automatically, keeping review and repair as separate jobs.

Simplification is its own station

/fstack-simplify only removes and reduces. It leaves working designs and frameworks alone.

It looks for things such as:

  • dead files and exports
  • abstractions with one caller
  • configuration nobody requested
  • dependencies used once
  • impossible error handling
  • comments that repeat the code
  • future features the future never asked for

Then it proposes deletions and tells me what I would lose.

Usually the answer should be: nothing.

The factory can produce too much code very quickly.

A deletion-only station is my counterweight.

The repository is the factory memory

Chat sessions end, models change, and context windows fill. A new agent tomorrow will not remember the decision made tonight.

The repository must carry the important state.

I use a few plain files:

  • AGENTS.md contains product context, architecture rules, and learned preferences
  • PLAN.md contains the current production order and its boundaries
  • docs/overview.md explains the product in plain language
  • docs/architecture.md explains how the parts fit together
  • docs/reference.md records files, configuration, commands, and environment needs
  • LEARNED.md stores short lessons that should change future work

/fstack-document creates or updates the three documentation layers.

/fstack-learn adds one lesson at a time. The entry is at most three lines.

For example:

## 2026-07-25 — Parallel file ownership
Never assign two workers to the same shared registry.
Build isolated files first, then let the manager integrate the registry.

Routine changes do not belong there.

Only a lesson that can save real time in a future session earns a place.

I also keep a global plain-text work log. A Git post-commit hook records each completed outcome, grouped by date and project. I wrote about how that work log works.

The repository explains the product, while the work log shows what changed across the factory.

Defaults keep the line moving

I use the same default web stack for most new projects:

  • Astro
  • HTMX when I need server interactions
  • Alpine.js when I need small client-side state
  • Cloudflare for deployment

The AHA Stack removes repeated setup decisions.

I do not spend the first hour comparing ten frontend frameworks and five hosting platforms.

For a static site, I might only need Astro.

For a server-rendered product, I can add HTMX, Alpine, D1, authentication, email, or payments as the product requires them.

The default gives me a known production line, not a rule that every product must look identical.

When the task specifically calls for another stack, I use another line. I have been producing Next.js editions of existing applications because the target is Vercel and the edition itself is the product.

The factory removes accidental choices while leaving room for real requirements.

What this looks like in my projects

I have been applying this system to very different work under ~/www.

In one project, I had to build a six-week course with 24 lessons, practical labs, an instructor guide, and 12 operating templates.

The curriculum and lesson contract came first. The content was then divided by week into independent file sets. The manager reviewed every batch, integrated the course navigation, checked the public/private publishing boundary, and ran the complete build.

In another project, I added a field-research layer across hundreds of migration routes.

I started with the data schema and validation rules, then ran the research route by route. I integrated the visible section only after the reports passed source-type, duplicate, attribution, depth, and date checks.

In another, I planned framework editions for 18 working software packages.

Before any port began, each software package received a parity contract covering routes, features, data, authentication, real-time behavior, integrations, and tests.

The projects were divided into cohorts:

  • static and browser-heavy products
  • standard applications
  • infrastructure-heavy applications

Independent editions could run in parallel. Shared baseline decisions came first. Every edition had to pass clean installation, native checks, tests, a production build, package review, and browser checks.

This is where the factory idea became concrete for me. Instead of a vague instruction to “make 18 apps,” I followed these steps:

  1. define what must remain true
  2. establish one known baseline
  3. divide the products by complexity
  4. give each cell a bounded edition
  5. inspect every result against the same contract
  6. publish only the editions that pass

The same system also works for smaller products.

A site with four pages does not need eight workers. Each delegation needs a brief, a worker run, and a review. If doing the task directly is faster and clearer, the manager does it.

The factory does not make every product the same

Factories bring images of identical objects moving down a conveyor belt.

That is not what I want for software.

The products I am building are different.

They include a content library, a business application, a course, a browser tool, a visual product, and a software package with source code.

They should not share the same interface, data model, or business rules.

What they share is the production method:

  • clarify before building
  • store context in the repository
  • plan before parallelizing
  • keep architecture decisions centralized
  • assign independent file sets
  • require explicit return reports
  • inspect artifacts instead of trusting summaries
  • verify the complete product
  • remove unnecessary complexity
  • record what future agents must know

The factory standardizes the process, not the product.

What I do not automate

There are parts I deliberately keep outside the line.

A worker does not get to change the product direction after finding an interesting feature in the code. Public names, pricing, positioning, and shared data contracts also stay with the manager unless a brief says otherwise.

A confident summary is not enough reason to merge, and a passing build does not make unfinished work ready to deploy. When a worker is uncertain, I want the uncertainty reported rather than turned into guessed code.

I also choose the fstack skills for the task instead of running all of them automatically.

I might need a plan but not a roast. A clear task does not need /fstack-nail, and a small change can go directly to checking and pushing.

The line adapts to the work.

Common factory failures

I have found a few failure modes that appear quickly.

Too many workers

More workers increase coordination work. If a project has three independent tasks, launching ten agents creates seven agents looking for something to do.

Weak briefs

“Build the settings area” leaves every important decision open.

A good brief names the pages, data, states, existing patterns, excluded work, tests, and files.

Shared-file collisions

Parallel workers should not edit the same registry or abstraction.

Give them isolated files. Integrate shared files after the batch.

Delegated architecture

Workers can investigate architecture options, but the manager selects one and puts it in every relevant brief.

Blind trust

A passing unit test does not prove the page works.

A worker report does not prove the requested file exists.

The final check must match the kind of product being built.

Chat-only decisions

A decision that exists only in one conversation will be lost.

Move it into AGENTS.md, PLAN.md, documentation, a test, or the code itself.

Measuring output instead of value

The factory can generate pages, components, tests, and documentation at impressive speed. None of that proves someone wants the product, so /fstack-roast and the product interview belong at the start.

How to build this setup yourself

You do not need a large platform.

Start with fstack:

npx skills@latest add flaviocopes/fstack

Then add a short coordination section to the repository’s AGENTS.md:

Use one agent as the planner, coordinator, and reviewer.

Use worker subagents only for bounded tasks with clear inputs,
file boundaries, constraints, and output format.

Workers may not redefine the plan, change architecture,
expand scope, or edit shared contracts unless instructed.

Every worker must return files inspected, files changed,
tests run, decisions made, uncertainties, and review points.

The coordinator reviews the actual artifacts before integration.
Long-lived project state belongs in repository files.

For a new product, the workflow is:

  1. Run /fstack-roast if the idea needs honest pressure.
  2. Run /fstack-interview to record product context.
  3. Run /fstack-nail if the first task is unclear.
  4. Run /fstack-plan and approve PLAN.md.
  5. Let the manager map dependencies and file ownership.
  6. Write one complete brief per worker task.
  7. Run independent tasks in parallel batches.
  8. Review every return as ACCEPT, PATCH, or RE-BRIEF.
  9. Let the manager integrate shared files.
  10. Run /fstack-check on the complete result.
  11. Run /fstack-simplify if the result grew too much.
  12. Update documentation and capture one useful lesson.
  13. Run /fstack-push when the work is ready.

Do it manually at first so you understand where the real gates are. Automate it after the process works.

The bottleneck moved

For most of my career, implementation was the bottleneck.

An idea could take weeks before I had something real enough to judge.

Now I can produce working software much faster.

The bottleneck moved to decisions:

  • is this worth building?
  • what is the smallest useful version?
  • what must stay true?
  • which work can safely run in parallel?
  • is the result coherent?
  • should this exist at all?

I do not want the software factory to become fully automatic. I want it to extend my judgment, not replace it with more output.

fstack is becoming an operating system for building

I still like that every fstack skill is small.

The factory did not require turning fstack into a large framework.

It required giving those small skills roles inside a larger system.

In this system, PLAN.md is the production order and AGENTS.md is the operating manual. A strong reasoning model manages the work. Today I use Fable, and Opus 5 is another great choice.

Composer subagents are the production cells. /fstack-check provides the quality gate, while /fstack-simplify removes excess. The documentation and work log hold the factory memory.

I still decide what enters the line and what leaves it.

This is how I am building now: a small production system that turns clear decisions into working software. I can understand each part and keep independent product decisions away from an agent swarm.

You can find fstack on GitHub. It is free, open source, and works with agents that support skills.

Tagged: AI · All topics

Want me to talk about your product? You can sponsor this site.

~~~

Related posts about ai: