We asked two coding agents to improve the same first-run experience. Our CLI should notice when a repository uses OpenSpec and do something useful with the specs and proposals already there.
Both got the same request, word for word. One worked with OpenSpec alone. The other also got an intent with the product decisions written out before it wrote its OpenSpec change.
One of those decisions concerned repositories whose OpenSpec config points to a separate store. The baseline agent ruled that case out of scope. The intent-first agent supported it, with a sensible answer when the store couldn't be found, because the intent named that behavior as required.
The request had left that boundary unstated. Without a decision, the agent made one.
This was one internal experiment, on a product we know well. It doesn't show that OpenSpec couldn't carry the same information. It shows that handing an agent the product decision changed what it built.
OpenSpec records the change you agreed to. An intent spec records why it was worth agreeing to.
Where the two fit
The question I get is whether an intent spec competes with OpenSpec. The better question is what has to travel from deciding on a change to implementing it.
An intent records the problem, the people affected, the evidence behind the decision, the outcome you want, and the boundaries the implementation must respect. It also gives unresolved choices a place to stay visible.
An OpenSpec change turns that direction into a proposal, spec deltas, design notes and tasks, next to the code. The two overlap. A proposal has to explain why the change matters too. What a separate intent adds is a product decision that stays put across implementation plans, repositories and later reviews.
| Intent spec | OpenSpec change | |
|---|---|---|
| Main question | What outcome are we after, and which decisions constrain it? | What has to change in this system to deliver it? |
| Review focus | Problem, evidence, outcomes, boundaries, open choices | Proposed behavior, design, tasks, implementation checks |
| Contributors | People with product, customer, design and engineering knowledge | The implementation team and its agents |
| Useful lifetime | Through implementation and outcome measurement | Through proposing, implementing and archiving the change |
These are responsibilities to agree on, not job titles to enforce. Engineers help shape product decisions. Product owners need to understand what implementation finds. A small team may do all of it together.
The intent gives them one record to review before each implementation plan takes its own shape.
Agents don't lack information. They lack permission to decide.
The store-pointer case was the visible difference. The bigger one was what the first run did at all.
The baseline built detection and routing: it found the OpenSpec files and told the agent where to look. The intent-first run built a reader that turned the change's contents into inputs for a readiness verdict.
Those are different answers to "do something useful." The extra product context made the intended behavior explicit.
The baseline also made good choices the intent-first run didn't. It handled cloud mode, and it capped its change listing to protect the agent's context budget. This wasn't a clean sweep.
There was a cost. The baseline took 12 minutes 25 seconds; the intent-first run took 18 minutes 28 seconds, about 49% longer. The two built different scope, so that's an observation from one run, not a general estimate of what writing an intent costs.
The question for a team trying this is whether the extra discussion and review catch decisions that would otherwise get expensive to revisit.
Implementation corrected the intent
The most useful part of the experiment ran the other way.
Our intent referred to "the active change." During implementation, the agent found that the OpenSpec version we tested doesn't record a single active change on disk. Several change directories can sit side by side. The requirement assumed information the implementation couldn't get.
The agent handled one change by naming it and several by listing them, and reported the mismatch. That gave us a concrete product question to go back to: what should first run do when several changes are present?
The intent-first implementation had a defect of its own. Its reader missed verification recorded in tasks.md. Later testing exposed that blind spot, and we fixed the reader.
Both findings matter. An explicit intent can guide a build and still carry a wrong assumption. A readiness check can miss information that is right there. Neither gets to be beyond question because it produced a verdict.
The loop that works: a decision guides the build, the build exposes a contradiction, and the people responsible review it. The revised decision feeds the next step.
A workflow to try
- Write the product decision down. Record the problem, the intended outcome, evidence references, boundaries and open choices. Link it to the item your team already tracks.
- Review readiness together. Use a check to surface gaps, then settle the choices that would change the plan. A passing check supports that review; it doesn't replace it.
- Create the OpenSpec change. Give the implementation team and its agents the reviewed intent. If several repositories are involved, link each change to the same product decision.
- Bring contradictions back. When implementation hits an impossible requirement or a missing decision that matters, record the finding and review the intent. Keep the reason for any revision visible.
- Return to the outcome after delivery. Archiving the implementation change is a milestone. Follow up on whether the outcome moved, and record what you learned.
That last step gives the intent a purpose after handoff. The decision and its evidence are still there when someone asks whether the work helped.
Keep the first attempt small
Pick one real change with a product choice that could reasonably be read two ways. Write a short intent and have the team review it before producing the OpenSpec change.
Agree where the decision lives. If your planning tool already holds it, decide what the file carries and how revisions reach the people implementing it. Linking two records only helps if everyone knows which one to update.
Keep private evidence in a system with access control. Repository files should carry safe summaries and references, not raw customer quotes, identities or confidential metrics.
Then review the handoff. Which questions came back? Which assumptions changed? Did the implementation expose a mistake in the intent? Did writing the decision down help someone settle a disagreement?
Those answers tell you more than the number of fields filled in or the length of the proposal. If the separate file only repeats a conversation that already works, reconsider what it adds.
Start with the change you already have
You don't need to reorganize your workflow to inspect an existing OpenSpec change. Pathmode's read-only preflight reads it as it is:
npx -y @pathmode/cli preflight openspec/changes/<change-id>The preflight runs locally, doesn't modify the change, and doesn't send its contents anywhere. npx may download the CLI package if it isn't already cached.
Treat a reported gap as something to inspect. It may point to an unresolved decision, or to information the reader didn't recognize. Our own experiment taught us to check both.
The OpenSpec integration page explains the setup. You can also start with a plain intent.md in the open IntentSpec format and review it with your team.
A spec is done when the code merges. A decision is done when you know whether it worked.
The OpenSpec change carries the first. The intent carries the second.