OpenSpec explained: turn an AI coding request into reviewable artifacts
Reading OpenSpec ArtifactGraph: why specs comes before design
Inspect declaration-order tie breaking and reproduce six graph checks without running an AI assistant.
What you will learn
- Follow Kahn’s algorithm
- Compare full order with current readiness
- Respect the prevalidated-input contract
Before you start
- Basic Git and Node knowledge
- A disposable sample repository
Display dependencies and missing evidence without automatically executing the next instruction.
Key takeaways
- The entire queue is re-sorted.
- The local fixture executes the actual pure class.
- Six graph checks do not verify the whole CLI.
Follow Kahn’s algorithm
getBuildOrder creates an incoming-edge count and reverse adjacency map, queues zero-dependency artifacts and removes them while decrementing dependent counts. The inspected class sorts the queue using each artifact’s position in the schema.
It re-sorts the whole queue after adding newly ready artifacts. Sorting only new arrivals could leave an earlier-declared ready item behind a later-declared waiting item. This is a deterministic ordering rule, not an alphabetical sort.
Compare full order with current readiness
getNextArtifacts skips completed IDs and accepts a remaining artifact only when every prerequisite is in the completed set. After proposal, the fixture returns specs and design; after proposal and specs, it returns design.
The executed fixture removes TypeScript syntax and module imports from the inspected pure class, then calls fromSchema on a synthetic valid schema. Six assertions cover order, readiness and completion. No schema loader, file detector, CLI or model runs in that test.
Respect the prevalidated-input contract
fromSchema explicitly expects a prevalidated schema. The fixture does not establish validation of cycles, duplicate IDs or unknown prerequisites. Do not call those inputs supported because the happy-path class test passes.
When diagnosing unexpected recommendations, inspect the schema declaration sequence, the completed set and dependency edges separately. A change to any one can alter readiness without indicating a topological-sort defect.
Decision guide
| Criterion | Option A | Option B |
|---|---|---|
| Best when | You need predictable behavior and easy auditing | You need adaptive optimization and have reliable telemetry |
| Main risk | May leave performance on the table | Can become difficult to explain or debug |
Implementation steps
- 1
Inspect declarationOrder and queue sorting.
- 2
Reproduce the completed-set transitions.
- 3
Keep schema validation outside the fixture claim.
Copy-ready example
{"completed":["proposal"],"ready":["specs","design"],"buildOrder":["proposal","specs","design","tasks"]}Frequently asked questions
Why is design not first alphabetically?
The class uses schema declaration position to break readiness ties.
Were malformed schemas tested?
No. The fixture uses the documented prevalidated-schema entry point.
Sources
- OpenSpec / src/core/artifact-graph/graph.tsSource checked 2026-09-23
- OpenSpec / schemas/spec-driven/schema.yamlSource checked 2026-09-23