You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Proposal: depends_on change metadata — detect and declare ordering between parallel changes #1915
Add an optional depends_on field to per-change metadata (.openspec.yaml) that names other changes this one builds on, and surface it wherever changes are listed. Detecting the dependency shouldn't be manual: when a new change is created, OpenSpec should compare it against the existing active changes and propose a depends_on entry when it looks like one builds on another, the same way /opsx:explore already inspects openspec list --json before thinking through a new idea.
Use case
With several changes in flight, nothing records that one change's scope only makes sense after another lands. Today the only way to discover that add-oauth-scopes needs add-oauth-provider to exist first is to read both proposals by hand. Once a project has more than a couple of parallel changes, an agent (or a person) picking up work has no way to tell which change is safe to start now versus which one will conflict with, or build on top of, something still in flight.
This is the ordering half of a problem the "priority"/"author" work in #1899 addressed for triage, and it's adjacent to the parallel-change overlap detection in #1387 / #1698 — but overlap detection reports that two changes touch the same requirement; it doesn't say which one should go first, or that one only makes sense once the other is archived.
Current behavior
Per-change metadata lives in .openspec.yaml, validated by ChangeMetadataSchema (src/core/change-metadata/schema.ts). It has no notion of one change relating to another.
openspec list (src/core/list.ts) has no concept of ordering or relationships between changes — each row is independent.
openspec new change (src/commands/workflow/new-change.ts) scaffolds a change without looking at what else is active.
/opsx:explore (src/core/templates/workflows/explore.ts) already runs openspec list --json up front to see active changes, but only uses that to orient the conversation — it never compares the new idea's scope against them.
Proposed behavior
Add depends_on: string[] (optional, change names) to ChangeMetadataSchema, validated against currently active changes — once a dependency archives, it's baked into the specs and there's nothing left to depend on.
When /opsx:explore or openspec new change runs, check the new change's stated scope/affected areas against existing active changes' proposals (already available via openspec list --json + openspec status) and, when there's a plausible overlap or ordering constraint, propose depends_on: [<existing-change>] back to the user rather than silently scaffolding an independent change. This is a proposal to confirm, not an automatic write — consistent with explore's existing "don't auto-capture" guardrail.
openspec validate (or a new check) could flag a depends_on cycle, or a dependency that names a change that no longer exists.
This maps cleanly onto a dependency-graph problem: declare depends_on: [change-id] in each change's .openspec.yaml, then have the CLI build a DAG at validate/create time. Validation catches the failure modes you care about: references to unknown change ids, self-references, and cycles - reported with the actual cycle path, not just 'cycle detected'. From the same graph the CLI derives a suggested implementation order via topological sort, so parallel changes get a deterministic sequence instead of tribal memory. Pseudocode: g = build_dag(changes, key=lambda c: c.depends_on); assert_no_unknown_or_self(g); order = toposort(g). I can deliver the metadata parsing, validation errors, and the ordering output together with tests. Want me to take a crack at it? Happy to open a PR with working code.
depends_on: string[] in .openspec.yaml, kebab-case validated
openspec validate checks for unresolved names, self-references, and cycles among active changes — cycles report the actual path (depends_on cycle: a -> b -> a), not just "cycle detected"
openspec new change --depends-on <name> validates against active changes at creation time
openspec list surfaces a "Blocked by" column, and --json exposes the raw depends_on array
Left out: computing a topological sort / suggested implementation order in the CLI itself. list --json exposes the raw graph, so I left deriving an order to downstream tooling rather than building it in.
If you're interested in building on top of it — the ordering piece or anything else — feel free, happy to have you pick it up from there instead of starting from scratch.
Summary
Add an optional
depends_onfield to per-change metadata (.openspec.yaml) that names other changes this one builds on, and surface it wherever changes are listed. Detecting the dependency shouldn't be manual: when a new change is created, OpenSpec should compare it against the existing active changes and propose adepends_onentry when it looks like one builds on another, the same way/opsx:explorealready inspectsopenspec list --jsonbefore thinking through a new idea.Use case
With several changes in flight, nothing records that one change's scope only makes sense after another lands. Today the only way to discover that
add-oauth-scopesneedsadd-oauth-providerto exist first is to read both proposals by hand. Once a project has more than a couple of parallel changes, an agent (or a person) picking up work has no way to tell which change is safe to start now versus which one will conflict with, or build on top of, something still in flight.This is the ordering half of a problem the "priority"/"author" work in #1899 addressed for triage, and it's adjacent to the parallel-change overlap detection in #1387 / #1698 — but overlap detection reports that two changes touch the same requirement; it doesn't say which one should go first, or that one only makes sense once the other is archived.
Current behavior
.openspec.yaml, validated byChangeMetadataSchema(src/core/change-metadata/schema.ts). It has no notion of one change relating to another.openspec list(src/core/list.ts) has no concept of ordering or relationships between changes — each row is independent.openspec new change(src/commands/workflow/new-change.ts) scaffolds a change without looking at what else is active./opsx:explore(src/core/templates/workflows/explore.ts) already runsopenspec list --jsonup front to see active changes, but only uses that to orient the conversation — it never compares the new idea's scope against them.Proposed behavior
depends_on: string[](optional, change names) toChangeMetadataSchema, validated against currently active changes — once a dependency archives, it's baked into the specs and there's nothing left to depend on.openspec listsurfaces the relationship — e.g. a column/marker for "blocked by " — and--jsonincludes the rawdepends_onarray, so tooling can do its own topological sort instead of everyone re-deriving order from directory timestamps or manual numbering (the workaround people reach for today, per Is it possible to track development order? #1145 / Support numbered change names (NNNNN-slug) for sequencing #1169)./opsx:exploreoropenspec new changeruns, check the new change's stated scope/affected areas against existing active changes' proposals (already available viaopenspec list --json+openspec status) and, when there's a plausible overlap or ordering constraint, proposedepends_on: [<existing-change>]back to the user rather than silently scaffolding an independent change. This is a proposal to confirm, not an automatic write — consistent with explore's existing "don't auto-capture" guardrail.openspec validate(or a new check) could flag adepends_oncycle, or a dependency that names a change that no longer exists.Related
lifecycle: status— record change state as data, not directory position (experimental) #1683 — other proposed additions to.openspec.yaml(lifecycle timestamps, status); same file, different field.