mirror of
https://github.com/Fission-AI/OpenSpec.git
synced 2026-10-12 05:00:36 +08:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8faf504363 | ||
|
|
17d1e5db3f | ||
|
|
3f5a66d3e4 | ||
|
|
c08fbc1ba0 | ||
|
|
938d03be9a |
@@ -1,5 +1,18 @@
|
||||
# @fission-ai/openspec
|
||||
|
||||
## 0.16.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- c08fbc1: Add new AI tool integrations and enhancements:
|
||||
|
||||
- **feat(iflow-cli)**: Add iFlow-cli integration with slash command support and documentation
|
||||
- **feat(init)**: Add IDE restart instruction after init to inform users about slash command availability
|
||||
**feat(antigravity)**: Add Antigravity slash command support
|
||||
- **fix**: Generate TOML commands for Qwen Code (fixes #293)
|
||||
- Clarify scaffold proposal documentation and enhance proposal guidelines
|
||||
- Update proposal guidelines to emphasize design-first approach before implementation
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Minor Changes
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fission-ai/openspec",
|
||||
"version": "0.15.0",
|
||||
"version": "0.16.0",
|
||||
"description": "AI-native system for spec-driven development",
|
||||
"keywords": [
|
||||
"openspec",
|
||||
|
||||
@@ -0,0 +1,426 @@
|
||||
# RFC 0001 Appendix: Research, Decisions & Background
|
||||
|
||||
> This document accompanies [RFC 0001: OpenSpec Workspaces](./0001-openspec-workspaces.md).
|
||||
> It contains the research, Q&A, decision rationale, and design exploration that informed the main RFC.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Executive Summary](#executive-summary)
|
||||
2. [Background & Motivation](#background--motivation)
|
||||
3. [Key Decisions (V1)](#key-decisions-v1)
|
||||
4. [Research: Cross-Platform Storage](#research-cross-platform-storage)
|
||||
5. [Q&A: Design Clarifications](#qa-design-clarifications)
|
||||
6. [Risk Analysis](#risk-analysis)
|
||||
7. [Alternatives Considered](#alternatives-considered)
|
||||
8. [Future Considerations](#future-considerations)
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
OpenSpec is being split into two concerns:
|
||||
|
||||
1. **Specs** (source of truth) — remain in-repo at `/openspec/specs/`
|
||||
2. **Change proposals** (planning context) — move to a centralized user-scoped directory at `~/.config/openspec/`
|
||||
|
||||
This enables:
|
||||
- Multi-repo planning without duplicating proposals
|
||||
- Simplified change lifecycle (no archival step)
|
||||
- Path to customizable planning workflows
|
||||
- Better agent context management
|
||||
|
||||
---
|
||||
|
||||
## Background & Motivation
|
||||
|
||||
### Problems Being Solved
|
||||
|
||||
1. **Multi-repo coordination**: Teams working across multiple repos currently must duplicate change proposals in each repo, leading to drift and coordination overhead.
|
||||
|
||||
2. **Convoluted archival process**: The current workflow requires agents to make exact copies of specs, then archive changes after applying. This is error-prone and adds friction.
|
||||
|
||||
3. **Limited customization**: The tightly-coupled structure makes it hard to customize the planning process or add features.
|
||||
|
||||
### Benefits of the New Approach
|
||||
|
||||
| Benefit | Single-Repo Users | Multi-Repo Teams |
|
||||
|---------|-------------------|------------------|
|
||||
| Simpler workflow | No archival step | Single change spans repos |
|
||||
| Better PRs | Spec + code diff together | Coordinated changes |
|
||||
| Agent context | Clear active change | Cross-repo awareness |
|
||||
| Customization | Planning templates | Shared workflows |
|
||||
|
||||
### Why Split Specs and Changes?
|
||||
|
||||
- **Specs are code** — they belong with the codebase, versioned in git, reviewed in PRs
|
||||
- **Changes are ephemeral** — they're planning artifacts that don't need to live in the repo permanently
|
||||
- **Cross-repo changes need a home** — can't pick one repo arbitrarily; centralized location is neutral ground
|
||||
|
||||
---
|
||||
|
||||
## Key Decisions (V1)
|
||||
|
||||
### 1. Workspace/Index Location
|
||||
|
||||
**Decision**: `~/.config/openspec/index.json` (XDG-style)
|
||||
|
||||
**Rationale**: XDG spec is the modern standard for CLI tools, has clear cross-platform mappings, and libraries exist in every language.
|
||||
|
||||
**RepoId format**: `{primary-remote-url}@{default-branch}`
|
||||
- Supports multiple local clone paths for the same repo
|
||||
- SSH/HTTPS variants normalize to same ID
|
||||
- Repos without remotes fall back to local path hash
|
||||
|
||||
### 2. Active Context Projection
|
||||
|
||||
**Decision**: Write a git-ignored shadow manifest `./.openspec-context.json` in each attached repo.
|
||||
|
||||
**V1 Schema**:
|
||||
```
|
||||
schemaVersion, generatedAt, repoId, workspaceId, branch,
|
||||
activeChangeId|null, changeTitle, status,
|
||||
specRoots, tasks array, warnings,
|
||||
sourceHash/sourceVersion
|
||||
```
|
||||
|
||||
**Rationale**: Agents can discover context without CLI calls; file is lightweight and regenerated on demand.
|
||||
|
||||
### 3. Refresh Policy
|
||||
|
||||
**Decision**: Regenerate the manifest on any context-touching command (`openspec status/context/set-active/attach`) if missing or branch mismatch detected. Force refresh via `openspec context --refresh`.
|
||||
|
||||
**V1 Simplification**: No age checks; git-less repos skip branch checks.
|
||||
|
||||
### 4. Drift Detection
|
||||
|
||||
**Decision**: `openspec verify` auto-runs on `status/context`, surfaces drift as **warnings only** (non-blocking).
|
||||
|
||||
**Rationale**: Start with visibility, not enforcement. Let users understand drift before making it blocking.
|
||||
|
||||
### 5. Task Storage
|
||||
|
||||
**Decision**: Stay as Markdown checkboxes in V1.
|
||||
|
||||
**Future option**: Normalize to structured format (JSONL/SQLite) for better agent integration, but not required for V1.
|
||||
|
||||
### 6. Cross-Repo Specs
|
||||
|
||||
**Decision**: Defer to future version with dedicated "specs repo" as canonical home for cross-repo capabilities.
|
||||
|
||||
**Rationale**: This is complex and not needed for V1. Single-repo and simple multi-repo cases work without it.
|
||||
|
||||
### 7. Active Change Detection
|
||||
|
||||
**Decision**: Use git branch to determine which change is active.
|
||||
|
||||
**How it works**:
|
||||
- When user creates a change, they optionally create a feature branch
|
||||
- OpenSpec detects current branch and maps it to corresponding change
|
||||
- If on main/master, user can manually select which change to work on
|
||||
|
||||
**Open questions** (deferred):
|
||||
- Where is branch→change mapping stored?
|
||||
- Handling multiple changes for same branch?
|
||||
- Branch renames?
|
||||
|
||||
### 8. Agent Integration Strategy
|
||||
|
||||
**Decision**: Support multiple modes (hybrid approach).
|
||||
|
||||
| Mode | Target | How it works |
|
||||
|------|--------|--------------|
|
||||
| SDK mode | Claude Code, etc. | OpenSpec invokes agent, injects context, verifies completion |
|
||||
| CLI mode | Cursor, etc. | Agent calls CLI commands, best-effort tracking |
|
||||
| Manual mode | Any | User manually syncs, OpenSpec provides verification |
|
||||
|
||||
**Rationale**: Provide best experience where possible while still working with any agent.
|
||||
|
||||
### 9. Spec Sync Strategy
|
||||
|
||||
**Decision**: Push-based updates as ideal path, `openspec verify` for manual sync/drift detection.
|
||||
|
||||
**Push-based** (ideal): All changes go through OpenSpec commands which update both the proposal and trigger code changes.
|
||||
|
||||
**Pull-based** (fallback): `openspec verify` command compares spec-deltas to actual spec files and reports what's out of sync.
|
||||
|
||||
**Automatic sync** (future): File watchers or git hooks, but start with manual for V1.
|
||||
|
||||
---
|
||||
|
||||
## Research: Cross-Platform Storage
|
||||
|
||||
### Location Options Compared
|
||||
|
||||
| Approach | macOS | Linux | Windows | Used by |
|
||||
|----------|-------|-------|---------|---------|
|
||||
| XDG spec | `~/.config/openspec` | `~/.config/openspec` | `%APPDATA%\openspec` | Many CLI tools |
|
||||
| Home dotfile | `~/.openspec` | `~/.openspec` | `%USERPROFILE%\.openspec` | npm, cargo, rustup |
|
||||
| App Support | `~/Library/Application Support/openspec` | `~/.local/share/openspec` | `%LOCALAPPDATA%\openspec` | VS Code, Electron apps |
|
||||
|
||||
### Recommendation
|
||||
|
||||
Use XDG-style (`~/.config/openspec`) because:
|
||||
- Modern standard for CLI tools
|
||||
- Clear cross-platform mappings
|
||||
- Libraries exist in every language (`dirs` in Rust, `appdirs` in Python, `env-paths` in Node)
|
||||
- Keeps home directory cleaner than dotfiles
|
||||
|
||||
**Note**: `~/.openspec` is hidden by default (dot prefix) which conflicts with "open in editor" goal. Consider `~/openspec` if visibility matters, but XDG is more conventional.
|
||||
|
||||
---
|
||||
|
||||
## Q&A: Design Clarifications
|
||||
|
||||
### Location and Structure
|
||||
|
||||
**Q1: Where exactly does `.openspec` live?**
|
||||
|
||||
A: `~/.config/openspec` (XDG-style). For V1, assume change proposals only exist locally. Cloud/git-based sync for team sharing is deferred.
|
||||
|
||||
**Q2: What's the structure inside `.openspec`?**
|
||||
|
||||
A: File-based structure so teams can open the folder in their code editor:
|
||||
```
|
||||
~/.config/openspec/
|
||||
├─ index.json # repo/workspace index
|
||||
└─ workspaces/<workspace-id>/
|
||||
├─ workspace.json # attached repos, defaults
|
||||
└─ changes/<change-id>/
|
||||
├─ proposal.md # overview, design choices
|
||||
├─ tasks.md # task breakdown with checkboxes
|
||||
└─ specs/ # spec deltas
|
||||
```
|
||||
|
||||
**Q3: How are repos "attached" to a workspace?**
|
||||
|
||||
A: Configuration reference (not symlinks). User selects a folder/repository locally. Does not need to be git-enabled, but git provides branch detection benefits.
|
||||
|
||||
### Multi-Repo Mechanics
|
||||
|
||||
**Q4: How does a single change span multiple repos?**
|
||||
|
||||
A: Expand existing spec-deltas concept across repos. Task phases can be split between repos (e.g., "Phase 1: API repo", "Phase 2: Frontend repo").
|
||||
|
||||
**Q5: How do PRs work across repos?**
|
||||
|
||||
A: Left to the developer. OpenSpec helps create changes in each repo; PR management is manual. This is intentional — automated cross-repo transactions are complex and error-prone.
|
||||
|
||||
**Q6: How do you handle version coordination?**
|
||||
|
||||
A: Planning is based on local version of repos (or main/master). Explicit version dependencies are out of scope for V1.
|
||||
|
||||
**Q7: Where do cross-repo specs live?**
|
||||
|
||||
A: Deferred. Initial thinking: a dedicated "specs repo" that OpenSpec manages. For V1, keep specs in individual repos.
|
||||
|
||||
### Agent Integration
|
||||
|
||||
**Q8: How do agents discover the relevant context?**
|
||||
|
||||
A: Agent calls OpenSpec CLI from the repository. CLI identifies workspace and returns relevant context. Alternatively, read `.openspec-context.json` manifest directly.
|
||||
|
||||
**Q9: Do agents need CLI commands to access context?**
|
||||
|
||||
A: CLI is the primary method. The manifest (`.openspec-context.json`) provides a cached view to reduce CLI calls. Trade-off: manifest can be stale, but refresh is cheap.
|
||||
|
||||
**Q10: What if an agent modifies specs directly?**
|
||||
|
||||
A: Changes live in `~/.config/openspec`, specs live in repos. Agent can modify specs directly (they're just files). `openspec verify` detects drift between expected and actual state.
|
||||
|
||||
### Workflow and State
|
||||
|
||||
**Q11: What's the lifecycle of a change?**
|
||||
|
||||
A: `Draft → In Progress → Completed`
|
||||
|
||||
There may be sub-states in drafting (research, planning, breakdown). This should be configurable for users.
|
||||
|
||||
**Q12: What does the "work log" contain?**
|
||||
|
||||
A: Agent-generated record of work done. Less important for V1; deferred.
|
||||
|
||||
**Q13: How does "active change" context work?**
|
||||
|
||||
A: Branch-based detection is the primary method. Open question: how to handle non-git repos or when working on main. Stored state vs. git reconstruction needs more thought.
|
||||
|
||||
**Q14: How do you resume work on a change?**
|
||||
|
||||
A: Agent reads the change, looks at which tasks are ticked off, reviews any work log, and picks up from there.
|
||||
|
||||
### Task Management
|
||||
|
||||
**Q15: Why is task management "unknown" if it's core to planning?**
|
||||
|
||||
A: Goal is minimal V1, not complete solution. Markdown checkboxes work today. Agent forgetfulness is a known issue but not blocking for V1.
|
||||
|
||||
**Q16: What's wrong with current task tracking?**
|
||||
|
||||
A: Agents forget to tick checkboxes after doing work. This is an agent behavior problem, not purely a data model problem. Solutions involve better prompting, verification, or agent-side tooling.
|
||||
|
||||
**Q17: Should task state live in `.openspec` or in-repo?**
|
||||
|
||||
A: Central (`~/.config/openspec`) for simplicity.
|
||||
|
||||
### Migration and Compatibility
|
||||
|
||||
**Q18: How do existing users migrate?**
|
||||
|
||||
A: Automatic migration on CLI update. Detect existing `/openspec/changes`, copy to workspace store, write manifests.
|
||||
|
||||
**Q19: Are you removing the in-repo changes workflow?**
|
||||
|
||||
A: Yes, eventually. One flow to maintain. May keep legacy layout as read-only during transition.
|
||||
|
||||
---
|
||||
|
||||
## Risk Analysis
|
||||
|
||||
### High Risk
|
||||
|
||||
#### Agent Context Accessibility (Partially Mitigated)
|
||||
|
||||
Moving change context outside the repo is the biggest risk. Currently, agents work because all context is co-located in `/openspec/`.
|
||||
|
||||
**Concerns**:
|
||||
- Agents lose direct filesystem access to change proposals
|
||||
- CLI fetch adds friction and indirection
|
||||
- Not all agent systems can invoke CLI commands mid-task
|
||||
- Mental model breaks: "where I'm coding" vs. "where my plan lives"
|
||||
|
||||
**Mitigation**: Hybrid agent integration (SDK/CLI/Manual modes), shadow manifest for quick reads.
|
||||
|
||||
### Medium-High Risk
|
||||
|
||||
#### Multi-Repo Coordination Complexity
|
||||
|
||||
Multi-repo is the main selling point but introduces complexity:
|
||||
- No atomic cross-repo git transactions
|
||||
- PR coordination is manual and error-prone
|
||||
- Version dependencies need explicit modeling
|
||||
- CI/CD becomes more complex
|
||||
|
||||
**Mitigation**: V1 keeps it simple — no automated PR orchestration, no version enforcement. Let users handle coordination manually.
|
||||
|
||||
#### Cross-Repo Spec Ownership
|
||||
|
||||
Where do specs live that span multiple repos?
|
||||
|
||||
**Options considered**:
|
||||
| Option | Problem |
|
||||
|--------|---------|
|
||||
| Duplicated in each repo | Sync problems, unclear authority |
|
||||
| In one "primary" repo | Arbitrary, hard to discover |
|
||||
| In centralized `.openspec` | Split location for specs |
|
||||
| In separate "specs repo" | Another repo to maintain |
|
||||
|
||||
**Decision**: Defer to future "specs repo" concept. V1 keeps specs in individual repos.
|
||||
|
||||
### Medium Risk
|
||||
|
||||
#### Task Management Undefined
|
||||
|
||||
Task management is central but left undefined. This affects:
|
||||
- Data model for tasks
|
||||
- Agent integration
|
||||
- Work log concept
|
||||
|
||||
**Mitigation**: Start with Markdown checkboxes. Iterate based on real usage.
|
||||
|
||||
#### Location and Portability (Partially Mitigated)
|
||||
|
||||
User-level directory creates challenges:
|
||||
- CI/CD access
|
||||
- Team collaboration
|
||||
- Machine portability
|
||||
- Discoverability
|
||||
|
||||
**Mitigation**: Cross-platform location research done. V1 is local-only; team sync deferred.
|
||||
|
||||
#### State Synchronization (Partially Mitigated)
|
||||
|
||||
Specs in-repo, changes out-of-repo can drift:
|
||||
- Direct spec edits bypass change tracking
|
||||
- Stale `.openspec` state
|
||||
- Orphaned changes when repos deleted
|
||||
|
||||
**Mitigation**: `openspec verify` for drift detection. Automatic sync is future work.
|
||||
|
||||
### Low-Medium Risk
|
||||
|
||||
#### Backwards Compatibility
|
||||
|
||||
Existing users have workflows around `/openspec/changes/`.
|
||||
|
||||
**Mitigation**: Clear migration path, automatic migration on update, optional read-only legacy support during transition.
|
||||
|
||||
---
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
### Keep Everything In-Repo
|
||||
|
||||
**Pros**: Simple, portable, git-versioned, agent-friendly
|
||||
**Cons**: Can't support multi-repo, archival is messy
|
||||
|
||||
**Why rejected**: Multi-repo is a key goal; this doesn't solve it.
|
||||
|
||||
### Monorepo-Only Support
|
||||
|
||||
**Pros**: Simpler than true multi-repo, single git history
|
||||
**Cons**: Many teams don't use monorepos, doesn't help existing multi-repo setups
|
||||
|
||||
**Why rejected**: Too limiting; multi-repo is common in practice.
|
||||
|
||||
### Git Submodules for Changes
|
||||
|
||||
**Pros**: Git-native, versioned, portable
|
||||
**Cons**: Submodules are notoriously painful, adds complexity
|
||||
|
||||
**Why rejected**: Complexity outweighs benefits.
|
||||
|
||||
### Cloud-First Storage
|
||||
|
||||
**Pros**: Team sync built-in, no local state issues
|
||||
**Cons**: Requires account/auth, internet dependency, privacy concerns
|
||||
|
||||
**Why rejected**: Local-first is simpler for V1; cloud can be added later.
|
||||
|
||||
---
|
||||
|
||||
## Future Considerations
|
||||
|
||||
### Post-V1 Features
|
||||
|
||||
1. **Team sync**: Git-based or cloud-based workspace sharing
|
||||
2. **CI/CD integration**: Environment overrides, workspace exports
|
||||
3. **Structured tasks**: JSONL or SQLite for better agent integration
|
||||
4. **Cross-repo specs**: Dedicated specs repo as canonical home
|
||||
5. **Work logs**: Agent-generated session records
|
||||
6. **Branch→change mapping**: More robust active change detection
|
||||
7. **API/SDK**: Programmatic access beyond CLI
|
||||
|
||||
### Open Design Questions
|
||||
|
||||
- How granular is drift detection?
|
||||
- Should verification block PR creation or just warn?
|
||||
- How to handle branch renames?
|
||||
- What if multiple changes exist for the same branch?
|
||||
- How to represent cross-repo spec ownership without a dedicated specs repo?
|
||||
|
||||
### Agent Integration Evolution
|
||||
|
||||
Current thinking on improving agent task completion:
|
||||
1. Better prompting (explicit reminders to tick checkboxes)
|
||||
2. Verification commands (agent calls `openspec verify` before finishing)
|
||||
3. SDK mode (OpenSpec invokes agent, validates completion)
|
||||
4. Work log (track what agent actually did vs. what was planned)
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [RFC 0001: OpenSpec Workspaces](./0001-openspec-workspaces.md) — the main RFC
|
||||
- XDG Base Directory Specification
|
||||
- Similar tools: Nx, Turborepo, Lerna (monorepo coordination)
|
||||
@@ -0,0 +1,328 @@
|
||||
# RFC 0001: OpenSpec Workspaces and Off-Repo Change Storage
|
||||
|
||||
**Status:** Draft
|
||||
**Authors/Reviewers:** TBC
|
||||
**Last Updated:** 2024-XX-XX
|
||||
|
||||
> **See also:** [Appendix: Research & Decisions](./0001-openspec-workspaces-appendix.md) for background research, Q&A, and detailed decision rationale.
|
||||
|
||||
## Purpose
|
||||
|
||||
**Problem:** Users working on features that span multiple repos must currently duplicate change proposals in each repo, leading to drift and coordination overhead. Single-repo users also suffer from a convoluted archive step when applying changes.
|
||||
|
||||
**Solution:**
|
||||
- Enable multi-repo planning by moving change proposals out of individual repos while keeping specs in-repo.
|
||||
- Preserve agent usability with a lightweight, discoverable context projection per repo.
|
||||
- Simplify the change lifecycle (apply changes directly, drop archiving) and keep the spec and code diff side-by-side.
|
||||
|
||||
## Goals (V1)
|
||||
|
||||
- Single source of truth for changes lives in a user-scoped workspace store (`~/.config/openspec`).
|
||||
- Specs stay in the repo; only change proposals and workspace metadata move out-of-repo.
|
||||
- Agents and humans can see "what change is active here?" via a small manifest in the repo root.
|
||||
- Lay the groundwork for customizable workflows (hooks, reusable instructions) scoped to a workspace.
|
||||
- Keep task tracking simple (Markdown checkboxes) while allowing future structured storage.
|
||||
- Provide a clear migration path from in-repo `/openspec/changes`.
|
||||
|
||||
## Non-Goals (V1)
|
||||
|
||||
- Team/shared cloud sync (local-only for now).
|
||||
- Automatic cross-repo PR orchestration or transactions.
|
||||
- Rich task model or work log; basic checkboxes only.
|
||||
- Replacing existing specs layout in-repo.
|
||||
- CI/CD integration (workspace store lives in user home; CI pipelines that need change context should use environment overrides or check in workspace exports—deferred to future work).
|
||||
|
||||
## Before and After (Conceptual)
|
||||
|
||||
```
|
||||
Before (today)
|
||||
repo/
|
||||
└─ openspec/
|
||||
├─ specs/
|
||||
└─ changes/<change-id>/
|
||||
├─ proposal.md
|
||||
├─ tasks.md
|
||||
└─ specs/... (deltas)
|
||||
|
||||
After (V1)
|
||||
repo/
|
||||
├─ openspec/specs/ # unchanged spec source of truth
|
||||
├─ .openspec-context.json # git-ignored manifest (shadow)
|
||||
└─ ...code...
|
||||
|
||||
~/.config/openspec/ # user-scoped workspace store
|
||||
├─ index.json # repo/workspace index
|
||||
└─ workspaces/<workspace-id>/
|
||||
├─ workspace.json # attached repos, defaults
|
||||
└─ changes/<change-id>/ # proposals, tasks, deltas
|
||||
├─ proposal.md
|
||||
├─ tasks.md
|
||||
└─ specs/... (deltas)
|
||||
```
|
||||
|
||||
## Proposed Model (High-Level)
|
||||
|
||||
- **Workspace store**: XDG path `~/.config/openspec` holds `index.json` plus per-workspace folders.
|
||||
- **Identifiers**:
|
||||
- `workspaceId`: user-provided slug or auto-generated UUID (e.g., `default`, `my-project`).
|
||||
- `changeId`: user-provided slug derived from change title or auto-generated (e.g., `add-user-auth`).
|
||||
- `repoId`: `{primary-remote-url}@{default-branch}` (normalized: SSH/HTTPS variants resolve to same ID). For repos without remotes, fallback to local path hash.
|
||||
- **Context projection**: generate `./.openspec-context.json` in each attached repo (git-ignored) with:
|
||||
- `schemaVersion`, `generatedAt`, `repoId`, `workspaceId`, `branch`
|
||||
- `activeChangeId|null`, `changeTitle`, `status`
|
||||
- `specRoots`, `tasks` (checkbox state), `warnings`
|
||||
- `sourceHash`/`sourceVersion` for drift detection
|
||||
- **Refresh policy**: regenerate manifest on `openspec status/context/set-active/attach`, or `openspec context --refresh`.
|
||||
- **Drift detection**: `openspec verify` runs on `status/context`, warns (non-blocking) when:
|
||||
- Manifest `sourceHash` (hash of change proposal + tasks) differs from workspace store.
|
||||
- In-repo specs differ from expected state based on applied changes.
|
||||
- Branch in manifest doesn't match current git branch.
|
||||
- **Tasks**: stay as Markdown checkboxes in change folders; structured format is future work.
|
||||
- **Cross-repo specs**: defer to future dedicated "specs repo"; out-of-scope for V1.
|
||||
|
||||
## Workspace Customization & Hooks
|
||||
|
||||
Workspaces double as the unit of customization. Moving changes into `~/.config/openspec` gives us a neutral location to store **per-workspace workflow configuration** that can be projected into every attached repo alongside the manifest. Early capabilities include:
|
||||
|
||||
- **Lifecycle hooks**: Users can define shell commands or scripts (e.g., `./scripts/post-create.sh`) that OpenSpec runs after key events such as `change create`, `change apply`, `task toggle`, or `context --refresh`. Hooks let teams codify "what happens next?" right after a proposal is created—notify Slack, scaffold implementation branches, sync Linear tickets, etc.
|
||||
- **Workflow presets**: Workspace metadata (`workspace.json`) can include reusable instructions/templates that describe the expected flow (e.g., "After proposal, run design review checklist", "Before apply, execute `openspec verify --strict`"). Agents surface these reminders in their startup instructions, and humans can read them from the manifest.
|
||||
- **Composable steps**: Hooks are optional and orderable, so teams can compose bespoke workflows (e.g., `change.create` → run linting hooks, attach repo-specific instructions; `change.apply` → trigger spec sync + notify QA). V1 focuses on definition + discovery—the appendix tracks richer automation (custom task types, SDK integrations) for future versions.
|
||||
|
||||
This section keeps the RFC honest about a core benefit of workspaces: breaking the monolithic flow into smaller, customizable checkpoints without hard-coding them in every repo. Detailed research and long-term options live in the appendix’s "Future Considerations" and "Risk Analysis" tables.
|
||||
|
||||
## ASCII Flow (Agent View)
|
||||
|
||||
```
|
||||
+---------------------------+
|
||||
| ~/.config/openspec |
|
||||
| - index.json |
|
||||
| - workspaces/<ws>/... |
|
||||
+-------------+-------------+
|
||||
|
|
||||
| openspec status/context --refresh
|
||||
v
|
||||
+---------------------------+
|
||||
| repo/ |
|
||||
| - .openspec-context.json | <- lightweight shadow manifest
|
||||
| - openspec/specs/... | <- truth for specs
|
||||
| - code |
|
||||
+---------------------------+
|
||||
```
|
||||
|
||||
## Agent Workflow
|
||||
|
||||
How agents discover and use change context:
|
||||
|
||||
1. **Discover active change**: Agent reads `.openspec-context.json` in repo root (or calls `openspec status --json`).
|
||||
- Manifest provides: `activeChangeId`, `changeTitle`, `status`, `tasks` summary, `warnings`.
|
||||
- If manifest missing or stale, agent calls `openspec context --refresh`.
|
||||
|
||||
2. **Read full change details**: Agent calls `openspec change show <changeId> --json` to get:
|
||||
- Full proposal content (`proposal.md`)
|
||||
- Complete task list with checkbox states (`tasks.md`)
|
||||
- Spec deltas (what specs will change)
|
||||
- Paths to all change artifacts in workspace store
|
||||
|
||||
3. **Update task progress**: Agent calls `openspec task toggle <changeId> <taskIndex>` or edits `tasks.md` directly via workspace path (provided in step 2).
|
||||
|
||||
4. **Resume work**: On session start, agent reads manifest → identifies incomplete tasks → continues from last known state.
|
||||
|
||||
**Fallback for non-CLI agents**: If agent cannot invoke CLI, it reads the manifest for summary context and relies on user to sync task state manually.
|
||||
|
||||
## Workflows (Before → After)
|
||||
|
||||
- **Create change**
|
||||
- *Before*: `openspec change create` writes under `repo/openspec/changes`.
|
||||
- *After*: same command writes under `~/.config/openspec/workspaces/<ws>/changes/<id>`, then projects manifest into repo.
|
||||
|
||||
- **Resume work**
|
||||
- *Before*: read `/openspec/changes/<id>` directly in repo.
|
||||
- *After*: `openspec status` (or manifest) tells active change; agent reads tasks/proposal via CLI or manifest pointers.
|
||||
|
||||
- **Apply spec update**
|
||||
- *Before*: copy deltas into `/openspec/specs` and archive change.
|
||||
- *After*: applying a change updates in-repo specs directly; no archive step. Change record stays in workspace store.
|
||||
|
||||
## CLI Impact (V1)
|
||||
|
||||
- **New/updated commands** (shape, not syntax-final):
|
||||
- `openspec context [--refresh]` → writes `.openspec-context.json`.
|
||||
- `openspec attach <repo-path>` → register repo to workspace, emit manifest.
|
||||
- `openspec status [--json]` → shows active workspace/change, drift warnings.
|
||||
- `openspec verify` → compare change store vs. repo specs/tasks, warn on drift.
|
||||
- `openspec change show <changeId> [--json]` → output full change details (proposal, tasks, spec deltas, artifact paths).
|
||||
- `openspec change apply <changeId>` → applies spec deltas to in-repo specs, updates change status to `completed`, refreshes manifest.
|
||||
- `openspec task toggle <changeId> <taskIndex>` → toggle checkbox state in `tasks.md`, refresh manifest.
|
||||
- Existing `change create/validate` operate on workspace store paths.
|
||||
|
||||
## Data Examples
|
||||
|
||||
- **Manifest sketch (`./.openspec-context.json`):**
|
||||
```json
|
||||
{
|
||||
"schemaVersion": "1",
|
||||
"generatedAt": "2024-XX-XXT12:00:00Z",
|
||||
"repoId": "git@github.com:org/api.git@main",
|
||||
"workspaceId": "my-project",
|
||||
"branch": "feature/add-auth",
|
||||
"activeChangeId": "add-user-auth",
|
||||
"changeTitle": "Add user authentication",
|
||||
"status": "in-progress",
|
||||
"specRoots": ["openspec/specs"],
|
||||
"tasks": [
|
||||
{"title": "Define auth spec", "done": true},
|
||||
{"title": "Implement JWT middleware", "done": false}
|
||||
],
|
||||
"warnings": [],
|
||||
"sourceHash": "abc123",
|
||||
"relatedRepos": [
|
||||
{"repoId": "git@github.com:org/frontend.git@main", "role": "consumer"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
*Note: `relatedRepos` shows other repos in the same workspace affected by this change. Each repo gets its own manifest with the same `activeChangeId`.*
|
||||
|
||||
- **Workspace index (`~/.config/openspec/index.json`):**
|
||||
```json
|
||||
{
|
||||
"workspaces": [
|
||||
{
|
||||
"id": "my-project",
|
||||
"repos": [
|
||||
{
|
||||
"repoId": "git@github.com:org/api.git@main",
|
||||
"paths": ["/Users/me/dev/api"]
|
||||
},
|
||||
{
|
||||
"repoId": "git@github.com:org/frontend.git@main",
|
||||
"paths": ["/Users/me/dev/frontend"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Migration (Happy Path)
|
||||
|
||||
- Detect existing `/openspec/changes` and prompt to migrate into the workspace store.
|
||||
- Copy change folders to `~/.config/openspec/workspaces/<ws>/changes/`.
|
||||
- Write manifests into each repo (`.openspec-context.json`) pointing to migrated changes.
|
||||
- Keep in-repo specs untouched; future changes update specs directly.
|
||||
- Optionally keep legacy layout temporarily as read-only until confident.
|
||||
|
||||
## Risks / Tradeoffs
|
||||
|
||||
- **Loss of co-location**: agents need CLI/manifest indirection; mitigated by shadow manifest and simple commands (see Agent Workflow).
|
||||
- **Portability**: local-only workspace; migration between machines requires exporting/importing the workspace folder.
|
||||
- **CI/CD access**: out-of-scope for V1 (see Non-Goals); workaround is environment override or workspace export.
|
||||
- **Drift**: specs live in-repo, changes live out-of-repo; mitigated by `openspec verify` and manifest hashes.
|
||||
- **Back-compat**: legacy `/openspec/changes` requires migration; optionally support read-only compatibility during transition.
|
||||
|
||||
## Open Questions (Post-V1)
|
||||
|
||||
- Where to store branch→change mapping (manifest vs. workspace config) and how to handle branch renames?
|
||||
- Minimal API/SDK needed for agent integrations vs. relying solely on CLI.
|
||||
- Packaging/sync of workspace store for teams (git repo? cloud bucket?).
|
||||
- How to represent cross-repo spec ownership without a dedicated specs repo?
|
||||
|
||||
## Acceptance Checklist (for reviewers)
|
||||
|
||||
- High-level model understandable via bullets + diagrams.
|
||||
- Data shapes for manifest and index are clear enough for implementation.
|
||||
- Migration story covers legacy users.
|
||||
- Risks called out with basic mitigations.
|
||||
|
||||
---
|
||||
|
||||
## Appendix: User Flows
|
||||
|
||||
### A. Single-Repo Setup
|
||||
|
||||
```bash
|
||||
cd ~/dev/my-project
|
||||
openspec init # creates workspace, attaches current repo
|
||||
# → ~/.config/openspec/index.json updated
|
||||
# → .openspec-context.json written (git-ignored)
|
||||
# → openspec/specs/ created if missing
|
||||
```
|
||||
|
||||
That's it. User is ready to create changes.
|
||||
|
||||
---
|
||||
|
||||
### B. Multi-Repo Setup
|
||||
|
||||
```bash
|
||||
# Create workspace and attach first repo
|
||||
cd ~/dev/api
|
||||
openspec init --workspace my-platform
|
||||
|
||||
# Attach additional repos to same workspace
|
||||
cd ~/dev/frontend
|
||||
openspec attach --workspace my-platform
|
||||
|
||||
cd ~/dev/shared-types
|
||||
openspec attach --workspace my-platform
|
||||
```
|
||||
|
||||
All three repos now share `my-platform` workspace. Changes created in any repo can reference specs across all attached repos.
|
||||
|
||||
---
|
||||
|
||||
### C. Creating a Change Proposal
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User
|
||||
participant CLI as openspec CLI
|
||||
participant WS as ~/.config/openspec
|
||||
participant Repo as repo/
|
||||
|
||||
User->>CLI: openspec change create "Add auth"
|
||||
CLI->>WS: Create workspaces/<ws>/changes/add-auth/
|
||||
CLI->>WS: Write proposal.md, tasks.md
|
||||
CLI->>Repo: Write .openspec-context.json
|
||||
CLI->>User: Change "add-auth" created ✓
|
||||
|
||||
Note over User,Repo: User/agent can now edit proposal.md and tasks.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### D. Applying a Change Proposal
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User
|
||||
participant CLI as openspec CLI
|
||||
participant WS as ~/.config/openspec
|
||||
participant Repo as repo/
|
||||
|
||||
User->>CLI: openspec change apply add-auth
|
||||
CLI->>WS: Read changes/add-auth/specs/*.md (deltas)
|
||||
CLI->>Repo: Merge deltas into openspec/specs/
|
||||
CLI->>WS: Update change status → "completed"
|
||||
CLI->>Repo: Refresh .openspec-context.json
|
||||
CLI->>User: Specs updated, change complete ✓
|
||||
|
||||
Note over Repo: User commits spec changes + code together
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### E. After the Work is Done
|
||||
|
||||
Once a change is applied:
|
||||
|
||||
| Location | State |
|
||||
|----------|-------|
|
||||
| `repo/openspec/specs/` | Updated with new/modified specs |
|
||||
| `repo/.openspec-context.json` | `activeChangeId: null` or next change |
|
||||
| `~/.config/openspec/.../changes/add-auth/` | Retained as historical record (status: `completed`) |
|
||||
|
||||
**Next steps for user:**
|
||||
1. `git add . && git commit` — spec updates and code ship together
|
||||
2. Create PR, merge
|
||||
3. Start next change or detach repo from workspace when done
|
||||
@@ -11,7 +11,6 @@ const FILE_PATHS: Record<SlashCommandId, string> = {
|
||||
|
||||
const FRONTMATTER: Record<SlashCommandId, string> = {
|
||||
proposal: `---
|
||||
agent: build
|
||||
description: Scaffold a new OpenSpec change and validate strictly.
|
||||
---
|
||||
The user has requested the following change proposal. Use the openspec instructions to create their change proposal.
|
||||
@@ -20,7 +19,6 @@ The user has requested the following change proposal. Use the openspec instructi
|
||||
</UserRequest>
|
||||
`,
|
||||
apply: `---
|
||||
agent: build
|
||||
description: Implement an approved OpenSpec change and keep tasks in sync.
|
||||
---
|
||||
The user has requested to implement the following change proposal. Find the change proposal and follow the instructions below. If you're not sure or if ambiguous, ask for clarification from the user.
|
||||
@@ -29,7 +27,6 @@ The user has requested to implement the following change proposal. Find the chan
|
||||
</UserRequest>
|
||||
`,
|
||||
archive: `---
|
||||
agent: build
|
||||
description: Archive a deployed OpenSpec change and update specs.
|
||||
---
|
||||
<ChangeId>
|
||||
|
||||
@@ -492,21 +492,21 @@ describe('InitCommand', () => {
|
||||
expect(await fileExists(openCodeArchive)).toBe(true);
|
||||
|
||||
const proposalContent = await fs.readFile(openCodeProposal, 'utf-8');
|
||||
expect(proposalContent).toContain('agent: build');
|
||||
expect(proposalContent).not.toContain('agent:');
|
||||
expect(proposalContent).toContain(
|
||||
'description: Scaffold a new OpenSpec change and validate strictly.'
|
||||
);
|
||||
expect(proposalContent).toContain('<!-- OPENSPEC:START -->');
|
||||
|
||||
const applyContent = await fs.readFile(openCodeApply, 'utf-8');
|
||||
expect(applyContent).toContain('agent: build');
|
||||
expect(applyContent).not.toContain('agent:');
|
||||
expect(applyContent).toContain(
|
||||
'description: Implement an approved OpenSpec change and keep tasks in sync.'
|
||||
);
|
||||
expect(applyContent).toContain('Work through tasks sequentially');
|
||||
|
||||
const archiveContent = await fs.readFile(openCodeArchive, 'utf-8');
|
||||
expect(archiveContent).toContain('agent: build');
|
||||
expect(archiveContent).not.toContain('agent:');
|
||||
expect(archiveContent).toContain(
|
||||
'description: Archive a deployed OpenSpec change and update specs.'
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user