Files
Clay Good a70daccf0e feat(skills): propose /opsx:update planning-artifact update skill (#1278)
* docs(openspec): propose add-update-workflow — graph-driven /opsx:update + cohesive audit

Dogfooded OpenSpec proposal for the missing first-class "update" action:
a /opsx:update workflow that propagates an edit to one artifact across its
downstream dependents (targeted mode) or audits a whole change for stale/
incoherent artifacts (audit mode) — driven by the schema's artifact graph,
never hardcoded filenames, editing planning artifacts only (never code).

- artifact-graph: expose reverse-dependency queries (getDependents/getDownstream)
  + a requires-edge mtime staleness signal (the engine already builds the
  dependents map at graph.ts:98 and discards it).
- cli-artifact-workflow: surface requires/dependents/stale on `openspec status
  --json` and add a `--impact <artifact>` downstream-revisit-order selector.
- opsx-update-skill: the user-facing /opsx:update command (targeted + audit).

Supersedes the proposal-only stub add-artifact-regeneration-support. Addresses
the cluster #1188/#705/#673/#247 (closes), #694/#684/#618 (answers), and is
graph-driven to avoid the #777/#666 hardcoded-artifact-pattern bug class.
Validates clean under `openspec validate --strict`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(openspec): make add-update-workflow deterministic & grounded (Tabish review)

Reframe per the steer "more deterministic and grounded in reality":

- Deterministic spine: the CLI computes the impact set (which downstream
  artifacts to revisit, in build order, with paths) as a pure function of
  schema edges + filesystem. The agent only rewrites prose. Grounded in real
  APIs already present: getUnlockedArtifacts (direct dependents), getBuildOrder
  (order), resolveArtifactOutputs (paths); reverse map built at graph.ts:82-87.
- Replace fragile mtime staleness with a newline-normalized SHA-256 content
  digest (reproducible cross-platform). Drift = upstream digest vs recorded
  baseline; no baseline => "unknown", never a false positive. mtime and pure-git
  rejected with rationale; digest ledger is a separable, optional layer.
- Explicit determinism boundary decision (CLI decides files/order/drift; agent
  rewrites). Skill MUST source the file list/order from `openspec status
  --impact`, never compute it.
- Corrected all code citations to verified lines (graph.ts:82-87,
  instruction-loader.ts:366/429, status.ts); noted #1277's coverage helpers are
  not in this branch's base (coordinate, don't reuse).
- Specs updated: artifact-graph Content Digest requirement; cli status digest +
  deterministic impact ordering; skill determinism + baseline-aware audit.
  tasks add digest/determinism/cross-platform tests + optional ledger section.

Still validates clean under `openspec validate add-update-workflow --strict`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(openspec): harden add-update-workflow determinism; drop direct name refs

- Digest ledger tracks DIRECT upstream digests; document that transitive drift
  emerges hop-by-hop as downstream is reconciled (no transitive bookkeeping).
- Ground audit's no-baseline structural facts on signals available in this
  branch (missing/empty output, blocked/incomplete); capability-coverage is an
  add-on only when #1277's validateChangeCapabilityCoverage is present.
- Add the "update revises only existing downstream; defer not-yet-created ones
  to /opsx:continue" rule across proposal/design/specs/tasks; impact entries now
  carry existence/status.
- Note artifact-level (not file-level) granularity and that getDownstream
  terminates by the schema's acyclic guarantee.
- Remove direct personal references from the docs.

Validates clean under `openspec validate add-update-workflow --strict`; 10 deltas.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(openspec): full issue/PR/discussion coverage + command-family design

After a comprehensive sweep of open issues, PRs, and discussions, grounded the
proposal in the complete adjacent landscape and answered the open design
questions the cluster raises:

- #783 (Cross-artifact quality review before apply) is now a primary Closes:
  it IS audit mode. Answer its open "new skill vs. extend validate" question via
  the determinism split — deterministic checks (drift/completeness/coverage) are
  CLI/validate-shaped; the semantic cross-artifact review is the skill. Added a
  skill spec scenario for the #783 patterns (scope contradiction, spec gap,
  duplication).
- Discussion #1206 ("refine proposal now?") + prior-art PR #372: official answer
  is /opsx:update.
- New design Decision 8 (command family): delineate /opsx:update from
  /opsx:clarify (#702, within-artifact), /opsx:review (#1251, plan-vs-code), and
  verify; /opsx:update consolidates update+regen+refine into one action,
  addressing skill-sprawl (#1263, #783).
- Reuse, don't reinvent: audit's empty/incomplete check reuses #1098's
  artifactOutputComplete (same outputs.ts the digest helper lives in); capability
  coverage reuses #1277's validateChangeCapabilityCoverage.
- New open questions: surface deterministic coherence in `validate` for a CI gate
  (#783-B, #829); naming reconciliation with #783's /opsx:refine.
- Confirmed add-update-command* branches are the `openspec update` tool-file
  refresh (not artifact update) — no collision.

Validates clean under --strict; 10 deltas; all relative links resolve.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(openspec): resolve open questions to committed decisions; drift in scope

Per review steer, every open question is now a committed happy-path decision so
build-out has no dangling forks, and the deterministic drift baseline is pulled
into scope (it is what makes audit-mode drift deterministic vs. agent-guessed):

- Digest ledger IN SCOPE (design Decision 3): per-artifact DIRECT upstream
  digests in ChangeMetadataSchema, written by a deterministic `openspec status
  --record`; pre-existing changes (no baseline) degrade to drift `unknown` +
  structural checks. Generating-flow auto-recording stays optional (graceful).
- cli-artifact-workflow spec: folded drift into the digest requirement (record
  baseline / drift vs baseline / unknown-without-baseline) — stays at 10 deltas.
- opsx-update-skill spec: skill records baseline via `--record` after each
  confirmed edit, so audits clear once reconciled.
- Replaced "## Open Questions" with "## Decisions resolved": ledger in scope;
  targeted entry baseline-aware; apply stays standalone (points to update on
  drift); cross-change (#247), continue/ff de-hardcoding (#777), and validate
  CI-gate (#783-B/#829) are named follow-ups, not deferrals of the core feature;
  /opsx:update kept as the umbrella name.
- Migration Plan + Capabilities + Impact + tasks updated; status JSON gains
  `drift`, CLI gains `--record`. Re-synced with upstream main (0 behind).

Validates clean under --strict; 10 deltas; all links resolve.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(openspec): harden add-update-workflow — close cross-OS, read-only, edge gaps

Stress-tested every claim against live source and fixed the soft spots:

- Cross-OS digest determinism (real bug): resolveArtifactOutputs (outputs.ts:34)
  sorts ABSOLUTE paths via .sort(), which differs by OS — so a multi-file glob
  artifact (specs/**/*.md) would hash differently on Windows vs POSIX. Digest now
  specified to order files by change-relative forward-slash path and hash
  relpath+content. Added spec scenarios (cross-platform glob stability; rename
  changes digest) and a cross-OS test task.
- Read-only status invariant: moved baseline recording OFF `openspec status`
  (a read command silently mutating the drift reference is a footgun) to a
  dedicated `openspec reconcile` write verb. Updated spec, skill, design, impact,
  capabilities, tasks; reconciled the "no new verb" claims.
- Edge case: missing upstream at record time is stored as an explicit `absent`
  marker so later creating it registers as drift (spec scenario added).
- Edge case: coherent change yields no edits (clean-path scenario).
- Grounding fixes: continue-change hardcoded block is duplicated (skill 103-112 +
  command 225-234) — both must be fixed in the #777 follow-up; verified no
  content-hash util exists.
- Fixed two stale claims the layered edits left: the Impact digest bullet
  (concatenation→relative-path) and the naming-boundary line.

Validates clean under --strict; 10 deltas (4+3+3), 44 scenarios; all links
resolve; re-synced with upstream main (0 behind); issue/PR/discussion sweep
re-run, no new items.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(openspec): pin data contracts + digest forward-compat; delineate #880

Grounded the surface so an implementer builds it without guessing, and added
proportionate forward-compatibility:

- New design "Data contracts" section with exact shapes: extended ArtifactStatus
  (requires/dependents/digest/drift/driftFrom — additive to the real interface at
  instruction-loader.ts:120), the --impact response, and the `.openspec.yaml`
  baselines ledger. All additive; nothing existing changes type.
- Digest scheme tag (`sha256-relpath-v1:`) + forward-compat: drift compares only
  same-scheme digests; an unrecognized/older scheme reports `unknown` rather than
  silently mis-comparing — re-reconcile restores it. Added a cli spec scenario
  and tasks for it.
- Grounded the ledger write: there is no central change-metadata writer today
  (change-metadata/index.ts only re-exports schema), so reconcile does a safe
  read-modify-write of .openspec.yaml mirroring the store's
  parse/serialize/writeStoreMetadataState pattern (foundation.ts).
- Coverage: re-swept; folded #880 (/opsx:validate code-vs-living-specs) into the
  plan-vs-code delineation alongside #1251/#1073. Main unchanged (546224e); all
  citations still valid.

Validates clean under --strict; 10 deltas; links resolve.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(openspec): simplify add-update-workflow to a thin /opsx:update skill

Rework per @TabishB review (PR #1278): the proposal over-built. Drop the
deterministic-spine machinery and lean on the existing status command.

- Cut the reverse-dependency graph API (getDependents/getDownstream),
  SHA-256 content digests, the .openspec.yaml baseline ledger, the
  `openspec reconcile` write op, the drift report, and `status --impact`.
  Removes the artifact-graph and cli-artifact-workflow spec deltas.
- Reframe propagation as bidirectional coherence (editing design can
  require revising proposal), not downstream-only.
- Center the feature on one thin skill over the existing
  `openspec status` / `openspec list`; design now sketches the actual
  minimal skill instruction body ("written by hand").
- v1 adds no new CLI/graph/schema code: just update-change.ts + wiring.

Validates clean: `openspec validate add-update-workflow --strict`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(update-workflow): pin the status path contract to existingOutputPaths

Address @alfred-openspec's review: the skill's write target was described
loosely as "resolved paths." Make it precise across proposal/design/spec/tasks:

- `openspec status --json` already returns everything the skill needs, in the
  top-level `artifactPaths` map — `resolvedOutputPath` and `existingOutputPaths`
  per artifact. No new CLI field is required.
- The skill edits `existingOutputPaths` (the concrete, glob-expanded files) and
  never writes to `resolvedOutputPath`, which for a glob artifact like
  `specs/**/*.md` remains the glob pattern rather than a real file.
- Add spec scenarios for editing a glob artifact's concrete files and for
  deferring a brand-new file under a glob artifact to `/opsx:continue`.
- Tighten the cross-platform scenario and add a template test (3.4) asserting
  the write target is `existingOutputPaths`, not a glob `resolvedOutputPath`.

Validates clean under `openspec validate add-update-workflow --strict`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(update-workflow): address review — default profile, next-step guidance, change-scoped naming

- Register /opsx:update in the default core profile, not expanded-only
  (maintainer call on the PR)
- Add next-step guidance: after updating, recommend /opsx:continue,
  /opsx:apply (esp. when the change was already implemented), or
  /opsx:archive — guidance only, never acted on
- Pin naming scope: skill openspec-update-change, change proposals only;
  generalizing update to other graph types is an explicit non-goal

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(skills): implement the /opsx:update skill (openspec-update-change)

Implements the approved add-update-workflow change: one thin skill over
the existing status/list commands, in the default core profile.

- new update-change.ts template (skill + command), registered across
  init, profiles, skill-generation, tool-detection, profile-sync-drift
- update joins CORE_WORKFLOWS and ALL_WORKFLOWS
- docs: opsx.md command row + usage note, commands.md reference section,
  supported-tools.md skill list
- retire the superseded add-artifact-regeneration-support stub
- template tests pin the guardrails (schema-driven ids, planning-only,
  existingOutputPaths write contract, next-step guidance); parity hashes
  regenerated; profile/init/update/config tests cover the new core set
- tasks.md checked off; validate --strict passes

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 16:13:36 +00:00

8.0 KiB

Why

OPSX names four first-class actions — "create, implement, update, archive — do any of them anytime" (docs/opsx.md:52). Three ship as commands. update does not exist. The only mechanism offered is "edit the files manually" — and when you edit one artifact, nothing helps you keep the rest of the change coherent. Worse, the manual workaround lets the agent edit code when the user only wanted to revise the plan (#1188).

This is the most-requested missing capability in the tracker. It is one gap with several faces, and the fix is small: a thin /opsx:update skill that revises a change's planning artifacts and keeps them coherent with each other, built on the existing openspec status / openspec list commands. No new graph engine, no digests, no ledger — just an agent that reads the change's artifacts and updates what needs updating, with the user's confirmation.

What Changes

The whole feature is a single new workflow skill, /opsx:update. The skill is deliberately change-scoped — openspec-update-change, following the openspec-<verb>-change naming of its siblings — and applies to change proposals only, not arbitrary artifact graphs (see design, Naming). Written by hand, its instruction set is short:

  1. Understand the request — what the user wants to revise (or, with no specific ask, "review this change for coherence").
  2. Get the artifacts — run openspec status --change <id> --json. Its artifactPaths map reports, per artifact, which files exist and where: existingOutputPaths is the concrete file list to edit — already expanded for glob artifacts like specs/**/*.md. (openspec list --json to pick the change when it isn't given.)
  3. Read and revise — read the relevant artifacts, make the requested edit, then check the change's other artifacts against it and propose any follow-on edits needed to keep the plan coherent.
  4. Confirm and apply — show each proposed revision, write only after the user confirms.
  5. Point to the next step — report where the change now stands and recommend what comes next: artifacts still missing → /opsx:continue; plan revised after the change was already implemented → /opsx:apply to carry the delta into code; everything done and implemented → /opsx:archive. Guidance only — the skill never acts on it.

Two guardrails make it the command the cluster asked for:

  • Planning artifacts only, never code. If a revised plan implies code changes, it hands off to /opsx:apply (#1188).
  • Schema-driven, not name-driven. Artifact ids and paths come from openspec status, so the skill works for custom schemas, not just the default proposal → specs → design → tasks (#777, #666).

Coherence is bidirectional. Earlier framing treated update as strictly "downstream" propagation. That is wrong: in proposal → specs → design → tasks, editing design can require revising proposal too. The skill reads the change's artifacts and reconciles them in whatever direction the edit demands, rather than assuming a fixed flow.

Deliberately not built (yet)

Per the steer to introduce as little code as possible, and only when there is a defined need, this change does not add: a reverse-dependency graph API, content digests / staleness signals, a .openspec.yaml baseline ledger, an openspec reconcile write op, a drift report, or a status --impact selector. The agent reads the change's artifacts directly — a handful of markdown files — which is enough to judge coherence. If a future, concrete need emerges (e.g. unattended drift detection across many changes), exposing the schema's requires edges on openspec status --json is a one-field additive follow-up. It is out of scope here.

Capabilities

New Capabilities

  • opsx-update-skill: A new /opsx:update workflow skill that revises a change's existing planning artifacts and keeps them coherent with one another. It reads the artifact set and paths from openspec status, reviews related artifacts in any direction (not only downstream), edits planning artifacts only and never code, and confirms each edit with the user. It ends with next-step guidance — recommending /opsx:continue, /opsx:apply, or /opsx:archive based on the change's state — without acting on it.

Impact

  • src/core/templates/workflows/update-change.ts (new) — the openspec-update-change skill template and the /opsx:update command template, mirroring the structure of continue-change.ts. Reads artifact ids and paths from openspec status --json; embeds no artifact-name patterns.
  • Skill/command registration + src/core/profiles.ts — add update to ALL_WORKFLOWS and to the default core profile (propose, explore, apply, sync, archive), so /opsx:update is part of the default install rather than expanded-only (maintainer call on the PR).
  • docs/opsx.md — add a /opsx:update row to the command table and a short "Updating a change" usage note.
  • openspec/changes/add-artifact-regeneration-support/ — the in-repo proposal-only stub for this gap is superseded; retire it or fold its notes into design.
  • No changes to src/core/artifact-graph/*, src/commands/workflow/status.ts, or ChangeMetadataSchema. The skill uses openspec status / openspec list as they exist today.

Issues addressed

Verified against Fission-AI/OpenSpec on 2026-06-30.

Closes (the missing-update-action family):

  • #1188 — "Add a command to update proposal, design and task" (and stop it editing code). Delivered as /opsx:update, planning-artifacts-only.
  • #705 — "Rebuild downstream artifacts from a modified upstream." Delivered as the skill's read-and-reconcile pass over the change's artifacts.
  • #673 — "clarify": update existing artifacts without auto-advancing the build frontier. /opsx:update revises in place and never creates the next artifact.
  • #247 — "review and update all change proposals." Delivered as the within-a-change coherence review; cross-change audit is a separate, later proposal.

Answers (questions whose honest answer today is "no command exists"):

  • #694, #684, #618 — "which command regenerates a document after the flow progressed / after apply?" → /opsx:update.
  • Discussion #1206 — the official answer becomes /opsx:update.

Supersedes:

  • openspec/changes/add-artifact-regeneration-support (in-repo, proposal-only stub) — same problem, replaced by this skill. Its hardcoded-filename dependency tracking and metadata-file staleness mechanism are dropped in favor of letting the agent read the artifacts.

Delineated from adjacent commands (distinct surfaces — coordinate, don't collide):

  • #702 /opsx:clarify — resolves ambiguity within one artifact via Q&A; a complementary upstream step. /opsx:update then reconciles the change's artifacts with each other.
  • #1251 /opsx:review, #880 — review the implementation (code) against the plan. /opsx:update is the mirror image: it keeps the plan coherent and never touches code.
  • #783 — cross-artifact quality review. The skill's coherence pass is the lightweight form of this; a deterministic validate-side check is a separate proposal.