A multi-agent pipeline that transforms raw product tickets into EARS-compliant technical specifications using Claude.
This repo implements the Specs rung of The PM Scaffold — a framework for product management in the agentic era. See the framework repo for the four-rung thesis, FAQ, and reference implementations across all rungs.
Writing clear, unambiguous technical specifications is one of the highest-friction tasks in product development. A vague ticket handed to an engineering team creates rework, back-and-forth, and delayed delivery. Doing it well takes time a PM rarely has.
This pipeline automates the cognitive work: it reads a raw ticket, surfaces ambiguity, resolves open questions using PM-standard assumptions, and outputs a structured EARS-compliant spec ready for developer consumption.
Built from a production system that reduced spec writing time by 60% across a global product team.
EARS (Easy Approach to Requirements Syntax) is a structured requirements format that eliminates ambiguity by enforcing consistent sentence patterns for each requirement type.
| Type | Pattern | Example |
|---|---|---|
| Ubiquitous | The system shall [action] |
The system shall validate email format on input. |
| Event-driven | WHEN [trigger], the system shall [action] |
WHEN a user submits the checkout form, the system shall validate all required fields before processing payment. |
| State-driven | WHILE [state], the system shall [action] |
WHILE a payment is processing, the system shall disable the submit button. |
| Unwanted behavior | IF [condition], THEN the system shall [action] |
IF payment authorization fails, THEN the system shall display an error message and retain all form data. |
| Optional feature | WHERE [feature is included], the system shall [action] |
WHERE express checkout is enabled, the system shall pre-populate saved shipping details. |
Raw Ticket
|
v
ORCHESTRATOR
|
|---> AMBIGUITY DETECTOR
| Identifies unclear requirements,
| missing context, open questions
|
|---> QUESTION RESOLVER (if ambiguities found)
| Resolves open questions using
| PM-standard assumptions, documents
| all assumptions made
|
|---> SPEC WRITER
Produces EARS-compliant requirements,
organized by requirement type
|
v
Structured Spec (Markdown + JSON)
Each agent is a focused Claude call with a dedicated system prompt. The orchestrator manages context passing between steps and decides whether the resolution step is needed based on ambiguity detector output.
1. Clone and install
git clone https://github.com/yourusername/ears-spec-agent.git
cd ears-spec-agent
pip install -r requirements.txt2. Set your API key
cp .env.example .env
# Add your ANTHROPIC_API_KEY to .env3. Run against an example ticket
python main.py --input examples/tickets/checkout_flow.md4. Run against your own ticket
python main.py --input path/to/your/ticket.md --output path/to/output/The pipeline produces two files per ticket:
[ticket_name]_spec.md — Human-readable EARS spec with requirements organized by type, assumptions documented, and open questions flagged for PM review.
[ticket_name]_spec.json — Structured JSON for downstream consumption (Jira, Confluence, coding agent context, etc.).
## EARS Specification: Checkout Flow Redesign
### Assumptions Made
- Guest checkout is out of scope for this iteration
- Payment methods limited to credit/debit and PayPal
- Error states should retain all valid form data
### Requirements
**Event-Driven**
- WHEN a user clicks "Proceed to Checkout," the system shall validate that all required cart items are in stock before rendering the checkout form.
- WHEN a user submits the checkout form, the system shall validate all required fields and display inline errors for any invalid inputs before processing payment.
**State-Driven**
- WHILE payment is processing, the system shall display a loading indicator and disable all form interaction.
**Unwanted Behavior**
- IF payment authorization fails, THEN the system shall display a user-friendly error message, retain all valid form data, and log the failure event with error code.
- IF a required field is left empty on submission, THEN the system shall highlight the field, display an inline error message, and prevent form submission.
**Ubiquitous**
- The system shall support checkout completion on mobile viewports (320px minimum width).
- The system shall log all checkout events to the analytics pipeline.ears-spec-agent/
├── main.py # CLI entry point
├── pipeline/
│ ├── orchestrator.py # Pipeline manager and context passing
│ └── agents/
│ ├── ambiguity_detector.py
│ ├── question_resolver.py
│ └── spec_writer.py
├── prompts/ # System prompts for each agent
│ ├── ambiguity_detector.md
│ ├── question_resolver.md
│ └── spec_writer.md
├── examples/
│ ├── tickets/ # Sample input tickets
│ └── specs/ # Sample generated specs
└── tests/
└── test_pipeline.py
| Variable | Description | Default |
|---|---|---|
ANTHROPIC_API_KEY |
Your Anthropic API key | Required |
MODEL |
Claude model to use | claude-opus-4-6 |
MAX_TOKENS |
Max tokens per agent call | 2048 |
Why prompt chaining over a single call? Each agent has a focused task and a dedicated system prompt. This produces higher quality output than asking a single call to detect ambiguity, resolve it, and write the spec simultaneously. It also makes the pipeline auditable: you can inspect each agent's output independently.
Why does the orchestrator skip resolution sometimes? If the ambiguity detector finds no open questions, sending an empty resolution step wastes tokens and adds latency. The orchestrator checks detector output and routes directly to the spec writer when the ticket is already clear.
Why EARS? EARS is the most widely adopted structured requirements format in software engineering. Requirements written in EARS syntax are directly consumable by coding agents (Cursor, Claude Code, GitHub Copilot) because each requirement maps cleanly to a single testable behavior.
- Anthropic Python SDK
- Pattern based on Building Effective Agents by Anthropic
MIT