Commit Graph
8 Commits
Author SHA1 Message Date
Clay Good 02d8c243c4 docs(troubleshooting): explain missing workflow commands (#1941)
* docs(troubleshooting): explain missing workflow commands

* test(docs): guard command troubleshooting guidance

* docs(setup): move workflow recovery to docs lab

* test(docs): scope core workflow assertions
2026-09-22 23:35:16 +00:00
summerandClay Good e09916e232 docs(start): explain the first change in a new project (#1146)
* docs: add beginner workflow guide

* docs(start): guide the first change in a new project

* docs(start): make greenfield guidance tool-neutral

* docs(start): use portable first-change prompts

---------

Co-authored-by: Clay Good <hi@claygood.com>
2026-09-22 17:29:01 +00:00
Clay Good c681df7058 docs(install): document Homebrew (#1946)
* docs(install): document Homebrew

* docs(install): clarify the Node prerequisite
2026-09-22 17:28:58 +00:00
Tabish Bidiwale bae58cf614 docs: fix Docslab links to unfinished pages (#1903) 2026-09-17 06:31:19 +00:00
Clay GoodandClaude Opus 5 5f5914e7f7 fix(skills): match natural "openspec <verb>" phrasing to its workflow (#1852)
* feat(skills): match natural "openspec <verb>" phrasing to its workflow

Users and agents say "openspec propose" / "openspec apply", but no workflow
skill description contained that phrasing, so an agent hearing it had nothing
to match and routinely hand-built the artifacts with the CLI instead of
running the workflow.

Each workflow skill's description now names the phrasings that should route
to it. `openspec update` is deliberately left unclaimed: it is a real CLI
command that refreshes generated files, unrelated to the update-change
workflow, so that skill claims "openspec update change" instead.

Descriptions are emitted as unquoted YAML plain scalars, so the new tests also
pin that the generated frontmatter still parses and the description round-trips.

Closes #1221

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

* fix(skills): derive the CLI-collision guard instead of hardcoding it

Review found the guard codified the one exception rather than the rule, so it
could never catch the next collision. It now reads every command name the CLI
registers and fails on any claimed phrase that shadows one, unless the phrase
is listed in DELIBERATE_CLI_PHRASE_CLAIMS with a reason.

Two routing fixes fall out of stating the rule:

- bulk-archive also claims "openspec archive all", so an exact-phrase match on
  "openspec archive" no longer pulls a multi-change request to the
  single-change skill.
- update-change now disclaims the openspec update CLI command in prose, not
  only by avoiding the string.

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

* fix(skills): drop the trailing clause and close the plural-archive hole

Review found the "- follow this skill rather than doing the work by hand"
trailer was decoration that contradicted two of the skills it was appended to:
sync-specs opens "This is an agent-driven operation - you will read delta specs
and directly edit main specs", and explore says "This is a stance, not a
workflow. There are no fixed steps." A description is read at selection time,
so the clause could not reach the hand-building it targeted anyway; the bodies
already carry that guidance. Removing it from all 12 also drops ~800 chars of
identical boilerplate that made update-change's CLI redirect read as filler.

Routing fixes:

- bulk-archive claims the plural phrasings that do not contain "all", so
  "openspec archive these three changes" no longer loses to the single-change
  skill on the bare literal.
- update-change redirects to the CLI command positively instead of negating
  ("run that command instead"), which routers honor far better than "not for".
- apply also claims "openspec implement", the natural English verb for it,
  which shadows no CLI command.

Corrects the recorded reason for claiming "openspec archive": the CLI command
does merge delta specs (docs/cli.md:631, src/core/archive.ts:1402). The real
reason is that the workflow confirms and verifies the merge before anything
moves, where the bare command does it in one shot.

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

* docs(quickstart): name the verb phrasing that now routes to a workflow

Also rewrites the changeset to house style: links the issue, names the
commands-only scope limit, and tells a reader they need `openspec update`
to pick it up.

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

* fix(skills): walk the real command tree instead of scanning the entrypoint

Mutation testing found the collision guard was a strict subset of reality,
not the superset its comment claimed. It scanned src/cli/index.ts for
`.command('…')`, but seven groups — spec, config, schema, store, doctor,
context, workset — are registered from their own modules, so 23 real command
names were invisible. A description claiming "openspec doctor" or
"openspec spec" passed 18/18 green.

It now walks the commander tree from the exported `program` (importing it does
not parse argv; runCli does that), and a sanity test pins the seven delegated
groups so the blind spot cannot come back.

Three more holes the same pass found, all confirmed by re-running the
mutations that previously slipped through:

- phrase extraction was case-sensitive and double-quote-only, so
  "Openspec update" and `openspec update` in backticks both evaded every
  guard. Matching is now case-insensitive and accepts either delimiter.
  Unquoted prose stays excluded on purpose: the update-change redirect names
  the CLI command in prose, and prose is not a routing trigger.
- prefix shadowing was unguarded, which is the exact shape of the
  archive/bulk-archive tension. A shorter phrase contained in another skill's
  longer phrase must now be declared in DELIBERATE_PHRASE_SHADOWING.
- both allowlists accepted an empty reason and never flagged stale entries.

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

* test(skills): let the CLI-collision guard ignore hidden workflow-verb hints

PR #1776 registers the workflow verbs (explore, propose, apply, ...) as
hidden CLI commands that only point the user at the workflow. Walking the
commander tree then saw "openspec explore" as a real command and failed
the collision guard for every skill trigger.

Skip a subcommand only when it is hidden AND named after a workflow.
Visible commands and hidden non-workflow commands are still guarded,
pinned by a synthetic commander tree.

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

* docs(changeset): drop em dashes from the release note

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

* fix(skills): drop the generic by-hand clause from the explore description

The other eleven descriptions dropped it; explore is a stance, not a
workflow, so telling the agent to follow it instead of doing the work
contradicts it. Adds a regression over every workflow description.

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

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 23:34:57 +00:00
Clay GoodandClaude Opus 5 3b8e5b6616 fix(nix): install shell completions with the flake package (#1785)
* fix(nix): install shell completions with the flake package

The flake exposed `openspec completion generate SHELL` but installed no
completion scripts, so a Nix install had no completions at the standard
locations. Generate the Bash, Fish, and Zsh scripts during postInstall and
place them with installShellCompletion.

Closes #1740

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

* docs: note that cross-compiled Nix builds omit completions

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

* ci: run the Nix job when the completion generator changes

The Nix build now runs `openspec completion generate`, so a change under
src/core/completions can break packaging without touching flake.nix.

Also drops the cross-compilation caveat from the Nix install docs: every
package this flake exposes is native (`legacyPackages.<system>` has
buildPlatform == hostPlatform), so `canExecute` is always true and the
completions are never omitted.

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

* docs: move the Nix completions note to the canonical pages

docs-lab/README.md makes docs-lab/ canonical and the old docs/ tree legacy, so
the fact is recorded in the two docs-lab pages that own it and docs/cli.md and
docs/installation.md are back to their state on main.

- docs-lab/start/installation.md, Nix: the package ships the scripts at the
  standard locations, so completion install is not needed.
- docs-lab/reference/cli.md, openspec completion: the same exception, stated
  where a reader looking up the command will hit it, linking to the Nix
  section rather than repeating the paths.

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

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 15:47:11 +00:00
Clay GoodandClaude Opus 5 b928165276 docs(explore): stop claiming explore never writes files (#1838)
* docs(explore): stop claiming explore never writes files

Sixteen lines across both documentation trees told users that
`/opsx:explore` creates no artifacts and writes no files, full stop.

That has been false since explore shipped (#467): its capture branch
writes the planning artifacts the user asked for, and can edit an
existing change's artifacts. #1503 later made it scaffold with
`openspec new change` first, closing #668 and #720.

The claim appeared in two shapes. Six lines denied the capability
outright ("Explore creates no artifacts and writes no code"). Ten more
said the same thing as a timing claim ("before any artifact exists"),
which reads as ordinary pitch copy and is what escaped the first pass.

Every site now carries one guarantee, worded the same way: explore
never writes code, and writes nothing else unless you ask, or say yes
when it offers. Four sites described only the user-initiated trigger,
which left the offer path - the one a reader actually hits - looking
like it did not exist.

docs/explore.md and docs/commands.md also gain a positive description
of capture where the denial used to sit, including what scaffolding
creates beyond the artifacts you named, and how capture differs from
handing off to propose (propose writes the set your schema requires;
capture writes only what you named).

Closes #1833

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

* test(docs): keep the retired explore wording retired

A flat list of the phrasings that actually carried the claim, swept
over the eleven pages that pitch explore. Fails on main with all
sixteen offenders; clean on this branch.

Modeled on test/vocabulary-sweep.test.ts, and deliberately a list
rather than a grammar. An earlier draft built the grammar - section
splitting, code-fence tracking, a conditional-marker exemption so
"creates no artifacts unless you ask" would pass - and measured
against realistic prose it was imprecise in both directions while
returning the same verdict on the real input. The list has no
exemption logic to get wrong, and any maintainer can extend it.

Phrasings that are only wrong in the absolute ("writes nothing",
"creates nothing") are left to review, since the conditional form of
each is the wording the failure message recommends.

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

* test(docs): pin the explore capture contract, not the word

The guide check matched any "capture", so "explore automatically captures
every artifact" passed. Both explore.md and commands.md now must name the
user trigger, `openspec new change`, and the named-artifacts scope, with no
capture line claiming it happens unprompted, and keep "never writes code".

Also scope the explore.md guarantee to the setup files a new change needs,
and make the commands.md offer name the change and its scope, which the
template asks for on main and after #1832.

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

* test(docs): accept negated unprompted-capture wording, catch non-capture verbs

The unprompted check matched "automatically" on any capture line, so the
correct "Explore does not automatically capture artifacts" failed, while
"Explore automatically writes planning artifacts" was never scanned because
it lacks the word capture. Check each clause of lines naming explore or
capture for an unprompted write verb with no preceding negation.

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

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 15:45:53 +00:00
Tabish Bidiwale f1b521dffa docs: rebuild docs site from docs-lab (#1649)
* docs: rebuild docs site from docs-lab

Replace the docs site's source tree with docs-lab, a page-by-page rebuild
of the OpenSpec docs (40 pages: Start / Guides / Customize / Multi-repo /
Reference / Help).

- Point website/docs.sync.config.mjs at ../docs-lab and restructure the
  sidebar into nested groups; sync script gains nested meta.json emission,
  leading-quote descriptions, idempotent writes, and diagram asset copying
- Remove the marketing landing page; / now redirects to /docs
  (meta-refresh page + Cloudflare _redirects)
- Add remark plugins (faq, file-steps, gfm-alert) and the FileSteps
  component backing the new page formats
- Add install.md at the repo root, curled by docs-lab/start/installation.md
  as an agent-executable install prompt
- Add the docs authoring skills (.agents/skills/{write,draft,verify}-
  openspec-docs); docs-lab/README.md links into write-openspec-docs

The old docs/ tree is now unused by the site and left for a follow-up.

Claude-Session: https://claude.ai/code/session_01BMMLYNJQPKXx1QHpnDn4ho

* docs: hold back unwritten pages, add worksets, drop diagram drafts

- website: comment out Overview, Guides, Architecture, Help, Legacy in
  docs.sync.config.mjs until those pages are written; temporary
  /docs -> /docs/installation redirect (Cloudflare _redirects + static
  export meta-refresh fallback in page.tsx)
- docs-lab: new multi-repo/worksets.md page, published under Multi-repo
- docs-lab: content revisions across start/, customize/, reference/,
  help/, multi-repo/; add review notes (Notes.md)
- remove docs-lab/diagrams option-* drafts and their website copies
- write-openspec-docs skill: add spoken-flow sentence rule

* docs: address review on PR #1649

- sync-docs: read the existing output directly instead of exists-then-read
  (CodeQL TOCTOU alert)
- hold back the headings-only Environment variables and Stores reference
  pages until written; links to them fall back to their GitHub source
- sources.md: cutover keeps docs/ in place and points at public/_redirects
- setup.md: label the workflow tree as the default set plus two optional ones

* docs: two review nits (spoken-flow rule, XDG_DATA_HOME note)
2026-08-21 20:45:19 +00:00