OpenSpec-practise

Closing Off Silent Failures: OpenSpec v1.13.0 Workflow Practice

OpenSpec v1.12.0 and v1.13.0 shipped in quick succession (September 2026), neither with breaking changes. The theme of v1.13.0 fits in one sentence: archive and the delta parser no longer quietly rewrite or drop what you wrote. This article walks the post-upgrade workflow (Explore → Propose → Apply → Archive) through a real change — “order list query” (order-list-query) — and records the changes in both releases that matter in practice, including validate --report findings catching 3 real issues in this repository on its very first run.

1. What Changed (Practice Perspective)

v1.12.0: Findings Reports and Code-Grounded Planning

v1.13.0: Delta Parser and Archive Robustness

2. The Practice Change: order-list-query

2.1 Explore: First Run of the New Template

Following the v1.13 explore template, the inventory step is now openspec list --specs (7 capabilities with requirement counts), cross-checked against the route tables of both implementations. Four gaps remained: order list query (small-medium), cart clear endpoint (tiny), payment implementation (large), product deletion (medium-large, stock references).

We picked order list query: GET /api/orders?userId= returning a user’s order history — the natural next gap in the order loop; the repo layer already had traversal; a pure ADDED requirement.

Reading the code during explore surfaced a dual-implementation divergence: the Python Order model has no user_id field, while Node’s order objects have always carried userId. Filtering by user therefore first required completing the model — a finding that directly shaped the design.

2.2 Propose: Context Loading in the New Flow

Per the new propose template’s step 2, openspec context --json runs first (returning the authoritative root path), and only then is the context field of config.yaml read as a planning constraint. Four artifacts:

2.3 Apply: Falling into the Same Pit a Second Time

Both implementations landed in ~20 lines each. The Node integration test failed on first run: the order assertion expected 201, got 400 (CART_EMPTY) — the exact pit PR #11 fixed in the performance test: the dev cart endpoint is pinned to user_dev, but the test ordered as a different user. Fixed with relative assertions from user_dev’s perspective (record the pre-existing order count, assert +2); multi-user isolation assertions moved to the Python side — Python’s cart requests carry userId, so multi-user E2E is natural there.

The repeat itself is worth recording: the dev server’s mock identity model (fixed user_dev) is in structural tension with tests that want multiple users. Unit tests cover isolation (direct service calls), integration covers a single-user loop, and Python covers multi-user — a reasonable division under the current architecture.

Results: Node 18/18, Python 6/6 green.

2.4 validate –report findings: 3 Real Issues on First Run

During wrap-up we ran the new report mode against the main specs:

$ openspec validate --report findings --specs
spec/cart-management
  [WARNING] overview: Purpose section is too brief (less than 50 characters)
spec/payment
  [WARNING] overview: Purpose section is too brief (less than 50 characters)
spec/product-query
  [WARNING] overview: Purpose section is still a placeholder rather than
  a Purpose anyone wrote ...
Totals: 7 passed, 0 failed (7 items)

All three warnings were real: cart/payment Purposes were indeed under 50 characters, and product-query’s Purpose was still the TBD - created by archiving change ... placeholder the CLI wrote during the v1.5.0 practice archive, never filled in. After fixing each one, findings came back empty. This neatly validated the evolution loop across v1.9.0 (Purpose format) → v1.11.0 (placeholder warning) → v1.12.0 (findings report): guards added version by version surface real, accumulated debt version by version.

2.5 Archive

A single openspec archive merged the delta (+1 added) and archived the change to openspec/changes/archive/2026-09-10-order-list-query/. Post-archive validation: no active changes, all 7 specs pass, findings empty.

3. Takeaways

3.1 v1.13.0’s Value Is Eliminating Silent Failures

The three parser failure modes (*/+ bullets ignored, duplicate delta sections half-applied, fenced blank lines rewritten) shared one property: the toolchain reported success while the result was wrong. That is more dangerous than a crash — it corrupts the “single source of truth” itself. v1.13.0 turns all of them into “either takes effect, or errors out.”

3.2 The Compounding Return of Tooling Guards

From v1.9.0 through v1.13.0, five upgrades kept reinforcing the same thing: spec content quality. Purpose migration → placeholder warning → findings report — each guard has paid off in a later practice. The value of an SDD toolchain is not just “faster generation” but “drift is discovered earlier.”

3.3 Open Observations


This article is based on the order-list-query practice in the OpenSpec Practise repository (2026-09-10); full artifacts live under openspec/changes/archive/2026-09-10-order-list-query/.