Skip to main content

Documentation Index

Fetch the complete documentation index at: https://acai.sh/llms.txt

Use this file to discover all available pages before exploring further.

Spec-driven development balances the speed of “vibe coding” with the professional rigor required to ship high-quality applications. It is essential for developers and teams who wish to leverage agentic software development tools like Claude and OpenCode in complex projects.

What is a spec?

In Acai.sh, every spec is a ‘Functional Requirements Doc’ for a single feature in your product. It is written as a feature.yaml file. Primarily, the spec is written as a list of acceptance criteria. It defines how your feature should behave, functionally. It also includes additional constraints or requirements that are neccesary for success. Here is a minimalist example:
feature:
  name: user-authentication
  product: enterprise-api

components:
  LOGIN:
    description: The login UI and journey
    requirements:
      1: Shows an email and password input
      2: Includes a "Forgot Password" link
      3: On success, navigates to the team overview
      4: On success, issues secure session token to client

constraints:
   AUTH:
    description: Additional eng. constraints
    requirements:
      1: Does not leak information about existence or absence of a user's email
      2: Session expires after 5 minutes of inactivity
      3: Session expires 12 hours after last login

Where is the spec?

In Acai, specs are committed to git repositories as .yaml files.
mapperoni.com
features
map-editor
map-editor.feature.yaml
src
.gitignore
Specs must be located in a features/ directory.
The file name must include the name of the feature.

The Feature.yaml Document

All acai specs are yaml. Yaml has a few key benefits over markdown, but remains lightweight and flexible.

Basic format

As shown in the example spec above, the document has three main sections:
  1. feature: Metadata about the feature, such as its name, version, product and description.
  2. components: Functional requirements, organized into component groups.
  3. constraints: Cross-cutting or plumbing requirements (like performance, authorization, data privacy)
To be compatible with the acai.sh dashboard and CLI, your feature.yaml must have a feature.name and feature.product defined.

Advanced Tips

Feature.yaml supports some useful patterns for adding additional notes and context in a structured way.
You can attach notes directly to requirements. These are passed along to the acai.sh server and included in CLI / API response payloads.There are two ways to add notes.
# Concise syntax
1-1: Hides exact location of the building
1-1-note: This was a customer request (April 2026)

# Verbose syntax
1-2:
  requirement: Hides exact location of the building
  note: This was a customer request (April 2026)
Your components and constraint groups support arbitrary name and description fields, which is a good place to add additional context.
components:
  LOGIN:
    name: Login Form
    description: A standard login UI component
    requirements:
      1: ...

constraints:
  AUTH:
    name: Authentication
    description: Additional eng. constraints around auth and security
    requirements:
      1: ...
You can associate a sub-requirement to a parent (up to 1 level of depth). This makes it easy to insert more requirements without needed to renumber existing ones.
components:
  MAP:
    requirements:
      1: Clicking a property opens the details panel
      1-1: Highlights the selected property on the map
      1-2: Sends an analytics event
If one requirement relates to another, you can reference it using its complete ID (known as the ACID) like my-feature.COMPONENT.1-1.
1: Opens the Panel (see property-map.PANEL.1)
1-1: Also zooms the map, similar to property-map.MAP.4
Instead of deleting them, you may want to flag them as deprecated to maintain a living history.
requirements:
  1-1:
    deprecated: true
    requirement: Shows a tutorial on first load
    note: Removed due to negative user feedback
  1-2:
    skipped: true
    requirement: Shows location search box
    note: Blocked by geolocation service issue #1234
  1-3:
    replaced_by: ["property-map.MAP.1-4", "property-map.MAP.1-5"]
    requirement: Fly to searched location
    note: Replaced by better UX

What makes a good spec?

There are some important best practices to follow.
  • Focus on the functional behavior, and key engineering constraints, and ideally only things that can be tested with a pass/fail. Feel free to use -note and description to provide soft or higher level guidance.
  • Avoid superficial requirements (design, layout, aesthetics, copywriting, etc.) unless they are mission-critical. Otherwise your spec will grow too large and your product will grow too rigid.
  • Omit obvious requirements. Have faith your developers can fill in the gaps!
  • Be descriptive, not prescriptive. Say what needs to be implemented, avoid prescribing how it gets implemented.
  • If you find yourself duplicating requirements in many specs, consider creating a core.feature.yaml or just putting guard rails in AGENTS.md and other docs.
  • The feature boundary is up to you, but smaller features are more maintainable. A small feature spec is easy to read and review, easy to ship and QA, easier to feature-flag and roll-back.

The Spec Lifecycle

Specs add the most value to teams working on complex, high-stakes projects. So how do we think about specs when working on a project with many services, many git repos, long-lived branches, and multiple QA cycles?

Mental model / data model

Acai abstracts this complexity by breaking your project into 4 core concepts.
EntityExample
Productmobile-app CLI web-app
ImplementationProd dev maintenence
Featurecarbon-calculator support-chat users-endpoint
StatesAssigned Completed Accepted Rejected
Let’s use an example to understand this better. Imagine a spec for a carbon calculator in a travel app.
  1. carbon-calculator.feature.yaml lives in your repo, on git branch called backend/main.
  2. The git branches backend/main and frontend/main are both tracked by the Production implementation.
    This happens automatically, the first time you run acai push --all --target Production
  3. Production is an implementation of the mobile-app product.
  4. When QA is done, all of the requirements defined in carbon-calculator.feature.yaml are marked as Accepted on Production
This simple model also works great for more complex monorepos and polyrepo projects. In any case, a team can have many products, and a product can have many features and many implementations, which track many git branches on many repos.
Example dashboard showing a list of implementations of the map-settings feature.

Spec journey

So the lifecycle of a feature from draft spec to production may differ from team to team, but the simplest example is this;
1

Create branch & write spec

Create a branch like feat/carbon-calculator and draft your feature.yaml
2

Push

Run acai push to extract the specs and push them to an Acai Server. This creates a new implementation, which is named after your branch by default.
3

Review

Invite your team to review by sending them a link to the Acai.sh dashboard for your new feature + implementation.
4

Integrate

When the spec and code passes QA, merge the code, delete the old implementation.
5

Push

When the feature is merged (e.g. to main), push again from the main branch so that the dashboard reflects the current state of your app. CI / GitHub actions are useful here.
Some teams prefer to review and merge specs to the main branch before even starting implementation. Other teams might even maintain a standalone specs repo. Acai.sh should work for all the common git workflows.