Upstream merge 1.5.0 - #6
Open
yumna-collab wants to merge 21 commits into
Open
Conversation
…-AI#1267) * Add changeset for stores beta and config JSON parsing * Remove leaked tool-wrapper lines from changeset
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…resolution (Fission-AI#1182, Fission-AI#1202, Fission-AI#1156) (Fission-AI#1280) * docs(openspec): propose resolution/validation parity bug bundle (Fission-AI#1182, Fission-AI#1202, Fission-AI#1156) Planning artifacts only (proposal/design/spec deltas/tasks) for a focused bug-fix bundle. Three read/validate paths silently diverge from the canonical logic a sibling command already gets right: - Fission-AI#1182 validate ignores workspace planning homes that status/instructions resolve - Fission-AI#1202 view counts only changes/<name>/tasks.md, ignoring the schema tasks glob - Fission-AI#1156 the SHALL/MUST body-keyword hint fires for deltas but not main specs Fix converges each divergent path onto the canonical one; parity is asserted by test. No new surface, no behavior change to the already-correct paths. Validates --strict. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(openspec): bulletproof the parity bundle after adversarial source review Hardened all three bugs after tracing each path to source with parallel verification agents. Material corrections: - Fission-AI#1182: reframed from "workspace planning home resolution" (planning homes are repo-only; the feature is now 'stores', and validate already accepts --store) to the real, reproducible-at-HEAD mechanism: validate's proposal.md membership gate (getActiveChangeIds) vs status/instructions' directory-existence rule (validateChangeExists). Pulled nested specs/<area>/<cap> delta discovery and bulk --all into scope; noted show.ts sibling. - Fission-AI#1202: widened from view-only to the shared helper's real blast radius — also the archive incomplete-task gate (silently archives unfinished glob-tasks changes: data safety) and a 2nd hardcoded copy in change.ts. Pinned apply.tracks as the source, change-dir scope containment, and the no-schema fallback. Added cli-archive delta for the gate. - Fission-AI#1156: the main-spec parser discards the requirement header before Zod runs, so the hint can't be "lifted" — fix needs header recovery (reuse requirement-blocks) + Zod de-dup, and the main-spec message can't be byte-identical to the delta's (no ADDED prefix). Pinned the actionable sentence + single-emission + regression scenarios across all main-spec surfaces. 4 deltas (cli-validate x2, cli-view, cli-archive). Validates --strict. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(openspec): deep-harden the parity bundle with empirical reproduction Round 2 of bulletproofing: 3 parallel agents reproduced every bug against the built (pre-fix) CLI and traced fix sites. This pass corrected two substantive errors in my own prior spec and closed several gaps. Fission-AI#1202 (two corrections to the prior draft): - apply.tracks is a FILENAME that selects the tracked artifact, NOT a glob; the glob is that artifact's `generates`. status resolves via resolveArtifactOutputs(changeDir, artifact.generates). Fixed all wording. - "view/archive counts equal status" is FALSE: status checks file EXISTENCE, not checkboxes (proven: status calls a 3/5 change isComplete:true). Deleted the two count-parity scenarios; reframed as resolution-mechanism parity (same files). - Added schema-resolution-failure fallback (resolveSchema throws; helper must catch or view/list/archive crash). Added projectRoot param + 6-site wiring. - Empirically PROVEN data-safety bug: archive moved a 3/5 unfinished change into changes/archive/. Fission-AI#1182: - Found a THIRD getActiveChangeIds site (interactive selector, validate.ts:97). - Proven: --all with a lone proposal-less change exits 0 silently. Added exit-code scenarios. Trimmed over-scope: getSpecIds spec-side is NOT a bug; no store-specific scenario needed; noun-form scoped out. Fission-AI#1156: - Refine-relaxation regression resolved: deltas don't use the Zod refine (validate imperatively), so REMOVE it (not relax) once applySpecRules owns both header-only and no-keyword cases. Added RENAMED (out-of-scope), lowercase, and the new no-body-line-valid-today scenarios; pinned exact message + prefix. Still 4 deltas; validates --strict; empirical evidence section added to design. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: converge validate/view/archive onto canonical resolution (Fission-AI#1182, Fission-AI#1202, Fission-AI#1156) Implements the resolution/validation parity bug bundle planned in openspec/changes/fix-validate-view-resolution-parity. Each fix points a divergent read/validate path at the canonical implementation a sibling command already gets right, with parity tests guarding against re-forking. Fission-AI#1182 — validate resolves changes like status. validate now resolves a change by directory existence (shared getAvailableChanges) instead of requiring proposal.md, at all three sites (targeted, bulk, interactive selector). A scaffolded/still-authoring change is validated rather than reported Unknown item; a resolved-but-invalid change exits non-zero. show.ts and the deprecated noun-form change validate are scoped out. #1182b — validateChangeDeltaSpecs recurses the nested multi-area layout (specs/<area>/<capability>/spec.md) via a new findDeltaSpecFiles walker, so a resolved multi-area change validates its deltas instead of reporting "No delta sections found". Fission-AI#1202 — getTaskProgressForChange resolves task progress through the tracked-tasks artifact's generates glob (the same resolveArtifactOutputs status uses), aggregating checkboxes across every matched tasks.md scoped to the change dir, with a never-throw fallback to a single top-level tasks.md. Updates all four callers (view/list/archive x2) for the new projectRoot arg and folds the second copy in change.ts onto the helper. Fixes view's Draft misclassification and the archive incomplete-task gate that let an unfinished glob-tasks change archive (data safety). Fission-AI#1156 — the SHALL/MUST body-keyword hint applies to main specs. applySpecRules recovers the requirement header via extractRequirementsSection and emits the targeted hint (header-only) or generic message (no keyword), exactly once; the Zod refine is removed (deltas never used it). The actionable sentence is byte-identical to the change-delta path. Adds parity/regression tests (Decision 7): validate<->status resolution incl. exit code, view/archive resolve the same files as status, and the main-spec<->delta actionable-sentence parity. Full suite green (1791 passed; only the pre-existing, environment-specific zsh-installer failures remain). Change validates --strict; all 36 repo specs pass --specs --strict with no new false positives. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(website): add Fumadocs documentation site for Cloudflare Pages Add a self-contained marketing + documentation site under website/, built with Fumadocs (Next.js) and configured as a static export so it deploys directly to Cloudflare Pages with no server runtime. What's included: - A marketing landing page (hero, the two-folder model, the four core ideas, the explore→propose→apply→archive loop, and the "why"). - 13 documentation pages rewritten for clarity and delight: introduction, installation, getting started, how commands work, core concepts, the workflow, explore first, existing projects, editing a change, customization, FAQ, and a reference section (slash commands, CLI, supported tools). - Static client-side search (Orama), per-page Open Graph images, and llms.txt / llms-full.txt routes — fitting for an AI-native tool. - website/README.md with one-table Cloudflare Pages deploy settings (root: website, build: npm run build, output: out). Content is faithful to the docs/ overhaul from Fission-AI#1237, restated in a simpler, friendlier voice. Verified with a clean `next build` (48 static pages, no warnings). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(website): sharpen the sell, add a Stores guide Completes the documentation work begun in Fission-AI#1237 by tightening the Fumadocs site toward the quality bar of the stores user-guide: - Intro now opens problem-first ("the requirements lived only in chat"), adds an honest "How it compares" table (Spec Kit / Kiro / nothing), and frames the tradeoff in a "When the ceremony isn't worth it" callout. - New Stores guide (beta) distilled from docs/stores-beta/user-guide.md: the problem, the annotated shape, a five-minute walkthrough with real command output, a role-based story, the root-resolution order, and an honest-limitations section. Linked from Existing Projects. Verified with a clean `next build` (51 static pages, no warnings). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(website): make the value tangible — landing sections + Examples page Continue the Fission-AI#1237 docs completion with a stronger product story: - Landing page now reads like a real product site: - "Works with the tools you already use" strip (15 named assistants + more) - "What a change actually looks like" — three real artifacts (proposal.md, a spec delta, tasks.md) so the workflow is concrete - "The honest middle" comparison block (Spec Kit / Kiro / no specs) - Robust hero gradient via color-mix instead of v3 theme() syntax - New Examples & Recipes page: seven copy-pasteable, narrated walkthroughs (small feature, bug fix, explore-first, parallel changes, no-behavior refactor with --skip-specs, step-by-step, onboard). Linked from the intro and getting-started. Verified: clean `next build` (54 static pages, no warnings); Tailwind opacity/color-mix utilities confirmed in the generated CSS; all internal links resolve. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(website): add favicon, sitemap, and robots for a complete public site - Branded SVG favicon (app/icon.svg) in the OpenSpec indigo. - Static sitemap.xml covering the home page and every doc, built from the content source and NEXT_PUBLIC_SITE_URL. - robots.txt allowing all and pointing at the sitemap. All three are emitted by the static export. Clean `next build`, 57 pages. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: lead with stores as "why teams adopt OpenSpec"; complete docs coverage Final pass completing the Fission-AI#1237 documentation work. Reposition stores (beta) as the team adoption story, consistently: - README.md gains a prominent "Why teams adopt OpenSpec" section right after the demo (cross-repo features, shared requirements, plan before code), leading with stores. - Landing page gains a matching "Why teams adopt OpenSpec" section. - Docs intro gains a teams card + callout pointing at stores. - Stores page expanded with full References and Worksets technical examples (the cross-team requirements story, workset create/open). Incorporate the remaining source-doc knowledge so the site is complete: - New pages: Glossary, Troubleshooting, Multi-Language, and an Agents & Automation reference (the machine-readable --json surfaces and workflow primitives that make OpenSpec AI-native). - The Workflow page now covers ff-vs-continue, a three-dimension verify example, and the update-vs-start-fresh decision guide. - Nav restructured with a Help section; reference section gains Agents. Build hardening: `build` now runs `fumadocs-mdx && next build` so the content source is always regenerated. Clean build: 69 static pages, no warnings; all internal links verified. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(website): fix docs GitHub source links + address review nits - page.tsx: prefix ViewOptionsPopover githubUrl with website/ so the "view/edit source" links resolve to website/content/docs/... instead of 404-ing on every deployed docs page (Alfred blocker). - installation.mdx: note that `yarn global add` is Classic Yarn only and point Yarn Berry users at `yarn dlx` / npm / pnpm. - index.mdx: label the comparison table's first column ("Option"). - (home)/page.tsx: use the shared docsRoute constant for all /docs links instead of hardcoded paths. Verified with `npm run build` in website/ — 69 static pages, and the built getting-started page links to blob/main/website/content/docs/... Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(website): mirror docs/*.md into the site + auto-deploy on a cadence Make the repository's docs/*.md the single source of truth for the docs site instead of maintaining a parallel set of hand-written MDX pages that silently drift. - scripts/sync-docs.mjs mirrors ../docs into content/docs/ on every build: derives title/description, injects Fumadocs frontmatter (+ githubSource), rewrites internal *.md links to /docs routes, and emits meta.json. Pages are written as .md so <placeholders>/{braces} in the docs stay literal and never break the MDX build. - docs.sync.config.mjs is the one manifest deciding which docs publish and their slug/section/icon. content/docs/ is now generated + git-ignored; the curated .mdx pages are removed. The marketing landing page stays hand-authored. - build/dev/types:check run sync:docs first, so the site is always current. - .github/workflows/deploy-docs.yml rebuilds and deploys to Cloudflare Pages via Wrangler on push to docs/**|website/**, daily on a schedule, on demand, and as a build-only check on PRs. Needs CLOUDFLARE_API_TOKEN + CLOUDFLARE_ACCOUNT_ID secrets and the DOCS_SITE_URL variable. - source.config.ts carries githubSource so "edit this page" opens the real docs/*.md; website/README.md documents the pipeline. Verified: clean build, 23 pages generated, 78 static pages, no warnings; all internal doc links resolve; MDX-hazard docs (cli, customization) build. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(website): fall back to default site URL when NEXT_PUBLIC_SITE_URL is empty The deploy workflow passes NEXT_PUBLIC_SITE_URL from the DOCS_SITE_URL repo variable, which resolves to an empty string when unset. `?? fallback` does not catch '' (only null/undefined), so `metadataBase: new URL('')` crashed `next build` with ERR_INVALID_URL while collecting page data. Use `||` so an empty value also falls back. Verified: `NEXT_PUBLIC_SITE_URL='' npm run build` now generates all 78 static pages. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: add reviewing, writing-specs, and team-workflow guides Fill the biggest gaps a new user hits, in the plain-language voice of the stores user guide: - reviewing-changes.md: the two-minute human review of an AI-drafted plan before /opsx:apply — what to open, in what order, and the red flags per artifact — plus the /opsx:verify pass after code. - writing-specs.md: what a strong requirement and scenario are made of, choosing ADDED/MODIFIED/REMOVED, and right-sizing a change. - team-workflow.md: how a change maps onto a branch and a pull request, reviewing spec deltas in a PR, when to archive, and parallel changes — framed as convention, since OpenSpec never touches git. Wire them into the docs map (README), the site nav (docs.sync.config.mjs), and light "next steps" cross-links from getting-started, editing-changes, and workflows. Verified: site builds clean, 26 pages, all internal links resolve. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(website): add one-time deploy setup checklist + landing-page note Spell out the three maintainer steps that activate auto-deploy (create the openspec-docs Pages project, add CLOUDFLARE_API_TOKEN/ACCOUNT_ID secrets, merge to main), and note that the pipeline mirrors docs on build regardless. Also flag that openspec.dev is a separate Astro landing page and whether to keep/port this Fumadocs landing page is a maintainer decision. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(website): address review feedback on docs-site PR Maintainer review (TabishB) + Alfred blocker: - deploy-docs.yml: guard the Cloudflare deploy on `github.ref == refs/heads/main`. A `workflow_dispatch` on a feature branch previously passed the guard and, since wrangler hardcodes `--branch=main` (a production deploy), would overwrite the live docs site. Non-main dispatches are now build-only. Also resolves Alfred's deploy-path blocker. - package.json: drop the direct `cnfast` dependency and delete the dead `lib/cn.ts` (nothing imports it; a class-merge helper isn't used). - package.json: declare `zod` (^4.4.3) — it was a phantom dep only resolving via fumadocs-mdx's hoisted copy. Refresh the lockfile. - docs page: omit the on-page <DocsDescription>. The frontmatter description is derived from the first body paragraph, so it rendered the intro twice on every page. Kept in generateMetadata for SEO/OG. - team-workflow.md: `openspec store create` does an initial commit, so scope "never commits" to the user's project and reframe the store clause as "never clones or syncs on its own." - README.md: bump stale "20+ AI assistants" to "30+" to match the site. Verified: npm run types:check + npm run build pass, 26 docs synced, intro paragraph now renders once per page. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(website): use pnpm to match the rest of the repo Per maintainer review (TabishB): the root repo is pnpm (ci.yml runs `pnpm install --frozen-lockfile` against a v9 `pnpm-lock.yaml`), but `website/` had introduced npm + a `package-lock.json`. Standardize on one package manager: - Replace website/package-lock.json with website/pnpm-lock.yaml (lockfileVersion 9.0, generated with pnpm v9 to match root). - deploy-docs.yml: add pnpm/action-setup@v4 (version 9, before setup-node, as in ci.yml), switch setup-node to `cache: pnpm` / `cache-dependency-path: website/pnpm-lock.yaml`, and `npm ci` → `pnpm install --frozen-lockfile`, `npm run build` → `pnpm run build`. - package.json scripts + README: `npm run ...` → `pnpm run ...`. website/ stays a standalone package (no pnpm-workspace.yaml), as before. Verified: `pnpm install --frozen-lockfile`, `pnpm run build`, and `pnpm run types:check` all pass — 26 docs synced, 87/87 static pages. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: temporarily disable docs deploy --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com> Co-authored-by: TabishB <tabishbidiwale@gmail.com>
* Fix archive exit code on validation failure In human (non-JSON) mode, openspec archive returned exit code 0 when validation failed and nothing was archived. The three blocking paths in ArchiveCommand.run() printed an error message but returned null silently, leaving process.exitCode at 0. Scripts and CI could not distinguish a blocked archive from a successful one. The --json path was already correct (it throws ArchiveBlockedError, caught by printJsonFailure which sets exitCode = 1). This was an asymmetry between the two modes for the same failure. Set process.exitCode = 1 at the three human-mode abort points before returning null: - delta-spec validation failure - spec rebuild failure - rebuilt-spec validation failure Legitimate user cancellations (selecting no change, declining a confirmation prompt) remain exit 0 by design. Aligns archive with the same exit-code guarantee already approved for apply instructions in Fission-AI#1250. References Fission-AI#498. * Add regression test for rebuilt-spec validation exit code Cover the third archive blocking path (spot 3): buildUpdatedSpec succeeds but Validator.validateSpecContent rejects the rebuilt content. Spy on validateSpecContent (same pattern as the existing --no-validate test) to force the rebuilt spec invalid while the rest of the flow runs for real, since this branch is otherwise defensive and nearly unreachable — spot 1 already enforces the same SHALL/MUST/scenario rules on the delta. Asserts process.exitCode === 1, the failure is logged, the main spec is left unchanged, and no archive is created.
…ssion-AI#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 Fission-AI#1188/Fission-AI#705/Fission-AI#673/Fission-AI#247 (closes), Fission-AI#694/Fission-AI#684/Fission-AI#618 (answers), and is graph-driven to avoid the Fission-AI#777/Fission-AI#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 Fission-AI#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 Fission-AI#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: - Fission-AI#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 Fission-AI#783 patterns (scope contradiction, spec gap, duplication). - Discussion Fission-AI#1206 ("refine proposal now?") + prior-art PR Fission-AI#372: official answer is /opsx:update. - New design Decision 8 (command family): delineate /opsx:update from /opsx:clarify (Fission-AI#702, within-artifact), /opsx:review (Fission-AI#1251, plan-vs-code), and verify; /opsx:update consolidates update+regen+refine into one action, addressing skill-sprawl (Fission-AI#1263, Fission-AI#783). - Reuse, don't reinvent: audit's empty/incomplete check reuses Fission-AI#1098's artifactOutputComplete (same outputs.ts the digest helper lives in); capability coverage reuses Fission-AI#1277's validateChangeCapabilityCoverage. - New open questions: surface deterministic coherence in `validate` for a CI gate (Fission-AI#783-B, Fission-AI#829); naming reconciliation with Fission-AI#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 (Fission-AI#247), continue/ff de-hardcoding (Fission-AI#777), and validate CI-gate (Fission-AI#783-B/Fission-AI#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 Fission-AI#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 Fission-AI#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 Fission-AI#880 (/opsx:validate code-vs-living-specs) into the plan-vs-code delineation alongside Fission-AI#1251/Fission-AI#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 Fission-AI#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>
…n-AI#1281) * docs(openspec): propose spec parser reading fidelity (fixes Fission-AI#361, Fission-AI#498, Fission-AI#312) The requirement-parsing layer silently misreads valid Markdown: - Fission-AI#361: requirement-body extraction returns only the first non-blank line, so a SHALL/MUST that wraps onto line 2 fails `validate --strict`. - Fission-AI#498: `validate` (delta-block parser) and `archive` (full-spec parser) recognize requirements by different rules, so a stray `###` header passes validate but becomes a phantom requirement that blocks archive. - Fission-AI#312 (residual): the requirement-body loop breaks on any `#` line without consulting the code-fence mask, truncating bodies that contain fenced code with `#` comments. Proposal: one shared, multi-line, fence-aware requirement-body extractor used by both the validator and the markdown parser; recognize only `### Requirement:`-prefixed level-3 headers; guarantee validate/archive parity. Adds regression + parity tests. Fission-AI#559 investigated and deferred (ambiguous root cause — see design.md). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(openspec): bulletproof parser-fidelity proposal with empirical evidence Hardened the proposal after reproducing every claim against main with the bundled CLI and correcting two inaccuracies: - Fission-AI#498 reframed: archive does NOT hard-fail. validate passes; archive emits NON-BLOCKING phantom "Proposal warnings in proposal.md" because validateChange/parseRequirements counts every level-3 header as a requirement, while the delta-block parser (validate) and specs-apply (rebuild) only recognize canonical `### Requirement:`. It is a consistency bug, not data loss. Verified the rebuilt spec is clean. - Fission-AI#312 reframed: the original repro is already fixed by codeFenceLineMask (requirement count verified correct). The residual is a regression hazard: the body loop is fence-unaware, harmless only while first-line-only, so the multi-line fix must be fence-aware from the start. Also: unify recognition on the canonical REQUIREMENT_HEADER_REGEX (/^###\s*Requirement:\s*(.+)$/i, case-insensitive); surfaced a third latent inconsistency (Zod substring includes('SHALL') vs delta word-boundary \b(SHALL|MUST)\b) and added a single-predicate requirement; verified zero non-Requirement level-3 headers in repo specs (CI-safe); added edge-case scenarios (multi-line spec+delta paths, fenced scenario-looking lines, REMOVED/RENAMED unaffected, display vs detection); replaced broken relative links with plain paths. Proposal passes `openspec validate --strict`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(openspec): deepen parser-fidelity proposal — add Fission-AI#418, upgrade Fission-AI#312, tier the risk Second adversarial bulletproofing pass (reproduced everything against main): - Add Fission-AI#418 (metadata-before-description): live on the spec path (req.text = "**ID**: ...") but ALREADY fixed on the delta path. The asymmetry is direct evidence for unifying the two extractors. - Upgrade Fission-AI#312 from "regression hazard" to LIVE bug: a fenced code block before the prose line makes req.text = "```bash" on both paths today (distinct from the already-fixed section-count manifestation). - Tier the fixes by risk after auditing the existing test contract (markdown-parser.test.ts, 15 tests green on main): Tier 1 (false-negative fixes Fission-AI#361/Fission-AI#418/Fission-AI#312): only widens what is read; updates one test (:331, which asserts the first-line bug). Fence tests (:106/:139) preserved because skip-and-join keeps SHALL-first bodies. Tier 2 (recognition tightening Fission-AI#498): canonical ### Requirement: only; a deliberate behavior change that updates bare-header tests (:258/:310) and needs a migration note. Flagged for maintainer decision, with a conservative opt-in-lint alternative documented. - Surface the four-column extractor divergence table (capture / metadata / recognition / predicate) and an explicit "Behavior changes and test impact" section with exact test line refs. Proposal passes `openspec validate --strict`. Does not claim Fission-AI#1156 (PR Fission-AI#1280). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(openspec): third pass — reject recognition tightening, add fenced-scenario bug, Fission-AI#498→safe INFO Third deep pass found the prior Tier 2 (recognition tightening to `### Requirement:`) was the WRONG fix and over-scoped: - Bare `### <statement>` headers are a SUPPORTED, tested requirement format: test/core/validation.test.ts asserts a bare-header spec is valid, and bare headers appear across json-converter/archive/spec tests and tmp-init fixtures. Tightening would break a large test surface and silently drop requirements from real specs. REJECTED, with evidence documented. - Replace the Fission-AI#498 fix with a SAFE INFO note in validate <change> that surfaces non-`### Requirement:` headers in delta sections. INFO never fails validation (strict: valid = no errors && no warnings), so nothing newly fails. - New bug found and folded in: countScenarios is fence-unaware, so a `#### Scenario:` inside a fenced block is counted as real — a malformed delta passes validate <change> while validate <spec> correctly fails. Same fence family. - Proved the archive WRITE path is independent of the reader: specs-apply rebuilds from raw `### Requirement:` blocks (extractRequirementsSection + RequirementBlock.raw), never parseSpec/req.text → Part A cannot change archived content. Net effect: recognition is unchanged, so the proposal now updates exactly ONE existing test (:331, the first-line assertion) instead of breaking bare-header tests. Consolidated to a single cli-validate delta (dropped cli-archive and openspec-conventions deltas). Dropped the no-space-header hypothesis (no divergence). Passes `openspec validate --strict`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(parser): unify the requirement reader, fence/metadata/multi-line aware (Fission-AI#361, Fission-AI#418, Fission-AI#312); surface Fission-AI#498 The requirement reader was implemented twice — MarkdownParser.parseRequirements (validate <spec>/archive) and Validator.extractRequirementText/countScenarios (validate <change>) — and the two had drifted. Both now delegate to one shared, fence-/metadata-/multi-line-aware extraction in parsers/requirement-text.ts so they cannot diverge again. Part A — unify the reader: - Capture the full requirement body up to the first non-fenced `#### Scenario:`, skipping blank, `**metadata**:`, and fenced-code lines; run SHALL/MUST detection over the whole body. Fixes a wrapped keyword being dropped (Fission-AI#361), metadata before the description failing validate <spec> (Fission-AI#418), and a fenced block before the prose line becoming the requirement text (Fission-AI#312). - Count only non-fenced `#### ` headers, so a `#### Scenario:` inside a fenced example no longer counts as a real scenario in validate <change> (parity with validate <spec>). - One whole-word `\b(SHALL|MUST)\b` predicate (containsShallOrMust) shared by the validator and base.schema, replacing the substring/word-boundary split. - Extract buildCodeFenceMask into the shared module; MarkdownParser and ChangeParser import it (single fence implementation). Part B — surface Fission-AI#498 safely: - validate <change> emits an INFO note when an ADDED/MODIFIED Requirements section contains a non-`### Requirement:` level-3 header (one the delta reader silently skips). INFO never changes the valid result, including under --strict, so nothing newly fails. Recognition is unchanged: bare `### <statement>` headers remain a supported requirement format. Write path is unaffected: specs-apply rebuilds from raw `### Requirement:` blocks, never req.text, so archived content cannot change. Displayed text in JSON output and delta descriptions now reflects the full body. Tests: markdown-parser.test.ts:331 updated to expect the full body; regression tests added for Fission-AI#361/Fission-AI#418/Fission-AI#312, the fenced scenario, the Fission-AI#498 INFO note, a single-line guard, and CRLF. Changeset added (patch). tasks.md completed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(parser): add cross-reader predicate + metadata-only guards (design edge cases) Exhaustive verification of the unified reader surfaced two design "edge cases for tests" not yet covered by committed unit tests: - Cross-reader predicate agreement: a SHALL substring inside a word ("MARSHALL") is rejected identically by validate <change> and validate <spec> — proving the one shared whole-word predicate, and guarding against a regression to the old substring check. - Metadata-only body still fails validation (no requirement text) on the delta path. Behavior unchanged; tests only. Full end-to-end parity across all four spec requirements confirmed against the real Validator; no spurious INFO note fires on any existing repo change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(parser): address review — metadata-only bodies, header-bounded extraction, reader-derived INFO - Skip **metadata**: lines only when other body text remains; a body written entirely as metadata (e.g. `**Constraint**: The system MUST ...`) is kept as the requirement text instead of being emptied (was a regression vs main). - Move the empty-body rule into the shared reader: both paths fall back to the header title, so the same block cannot pass one path and fail the other. - End body extraction at any non-fenced markdown header, restoring old-reader parity: a stray `### Background` divider's notes no longer satisfy the SHALL/MUST check. - Replace the standalone fence-aware INFO scanner with skipped-header collection inside parseDeltaSpec, so the note reflects exactly what the reader skipped (same section boundaries, no whole-file fence mask). - Special-case the nameless `### Requirement:` INFO message; document that the any-#### scenario match is deliberate spec-path parity; un-export REQUIREMENT_HEADER_REGEX; move the import up top. - Soften the changeset claim and list the known remaining divergences in design.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(openspec): record the no-space ###Requirement: divergence as a known leftover Jun's edge (reproduced): the delta/write reader's REQUIREMENT_HEADER_REGEX accepts `###Requirement:` with no space, but MarkdownParser.parseSections requires whitespace (per GFM) — so a no-space requirement validates as a change with zero INFO, syncs as-is, then fails validate <spec>. Pre-existing on main and out of scope here (tightening the shared regex would change write-path recognition); documented under known remaining divergences with the follow-up options, folded together with the bullet from the merge resolution. Corrects c63913b's 'no divergence' note. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: TabishB <tabishbidiwale@gmail.com>
…ommands (Fission-AI#1300) * feat(skills): auto-approve the openspec CLI in generated skills Emit `allowed-tools: Bash(openspec:*)` in every generated SKILL.md so agents that honor the Agent Skills standard run `openspec` commands without prompting on each call. Scope is limited to the CLI; per the standard `allowed-tools` pre-approves rather than restricts, so every other tool a skill uses stays available under the user's normal permission settings. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(commands): auto-approve the openspec CLI in Claude slash commands Extend the allowed-tools pre-approval to the second surface: Claude Code /opsx:* slash commands share the skill frontmatter contract, so the Claude command adapter now emits `allowed-tools: Bash(openspec:*)` too. The value is single-sourced in `src/core/shared/allowed-tools.ts` (a leaf module both surfaces import). Other command adapters are unchanged — no other tool's slash-command format defines a per-command pre-approval field; on the skills side every tool already gets the standard field via generateSkillContent and non-implementing tools ignore the unknown key. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix archive scenario drift for Fission-AI#1246 * fix archive scenario drift for Fission-AI#1246 * remove local openspec change docs
* chore: remove stale npm lockfile * ci: use package manager metadata for pnpm setup * chore: scope npm lockfile ignore to root
* feat(tools): add Trae command adapter - Added Trae command adapter for generating `.trae/commands/opsx-<id>.md` files - Complete unit tests (9 test cases) and integration tests - Updated documentation and .gitignore - Fixed YAML escaping for carriage returns (\r) Co-Authored-By: Claude Code <noreply@anthropic.com> * fix: handle empty string in YAML escaping - Add explicit check for empty string in escapeYamlValue - Return quoted empty string '""' instead of unquoted empty scalar - Update test to verify empty string is properly quoted Co-Authored-By: Claude Code <noreply@anthropic.com> * fix: address PR review feedback for Trae adapter - Update docs/commands.md Trae entry to reflect generated opsx-* commands - Export traeAdapter from adapters/index.ts Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs: align Trae command adapter docs --------- Co-authored-by: jjxyxsjr <jjxyxsjr@users.noreply.github.com> Co-authored-by: Claude Code <noreply@anthropic.com> Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com> Co-authored-by: TabishB <tabishbidiwale@gmail.com>
* feat: add Oh My Pi (OMP) tool support Add ToolCommandAdapter for Oh My Pi terminal AI coding agent. - New adapter: src/core/command-generation/adapters/oh-my-pi.ts - Commands: .omp/commands/opsx-<id>.md with description frontmatter - Hyphen transform: /opsx: -> /opsx- (filename = command name) - Argument injection: **Provided arguments**: $@ after **Input**: heading - escapeYamlValue applied to description field - Register in CommandAdapterRegistry and adapters/index.ts - Add oh-my-pi to AI_TOOLS with skillsDir: '.omp' - Add to hyphen command transformer whitelist in init.ts and update.ts - Full test coverage (10 cases) in adapters.test.ts - Update docs/supported-tools.md with directory reference and tool ID Closes Fission-AI#713 * fix: address CodeRabbit nitpicks - Move ohMyPiAdapter import before opencodeAdapter (alphabetical order) - Break long SHALL sentence and remove redundant 'follows after' in spec * docs: polish Oh My Pi support * docs: address Oh My Pi review nits --------- Co-authored-by: TabishB <tabishbidiwale@gmail.com> Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
* fix windows ci test flake hardening * restore required test check status
* ci(release): add beta prerelease workflow Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix: harden beta release workflow --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: TabishB <tabishbidiwale@gmail.com>
…-AI#1267) * Add changeset for stores beta and config JSON parsing * Remove leaked tool-wrapper lines from changeset
…resolution (Fission-AI#1182, Fission-AI#1202, Fission-AI#1156) (Fission-AI#1280) * docs(openspec): propose resolution/validation parity bug bundle (Fission-AI#1182, Fission-AI#1202, Fission-AI#1156) Planning artifacts only (proposal/design/spec deltas/tasks) for a focused bug-fix bundle. Three read/validate paths silently diverge from the canonical logic a sibling command already gets right: - Fission-AI#1182 validate ignores workspace planning homes that status/instructions resolve - Fission-AI#1202 view counts only changes/<name>/tasks.md, ignoring the schema tasks glob - Fission-AI#1156 the SHALL/MUST body-keyword hint fires for deltas but not main specs Fix converges each divergent path onto the canonical one; parity is asserted by test. No new surface, no behavior change to the already-correct paths. Validates --strict. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(openspec): bulletproof the parity bundle after adversarial source review Hardened all three bugs after tracing each path to source with parallel verification agents. Material corrections: - Fission-AI#1182: reframed from "workspace planning home resolution" (planning homes are repo-only; the feature is now 'stores', and validate already accepts --store) to the real, reproducible-at-HEAD mechanism: validate's proposal.md membership gate (getActiveChangeIds) vs status/instructions' directory-existence rule (validateChangeExists). Pulled nested specs/<area>/<cap> delta discovery and bulk --all into scope; noted show.ts sibling. - Fission-AI#1202: widened from view-only to the shared helper's real blast radius — also the archive incomplete-task gate (silently archives unfinished glob-tasks changes: data safety) and a 2nd hardcoded copy in change.ts. Pinned apply.tracks as the source, change-dir scope containment, and the no-schema fallback. Added cli-archive delta for the gate. - Fission-AI#1156: the main-spec parser discards the requirement header before Zod runs, so the hint can't be "lifted" — fix needs header recovery (reuse requirement-blocks) + Zod de-dup, and the main-spec message can't be byte-identical to the delta's (no ADDED prefix). Pinned the actionable sentence + single-emission + regression scenarios across all main-spec surfaces. 4 deltas (cli-validate x2, cli-view, cli-archive). Validates --strict. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(openspec): deep-harden the parity bundle with empirical reproduction Round 2 of bulletproofing: 3 parallel agents reproduced every bug against the built (pre-fix) CLI and traced fix sites. This pass corrected two substantive errors in my own prior spec and closed several gaps. Fission-AI#1202 (two corrections to the prior draft): - apply.tracks is a FILENAME that selects the tracked artifact, NOT a glob; the glob is that artifact's `generates`. status resolves via resolveArtifactOutputs(changeDir, artifact.generates). Fixed all wording. - "view/archive counts equal status" is FALSE: status checks file EXISTENCE, not checkboxes (proven: status calls a 3/5 change isComplete:true). Deleted the two count-parity scenarios; reframed as resolution-mechanism parity (same files). - Added schema-resolution-failure fallback (resolveSchema throws; helper must catch or view/list/archive crash). Added projectRoot param + 6-site wiring. - Empirically PROVEN data-safety bug: archive moved a 3/5 unfinished change into changes/archive/. Fission-AI#1182: - Found a THIRD getActiveChangeIds site (interactive selector, validate.ts:97). - Proven: --all with a lone proposal-less change exits 0 silently. Added exit-code scenarios. Trimmed over-scope: getSpecIds spec-side is NOT a bug; no store-specific scenario needed; noun-form scoped out. Fission-AI#1156: - Refine-relaxation regression resolved: deltas don't use the Zod refine (validate imperatively), so REMOVE it (not relax) once applySpecRules owns both header-only and no-keyword cases. Added RENAMED (out-of-scope), lowercase, and the new no-body-line-valid-today scenarios; pinned exact message + prefix. Still 4 deltas; validates --strict; empirical evidence section added to design. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: converge validate/view/archive onto canonical resolution (Fission-AI#1182, Fission-AI#1202, Fission-AI#1156) Implements the resolution/validation parity bug bundle planned in openspec/changes/fix-validate-view-resolution-parity. Each fix points a divergent read/validate path at the canonical implementation a sibling command already gets right, with parity tests guarding against re-forking. Fission-AI#1182 — validate resolves changes like status. validate now resolves a change by directory existence (shared getAvailableChanges) instead of requiring proposal.md, at all three sites (targeted, bulk, interactive selector). A scaffolded/still-authoring change is validated rather than reported Unknown item; a resolved-but-invalid change exits non-zero. show.ts and the deprecated noun-form change validate are scoped out. #1182b — validateChangeDeltaSpecs recurses the nested multi-area layout (specs/<area>/<capability>/spec.md) via a new findDeltaSpecFiles walker, so a resolved multi-area change validates its deltas instead of reporting "No delta sections found". Fission-AI#1202 — getTaskProgressForChange resolves task progress through the tracked-tasks artifact's generates glob (the same resolveArtifactOutputs status uses), aggregating checkboxes across every matched tasks.md scoped to the change dir, with a never-throw fallback to a single top-level tasks.md. Updates all four callers (view/list/archive x2) for the new projectRoot arg and folds the second copy in change.ts onto the helper. Fixes view's Draft misclassification and the archive incomplete-task gate that let an unfinished glob-tasks change archive (data safety). Fission-AI#1156 — the SHALL/MUST body-keyword hint applies to main specs. applySpecRules recovers the requirement header via extractRequirementsSection and emits the targeted hint (header-only) or generic message (no keyword), exactly once; the Zod refine is removed (deltas never used it). The actionable sentence is byte-identical to the change-delta path. Adds parity/regression tests (Decision 7): validate<->status resolution incl. exit code, view/archive resolve the same files as status, and the main-spec<->delta actionable-sentence parity. Full suite green (1791 passed; only the pre-existing, environment-specific zsh-installer failures remain). Change validates --strict; all 36 repo specs pass --specs --strict with no new false positives. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolves all conflicts from merging fission/main (through the 1.5.0 release, 17 commits: OMP tool support, Trae adapter, requirement-reader unification, validate/view/archive resolution refactor, skill auto-approve generation, archive exit-code/scenario-drift fixes, pnpm-only lockfile, Windows CI hardening, beta prerelease workflow) into our fork while preserving all Codewalla customizations (telemetry, comprehension tracking, Jira-native README/workflow branding, custom CI removal). This supersedes the prior partial 2-commit cherry-pick state on origin/upstream-merge-1.5.0. Key resolutions: - CORE_WORKFLOWS/ALL_WORKFLOWS now include both our `modify` workflow and upstream's new `update` workflow (13 total workflows); all dependent tests and golden hashes in skill-generation and skill-templates-parity suites updated accordingly. - validator.ts: took upstream's stray-header INFO surfacing and shared requirement-text helpers (pure additive refactor, no our-side logic there). - run-cli.ts: adopted upstream's safer mergeEnv() for the Windows path, keeping our POSTHOG_HOST override alongside upstream's OPENSPEC_TELEMETRY flag so both disable mechanisms remain in test env. - package.json: kept our package name/description, took upstream's 1.5.0 version bump. - Removed the stale .changeset/stores-beta-config-parse.md already consumed by upstream's 1.5.0 release. - Accepted upstream's package-lock.json deletion (project is pnpm-only). - Kept our fork's deliberate removal of .github/workflows/ci.yml and release-prepare.yml (dropped in our 1.2.0 commit to streamline this internal fork); flagged for human review since it means we don't inherit upstream's Windows CI hardening/beta-prerelease workflow automation, only its source-level fixes. All 115 test files / 1954 tests pass; build succeeds.
Complete the Fission-AI 1.5.0 upstream sync (was 2/17 commits, now full)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request Description:
Title: feat: add Stores (beta) for cross-repo planning with CLI improvements
Overview:
This PR introduces the Stores beta feature from upstream OpenSpec v1.5.0 as the primary enhancement, while also including critical CLI bugfixes that improve data safety and validation reliability.
Primary Changes:
Stores (Beta Feature)
Commit: 96f6cac
Impact: Enables standalone planning repositories shared across code repos.
Features:
Config Parsing Fix:
Impact: Configuration values wrapped in JSON containers now parse correctly.
Benefit: Improves reliability of store configuration and other config-dependent features.
Additional Changes:
CLI Bugfixes
Silent archiving of incomplete tasks
Validation issues with nested specs
Resolution parity across validate, view, and archive commands
Addresses: openspec validate cannot resolve changes in a workspace planning home Fission-AI/OpenSpec#1182, Feedback: openspec view does not detect nested tasks.md files Fission-AI/OpenSpec#1202, 1.4.0 clearer SHALL/MUST hint does not apply to main specs Fission-AI/OpenSpec#1156
Implementation Details:
Approach: Strategic cherry-pick from upstream (not blind merge)
Rationale: Preserves Codewalla-specific customizations while adding new capability
Preserved Features:
Beta Status:
The Stores feature is in very early beta. Expect rough edges and potential breaking changes in upcoming releases as the upstream API stabilizes.
Testing:
References:
Upstream Version: Fission AI v1.5.0
Upstream PR: Fission-AI#1267 (Stores), Fission-AI#1280 (CLI fixes)