Skip to content

openspec archive does not preserve blank lines around ## Requirements in the target spec #1625

Description

@jorgeperezj

What happens

When openspec archive <change> syncs a delta into openspec/specs/<capability>/spec.md, it rewrites the file without the blank lines that surrounded the ## Requirements heading. The heading ends up glued to the preceding paragraph and to the first requirement:

 ...ends the Purpose paragraph.
-
 ## Requirements
-
 ### Requirement: First one

Expected: the heading keeps one blank line before and after, as it had.

How consistently

Five out of five archive runs, across four different capability files, in a single day:

Capability Runs affected
conversation-orchestration 2
destination-adapter-dentos-v1 2
destination-adapter-contract 1
booking-saga 1
verification-loop 2

It reproduces every time, on files that were correctly formatted before the run. Requirement and scenario counts are unaffected — nothing is lost, so it is purely a formatting regression, but it means every archive produces a diff that has to be hand-corrected before review.

Two related observations, in case they share a cause

  1. A --- separator closing a requirement was consumed in one run (not in the others), so the requirement ran directly into the next heading.
  2. The delta's text is inserted verbatim. A delta paragraph written as one long line stays one long line in a target file that otherwise wraps at ~100 columns. Probably by design, but combined with (3) below it has a sharp edge.
  3. openspec validate reads only the first non-empty line of a requirement's body when checking for SHALL/MUST. So if an author wraps a requirement paragraph and the SHALL lands on the second line, the whole capability fails validation with must contain SHALL or MUST — which is confusing, because the requirement does contain SHALL. If that check is meant to scan the requirement body, scanning only the first line looks like a bug; if it is meant to scan only the first line, the error message could say so.

Environment

  • @fission-ai/openspec@1.4.1, installed globally, on Windows (Node 22).
  • Repo layout: openspec/specs/<capability>/spec.md, openspec/changes/<slug>/specs/<capability>/spec.md, schema spec-driven.

Why it matters for us

Our review process has a gate dedicated to checking that a delta was integrated rather than pasted over. Because the tool reformats the target, every archive diff carries unrelated whitespace noise, which makes the real question — did any published scenario disappear? — harder to see. We ended up documenting "read the sync diff by hand, always" as a process step.

Happy to send a PR if you can point at where the target file is written.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions