Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
cbb38f3
docs(stores): add initiatives guide + a real example
clay-good Jun 30, 2026
e179ae4
docs(stores): show an initiative as a collection of artifact types
clay-good Jun 30, 2026
8825ed2
docs(stores): add one-pager artifact type + a completed example graph
clay-good Jun 30, 2026
4aa2ebe
docs(stores): add a "Where this could go" section
clay-good Jun 30, 2026
9288424
docs(stores): rework initiatives prototype around the define-your-own…
clay-good Jul 1, 2026
2e1ce30
docs(stores): lock initiative precedence to canonical-store/local-shadow
clay-good Jul 1, 2026
7324d11
feat(stores): working prototype — store-aware schemas, initiative rol…
clay-good Jul 1, 2026
84681ba
feat(stores): surface a store's artifact types + initiatives in the a…
clay-good Jul 1, 2026
567456a
feat(stores): surface a store's artifact types + initiatives in `open…
clay-good Jul 1, 2026
44223bc
docs(stores): reflect that cross-repo artifact/initiative discovery n…
clay-good Jul 1, 2026
74e7360
feat(stores): add `openspec new initiative` thin scaffold
clay-good Jul 1, 2026
dec9652
docs(stores): use `openspec new initiative` in the guide's happy path
clay-good Jul 1, 2026
f3a5767
feat(stores): roll up initiative status across repos (cross-repo)
clay-good Jul 2, 2026
f0164d2
feat(stores): the plan folder — one clean prototype for work above a …
clay-good Jul 2, 2026
f6fe4c6
feat(stores): make the plan destination-first
clay-good Jul 2, 2026
66f6fed
fix(stores): surface destination-only plans in agent context
clay-good Jul 2, 2026
9cda627
feat(stores): the handoff — capture, decompose, hand off through changes
clay-good Jul 2, 2026
f90fb62
docs(stores): point the plan guide at worksets and schemas
clay-good Jul 2, 2026
8c7c25e
feat(stores): initiatives — a portfolio of finite work above evergree…
clay-good Jul 6, 2026
5ee8f92
Merge branch 'main' of https://github.com/Fission-AI/OpenSpec into do…
clay-good Jul 6, 2026
72c437b
fix(stores): pass projectRoot to task progress after merging main
clay-good Jul 6, 2026
bcf9c22
Merge branch 'main' of https://github.com/Fission-AI/OpenSpec into do…
clay-good Jul 8, 2026
a81ef23
fix(tests): reconcile workflow list and golden hashes after merging main
clay-good Jul 8, 2026
e9dff7d
feat(stores): encode PM → engineering handoffs as pull-based stage tr…
clay-good Jul 8, 2026
ba07f5a
fix(tests): bump skill-generation template counts to 13 after update-…
clay-good Jul 8, 2026
2f682ed
refactor(stores): make stage workflows fully persona-agnostic
clay-good Jul 8, 2026
74f2c17
feat(stores): close the dogfooded gaps — discovery on link, the upstr…
clay-good Jul 9, 2026
5dfdd78
feat(stores): teach the initiatives layout in the empty states
clay-good Jul 9, 2026
f588309
feat(stores): dead-simple team path — three commands, all wiring auto…
clay-good Jul 9, 2026
a6e2e30
fix(tests): set USERPROFILE alongside HOME in the default-path setup …
clay-good Jul 9, 2026
acb792d
refactor(stores): dissolve initiatives into typed changes + serves links
clay-good Jul 13, 2026
6c7ee0e
test(stores): retarget suite to serves links, downstream rollup, sche…
clay-good Jul 13, 2026
5b5b8f7
chore(stores): drop stale initiative-era exploration notes and update…
clay-good Jul 13, 2026
428b254
feat(stores): make the happy path one command deep
clay-good Jul 13, 2026
6d67c21
docs(stores): teach the happy path in the upstream-work guide and cha…
clay-good Jul 13, 2026
3b20c64
fix(stores): dogfood round findings — legacy string refs readable, ro…
clay-good Jul 13, 2026
4684edf
docs(stores): integrate upstream work into the beta guide, CLI refere…
clay-good Jul 13, 2026
e63ff98
chore: merge main (docs deploy workflow, release skill, v1.6.0 packag…
clay-good Jul 13, 2026
f4d35c5
refactor(schemas): fold scaffolding into schema init; seed spec Purpo…
clay-good Jul 13, 2026
1ec6c8f
docs(stores): state the any-format contract and the validate seam hon…
clay-good Jul 13, 2026
0948f02
fix(validate): stop demanding delta specs from spec-less workflow sch…
clay-good Jul 13, 2026
6737f23
feat(stores): stateless --scan for the rollup — the CI pattern now ru…
clay-good Jul 13, 2026
985d895
fix(stores): close the fresh-eyes findings from two independent sessions
clay-good Jul 13, 2026
f7c1d65
feat(schemas): sharpen the requirements workflow with deferrals, sign…
clay-good Jul 14, 2026
5ebeb86
feat(stores): divergence rule in the upstream block — intent stays ho…
clay-good Jul 14, 2026
714adad
feat(stores): executable structure + one door
clay-good Jul 14, 2026
981835a
docs(stores): bring the change record and every guide current with th…
clay-good Jul 14, 2026
a77d697
docs(stores): align the upstream-work guide vocabulary with the PR fr…
clay-good Jul 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ That second one matters more than it looks. OpenSpec has two halves: a command l
| Doc | What it gives you |
|-----|-------------------|
| [Stores: User Guide](stores-beta/user-guide.md) | Plan in its own repo when your work spans repos or teams |
| [Initiatives](stores-beta/initiatives.md) | Define your own planning artifacts and share them in a store every repo can read |
| [Agent Contract](agent-contract.md) | The machine-readable CLI surfaces agents drive |

## The thirty-second version
Expand Down
6 changes: 3 additions & 3 deletions docs/agent-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Successful JSON payloads embed the root:
## 4. Command JSON shapes

### 4.1 `list --json`
`{ "changes": [ { "name", "completedTasks", "totalTasks", "lastModified", "status": "no-tasks"|"complete"|"in-progress" } ], "root": RootOutput }` — note the per-change `status` is a string enum here. `--specs`: `{ "specs": [ { "id", "requirementCount" } ], "root" }`.
`{ "changes": [ { "name", "completedTasks", "totalTasks", "lastModified", "status": "no-tasks"|"complete"|"in-progress" } ], "root": RootOutput }` — note the per-change `status` is a string enum here. `--specs`: `{ "specs": [ { "id", "requirementCount" } ], "root" }`. `--initiatives`: `{ "initiatives": [ { "id", "title", "changes": [], "changesComplete", "changesTotal", "tasksComplete", "tasksTotal", "shadowsStore"? } ], "root" }` — `shadowsStore` is the id of a referenced store whose canonical initiative this local one shadows (absent when there is no collision).

### 4.2 `show <item> --json`
Change: `{ "id", "title", "deltaCount", "deltas": [...], "root" }`. Spec: `{ "id", "title", "overview", "requirementCount", "requirements": [...], "metadata": { "version", "format", "sourcePath"? }, "root" }`.
Expand Down Expand Up @@ -80,7 +80,7 @@ Success: `{ "archive": { "change", "archivedAs": "YYYY-MM-DD-name", "path", "spe
setup/register: `{ "store": {id, root, metadata_path?}, "registry": {path, registered, already_registered}, "git": {is_repository, initialized, committed}, "created_files": [], "status": [] }`. unregister/remove: `{ "store", "registry": {path, removed}, "files": {deleted, deleted_path, left_on_disk}, "status": [] }`. list: `{ "stores": [{id, root}], "status": [] }`. doctor: `{ "stores": [ { id, root, metadata_path?, openspec_root: {...healthy, status}, metadata: {present, valid, id?, remote}, git: {is_repository, has_commits, has_uncommitted_changes, has_remote, origin_url}, status } ], "status": [] }` (`null` = unknown/not probed). Health findings exit 0; failures exit 1 with the matching null-shape. Prompt cancellation exits 130.

### 4.12 `schemas --json` / `templates --json`
`schemas`: bare array `[ {name, description, artifacts, source} ]`. `templates`: keyed object `{ "<artifactId>": {path, source} }`. Both cwd-based, no root/status keys.
`schemas`: bare array `[ {name, description, artifacts, source} ]` — supports `--store <id>` to list a store's schemas (success stays a bare array; a store-resolution failure emits `{status: [...]}` like other commands). `templates`: keyed object `{ "<artifactId>": {path, source} }`, cwd-based, no `--store`.

## 5. Exit-code contract

Expand Down Expand Up @@ -133,5 +133,5 @@ Recorded by the capstone audit; published-key renames are product decisions defe
4. Four parallel envelope type declarations exist in src; archive diagnostics never carry `target`.
5. `list --json` reuses the `status` key as a string enum per change.
6. Only `validate` output carries a `version` field.
7. `schemas`/`templates` ignore root selection (cwd-based, no `--store`).
7. `schemas` honors root selection (`--store <id>` lists a store's schemas); `templates` is still cwd-based (no `--store`).
8. Deprecated noun forms (`change`/`spec` subcommands) emit unenveloped payloads without `root`/`status`.
164 changes: 164 additions & 0 deletions docs/stores-beta/initiatives.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# Initiatives: your plan, your artifacts, shared across repos

> **Beta.** This builds on [stores](user-guide.md). Names and file shapes may
> change between releases.

## The one idea

Kiro hands you `requirements → design → tasks`. Spec-Kit hands you
`spec → plan → tasks`. You use the artifacts they picked.

OpenSpec is different:

> **You define the artifacts your team actually uses — a brief, a persona, a
> decision record, anything — and share them in one place every repo can read.**

That one place is a **store**. The plan that lives there is an **initiative**.

## What an initiative is

An **initiative** is the home for a big effort — work that is too large for a
single change.

It holds three things:

- **the brief** — what you are doing, and why
- **the artifacts you choose** — personas, decision records, whatever your team
works from
- **the changes** that carry it out — each one still a normal OpenSpec change,
with live status

One effort. One home. Read by every repo that needs it.

```text
acme-plans (a store: planning in its own repo)
openspec/initiatives/
smoother-setup/
initiative.yaml the title, and the changes it groups
brief.md what this is, and why
personas/ who we build for ← your own artifact types
decisions/ the calls we made ← your own artifact types
```

## The happy path

*A team is making setup smoother. The work spans a CLI repo and a docs repo.
The plan should not live in either one.*

### 1. Put the plan in a store

A store is planning in its own git repo. Stand one up once:

```bash
openspec store setup acme-plans --path ~/openspec/acme-plans
```

Now the plan has a home of its own — not buried in anyone's code.

### 2. Define your own artifacts

This is the superpower. Your team works from personas and decision records, so
make those first-class. Describe them once, in a small **schema**:

```yaml
# acme-plans/openspec/schemas/initiative/schema.yaml
artifacts:
- id: brief # what and why
- id: persona # who we build for
- id: decision # a call we made, and the trade-off
```

These are *your* artifact types — labeled in your words. OpenSpec knows them and
lists them like any other schema, from any repo that can reach the store:

```bash
openspec schemas --store acme-plans
```

```text
Available schemas:

spec-driven
Default OpenSpec workflow - proposal → specs → design → tasks
Artifacts: proposal → specs → design → tasks

team-brief (project)
Our own planning artifacts — a brief, then a decision record.
Artifacts: brief → decision
```

### 3. Group the changes it takes

The initiative names the changes that carry it out. Each change is a normal
OpenSpec change — nothing new to learn. You never track status by hand; ask
OpenSpec:

```bash
openspec list --initiatives --store acme-plans
```

```text
Initiatives:
smoother-setup 2/4 changes complete
```

One command. Where the whole effort stands.

### 4. Every repo reads it — nothing copied

Each code repo adds one line to its `openspec/config.yaml`:

```yaml
references:
- acme-plans
```

Now the coding agent in *that* repo sees the shared plan — the brief, the
personas, the decisions, the changes — and builds against it. No pasting. No
drift. The plan is read by name, live from the store.

That is the whole happy path: **your store, your artifacts, read by every
repo, with live status.**

## When two initiatives collide

The question every team hits: the store has an initiative called
`smoother-setup`, and someone starts a local one by the same name in their own
repo. Which wins?

**The rule: the store is canonical.** The store holds the shared, agreed-upon
initiative. A local one with the same name is treated as a *draft that shadows
it* — OpenSpec keeps letting you work locally, but tells you plainly, right in
the list:

```text
Initiatives:
smoother-setup 2/4 changes complete (shadows: acme-plans)
```

Nothing diverges silently. You always know there is a shared source of truth,
and you can reconcile when you are ready. (This mirrors how OpenSpec already
handles schemas: a project schema *shadows* a package one, and `openspec schema
which` shows you it is happening.)

## What works in this prototype

This is a working prototype — every command above runs today:

- **Your own artifact types, discoverable across the store boundary.**
`openspec schemas --store <id>` lists a store's custom schemas from any repo.
- **Initiatives with live, rolled-up status.** `openspec list --initiatives`
reads each initiative's manifest and rolls up the status of the changes it
groups, from the same source as `openspec list --changes`.
- **Canonical-vs-shadow precedence, enforced.** A local initiative that shares an
id with one in a referenced store is reported as a shadow — never silently
overriding it, never blocking your local work.
- **Read by name via `references:`.** A repo declares the store once and its
agent builds against the shared plan; nothing is copied.

Still a prototype: the initiative folder is a light convention (an
`initiative.yaml` manifest — not a revived command group), and richer rollups
(tasks across every referencing repo) are the next step.

Start simple: one initiative folder in a store, grouping a few real changes,
with the artifacts your team already uses.
7 changes: 4 additions & 3 deletions docs/stores-beta/user-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,10 @@ tells you which case you're in.
- **No sync, ever — by design.** OpenSpec never clones, pulls, or pushes.
A stale checkout shows stale specs until *you* pull; references are
indexed live from whatever is on disk.
- **Some commands stay where they are.** `view`, `templates`, `schemas`,
and the deprecated noun forms (`openspec change show`, ...) act on the
current directory only — no `--store`.
- **Some commands stay where they are.** `view`, `templates`, and the
deprecated noun forms (`openspec change show`, ...) act on the current
directory only — no `--store`. (`schemas` now accepts `--store` — see the
[initiatives guide](initiatives.md).)
- **Per-machine state is per-machine.** The store registry and worksets
are local settings. Nothing about your machine's layout is
ever committed to shared planning.
Expand Down
88 changes: 88 additions & 0 deletions openspec/changes/initiatives-in-stores/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
## Context

Stores let planning live in its own repo, and a code repo can `reference` a
store for read-only context. Separately, OpenSpec's artifact-graph lets a
project define its own artifact types in a schema (`openspec/schemas/<name>/`),
resolved project → user → package.

These two systems do not meet yet. Schema/artifact discovery resolves against
the *current* repo only. So the compelling story — "define your own artifacts,
share them in a store, read them from every repo" — is true for *authoring* but
not for *discovery across repos*. This design closes that seam and settles the
one open product question: initiative precedence.

## Goals / Non-Goals

**Goals:**
- A repo that references a store can discover that store's schemas, artifact
types, and initiatives.
- One clear, defensible default for initiative precedence.
- Reuse existing machinery (the resolver's root argument, the shadowing model,
`openspec list` status) rather than new subsystems.

**Non-Goals:**
- Reviving the deleted heavyweight initiative command groups (collections,
resolution, templates). Kept deliberately light.
- Syncing stores. Stores are plain git repos; OpenSpec never clones or pulls.
- Changing where commands *act*. References stay read-only context.

## Decisions

### 1. Discovery follows references, read-only

Referenced stores already resolve to on-disk roots for `context`/`doctor`. Feed
those same roots into the artifact-graph resolver (which already takes a
`projectRoot`) so a store's `openspec/schemas/` participates in discovery. A
referenced store's artifacts are always read-only context, never a place
commands write.

**Alternative considered:** copy a store's schemas into the referencing repo.
Rejected — that is the drift we are trying to remove.

### 2. Initiative precedence: canonical store, local shadow (decided)

When a local initiative and a store initiative share an id, the **store is
canonical** and the local one is a **shadow**: work continues locally, but
OpenSpec reports the shadow so nothing diverges silently.

**This is the policy we are building.** It is the only option that serves an org
on all three axes at once:

- **Governance** — the store stays the single source of truth every repo points
at, so the shared plan is auditable and one place.
- **No silent drift** — the shadow is surfaced, so a local divergence is visible
and reconcilable, not discovered later in review.
- **Velocity** — local work is never blocked, so a developer can still iterate.

It also reuses a pattern OpenSpec *already uses* for schemas (`openspec schema
which` shows `shadows:`) — the least code and the most native-feeling. Note it
governs *identity/reporting* only; it does not change where commands act.

**Alternatives rejected:**

- *Local silently wins* (today's root-selection order, nearest `openspec/`
takes precedence). Rejected — it fails governance: a repo can quietly override
the shared plan and nobody knows.
- *Store hard-wins, local blocked.* Rejected — it fails velocity: devs can't
experiment locally, so they route around OpenSpec, defeating the point.

## Risks / Trade-offs

- [Discovery surfaces stale store content if a checkout is behind] → same as all
store reads today; references are indexed live from disk, and `openspec
doctor` already reports missing/registered stores.
- [Two precedence concepts in the codebase — root-selection order vs. initiative
identity] → mitigated by scoping identity-precedence to reporting only, and
documenting that commands still act per root-selection.

## Migration Plan

Purely additive. No existing command changes behavior when no store is
referenced. Ship behind the existing stores beta surface.

## Open Questions

- Whether initiatives get a thin scaffold command later, or stay a plain-folder
convention for the prototype. This change assumes the latter.

(Precedence policy is settled: canonical store, local shadow — see Decision 2.)
68 changes: 68 additions & 0 deletions openspec/changes/initiatives-in-stores/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
## Why

A team's biggest work is never one change — it is an *initiative*: a brief, the
artifacts the team works from (personas, decisions, whatever they use), and the
changes that carry it out. OpenSpec has no shared home for that today, so it
lives in someone's head or a stray doc.

Stores (beta) give planning its own repo. And OpenSpec already lets a team
**define its own artifact types** in a schema — something Kiro, Spec-Kit, and
GSD do not. Put those two together and OpenSpec can do what none of them can:
**a shared initiative, with your own artifacts, read by every repo.**

The blocker is that artifact discovery is not store-aware. `openspec schemas`,
`openspec templates`, and `openspec view` look only at the current repo. So a
repo that *references* a store cannot see the store's initiatives or custom
artifact types, and there is no rule for what happens when a local initiative
and a store initiative share a name. This change closes that gap.

## What Changes

### 1. Store-aware artifact and schema discovery

Make discovery follow references. When a repo references a store, its custom
artifact types and initiatives become discoverable from that repo:

- `openspec schemas --store <id>` lists a store's schemas (today it is cwd-only).
- Referenced stores' schemas and initiatives appear in `openspec context` and in
the agent instruction block, each with a one-line summary and a fetch command.

### 2. Initiative precedence: canonical vs. shadow

Define the rule the owner asked about — a local initiative vs. a store one of the
same name:

- The **store initiative is canonical.** A local initiative with the same id is a
**shadow** — you keep working locally, but OpenSpec tells you it shadows the
canonical one, so nothing diverges silently.
- This reuses the shadowing model OpenSpec already applies to schemas (project
shadows user shadows package), surfaced the same way `openspec schema which`
surfaces it.

### 3. Initiative as a first-class, checkable grouping

An initiative is a folder with a brief and the changes it groups. Give it just
enough structure to be checked and rolled up — no revival of the old
heavyweight initiative command groups.

- `openspec list --initiatives [--store <id>]` lists initiatives and rolls up the
live status of the changes each one groups.

## Capabilities

### New Capabilities
- `store-aware-artifacts`: discover and resolve a store's schemas, artifact
types, and initiatives from a repo that references it, with a defined
canonical-vs-shadow precedence rule.

### Modified Capabilities
None.

## Impact

- Affected commands: `schemas`, `context`, `instructions`, `list` (additive
`--store` / `--initiatives` behavior; existing behavior unchanged).
- Affected core: artifact-graph resolver (accept a store root), root-selection
(initiative precedence).
- No breaking changes. Everything degrades to today's cwd-only behavior when no
store is referenced.
Loading
Loading