diff --git a/docs/concepts.md b/docs/concepts.md index 2ec1772d4..2784ac305 100644 --- a/docs/concepts.md +++ b/docs/concepts.md @@ -133,6 +133,52 @@ The system MUST expire sessions after 30 minutes of inactivity. - **SHOULD** — recommended, but exceptions exist - **MAY** — optional +### What a Spec Is (and Is Not) + +A spec is a **behavior contract**, not an implementation plan. + +Good spec content: +- Observable behavior users or downstream systems rely on +- Inputs, outputs, and error conditions +- External constraints (security, privacy, reliability, compatibility) +- Scenarios that can be tested or explicitly validated + +Avoid in specs: +- Internal class/function names +- Library or framework choices +- Step-by-step implementation details +- Detailed execution plans (those belong in `design.md` or `tasks.md`) + +Quick test: +- If implementation can change without changing externally visible behavior, it likely does not belong in the spec. + +### Keep It Lightweight: Progressive Rigor + +OpenSpec aims to avoid bureaucracy. Use the lightest level that still makes the change verifiable. + +**Lite spec (default):** +- Short behavior-first requirements +- Clear scope and non-goals +- A few concrete acceptance checks + +**Full spec (for higher risk):** +- Cross-team or cross-repo changes +- API/contract changes, migrations, security/privacy concerns +- Changes where ambiguity is likely to cause expensive rework + +Most changes should stay in Lite mode. + +### Human + Agent Collaboration + +In many teams, humans explore and agents draft artifacts. The intended loop is: + +1. Human provides intent, context, and constraints. +2. Agent converts this into behavior-first requirements and scenarios. +3. Agent keeps implementation detail in `design.md` and `tasks.md`, not `spec.md`. +4. Validation confirms structure and clarity before implementation. + +This keeps specs readable for humans and consistent for agents. + ## Changes A change is a proposed modification to your system, packaged as a folder with everything needed to understand and implement it. diff --git a/openspec/changes/simplify-skill-installation/.openspec.yaml b/openspec/changes/simplify-skill-installation/.openspec.yaml new file mode 100644 index 000000000..c8d3976ae --- /dev/null +++ b/openspec/changes/simplify-skill-installation/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-02-17 diff --git a/openspec/changes/simplify-skill-installation/design.md b/openspec/changes/simplify-skill-installation/design.md new file mode 100644 index 000000000..f302b7428 --- /dev/null +++ b/openspec/changes/simplify-skill-installation/design.md @@ -0,0 +1,193 @@ +## Context + +OpenSpec currently installs 10 workflows (skills + commands) for every user, overwhelming new users. The init flow asks multiple questions (profile, delivery, tools) creating friction before users can experience value. + +Current architecture: +- `src/core/init.ts` - Handles tool selection and skill/command generation +- `src/core/config.ts` - Defines `AI_TOOLS` with `skillsDir` mappings +- `src/core/shared/skill-generation.ts` - Generates skill files from templates +- `src/core/templates/workflows/*.ts` - Individual workflow templates +- `src/prompts/searchable-multi-select.ts` - Tool selection UI + +Global config exists at `~/.config/openspec/config.json` for telemetry/feature flags. Profile/delivery settings will extend this existing config. + +## Goals / Non-Goals + +**Goals:** +- Get new users to "aha moment" in under 1 minute +- Smart defaults init with auto-detection and confirmation (core profile, both delivery) +- Auto-detect installed tools from existing directories +- Introduce profile system (core/custom) for workflow selection +- Introduce delivery config (skills/commands/both) as power-user setting +- Create new `propose` workflow combining `new` + `ff` +- Fix tool selection UX (space to select, enter to confirm) +- Maintain backwards compatibility for existing users + +**Non-Goals:** +- Removing any existing workflows (all remain available via custom profile) +- Per-project profile/delivery settings (user-level only) +- Changing the artifact structure or schema system +- Modifying how skills/commands are formatted or written + +## Decisions + +### 1. Extend Existing Global Config + +Add profile/delivery settings to existing `~/.config/openspec/config.json` (via `src/core/global-config.ts`). + +**Rationale:** Global config already exists with XDG/APPDATA cross-platform path handling, schema evolution, and merge-with-defaults behavior. Reusing it avoids a second config file and leverages existing infrastructure. + +**Schema extension:** +```json +{ + "telemetry": { ... }, // existing + "featureFlags": { ... }, // existing + "profile": "core", // NEW + "delivery": "both", // NEW + "workflows": [...] // NEW (only for custom profile) +} +``` + +**Alternatives considered:** +- New `~/.openspec/config.yaml`: Creates second config file, different format, path confusion +- Project config: Would require syncing mechanism, users edit it directly +- Environment variables: Less discoverable, harder to persist + +### 2. Profile System with Two Tiers + +``` +core (default): propose, explore, apply, archive (4) +custom: user-defined subset of workflows +``` + +**Rationale:** Core covers the essential loop (propose → explore → apply → archive). Custom allows users to pick exactly what they need via an interactive picker. + +**Configuration UX:** +``` +$ openspec config profile + +Delivery: [skills] [commands] [both] + ^^^^^^ + +Workflows: (space to toggle, enter to save) +[x] propose +[x] explore +[x] apply +[x] archive +[ ] new +[ ] ff +... +``` + +**Alternatives considered:** +- Three tiers (core/extended/custom): Extended is redundant - users who want all workflows can select them in custom +- Separate commands for profile and delivery: Combining into one picker reduces cognitive load + +### 3. Propose Workflow = New + FF Combined + +Single workflow that creates a change and generates all artifacts in one step. + +**Rationale:** Most users want to go from idea to implementation-ready. Separating `new` (creates folder) and `ff` (generates artifacts) adds unnecessary steps. Power users who want control can use `new` + `continue` via custom profile. + +**Implementation:** New template in `src/core/templates/workflows/propose.ts` that: +1. Creates change directory via `openspec new change` +2. Runs artifact generation loop (like ff does) +3. Includes onboarding-style explanations in output + +### 4. Auto-Detection with Confirmation + +Scan for existing tool directories, pre-select detected tools, ask for confirmation. + +**Rationale:** Reduces questions while still giving user control. Better than full auto (no confirmation) which might install unwanted tools, or no detection (always ask) which adds friction. + +**Detection logic:** +```typescript +// Use existing AI_TOOLS config to get directory mappings +// Each tool in AI_TOOLS has a skillsDir property (e.g., '.claude', '.cursor', '.windsurf') +// Scan cwd for existing directories matching skillsDir values, pre-select matches +const detectedTools = AI_TOOLS.filter(tool => + fs.existsSync(path.join(cwd, tool.skillsDir)) +); +``` + +### 5. Delivery as Part of Profile Config + +Delivery preference (skills/commands/both) stored in global config, defaulting to "both". + +**Rationale:** Most users don't know or care about this distinction. Power users who have a preference can set it via `openspec config profile` interactive picker. Not worth asking during init. + +### 6. Filesystem as Truth for Installed Workflows + +What's installed in `.claude/skills/` (etc.) is the source of truth, not config. + +**Rationale:** +- Backwards compatible with existing installs +- User can manually add/remove skill directories +- Config profile is a "template" for what to install, not a constraint + +**Behavior:** +- `openspec init` sets up new projects OR re-initializes existing projects (selects tools, generates workflows) +- `openspec update` refreshes an existing project to match current config (no tool selection) +- `openspec config profile` updates global config only, offers to run update if in a project +- Extra workflows (not in profile) are preserved +- Delivery changes are applied: switching to `skills` removes commands, switching to `commands` removes skills + +**When to use init vs update:** +- `init`: First time setup, or when you want to change which tools are configured +- `update`: After changing config, or to refresh templates to latest version + +### 7. Fix Multi-Select Keybindings + +Change from tab-to-confirm to industry-standard space/enter. + +**Rationale:** Tab to confirm is non-standard and confuses users. Most CLI tools use space to toggle, enter to confirm. + +**Implementation:** Modify `src/prompts/searchable-multi-select.ts` keybinding configuration. + +## Risks / Trade-offs + +**Risk: Breaking existing user workflows** +→ Mitigation: Filesystem is truth, existing installs untouched. All workflows available via custom profile. + +**Risk: Propose workflow duplicates ff logic** +→ Mitigation: Extract shared artifact generation into reusable function, both `propose` and `ff` call it. + +**Risk: Global config file management** +→ Mitigation: Create directory/file on first use. Handle missing file gracefully (use defaults). + +**Risk: Auto-detection false positives** +→ Mitigation: Show detected tools and ask for confirmation, don't auto-install silently. + +**Trade-off: Core profile has only 4 workflows** +→ Acceptable: These cover the main loop. Users who need more can use `openspec config profile` to select additional workflows. + +## Migration Plan + +1. **Phase 1: Add infrastructure** + - Extend global-config.ts with profile/delivery/workflows fields + - Profile definitions and resolution + - Tool auto-detection + +2. **Phase 2: Create propose workflow** + - New template combining new + ff + - Enhanced UX with explanatory output + +3. **Phase 3: Update init flow** + - Smart defaults with tool confirmation + - Auto-detect and confirm tools + - Respect profile/delivery settings + +4. **Phase 4: Add config profile command** + - `openspec config profile` interactive picker + - `openspec config profile core` preset shortcut + +5. **Phase 5: Update the update command** + - Read global config for profile/delivery + - Add missing workflows from profile + - Delete files when delivery changes (e.g., commands removed if `skills`) + - Display summary of changes + +6. **Phase 6: Fix multi-select UX** + - Update keybindings in searchable-multi-select + +**Rollback:** All changes are additive. Existing behavior preserved via custom profile with all workflows selected. diff --git a/openspec/changes/simplify-skill-installation/proposal.md b/openspec/changes/simplify-skill-installation/proposal.md new file mode 100644 index 000000000..0cff8eb3a --- /dev/null +++ b/openspec/changes/simplify-skill-installation/proposal.md @@ -0,0 +1,189 @@ +## Why + +Users have complained that there are too many skills/commands (currently 10) and new users feel overwhelmed. We want to simplify the default experience while preserving power-user capabilities and backwards compatibility. + +The goal: **get users to an "aha moment" in under a minute**. + +```text +0:00 $ openspec init + ✓ Done. Run /opsx:propose "your idea" + +0:15 /opsx:propose "add user authentication" + +0:45 Agent creates proposal.md, design.md, tasks.md + "Whoa, it planned the whole thing for me" ← AHA + +1:00 /opsx:apply +``` + +Additionally, users have different preferences for how workflows are delivered (skills vs commands vs both), but this should be a power-user configuration, not something new users think about. + +## What Changes + +### 1. Smart Defaults Init + +Init auto-detects tools and asks for confirmation: + +```text +$ openspec init + +Detected tools: + [x] Claude Code + [x] Cursor + [ ] Windsurf + +Press Enter to confirm, or Space to toggle + +Setting up OpenSpec... +✓ Done + +Start your first change: + /opsx:propose "add dark mode" +``` + +**No prompts for profile or delivery.** Defaults are: +- Profile: core +- Delivery: both + +Power users can customize via `openspec config profile`. + +### 2. Tool Detection Behavior + +Init scans for existing tool directories (`.claude/`, `.cursor/`, etc.): +- **Tools detected (interactive):** Shows pre-selected checkboxes, user confirms or adjusts +- **No tools detected (interactive):** Prompts for full tool selection +- **Non-interactive (CI):** Uses detected tools automatically, fails if none detected + +### 3. Fix Tool Selection UX + +Current behavior confuses users: +- Tab to confirm (unexpected) + +New behavior: +- **Space** to toggle selection +- **Enter** to confirm + +### 4. Introduce Profiles + +Profiles define which workflows to install: + +- **core** (default): `propose`, `explore`, `apply`, `archive` (4 workflows) +- **custom**: User-selected subset of workflows + +The `propose` workflow is new - it combines `new` + `ff` into a single command that creates a change and generates all artifacts. + +### 5. Improved Propose UX + +`/opsx:propose` should naturally onboard users by explaining what it's doing: + +```text +I'll create a change with 3 artifacts: +- proposal.md (what & why) +- design.md (how) +- tasks.md (implementation steps) + +When ready to implement, run /opsx:apply +``` + +This teaches as it goes - no separate onboarding needed for most users. + +### 6. Introduce Delivery Config + +Delivery controls how workflows are installed: + +- **both** (default): Skills and commands +- **skills**: Skills only +- **commands**: Commands only + +Stored in existing global config (`~/.config/openspec/config.json`). Not prompted during init. + +### 7. New CLI Commands + +```shell +# Profile configuration (interactive picker for delivery + workflows) +openspec config profile # interactive picker +openspec config profile core # preset shortcut (core workflows, preserves delivery) +``` + +The interactive picker allows users to configure both delivery method and workflow selection in one place: + +``` +$ openspec config profile + +Delivery: [skills] [commands] [both] + ^^^^^^ + +Workflows: (space to toggle, enter to save) +[x] propose +[x] explore +[x] apply +[x] archive +[ ] new +[ ] ff +[ ] continue +[ ] verify +[ ] sync +[ ] bulk-archive +[ ] onboard +``` + +### 8. Backwards Compatibility + +- Existing users with all workflows keep them (extra workflows not in profile are preserved) +- `openspec init` sets up new projects using current profile config +- `openspec update` applies config changes to existing projects (adds missing workflows, refreshes templates) +- Delivery changes are applied: switching to `skills` removes command files, switching to `commands` removes skill files +- All workflows remain available via custom profile + +## Capabilities + +### New Capabilities + +- `profiles`: Support for workflow profiles (core, custom) with interactive configuration +- `delivery-config`: User preference for delivery method (skills, commands, both) +- `propose-workflow`: Combined workflow that creates change + generates all artifacts +- `user-config`: Extend existing global config with profile/delivery settings +- `available-tools`: Detect what AI tools the user has from existing directories + +### Modified Capabilities + +- `cli-init`: Smart defaults with auto-detection and confirmation +- `tool-selection-ux`: Space to select, Enter to confirm +- `skill-generation`: Conditional based on profile and delivery settings +- `command-generation`: Conditional based on profile and delivery settings + +## Impact + +### New Files +- `src/core/templates/workflows/propose.ts` - New propose workflow template +- `src/core/profiles.ts` - Profile definitions and logic +- `src/core/available-tools.ts` - Detect what AI tools user has from directories + +### Modified Files +- `src/core/init.ts` - Smart defaults, auto-detection, tool confirmation +- `src/core/config.ts` - Add profile and delivery types +- `src/core/global-config.ts` - Add profile, delivery, workflows fields to schema +- `src/core/shared/skill-generation.ts` - Filter by profile, respect delivery +- `src/core/shared/tool-detection.ts` - Update SKILL_NAMES and COMMAND_IDS to include propose +- `src/commands/config.ts` - Add `profile` subcommand with interactive picker +- `src/commands/update.ts` - Add profile/delivery support, file deletion for delivery changes +- `src/prompts/searchable-multi-select.ts` - Fix keybindings (space/enter) + +### Global Config Schema Extension +```json +// ~/.config/openspec/config.json (extends existing) +{ + "telemetry": { ... }, // existing + "featureFlags": { ... }, // existing + "profile": "core", // NEW: core | custom + "delivery": "both", // NEW: both | skills | commands + "workflows": ["propose", ...] // NEW: only if profile: custom +} +``` + +## Profiles Reference + +| Profile | Workflows | Description | +|---------|-----------|-------------| +| core | propose, explore, apply, archive | Streamlined flow for most users (default) | +| custom | user-defined | Pick exactly what you need via `openspec config profile` | diff --git a/openspec/changes/simplify-skill-installation/specs/available-tools/spec.md b/openspec/changes/simplify-skill-installation/specs/available-tools/spec.md new file mode 100644 index 000000000..fb27c3988 --- /dev/null +++ b/openspec/changes/simplify-skill-installation/specs/available-tools/spec.md @@ -0,0 +1,48 @@ +## Purpose + +Available tools detection SHALL enable smart defaults init by auto-discovering which AI tools the user has installed, reducing setup friction while maintaining user control. + +## ADDED Requirements + +### Requirement: Detect tools from directories +The system SHALL detect installed AI tools by scanning for their configuration directories. + +#### Scenario: Detect Claude Code +- **WHEN** `.claude/` directory exists in project root +- **THEN** the system SHALL detect Claude Code as an installed tool + +#### Scenario: Detect Cursor +- **WHEN** `.cursor/` directory exists in project root +- **THEN** the system SHALL detect Cursor as an installed tool + +#### Scenario: Detect Windsurf +- **WHEN** `.windsurf/` directory exists in project root +- **THEN** the system SHALL detect Windsurf as an installed tool + +#### Scenario: Detect multiple tools +- **WHEN** multiple tool directories exist (e.g., `.claude/`, `.cursor/`) +- **THEN** the system SHALL detect all matching tools + +#### Scenario: No tools detected +- **WHEN** no tool directories exist in project root +- **THEN** the system SHALL return an empty list of detected tools + +### Requirement: Detection covers all supported tools +The system SHALL check for all tools defined in `AI_TOOLS` that have a `skillsDir` property. + +#### Scenario: Detection mapping +- **WHEN** scanning for tools +- **THEN** the system SHALL check for each tool's `skillsDir` value (e.g., `.claude`, `.cursor`, `.windsurf`) + +### Requirement: Cross-platform directory detection +The system SHALL use cross-platform path handling for directory detection. + +#### Scenario: Path construction +- **WHEN** checking for tool directories +- **THEN** the system SHALL use `path.join()` to construct paths + +#### Scenario: Case sensitivity on different platforms +- **WHEN** checking for directories on any filesystem +- **THEN** the system SHALL use `fs.existsSync()` with exact directory names from AI_TOOLS +- **THEN** the operating system's filesystem SHALL handle case sensitivity natively +- **THEN** the system SHALL NOT perform manual case normalization diff --git a/openspec/changes/simplify-skill-installation/specs/cli-init/spec.md b/openspec/changes/simplify-skill-installation/specs/cli-init/spec.md new file mode 100644 index 000000000..00e5f0b62 --- /dev/null +++ b/openspec/changes/simplify-skill-installation/specs/cli-init/spec.md @@ -0,0 +1,115 @@ +## Purpose + +The init command SHALL provide a streamlined setup experience that auto-detects tools and uses smart defaults, getting users to their first change in under a minute. + +## MODIFIED Requirements + +### Requirement: Skill generation per tool (REPLACES fixed 9-skill mandate) +The init command SHALL generate skills based on the active profile, not a fixed set. + +#### Scenario: Core profile skill generation +- **WHEN** user runs init with profile `core` +- **THEN** the system SHALL generate skills for workflows in CORE_WORKFLOWS constant: propose, explore, apply, archive +- **THEN** the system SHALL NOT generate skills for workflows outside the profile + +#### Scenario: Custom profile skill generation +- **WHEN** user runs init with profile `custom` +- **THEN** the system SHALL generate skills only for workflows listed in config `workflows` array + +### Requirement: Command generation per tool (REPLACES fixed 9-command mandate) +The init command SHALL generate commands based on profile AND delivery settings. + +#### Scenario: Skills-only delivery +- **WHEN** delivery is set to `skills` +- **THEN** the system SHALL NOT generate any command files + +#### Scenario: Commands-only delivery +- **WHEN** delivery is set to `commands` +- **THEN** the system SHALL NOT generate any skill files + +#### Scenario: Both delivery +- **WHEN** delivery is set to `both` +- **THEN** the system SHALL generate both skill and command files for profile workflows + +### Requirement: Smart defaults init flow +The init command SHALL work with sensible defaults and tool confirmation, minimizing required user input. + +#### Scenario: Init with detected tools (interactive) +- **WHEN** user runs `openspec init` interactively and tool directories are detected +- **THEN** the system SHALL show detected tools pre-selected +- **THEN** the system SHALL ask for confirmation (not full selection) +- **THEN** the system SHALL use default profile (`core`) and delivery (`both`) + +#### Scenario: Init with no detected tools (interactive) +- **WHEN** user runs `openspec init` interactively and no tool directories are detected +- **THEN** the system SHALL prompt for tool selection +- **THEN** the system SHALL use default profile (`core`) and delivery (`both`) + +#### Scenario: Non-interactive with detected tools +- **WHEN** user runs `openspec init` non-interactively (e.g., in CI) +- **AND** tool directories are detected +- **THEN** the system SHALL use detected tools automatically without prompting +- **THEN** the system SHALL use default profile and delivery + +#### Scenario: Non-interactive with no detected tools +- **WHEN** user runs `openspec init` non-interactively +- **AND** no tool directories are detected +- **THEN** the system SHALL fail with exit code 1 +- **AND** display message to use `--tools` flag + +#### Scenario: Non-interactive with explicit tools +- **WHEN** user runs `openspec init --tools claude` +- **THEN** the system SHALL use specified tools +- **THEN** the system SHALL NOT prompt for any input + +#### Scenario: Interactive with explicit tools +- **WHEN** user runs `openspec init --tools claude` interactively +- **THEN** the system SHALL use specified tools (ignoring auto-detection) +- **THEN** the system SHALL NOT prompt for tool selection +- **THEN** the system SHALL proceed with default profile and delivery + +#### Scenario: Init success message +- **WHEN** init completes successfully +- **THEN** the system SHALL display a tool-appropriate success message +- **THEN** for tools using colon syntax (Claude Code): "Start your first change: /opsx:propose \"your idea\"" +- **THEN** for tools using hyphen syntax (Cursor, others): "Start your first change: /opsx-propose \"your idea\"" + +### Requirement: Init respects global config +The init command SHALL read and apply settings from global config. + +#### Scenario: User has profile preference +- **WHEN** global config contains `profile: "custom"` with custom workflows +- **THEN** init SHALL install custom profile workflows + +#### Scenario: User has delivery preference +- **WHEN** global config contains `delivery: "skills"` +- **THEN** init SHALL install only skill files, not commands + +#### Scenario: Override via flags +- **WHEN** user runs `openspec init --profile core` +- **THEN** the system SHALL use the flag value instead of config value +- **THEN** the system SHALL NOT update the global config + +### Requirement: Init preserves existing workflows +The init command SHALL NOT remove workflows that are already installed, but SHALL respect delivery setting. + +#### Scenario: Existing custom installation +- **WHEN** user has custom profile with extra workflows and runs `openspec init` with core profile +- **THEN** the system SHALL NOT remove extra workflows +- **THEN** the system SHALL regenerate core workflow files, overwriting existing content with latest templates + +#### Scenario: Init with different delivery setting +- **WHEN** user runs `openspec init` on existing project +- **AND** delivery setting differs from what's installed (e.g., was `both`, now `skills`) +- **THEN** the system SHALL generate files matching current delivery setting +- **THEN** the system SHALL delete files that don't match delivery (e.g., commands removed if `skills`) +- **THEN** this applies to all workflows, including extras not in profile + +### Requirement: Init tool confirmation UX +The init command SHALL show detected tools and ask for confirmation. + +#### Scenario: Confirmation prompt +- **WHEN** tools are detected in interactive mode +- **THEN** the system SHALL display: "Detected: Claude Code, Cursor" +- **THEN** the system SHALL show pre-selected checkboxes for confirmation +- **THEN** the system SHALL allow user to deselect unwanted tools diff --git a/openspec/changes/simplify-skill-installation/specs/cli-update/spec.md b/openspec/changes/simplify-skill-installation/specs/cli-update/spec.md new file mode 100644 index 000000000..566c90118 --- /dev/null +++ b/openspec/changes/simplify-skill-installation/specs/cli-update/spec.md @@ -0,0 +1,76 @@ +## Purpose + +The update command SHALL apply global configuration changes to existing projects, syncing profile and delivery preferences without requiring full re-initialization. + +## MODIFIED Requirements + +### Requirement: Update respects global profile config +The update command SHALL read global config and apply profile settings to the project. + +#### Scenario: Update adds missing workflows from config +- **WHEN** user runs `openspec update` +- **AND** global config specifies workflows not currently installed in the project +- **THEN** the system SHALL generate skill/command files for missing workflows +- **THEN** the system SHALL display: "Added: " + +#### Scenario: Update refreshes existing workflows +- **WHEN** user runs `openspec update` +- **AND** workflows are already installed in the project +- **THEN** the system SHALL refresh those workflow files with latest templates +- **THEN** the system SHALL display: "Updated: " + +#### Scenario: Update with no changes needed +- **WHEN** user runs `openspec update` +- **AND** installed workflows match global config +- **AND** all templates are current +- **AND** delivery setting matches installed files +- **THEN** the system SHALL display: "Already up to date." + +#### Scenario: Update summary output +- **WHEN** update completes with changes +- **THEN** the system SHALL display a summary: + - "Added: propose, explore" (new workflows installed) + - "Updated: apply, archive" (existing workflows refreshed) + - "Removed: 4 command files" (if delivery changed) +- **THEN** the system SHALL list affected tools: "Tools: Claude Code, Cursor" + +### Requirement: Update respects delivery setting +The update command SHALL add or remove files based on the delivery setting. + +#### Scenario: Delivery changed to skills-only +- **WHEN** user runs `openspec update` +- **AND** global config specifies `delivery: skills` +- **AND** project has command files installed +- **THEN** the system SHALL delete command files for workflows in the profile +- **THEN** the system SHALL generate/update skill files only +- **THEN** the system SHALL display: "Removed: command files (delivery: skills)" + +#### Scenario: Delivery changed to commands-only +- **WHEN** user runs `openspec update` +- **AND** global config specifies `delivery: commands` +- **AND** project has skill files installed +- **THEN** the system SHALL delete skill directories for workflows in the profile +- **THEN** the system SHALL generate/update command files only +- **THEN** the system SHALL display: "Removed: skill directories (delivery: commands)" + +#### Scenario: Delivery is both +- **WHEN** user runs `openspec update` +- **AND** global config specifies `delivery: both` +- **THEN** the system SHALL generate/update both skill and command files + +### Requirement: Extra workflows preserved +The update command SHALL NOT remove workflow files that aren't in the current profile. + +#### Scenario: Extra workflows from previous profile +- **WHEN** user runs `openspec update` +- **AND** project has workflows not in current profile (e.g., user switched from custom to core) +- **THEN** the system SHALL NOT delete those extra workflow files +- **THEN** the system SHALL only add/update workflows in the current profile +- **THEN** the system SHALL display a note: "Note: extra workflows not in profile (use `openspec config profile` to manage)" + +#### Scenario: Delivery change with extra workflows +- **WHEN** user runs `openspec update` +- **AND** delivery changed (e.g., `both` → `skills`) +- **AND** project has extra workflows not in current profile +- **THEN** the system SHALL delete files for extra workflows that match the removed delivery type +- **THEN** for example: if switching to `skills`, all command files are deleted (including for extra workflows) diff --git a/openspec/changes/simplify-skill-installation/specs/command-generation/spec.md b/openspec/changes/simplify-skill-installation/specs/command-generation/spec.md new file mode 100644 index 000000000..a5f3c62d2 --- /dev/null +++ b/openspec/changes/simplify-skill-installation/specs/command-generation/spec.md @@ -0,0 +1,37 @@ +## Purpose + +Command generation SHALL create CLI command files for workflows based on profile and delivery settings, enabling users to choose their preferred invocation method. + +## MODIFIED Requirements + +### Requirement: Conditional command generation +The command generation system SHALL respect profile and delivery settings. + +#### Scenario: Generate commands for profile workflows only +- **WHEN** generating commands with profile `core` +- **THEN** the system SHALL only generate commands for: `propose`, `explore`, `apply`, `archive` +- **THEN** the system SHALL NOT generate commands for workflows not in the profile + +#### Scenario: Skip command generation when delivery is skills-only +- **WHEN** generating with delivery set to `skills` +- **THEN** the system SHALL NOT generate any command files +- **THEN** the system SHALL only generate skill files + +#### Scenario: Generate commands when delivery is both or commands +- **WHEN** generating with delivery set to `both` or `commands` +- **THEN** the system SHALL generate command files for profile workflows + +### Requirement: Include propose command template +The command generation system SHALL include the new `propose` workflow template. + +#### Scenario: Propose command in templates +- **WHEN** getting command templates +- **THEN** the system SHALL include `propose` command template +- **THEN** the template SHALL generate command with id `propose` + +### Requirement: Command file naming for propose +The propose command SHALL follow existing naming conventions. + +#### Scenario: Propose command file path +- **WHEN** generating propose command for Claude Code +- **THEN** the file path SHALL be `.claude/commands/opsx/propose.md` diff --git a/openspec/changes/simplify-skill-installation/specs/delivery-config/spec.md b/openspec/changes/simplify-skill-installation/specs/delivery-config/spec.md new file mode 100644 index 000000000..888965872 --- /dev/null +++ b/openspec/changes/simplify-skill-installation/specs/delivery-config/spec.md @@ -0,0 +1,46 @@ +## Purpose + +Delivery configuration SHALL allow power users to control how workflows are installed (skills, commands, or both) without affecting the default experience for new users. + +## ADDED Requirements + +### Requirement: Delivery options +The system SHALL support three delivery methods: `both`, `skills`, and `commands`. + +#### Scenario: Both delivery +- **WHEN** delivery is set to `both` +- **THEN** the system SHALL install both skill files and command files for each workflow + +#### Scenario: Skills-only delivery +- **WHEN** delivery is set to `skills` +- **THEN** the system SHALL install only skill files (SKILL.md) for each workflow +- **THEN** the system SHALL NOT install command files + +#### Scenario: Commands-only delivery +- **WHEN** delivery is set to `commands` +- **THEN** the system SHALL install only command files for each workflow +- **THEN** the system SHALL NOT install skill files + +### Requirement: Delivery CLI commands +The system SHALL provide CLI commands for managing delivery preference. + +#### Scenario: Set delivery preference +- **WHEN** user runs `openspec config set delivery ` +- **THEN** the system SHALL update the global config delivery setting +- **THEN** the system SHALL output confirmation of the change + +#### Scenario: Get delivery preference +- **WHEN** user runs `openspec config get delivery` +- **THEN** the system SHALL display the current delivery setting +- **THEN** if delivery is not explicitly set, the system SHALL display "both (default)" + +#### Scenario: Invalid delivery value +- **WHEN** user runs `openspec config set delivery ` +- **THEN** the system SHALL display an error with valid options + +### Requirement: Delivery defaults +The system SHALL use `both` as the default delivery method. + +#### Scenario: No delivery config exists +- **WHEN** global config does not specify delivery +- **THEN** the system SHALL behave as if delivery is `both` diff --git a/openspec/changes/simplify-skill-installation/specs/profiles/spec.md b/openspec/changes/simplify-skill-installation/specs/profiles/spec.md new file mode 100644 index 000000000..0c73cfc4b --- /dev/null +++ b/openspec/changes/simplify-skill-installation/specs/profiles/spec.md @@ -0,0 +1,92 @@ +## Purpose + +Profiles SHALL define which workflows to install, enabling a streamlined core experience for new users while allowing power users to customize their workflow selection. + +## ADDED Requirements + +### Requirement: Profile definitions +The system SHALL support two workflow profiles: `core` and `custom`. + +#### Scenario: Core profile contents +- **WHEN** profile is set to `core` +- **THEN** the profile SHALL include workflows: `propose`, `explore`, `apply`, `archive` + +#### Scenario: Custom profile contents +- **WHEN** profile is set to `custom` +- **THEN** the profile SHALL include only the workflows specified in global config `workflows` array + +### Requirement: Delivery is independent of profile +The delivery setting controls HOW workflows are installed, separate from WHICH workflows are installed. + +#### Scenario: Core profile with custom delivery +- **WHEN** profile is set to `core` +- **AND** delivery is set to `skills` +- **THEN** the system SHALL install core workflows as skills only (no commands) + +#### Scenario: Delivery defaults +- **WHEN** delivery is not set in global config +- **THEN** the system SHALL default to `both` + +### Requirement: Profile configuration via interactive picker +The system SHALL provide an interactive picker for configuring profiles. + +#### Scenario: Interactive profile configuration +- **WHEN** user runs `openspec config profile` +- **THEN** the system SHALL display an interactive picker with: + - Delivery selection: `skills`, `commands`, `both` + - Workflow toggles for all available workflows +- **THEN** the system SHALL pre-select current config values +- **THEN** on confirmation, the system SHALL update global config +- **THEN** the system SHALL set profile to `custom` if user changes from core defaults +- **THEN** the system SHALL NOT modify any project files +- **THEN** the system SHALL display: "Config updated. Run `openspec update` in your projects to apply." + +#### Scenario: Core preset shortcut +- **WHEN** user runs `openspec config profile core` +- **THEN** the system SHALL set profile to `core` +- **THEN** the system SHALL set workflows to `['propose', 'explore', 'apply', 'archive']` +- **THEN** the system SHALL NOT change the delivery setting (preserves user preference) +- **THEN** the system SHALL NOT modify any project files +- **THEN** the system SHALL display: "Config updated. Run `openspec update` in your projects to apply." +- **THEN** the new profile takes effect on the next `openspec init` or `openspec update` run + +#### Scenario: Config profile run inside a project +- **WHEN** user runs `openspec config profile` inside an OpenSpec project directory +- **THEN** after updating global config, the system SHALL prompt: "Apply to this project now? (y/n)" +- **WHEN** user confirms +- **THEN** the system SHALL run `openspec update` automatically +- **THEN** the system SHALL still display: "Run `openspec update` in your other projects to apply." + +#### Scenario: Config profile - user declines apply +- **WHEN** user runs `openspec config profile` inside an OpenSpec project directory +- **AND** user declines the "Apply to this project now?" prompt +- **THEN** the system SHALL display: "Config updated. Run `openspec update` in your projects to apply." +- **THEN** the system SHALL exit successfully without modifying project files + +#### Scenario: Config profile non-interactive +- **WHEN** user runs `openspec config profile` non-interactively (e.g., in CI, no TTY) +- **THEN** the system SHALL display an error: "Interactive mode required. Use `openspec config profile core` or set config via environment/flags." +- **THEN** the system SHALL exit with code 1 + +### Requirement: Config is global, projects are explicit +Config changes do NOT automatically propagate to projects. + +#### Scenario: Config update does not modify projects +- **WHEN** user updates config via `openspec config profile` +- **THEN** the system SHALL only update global config (`~/.config/openspec/config.json`) +- **THEN** the system SHALL NOT modify any project skill/command files +- **THEN** existing projects retain their current workflow files until user runs `openspec update` + +### Requirement: Config changes applied via update command +The existing `openspec update` command applies the current global config to a project. See `specs/cli-update/spec.md` for detailed update behavior. + +### Requirement: Profile defaults +The system SHALL use `core` as the default profile for new users. + +#### Scenario: No global config exists +- **WHEN** global config file does not exist +- **THEN** the system SHALL behave as if profile is `core` + +#### Scenario: Global config exists but profile field absent +- **WHEN** global config file exists but does not contain a `profile` field +- **THEN** the system SHALL behave as if profile is `core` diff --git a/openspec/changes/simplify-skill-installation/specs/propose-workflow/spec.md b/openspec/changes/simplify-skill-installation/specs/propose-workflow/spec.md new file mode 100644 index 000000000..34bb6c8d8 --- /dev/null +++ b/openspec/changes/simplify-skill-installation/specs/propose-workflow/spec.md @@ -0,0 +1,41 @@ +## Purpose + +The propose workflow SHALL combine change creation and artifact generation into a single command, reducing friction for new users while teaching them the OpenSpec workflow through embedded guidance. + +## ADDED Requirements + +### Requirement: Propose workflow creation +The system SHALL provide a `propose` workflow that creates a change and generates all artifacts in one step. + +#### Scenario: Basic propose invocation +- **WHEN** user invokes `/opsx:propose "add user authentication"` +- **THEN** the system SHALL create a change directory with kebab-case name +- **THEN** the system SHALL generate all artifacts needed for implementation: proposal.md, design.md, specs/, tasks.md + +#### Scenario: Propose with existing change name +- **WHEN** user invokes `/opsx:propose` with a name that already exists +- **THEN** the system SHALL ask if user wants to continue existing change or create new +- **THEN** if "continue": the system SHALL resume artifact generation from last completed state +- **THEN** if "create new": the system SHALL prompt for a new name +- **THEN** in non-interactive mode: the system SHALL fail with error suggesting to use a different name + +### Requirement: Propose workflow onboarding UX +The `propose` workflow SHALL include explanatory output to help new users understand the process. + +#### Scenario: First-time user guidance +- **WHEN** user invokes `/opsx:propose` +- **THEN** the system SHALL explain what artifacts will be created (proposal.md, design.md, specs/, tasks.md) +- **THEN** the system SHALL indicate next step (`/opsx:apply` to implement) + +#### Scenario: Artifact creation progress +- **WHEN** the system creates each artifact +- **THEN** the system SHALL show progress (e.g., "✓ Created proposal.md") + +### Requirement: Propose workflow combines new and ff +The `propose` workflow SHALL perform the same operations as running `new` followed by `ff`. + +#### Scenario: Equivalent to new + ff +- **WHEN** user invokes `/opsx:propose "feature name"` +- **THEN** the result SHALL be functionally equivalent to invoking `/opsx:new "feature-name"` followed by `/opsx:ff feature-name` +- **THEN** the same directory structure and artifacts SHALL be created +- **THEN** console output MAY differ (propose includes onboarding explanations) diff --git a/openspec/changes/simplify-skill-installation/specs/skill-generation/spec.md b/openspec/changes/simplify-skill-installation/specs/skill-generation/spec.md new file mode 100644 index 000000000..b94557f1e --- /dev/null +++ b/openspec/changes/simplify-skill-installation/specs/skill-generation/spec.md @@ -0,0 +1,36 @@ +## Purpose + +Skill generation SHALL create skill files for workflows based on profile and delivery settings, supporting both the streamlined core profile and custom user configurations. + +## MODIFIED Requirements + +### Requirement: Conditional skill generation +The skill generation system SHALL respect profile and delivery settings. + +#### Scenario: Generate skills for profile workflows only +- **WHEN** generating skills with profile `core` +- **THEN** the system SHALL only generate skills for: `propose`, `explore`, `apply`, `archive` +- **THEN** the system SHALL NOT generate skills for workflows not in the profile + +#### Scenario: Skip skill generation when delivery is commands-only +- **WHEN** generating with delivery set to `commands` +- **THEN** the system SHALL NOT generate any skill files + +#### Scenario: Generate skills when delivery is both or skills +- **WHEN** generating with delivery set to `both` or `skills` +- **THEN** the system SHALL generate skill files for profile workflows + +### Requirement: Include propose skill template +The skill generation system SHALL include the new `propose` workflow template. + +#### Scenario: Propose skill in templates +- **WHEN** getting skill templates +- **THEN** the system SHALL include `openspec-propose` template +- **THEN** the template SHALL be in addition to templates listed in SKILL_NAMES constant + +### Requirement: Skill names constant update +The `SKILL_NAMES` constant SHALL include the propose workflow. + +#### Scenario: Updated skill names +- **WHEN** referencing `SKILL_NAMES` constant +- **THEN** it SHALL include `openspec-propose` in addition to existing names diff --git a/openspec/changes/simplify-skill-installation/specs/tool-selection-ux/spec.md b/openspec/changes/simplify-skill-installation/specs/tool-selection-ux/spec.md new file mode 100644 index 000000000..0ceaf4837 --- /dev/null +++ b/openspec/changes/simplify-skill-installation/specs/tool-selection-ux/spec.md @@ -0,0 +1,40 @@ +## Purpose + +Tool selection UX SHALL use industry-standard keybindings (space to toggle, enter to confirm) to reduce user confusion during initialization. + +## MODIFIED Requirements + +### Requirement: Multi-select keybindings +The tool selection prompt SHALL use standard keybindings for multi-select. + +#### Scenario: Toggle selection with space +- **WHEN** user presses Space key on a tool option +- **THEN** the system SHALL toggle the selection state of that option + +#### Scenario: Confirm selection with enter +- **WHEN** user presses Enter key +- **THEN** the system SHALL confirm the current selection and proceed + +#### Scenario: Navigate with arrow keys +- **WHEN** user presses Up or Down arrow keys +- **THEN** the system SHALL move the cursor to the previous or next option + +### Requirement: Remove tab-to-confirm behavior +The tool selection prompt SHALL NOT use Tab to confirm selection. + +#### Scenario: Tab key behavior +- **WHEN** user presses Tab key +- **THEN** the system SHALL NOT confirm selection +- **THEN** the system MAY move focus or do nothing (implementation-dependent) + +### Requirement: Selection feedback +The tool selection prompt SHALL clearly indicate selected and unselected states. + +#### Scenario: Visual feedback +- **WHEN** displaying tool options +- **THEN** selected options SHALL show a filled checkbox (e.g., `[x]`) +- **THEN** unselected options SHALL show an empty checkbox (e.g., `[ ]`) + +#### Scenario: Help text +- **WHEN** displaying the selection prompt +- **THEN** the system SHALL show hint text: "Space to toggle, Enter to confirm" diff --git a/openspec/changes/simplify-skill-installation/specs/user-config/spec.md b/openspec/changes/simplify-skill-installation/specs/user-config/spec.md new file mode 100644 index 000000000..3d1d76024 --- /dev/null +++ b/openspec/changes/simplify-skill-installation/specs/user-config/spec.md @@ -0,0 +1,43 @@ +## Purpose + +User configuration SHALL extend the existing global config to store profile and delivery preferences, enabling persistent customization across projects. + +## MODIFIED Requirements + +### Requirement: Global configuration storage (EXTENDS existing) +The system SHALL store profile, delivery, and workflows settings in the existing global config file alongside telemetry and feature flags. + +#### Scenario: Profile config structure +- **WHEN** reading or writing profile configuration +- **THEN** the config contains `profile` (string: core|custom), `delivery` (string: both|skills|commands), and optionally `workflows` (array of strings) + +#### Scenario: Schema evolution for new fields +- **WHEN** loading config without profile/delivery fields +- **THEN** the system SHALL use defaults: profile=core, delivery=both +- **AND** existing telemetry/featureFlags fields SHALL be preserved + +#### Scenario: Custom profile with workflows +- **WHEN** config contains `profile: "custom"` +- **THEN** the system SHALL read the `workflows` array for the list of enabled workflows +- **AND** if `workflows` is missing, SHALL treat as empty array + +## ADDED Requirements + +### Requirement: Profile config defaults +The system SHALL use sensible defaults when profile settings are missing. + +#### Scenario: Missing profile field +- **WHEN** config file exists but has no `profile` field +- **THEN** the system SHALL behave as if `profile: "core"` + +#### Scenario: Missing delivery field +- **WHEN** config file exists but has no `delivery` field +- **THEN** the system SHALL behave as if `delivery: "both"` + +### Requirement: Config list shows profile settings +The `openspec config list` command SHALL display profile and delivery settings. + +#### Scenario: List all config with profile +- **WHEN** user runs `openspec config list` +- **THEN** the system SHALL display profile, delivery, and workflows settings +- **AND** SHALL indicate which values are defaults vs explicitly set diff --git a/openspec/changes/simplify-skill-installation/tasks.md b/openspec/changes/simplify-skill-installation/tasks.md new file mode 100644 index 000000000..7d586e645 --- /dev/null +++ b/openspec/changes/simplify-skill-installation/tasks.md @@ -0,0 +1,108 @@ +## 1. Global Config Extension + +- [ ] 1.1 Extend `src/core/global-config.ts` schema with `profile`, `delivery`, and `workflows` fields +- [ ] 1.2 Add TypeScript types for profile (`core` | `custom`), delivery (`both` | `skills` | `commands`), and workflows (string array) +- [ ] 1.3 Update `GlobalConfig` interface and defaults (profile=`core`, delivery=`both`) +- [ ] 1.4 Update existing `readGlobalConfig()` to handle missing new fields with defaults +- [ ] 1.5 Add tests for schema evolution (existing config without new fields) + +## 2. Profile System + +- [ ] 2.1 Create `src/core/profiles.ts` with profile definitions (core, custom) +- [ ] 2.2 Define `CORE_WORKFLOWS` constant: `['propose', 'explore', 'apply', 'archive']` +- [ ] 2.3 Define `ALL_WORKFLOWS` constant with all 11 workflows +- [ ] 2.4 Add `COMMAND_IDS` constant to `src/core/shared/tool-detection.ts` (parallel to existing SKILL_NAMES) +- [ ] 2.5 Implement `getProfileWorkflows(profile, customWorkflows?)` resolver function +- [ ] 2.6 Add tests for profile resolution + +## 3. Config Profile Command (Interactive Picker) + +- [ ] 3.1 Add `config profile` subcommand to `src/commands/config.ts` +- [ ] 3.2 Implement interactive picker UI with delivery selection (skills/commands/both) +- [ ] 3.3 Implement interactive picker UI with workflow toggles +- [ ] 3.4 Pre-select current config values in picker +- [ ] 3.5 Update global config on confirmation (config-only, no file regeneration) +- [ ] 3.6 Display post-update message: "Config updated. Run `openspec update` in your projects to apply." +- [ ] 3.7 Detect if running inside an OpenSpec project and offer to run update automatically +- [ ] 3.8 Implement `config profile core` preset shortcut (preserves delivery setting) +- [ ] 3.9 Handle non-interactive mode: error with helpful message +- [ ] 3.10 Add tests for config profile command + +## 4. Available Tools Detection + +- [ ] 4.1 Create `src/core/available-tools.ts` (separate from existing `tool-detection.ts`) +- [ ] 4.2 Implement `getAvailableTools(projectPath)` that scans for AI tool directories (`.claude/`, `.cursor/`, etc.) +- [ ] 4.3 Use `AI_TOOLS` config to map directory names to tool IDs +- [ ] 4.4 Add tests for available tools detection including cross-platform paths + +## 5. Propose Workflow Template + +- [ ] 5.1 Create `src/core/templates/workflows/propose.ts` +- [ ] 5.2 Implement skill template that combines new + ff behavior +- [ ] 5.3 Add onboarding-style explanatory output to template +- [ ] 5.4 Implement command template for propose +- [ ] 5.5 Export templates from `src/core/templates/skill-templates.ts` +- [ ] 5.6 Add `openspec-propose` to `SKILL_NAMES` in `src/core/shared/tool-detection.ts` +- [ ] 5.7 Add `propose` to command templates in `src/core/shared/skill-generation.ts` +- [ ] 5.8 Add `propose` to `COMMAND_IDS` in `src/core/shared/tool-detection.ts` + +## 6. Conditional Skill/Command Generation + +- [ ] 6.1 Update `getSkillTemplates()` to accept profile filter parameter +- [ ] 6.2 Update `getCommandTemplates()` to accept profile filter parameter +- [ ] 6.3 Update `generateSkillsAndCommands()` in init.ts to respect delivery setting +- [ ] 6.4 Add logic to skip skill generation when delivery is 'commands' +- [ ] 6.5 Add logic to skip command generation when delivery is 'skills' +- [ ] 6.6 Add tests for conditional generation + +## 7. Init Flow Updates + +- [ ] 7.1 Update init to call `getAvailableTools()` first +- [ ] 7.2 Update init to read global config for profile/delivery defaults +- [ ] 7.3 Change tool selection to show pre-selected detected tools +- [ ] 7.4 Update success message to show `/opsx:propose` prompt +- [ ] 7.5 Add `--profile` flag to override global config +- [ ] 7.6 Update non-interactive mode to use defaults without prompting +- [ ] 7.7 Add tests for init flow with various scenarios + +## 8. Update Command (Profile Support) + +- [ ] 8.1 Modify existing `src/commands/update.ts` to read global config for profile/delivery/workflows +- [ ] 8.2 Add logic to detect which workflows are in config but not installed (to add) +- [ ] 8.3 Add logic to detect which workflows are installed and need refresh (to update) +- [ ] 8.4 Respect delivery setting: generate only skills if `skills`, only commands if `commands` +- [ ] 8.5 Delete files when delivery changes: remove commands if `skills`, remove skills if `commands` +- [ ] 8.6 Generate new workflow files for missing workflows in profile +- [ ] 8.7 Display summary: "Added: X, Y" / "Updated: Z" / "Removed: N files" / "Already up to date." +- [ ] 8.8 List affected tools in output: "Tools: Claude Code, Cursor" +- [ ] 8.9 Add tests for update command with profile scenarios (including delivery changes) + +## 9. Tool Selection UX Fix + +- [ ] 9.1 Update `src/prompts/searchable-multi-select.ts` keybindings +- [ ] 9.2 Change Space to toggle selection +- [ ] 9.3 Change Enter to confirm selection +- [ ] 9.4 Remove Tab-to-confirm behavior +- [ ] 9.5 Add hint text "Space to toggle, Enter to confirm" +- [ ] 9.6 Add tests for keybinding behavior + +## 10. Scaffolding Verification + +- [ ] 10.1 Verify `openspec new change` creates `.openspec.yaml` with schema and created fields + + + + + +## 11. Explore Workflow Updates + +- [ ] 11.1 Update `src/core/templates/workflows/explore.ts` to reference `/opsx:propose` instead of `/opsx:new` and `/opsx:ff` +- [ ] 11.2 Update explore's "next steps" summary to show single propose path +- [ ] 11.3 Review explore → propose transition UX (see `openspec/explorations/explore-workflow-ux.md` for open questions) + +## 12. Integration & Documentation + +- [ ] 12.1 Run full test suite and fix any failures +- [ ] 12.2 Test on Windows (or verify CI passes on Windows) +- [ ] 12.3 Test end-to-end flow: init → propose → apply → archive +- [ ] 12.4 Update CLI help text for new commands diff --git a/openspec/config.yaml b/openspec/config.yaml index 83ed33952..ec9f5bca2 100644 --- a/openspec/config.yaml +++ b/openspec/config.yaml @@ -16,9 +16,14 @@ rules: specs: - Include scenarios for Windows path handling when dealing with file paths - Requirements involving paths must specify cross-platform behavior + - Be explicit about mechanisms, not just outcomes (say HOW, not just WHAT) + - If we generate artifacts, specify deletion/modification by explicit list lookup, not pattern matching tasks: - Add Windows CI verification as a task when changes involve file paths - Include cross-platform testing considerations design: - Document any platform-specific behavior or limitations - Prefer Node.js path module over string manipulation for paths + - Use existing constants and lists - don't invent detection mechanisms + - Prefer explicit lookups over pattern matching or regex + - If we generate it, we track it by name in a constant diff --git a/openspec/explorations/explore-workflow-ux.md b/openspec/explorations/explore-workflow-ux.md new file mode 100644 index 000000000..bca7f59a0 --- /dev/null +++ b/openspec/explorations/explore-workflow-ux.md @@ -0,0 +1,103 @@ +# Explore Workflow UX + +## Context + +The explore workflow is part of the core loop (`propose`, `explore`, `apply`, `archive`). Users should be able to think through ideas in explore mode, then smoothly transition into a formal change proposal. + +Currently, explore references `/opsx:new` and `/opsx:ff` which are being replaced with `/opsx:propose`. But beyond just updating references, there are deeper UX questions about how explore should work. + +## Open Questions + +### Exploration Artifacts + +1. **Should exploration be exportable to .md?** + - Currently explorations are ephemeral (just conversation) + - Would users benefit from saving exploration notes? + +2. **Where should exploration files live?** + - `openspec/explorations/.md`? + - `openspec/changes//explorations/`? + - Somewhere else? + +3. **What should the format be?** + - Free-form markdown? + - Structured template (problem, insights, open questions)? + - Conversation transcript? + +### Multiple Explorations + +4. **Can a user have multiple explorations related to a change?** + - e.g., exploring auth approaches separately from UI approaches + - How would these relate to each other? + +5. **How do explorations relate to changes?** + - Before change exists: standalone exploration + - After change exists: exploration linked to change? + +### Lifecycle & Transitions + +6. **What happens before a change proposal exists?** + - Exploration is standalone + - When ready, user runs `/opsx:propose` + - Should exploration context automatically seed the proposal? + +7. **What happens after a change proposal exists?** + - Exploration can reference existing artifacts + - Should exploration be able to update artifacts directly? + - Or just inform the user what to update? + +8. **How does explore → propose transition work?** + - Manual: user copies insights and runs propose separately + - Semi-auto: explore offers "Create proposal from this exploration?" + - Auto: explore detects crystallization and proactively starts propose + +### Context Handoff + +9. **How do exploration insights flow into proposals?** + - User manually incorporates insights + - Exploration summary becomes input to propose prompt + - Exploration file linked/referenced in proposal + +10. **Should propose be able to read exploration files?** + - "I see you explored authentication approaches. Using those insights..." + +## Potential Approaches + +### Approach A: Ephemeral Explorations (Status Quo+) +- Explorations remain conversational only +- Just update references to `/opsx:propose` +- User manually carries insights forward +- **Pro:** Simple, no new artifacts +- **Con:** Insights can be lost, no audit trail + +### Approach B: Optional Export +- Add "save exploration" option at end +- Saves to `openspec/explorations/.md` +- Propose can optionally read these for context +- **Pro:** Opt-in complexity, preserves insights +- **Con:** Another artifact type to manage + +### Approach C: Exploration as Proposal Seed +- Exploration automatically saves structured notes +- When transitioning to propose, notes become proposal input +- **Pro:** Seamless handoff, context preserved +- **Con:** More complexity, tight coupling + +### Approach D: Explorations Within Changes +- Before change: standalone exploration +- After change created: exploration notes live in `changes//explorations/` +- Artifacts can reference exploration notes +- **Pro:** Clear relationship to changes +- **Con:** Where do pre-change explorations go? + +## Next Steps + +- [ ] User research: How do people actually use explore today? +- [ ] Prototype: Try saving explorations and see if propose benefits +- [ ] Decide: Pick an approach based on findings +- [ ] Implement: Update explore workflow accordingly + +## Related + +- `openspec/changes/simplify-skill-installation/` - current change updating core workflows +- `src/core/templates/workflows/explore.ts` - explore workflow template diff --git a/openspec/explorations/workspace-architecture.md b/openspec/explorations/workspace-architecture.md new file mode 100644 index 000000000..f9ac81821 --- /dev/null +++ b/openspec/explorations/workspace-architecture.md @@ -0,0 +1,681 @@ +# Workspace Exploration + +## Context + +While simplifying skill installation, we identified deeper questions about how profiles, config, and workspaces should work together. This doc captures what we've decided, what's open, and what needs research. + +**Update:** Initial exploration revealed that "workspaces" isn't primarily about config layering—it's about a more fundamental question: **where do specs and changes live when work spans multiple modules or repositories?** + +--- + +## Part 1: Profile & Config (Original Scope) + +### What We've Decided + +#### Profile UX (Simplified) + +**Before (original proposal):** +``` +openspec profile set core|extended +openspec profile install +openspec profile uninstall +openspec profile list +openspec profile show +openspec config set delivery skills|commands|both +openspec config get delivery +openspec config list +``` +8 subcommands, two concepts (profile + config) + +**After (simplified):** +``` +openspec config profile # interactive picker (delivery + workflows) +openspec config profile core # preset shortcut +openspec config profile extended # preset shortcut +``` +1 command with presets, one concept + +#### Interactive Picker + +``` +$ openspec config profile + +Delivery: [skills] [commands] [both] + ^^^^^^ + +Workflows: (space to toggle, enter to save) +[x] propose +[x] explore +[x] apply +[x] archive +[ ] new +[ ] ff +[ ] continue +[ ] verify +[ ] sync +[ ] bulk-archive +[ ] onboard +``` + +One place to configure both delivery method and workflow selection. + +#### Why "Profile" (Not "Workflows") + +Profiles as an abstraction allow for future extensibility: +- Methodology bundles (spec-driven, test-driven) +- User-created profiles +- Shareable profiles +- Different skill/command sets for different approaches + +### Config Layering Research + +We researched how similar tools handle config layering: + +| Tool | Model | Key Pattern | +|------|-------|-------------| +| **VSCode** | User → Workspace → Folder | Objects merge, primitives override. Workspace = committed `.vscode/` in repo | +| **ESLint (flat)** | Single root config | *Deliberately killed cascading* - "complexity exploded exponentially" | +| **Turborepo** | Root + package extends | Per-package `turbo.json` with `extends: ["//"]` for overrides | +| **Nx** | Integrated vs Package-based | Two modes - shared root OR per-package. Hard to migrate from integrated. | +| **pnpm** | Workspace root defines scope | `pnpm-workspace.yaml` at root. Dependencies can be shared or per-package | +| **Claude Code** | Global + Project | `~/.claude/` for global, `.claude/` per-project. No workspace tracking. | +| **Kiro** | Distributed per-root | Each folder has `.kiro/`. Aggregated display, no inheritance. | + +**Key insight from ESLint:** The ESLint team explicitly removed cascading in flat config because cascading was a complexity nightmare. Their new model: one config at root, use glob patterns to target subdirectories. + +**Recommendation for profiles/config:** Two layers is enough. +- **Global** = user's defaults (`~/.config/openspec/`) +- **Project** = repo-level config (`.openspec/` or committed to repo) + +No "workspace" layer needed for config. This matches Claude Code's model. + +### Config Decision (For This Change) + +Keep it simple: +1. Global profile as default for `openspec init` +2. `openspec init` applies current profile to project +3. No workspace tracking (yet) +4. No auto-sync of existing projects + +This is explicit and doesn't prevent future features. + +--- + +## Part 2: The Deeper Problem (Spec & Change Organization) + +### The Real Question + +The workspace question isn't about config—it's about **where specs and changes live** when: + +1. **Monorepos**: A spec or change might span multiple packages/apps +2. **Multi-repo**: A change might span multiple repositories entirely +3. **Cross-functional work**: A feature affects multiple teams (backend, web, iOS, Android) + +### Current OpenSpec Architecture + +OpenSpec currently assumes: +- One `openspec/` per repo, always at root +- CLI doesn't walk up directories—expects you're at root +- Changes can touch ANY spec (no scoping) +- Single config applies to everything +- No notion of "scope" or "boundary" within a project + +``` +openspec/ +├── specs/ +│ ├── auth/spec.md # Domain-organized specs +│ ├── payments/spec.md +│ └── checkout/spec.md +├── changes/ +│ └── add-oauth/ +│ ├── proposal.md +│ ├── design.md +│ ├── tasks.md +│ └── specs/ # Delta specs (can touch multiple) +│ ├── auth/spec.md +│ └── checkout/spec.md +└── config.yaml +``` + +**This works well for single-project repos.** But what about: +- Large monorepos with 50+ packages? +- Multi-repo microservices? +- Cross-functional features spanning multiple teams? + +### The Checkout/Payment Example + +Imagine a payment system with: +- **Backend billing team**: Owns payment processing +- **Web team**: Owns web checkout UX +- **iOS team**: Owns iOS checkout UX +- **Android team**: Owns Android checkout UX +- **Cross-cutting**: The payment *contract* all clients must follow + +**Questions:** +- Where does the shared payment contract spec live? +- Where do platform-specific checkout specs live? +- If iOS spec "extends" the shared contract, how is that expressed? +- When the contract changes, how do downstream specs get updated? +- Who owns what? + +### The Core Tension + +``` + SCOPE + │ + Narrow │ Broad + (team/module) │ (cross-cutting) + │ + ┌─────────────────┼─────────────────┐ + │ │ │ + │ "Our team's │ "Shared │ + │ checkout │ checkout │ + │ behavior" │ contract" │ + │ │ │ +────┼─────────────────┼─────────────────┼──── OWNERSHIP + │ │ │ + │ Easy: │ Hard: │ + │ One team, │ Multiple │ + │ one spec │ stakeholders │ + │ │ │ + └─────────────────┴─────────────────┘ +``` + +--- + +## Part 3: How Other Domains Solve This + +### Patterns from Research + +| Domain | Shared Stuff | Specific Stuff | How They Connect | +|--------|-------------|----------------|------------------| +| **Protobuf** | `common/` at root | `domain/service/` per service | Imports from common | +| **Design Systems** | Design tokens, component names, APIs | Platform implementations | "Same properties, different rendering" | +| **DDD** | Shared Kernel | Bounded Contexts | Context mapping defines relationships | +| **RFCs** | Cross-cutting RFCs | Team-scoped RFCs | Different review processes | +| **OpenAPI** | Base schemas | Per-service specs | `$ref` to shared definitions | + +### Protobuf Monorepo Pattern + +``` +proto/ +├── common/ # Shared, low-churn types +│ └── money.proto +│ └── address.proto +├── billing/ # Domain-specific +│ └── service.proto +└── checkout/ + └── service.proto # Imports from common/ +``` + +**Key insight:** "Most engineering organizations should keep their proto files in one repo. The mental overhead stays constant instead of scaling with organization size." + +### Design Systems Pattern (Booking.com, Uber) + +> "Components can look quite different between iOS and Android, as they use native app design standards, but still share the **same exact properties in code**. This is what makes properties so powerful—it's the **one source of truth** for every component." + +**Key insight:** Shared spec defines the *contract* (properties, behavior). Platform specs define *implementation details* (how it looks/works on that platform). + +### DDD Bounded Contexts + +> "One context, one team. Clear ownership avoids miscommunication." + +**Key insight:** Specs should have clear ownership. Cross-cutting concerns use a "Shared Kernel" pattern—explicitly shared code/specs that require coordination to change. + +--- + +## Part 4: Three Models for OpenSpec + +### Model A: Flat Root (Current) + +``` +openspec/ +├── specs/ +│ ├── checkout-contract/ # Shared contract +│ ├── checkout-web/ # Web-specific +│ ├── checkout-ios/ # iOS-specific +│ ├── checkout-android/ # Android-specific +│ ├── billing/ # Backend +│ └── ... (50+ specs at root level) +└── changes/ +``` + +**Pros:** +- Simple mental model +- All specs in one place +- No nesting complexity + +**Cons:** +- Gets unwieldy at scale (50+ directories) +- No clear ownership signals +- Hard to see which specs are related +- Naming conventions become critical (`checkout-*`) + +### Model B: Nested Specs (Domain → Platform) + +``` +openspec/ +├── specs/ +│ ├── checkout/ +│ │ ├── spec.md # Shared contract (the "interface") +│ │ ├── web/spec.md # Web implementation spec +│ │ ├── ios/spec.md # iOS implementation spec +│ │ └── android/spec.md # Android implementation spec +│ └── billing/ +│ └── spec.md +└── changes/ +``` + +**Pros:** +- Clear hierarchy (shared at top, specific nested) +- Related specs are co-located +- Scales better visually +- Ownership can follow structure + +**Cons:** +- More complex spec references (`checkout/web` vs `checkout`) +- Need to define inheritance/extension semantics +- Does iOS spec "extend" base spec, or just reference it? + +**Open question:** What does "extends" mean? +```yaml +# checkout/ios/spec.md +extends: ../spec.md # Inherits all requirements? +requirements: + - System SHALL support Apple Pay # Adds to base? +``` + +### Model C: Distributed Specs (Near the Code) + +``` +monorepo/ +├── services/ +│ └── billing/ +│ └── openspec/specs/billing/spec.md +├── clients/ +│ ├── web/ +│ │ └── openspec/specs/checkout/spec.md +│ ├── ios/ +│ │ └── openspec/specs/checkout/spec.md +│ └── android/ +│ └── openspec/specs/checkout/spec.md +└── openspec/ # Root-level for cross-cutting + ├── specs/ + │ └── checkout-contract/spec.md # Shared contract + └── changes/ # Where do cross-cutting changes live? +``` + +**Pros:** +- Specs live near the code they describe +- Teams own their specs naturally +- Works for multi-repo too (each repo has its own `openspec/`) + +**Cons:** +- Cross-cutting specs are awkward (where do they go?) +- Changes that span multiple `openspec/` directories = ??? +- Need a "workspace" concept to aggregate +- Multiple `openspec/` roots to manage + +### Model D: Hybrid (Model B Inside Each Project + Model C Across Projects) + +Use one `openspec/` root per project, but allow nested specs within that root for clear ownership and shared contracts. +For multi-repo work, use a workspace manifest to coordinate multiple projects without duplicating canonical specs. + +**Monorepo shape (single project, nested specs):** +``` +repo/ +└── openspec/ + ├── specs/ + │ ├── contracts/ + │ │ └── checkout/spec.md + │ ├── billing/ + │ │ └── spec.md + │ └── checkout/ + │ ├── web/spec.md + │ ├── ios/spec.md + │ └── android/spec.md + └── changes/ + └── add-3ds/ + ├── proposal.md + ├── design.md + ├── tasks.md + └── specs/ + ├── contracts/checkout/spec.md + ├── billing/spec.md + ├── checkout/web/spec.md + ├── checkout/ios/spec.md + └── checkout/android/spec.md +``` + +**Multi-repo shape (multiple projects + workspace orchestration):** +``` +~/work/ +├── contracts/ +│ └── openspec/ +│ ├── specs/checkout/spec.md +│ └── changes/add-3ds-contract/ +├── billing-service/ +│ └── openspec/ +│ ├── specs/billing/spec.md +│ └── changes/add-3ds-billing/ +├── web-client/ +│ └── openspec/ +│ ├── specs/checkout/spec.md +│ └── changes/add-3ds-web/ +├── ios-client/ +│ └── openspec/ +│ ├── specs/checkout/spec.md +│ └── changes/add-3ds-ios/ +└── payments-workspace/ + └── .openspec-workspace/ + ├── workspace.yaml + └── initiatives/add-3ds/links.yaml +``` + +`workspace.yaml` lists projects/roots. `links.yaml` maps one cross-cutting initiative to per-project changes. +Canonical specs stay in owning repos; workspace data is coordination metadata only. + +**Pros:** +- Clear ownership boundaries (one project owns its specs and changes) +- Shared contracts can have a dedicated owner repo (no duplication as source of truth) +- Works for monorepo and multi-repo with one mental model +- Avoids inheritance complexity (relationships can start as explicit references) +- Incremental migration path from current model + +**Cons:** +- Requires new workspace UX for cross-repo coordination +- Cross-repo feature work creates multiple change IDs to manage +- Needs conventions for contracts ownership and initiative linking +- Some users may expect one global "mega change" instead of linked per-project changes +- Tooling must support nested spec paths in both main specs and change deltas + +--- + +## Part 5: Multi-Repo Considerations + +For multi-repo setups, Model C (or the coordination half of Model D) is almost forced: + +``` +~/work/ +├── billing-service/ +│ └── openspec/specs/billing/ +├── web-client/ +│ └── openspec/specs/checkout/ +├── ios-client/ +│ └── openspec/specs/checkout/ +└── contracts/ # Dedicated repo for shared specs? + └── openspec/specs/ + └── checkout-contract/ +``` + +### Questions for Multi-Repo + +1. **Where do shared specs live?** + - Dedicated "contracts" repo? + - Duplicated in each repo (drift risk)? + - One repo is "source of truth" and others reference it? + +2. **Where do cross-repo changes live?** + - In one of the repos? (feels wrong—biased ownership) + - In a separate "workspace" repo? + - In `~/.config/openspec/workspaces/my-platform/changes/`? + +3. **How do changes propagate?** + - Change to `checkout-contract` affects all client repos + - Do we need explicit dependency tracking? + - Or is this "out of band" (teams coordinate manually)? + +### What "Workspace" Might Mean for Multi-Repo + +If we add workspace support, it could be: + +> **A workspace is a collection of OpenSpec roots that can be operated on together.** + +```yaml +# ~/.config/openspec/workspaces.yaml (or similar) +workspaces: + my-platform: + roots: + - ~/work/billing-service + - ~/work/web-client + - ~/work/ios-client + - ~/work/contracts + shared_context: | + All services use TypeScript. + API contracts follow OpenAPI 3.1. +``` + +This would enable: +1. **Cross-repo changes**: Create a change that tracks deltas across multiple roots +2. **Aggregated spec view**: See all specs across workspace +3. **Shared context**: Context/rules that apply to all roots + +--- + +## Part 6: Key Design Questions + +### 1. Should specs be hierarchical (with inheritance)? + +**Option A: No inheritance, just organization** +- Nested directories are purely organizational +- Each spec is independent +- Relationships are implicit (naming) or documented manually + +**Option B: Explicit inheritance** +```yaml +# checkout/ios/spec.md +extends: ../spec.md +requirements: + - System SHALL support Apple Pay # Adds to base +``` +- Child specs inherit parent requirements +- Can add, override, or extend +- More powerful but more complex + +**Option C: References without inheritance** +```yaml +# checkout/ios/spec.md +references: + - ../spec.md # "See also" but no inheritance +requirements: + - System SHALL implement checkout per checkout-contract + - System SHALL support Apple Pay +``` +- Explicit references for documentation +- No automatic inheritance +- Simpler semantics + +### 2. Where does the "shared kernel" live? + +**Option A: Root level (Model B)** +- `openspec/specs/checkout/spec.md` is the shared kernel +- Platform specs nest under it + +**Option B: Dedicated area** +- `openspec/specs/_shared/checkout-contract/spec.md` +- Or `openspec/specs/_contracts/checkout/spec.md` +- Explicit "shared" namespace + +**Option C: Separate repo (Model C for multi-repo)** +- A dedicated `contracts` or `specs` repo +- Other repos reference it + +### 3. What's a "workspace" vs a "project"? + +If we introduce workspaces: + +| Concept | Definition | +|---------|------------| +| **Project** | Single OpenSpec root (one `openspec/` directory) | +| **Workspace** | Collection of projects that can be operated on together | + +A workspace would enable: +- Aggregated spec viewing across projects +- Cross-project changes +- Shared context across projects + +**Question:** Do we need explicit workspace tracking, or just ad-hoc multi-root (like Claude Code's `/add-dir`)? + +### 4. Does OpenSpec need to understand dependencies? + +If `checkout-web` depends on `checkout-contract`: +- Should OpenSpec know this relationship? +- Should a change to `checkout-contract` warn about downstream specs? +- Or is dependency tracking "out of scope"? + +**Trade-off:** +- With dependency tracking: More powerful, automatic propagation warnings +- Without: Simpler, teams manage dependencies themselves + +### 5. How should changes work for cross-cutting work? + +**For monorepos (Model B):** +- One change, multiple delta specs in `specs/` +- Already works today + +**For multi-repo (Model C):** +- Option A: One "workspace change" that references multiple repo changes +- Option B: Separate changes in each repo that reference each other +- Option C: Changes always live in one repo, reference specs in others + +--- + +## Part 7: What Would "Amazing" Look Like? + +Based on research, teams love: + +1. **One place to look** (Protobuf: "mental overhead stays constant") +2. **Clear ownership** (DDD: "one context, one team") +3. **Shared contracts with local extensions** (Design Systems: "same properties, different rendering") +4. **Automatic consistency** (Design Systems: "design tokens as foundation") +5. **Low cognitive load** (shouldn't have to think about organization too much) + +### Possible North Stars + +**Ambitious:** +> OpenSpec automatically understands your repo structure, detects cross-cutting specs, and helps you create changes that flow to the right places. + +**Simpler:** +> You organize specs however you want. OpenSpec just works. + +**Practical:** +> Nested specs for organization. Explicit dependencies for cross-cutting. No magic. + +--- + +## Part 8: Possible Paths Forward + +### For This Change (simplify-skill-installation) + +Don't solve spec organization now. Keep scope to: +1. Profile UX simplification +2. `openspec init` improvements +3. No workspace tracking yet + +### Future: Spec Organization Change + +A separate change to explore and implement: + +1. **Decide on Model A, B, C, or D (hybrid)** +2. **Decide on inheritance semantics** (or none) +3. **Update spec resolution** to handle nesting +4. **Update change deltas** to handle nested specs + +### Future: Multi-Repo / Workspace Change + +If needed, a separate change for: + +1. **Define workspace concept** +2. **Implement workspace tracking** (or ad-hoc multi-root) +3. **Cross-repo changes** +4. **Shared context across repos** + +--- + +## Part 9: Spec Philosophy (Behavior First, Lightweight, Agent-Aligned) + +### What is a spec in OpenSpec? + +For OpenSpec, a spec should be treated as a **verifiable behavior contract at a boundary**: +- What users, integrators, or operators can observe and rely on +- What can be validated with tests, checks, or explicit review +- What should remain stable even if internal implementation changes + +### What should and should not be in specs + +**Include:** +- Observable behavior and outcomes +- Interface/data contracts (inputs, outputs, error conditions) +- Non-functional constraints that matter externally (privacy, security, reliability) +- Compatibility guarantees that downstream consumers depend on + +**Avoid:** +- Internal implementation details (class names, library choices, control flow) +- Tooling mechanics that can change without affecting behavior +- Step-by-step execution plans (belongs in tasks/design) + +### Keep rigor proportional (to avoid bureaucracy) + +Use progressive rigor: + +1. **Lite spec (default for most changes)** + - Short behavior bullets, clear scope, and acceptance checks +2. **Full spec (only for high-risk or cross-boundary work)** + - Deeper contract detail for API breaks, migrations, security/privacy, or cross-team/repo changes + +This keeps day-to-day usage lightweight while preserving clarity where failures are expensive. + +### Human exploration -> agent-authored specs + +OpenSpec is often agent-authored from human exploration. To make that reliable: + +- Humans provide intent, constraints, and examples from exploration +- Agents convert that into concise, behavior-first requirements and scenarios +- Agents keep implementation detail in design/tasks, not specs +- Validation checks enforce structure and testability + +In short: humans shape intent; agents produce consistent, verifiable contracts. + +### Where this philosophy should live + +To avoid losing this in exploration notes, codify it in: +1. `docs/concepts.md` for human-facing framing +2. `openspec/specs/openspec-conventions/spec.md` for normative spec conventions +3. `openspec/specs/docs-agent-instructions/spec.md` for agent-instruction authoring rules + +--- + +## Summary + +| Question | Status | Notes | +|----------|--------|-------| +| Profile UX | Decided | `openspec config profile` with presets | +| Config layering | Decided | Two layers: global + project (no workspace layer) | +| Spec organization | Open | Four models under consideration (including hybrid Model D) | +| Spec philosophy | Direction set | Behavior-first contracts, progressive rigor, and agent-aligned authoring | +| Spec inheritance | Open | Inheritance vs references vs none | +| Multi-repo support | Open | Workspace concept TBD | +| Dependency tracking | Open | Probably out of scope initially | + +### Key Insight + +The "workspace" question is really two separate questions: +1. **Config/profile scope** → Solved with global + project (no workspace needed) +2. **Spec/change organization** → Unsolved, needs deeper design work + +These should be separate changes with separate explorations. + +--- + +## References + +- [VSCode Settings Precedence](https://code.visualstudio.com/docs/configure/settings) +- [ESLint Flat Config in Monorepos Discussion](https://github.com/eslint/eslint/discussions/16960) +- [Turborepo Package Configurations](https://turborepo.dev/docs/reference/package-configurations) +- [pnpm Workspaces](https://pnpm.io/workspaces) +- [Claude Code Settings](https://code.claude.com/docs/en/settings) +- [Kiro Multi-Root Workspaces](https://kiro.dev/docs/editor/multi-root-workspaces/) +- [DDD Bounded Context](https://martinfowler.com/bliki/BoundedContext.html) +- [Protobuf Monorepo Patterns](https://www.lesswrong.com/posts/xts8dC3NeTHwqYgCG/keep-your-protos-in-one-repo) +- [Booking.com Multi-Platform Design System](https://booking.design/how-we-built-our-multi-platform-design-system-at-booking-com-d7b895399d40) +- [InnerSource RFC Patterns](https://patterns.innersourcecommons.org/p/transparent-cross-team-decision-making-using-rfcs) diff --git a/openspec/specs/docs-agent-instructions/spec.md b/openspec/specs/docs-agent-instructions/spec.md index 1c1929103..8f2931fbd 100644 --- a/openspec/specs/docs-agent-instructions/spec.md +++ b/openspec/specs/docs-agent-instructions/spec.md @@ -37,3 +37,26 @@ The documentation SHALL separate beginner essentials from advanced topics so new - **AND** move advanced topics (multi-capability changes, archiving details, tooling deep dives) into clearly labeled later sections - **AND** provide anchor links from the quick-reference to those advanced sections +### Requirement: Behavior-First Spec Authoring Guidance +Agent instruction docs SHALL explicitly teach that specs capture observable behavior contracts, while implementation details belong in design/tasks. + +#### Scenario: Distinguishing spec vs implementation content +- **WHEN** `openspec/AGENTS.md` explains how to write `spec.md` +- **THEN** it SHALL instruct agents to include externally verifiable behavior, inputs/outputs, errors, and constraints +- **AND** it SHALL instruct agents to avoid internal library/framework choices and class/function-level implementation details in specs + +#### Scenario: Routing detail to the right artifact +- **WHEN** implementation detail is necessary +- **THEN** instructions SHALL direct the agent to place it in `design.md` or `tasks.md`, not in the behavioral requirements section of `spec.md` + +### Requirement: Lightweight-by-Default Guidance +Agent instruction docs SHALL promote minimal ceremony and proportional rigor for spec authoring. + +#### Scenario: Applying progressive rigor +- **WHEN** an agent drafts specs for routine changes +- **THEN** instructions SHALL favor concise, lightweight requirements and scenarios +- **AND** reserve deeper, fuller specification style for higher-risk changes (such as API breaks, migrations, cross-team, or security/privacy sensitive work) + +#### Scenario: Time-to-clarity optimization +- **WHEN** guidance discusses drafting workflow +- **THEN** it SHALL emphasize producing the smallest spec that is still testable and reviewable diff --git a/openspec/specs/openspec-conventions/spec.md b/openspec/specs/openspec-conventions/spec.md index dec8c32ef..52974366f 100644 --- a/openspec/specs/openspec-conventions/spec.md +++ b/openspec/specs/openspec-conventions/spec.md @@ -13,6 +13,29 @@ OpenSpec conventions SHALL mandate a structured spec format with clear requireme - **WHEN** writing or updating OpenSpec specifications - **THEN** authors SHALL use `### Requirement: ...` followed by at least one `#### Scenario: ...` section +### Requirement: Behavior-First Specification Boundary +OpenSpec specifications SHALL capture verifiable behavior contracts and avoid internal implementation detail. + +#### Scenario: Writing behavior requirements +- **WHEN** documenting a capability in `spec.md` +- **THEN** requirements focus on externally observable behavior, interfaces, error handling, and constraints +- **AND** scenarios remain testable or explicitly verifiable + +#### Scenario: Avoiding implementation leakage +- **WHEN** details involve concrete library choices, class/function structure, or execution mechanics +- **THEN** those details SHALL be documented in `design.md` or `tasks.md` instead of behavioral requirements + +### Requirement: Progressive Rigor +OpenSpec conventions SHALL keep specs lightweight by default and scale rigor only when risk or coordination complexity demands it. + +#### Scenario: Routine change specification +- **WHEN** a change is local and low-risk +- **THEN** authors use concise, behavior-first requirements with minimal ceremony + +#### Scenario: High-risk or cross-boundary change specification +- **WHEN** a change is cross-team, cross-repo, API-contract breaking, migration-heavy, or security/privacy sensitive +- **THEN** authors increase detail and explicit validation expectations proportionally + ### Requirement: Project Structure An OpenSpec project SHALL maintain a consistent directory structure for specifications and changes. @@ -471,4 +494,4 @@ Clean future state storage provides: The structured format adds: - **Visual Consistency**: Requirement and Scenario prefixes make sections instantly recognizable - **Parseability**: Consistent structure enables tooling and automation -- **Gradual Adoption**: Existing specs can migrate incrementally \ No newline at end of file +- **Gradual Adoption**: Existing specs can migrate incrementally