diff --git a/docs/glossary.md b/docs/glossary.md index 345125f38..99be66943 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -14,7 +14,7 @@ Terms are grouped by topic, then alphabetized within each group. **Artifact.** A document inside a change. The standard artifacts are the proposal, the delta specs, the design, and the tasks. They're created in dependency order and feed into each other. -**Delta spec.** A spec inside a change that describes only what's changing, using `ADDED`, `MODIFIED`, and `REMOVED` sections, rather than restating the entire spec. This is what lets OpenSpec edit existing systems cleanly. See [Concepts](concepts.md#delta-specs). +**Delta spec.** A spec inside a change that describes only what's changing, using `ADDED`, `MODIFIED`, and `REMOVED` sections, rather than restating the entire current spec. A delta is a proposed edit, not a second copy of the destination. This is what lets OpenSpec edit existing systems cleanly. See [Concepts](concepts.md#delta-specs). **Domain.** A logical grouping for specs, like `auth/`, `payments/`, or `ui/`. You choose domains that match how you think about your system. @@ -36,9 +36,9 @@ Terms are grouped by topic, then alphabetized within each group. ## The lifecycle -**Archive.** The act of finishing a change. Its delta specs merge into the main specs, and the change folder moves to `openspec/changes/archive/YYYY-MM-DD-/`. After archiving, your specs describe the new reality. See [Concepts](concepts.md#archive). +**Archive.** The act of finishing a change. Its delta specs are applied to the current specs; for a brand-new capability this creates the first current spec, while an existing capability is updated. The change folder then moves to `openspec/changes/archive/YYYY-MM-DD-/`. After archiving, your specs describe the new reality. See [Concepts](concepts.md#archive). -**Sync.** Merging a change's delta specs into the main specs *without* archiving the change. Usually automatic (archive offers to do it), but available on its own as `/opsx:sync` for long-running changes. See [Commands](commands.md#opsxsync). +**Sync.** Applying a change's delta specs to the current specs *without* archiving the change. If the capability is new, this creates its first current spec; it is not a requirement that a pre-existing spec already exists. Usually automatic (archive offers to do it), but available on its own as `/opsx:sync` for long-running changes. See [Commands](commands.md#opsxsync). ## Workflow and commands diff --git a/docs/overview.md b/docs/overview.md index 6321a3439..21b562e94 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -23,7 +23,7 @@ proposal ──► specs ──► design ──► tasks ──► implement You can revisit any of them at any time. They're enablers, not gates. (More on that below.) -**5. Archiving folds the change back into the truth.** When the work is done, you archive the change. Its delta specs merge into your main specs, and the change folder moves to `changes/archive/` with a date stamp. Now your specs describe the new reality, and you're ready for the next change. The cycle closes. +**5. Archiving folds the change back into the truth.** When the work is done, you archive the change. Its delta specs are applied to the current specs: an existing capability is updated, while a brand-new capability receives its first current spec. The change folder then moves to `changes/archive/` with a date stamp. Now your specs describe the new reality, and you're ready for the next change. The cycle closes. ## The picture diff --git a/docs/workflows.md b/docs/workflows.md index 78d27a32c..7745670f6 100644 --- a/docs/workflows.md +++ b/docs/workflows.md @@ -388,18 +388,20 @@ AI: Archiving add-auth... ✓ design.md exists ✓ tasks.md exists (12/12 tasks complete) - Delta specs: Not yet synced to main - → Would you like to sync now? + Delta specs: Not yet applied to current specs + → Apply them to current specs now? You: Yes -AI: ✓ Synced specs to openspec/specs/auth/spec.md +AI: ✓ Applied delta specs to openspec/specs/auth/spec.md ✓ Moved to openspec/changes/archive/2025-01-24-add-auth/ Change archived successfully. ``` -Archive will prompt if specs aren't synced. It won't block on incomplete tasks, but it will warn you. +Archive will prompt if delta specs have not been applied to the current specs. For a new capability, +this application creates the first current spec; it does not require a pre-existing main spec. It +won't block on incomplete tasks, but it will warn you. ## When to Use What diff --git a/src/core/templates/workflows/archive-change.ts b/src/core/templates/workflows/archive-change.ts index 2dae74d43..63168417d 100644 --- a/src/core/templates/workflows/archive-change.ts +++ b/src/core/templates/workflows/archive-change.ts @@ -95,27 +95,27 @@ ${STORE_SELECTION_GUIDANCE} delta specs from other artifacts. **If delta specs exist:** - - Compare each delta spec with its corresponding main spec at \`/openspec/specs//spec.md\` (use the store-aware \`planningHome.root\` from step 2, not a hardcoded repo path) + - Compare each delta spec with its corresponding current spec at \`/openspec/specs//spec.md\` (use the store-aware \`planningHome.root\` from step 2, not a hardcoded repo path). If the capability is new, the current spec does not exist yet and the delta will create it. - Determine what changes would be applied (adds, modifications, removals, renames) - Show a combined summary before prompting **Prompt options:** - - If changes needed: "Sync now (recommended)", "Archive without syncing" - - If already synced: "Archive now", "Sync anyway", "Cancel" + - If changes needed: "Apply to current specs now (recommended)", "Archive without applying" + - If already applied: "Archive now", "Apply again", "Cancel" Route on the answer: - "Cancel" — stop, do not archive - - "Archive without syncing" or "Archive now" — proceed to archive - - "Sync now" or "Sync anyway" — sync, then verify (below) + - "Archive without applying" or "Archive now" — proceed to archive + - "Apply to current specs now" or "Apply again" — apply, then verify (below) - Anything else — ask again rather than archiving - Before a selected sync writes any main spec, run + Before a selected application writes any current spec, run \`openspec instructions specs --change "" --json\` once with the same selected-root flags. Require a zero exit status and valid artifact-instruction JSON. If the lookup fails or returns invalid JSON, report the error and stop - before writing any main spec or moving the change. A valid response with omitted + before writing any current spec or moving the change. A valid response with omitted \`rules\` is the no-rules case. Apply returned \`rules\` only to the content and - form of main specs produced by this merge; do not use them as archive guidance, + form of current specs produced by this application; do not use them as archive guidance, change CLI behavior, or copy the rule text into any output file. Then run the \`openspec-sync-specs\` workflow inline (agent-driven intelligent merge) for change '', passing the delta spec analysis and the fetched specs-rule snapshot from above, and wait for it to finish. The inline sync must reuse that snapshot without fetching \`specs\` instructions again. Do not delegate it to a background task — step 5 would move \`changeRoot\` out from under a sync that is still reading it, leaving the change archived and the main specs never updated. If your agent can only run it by delegation, delegate synchronously and wait for the result. @@ -162,7 +162,7 @@ ${STORE_SELECTION_GUIDANCE} **Change:** **Schema:** **Archived to:** the archive path derived from \`planningHome.changesDir\`// -**Specs:** <"✓ Synced to main specs" only if the step 4 verification passed; otherwise "No delta specs" or "Sync skipped"> +**Specs:** <"✓ Applied to current specs" only if the step 4 verification passed; otherwise "No delta specs" or "Application skipped"> <"All artifacts complete. All tasks complete." — or, if archived with warnings, list them instead (e.g. "Archived with 2 incomplete tasks")> \`\`\` @@ -277,27 +277,27 @@ ${STORE_SELECTION_GUIDANCE} delta specs from other artifacts. **If delta specs exist:** - - Compare each delta spec with its corresponding main spec at \`/openspec/specs//spec.md\` (use the store-aware \`planningHome.root\` from step 2, not a hardcoded repo path) + - Compare each delta spec with its corresponding current spec at \`/openspec/specs//spec.md\` (use the store-aware \`planningHome.root\` from step 2, not a hardcoded repo path). If the capability is new, the current spec does not exist yet and the delta will create it. - Determine what changes would be applied (adds, modifications, removals, renames) - Show a combined summary before prompting **Prompt options:** - - If changes needed: "Sync now (recommended)", "Archive without syncing" - - If already synced: "Archive now", "Sync anyway", "Cancel" + - If changes needed: "Apply to current specs now (recommended)", "Archive without applying" + - If already applied: "Archive now", "Apply again", "Cancel" Route on the answer: - "Cancel" — stop, do not archive - - "Archive without syncing" or "Archive now" — proceed to archive - - "Sync now" or "Sync anyway" — sync, then verify (below) + - "Archive without applying" or "Archive now" — proceed to archive + - "Apply to current specs now" or "Apply again" — apply, then verify (below) - Anything else — ask again rather than archiving - Before a selected sync writes any main spec, run + Before a selected application writes any current spec, run \`openspec instructions specs --change "" --json\` once with the same selected-root flags. Require a zero exit status and valid artifact-instruction JSON. If the lookup fails or returns invalid JSON, report the error and stop - before writing any main spec or moving the change. A valid response with omitted + before writing any current spec or moving the change. A valid response with omitted \`rules\` is the no-rules case. Apply returned \`rules\` only to the content and - form of main specs produced by this merge; do not use them as archive guidance, + form of current specs produced by this application; do not use them as archive guidance, change CLI behavior, or copy the rule text into any output file. Then run the \`/opsx:sync\` workflow inline (agent-driven intelligent merge) for change '', passing the delta spec analysis and the fetched specs-rule snapshot from above, and wait for it to finish. The inline sync must reuse that snapshot without fetching \`specs\` instructions again. Do not delegate it to a background task — step 5 would move \`changeRoot\` out from under a sync that is still reading it, leaving the change archived and the main specs never updated. If your agent can only run it by delegation, delegate synchronously and wait for the result. @@ -344,7 +344,7 @@ ${STORE_SELECTION_GUIDANCE} **Change:** **Schema:** **Archived to:** the archive path derived from \`planningHome.changesDir\`// -**Specs:** ✓ Synced to main specs +**Specs:** ✓ Applied to current specs All artifacts complete. All tasks complete. \`\`\` @@ -370,12 +370,12 @@ All artifacts complete. All tasks complete. **Change:** **Schema:** **Archived to:** the archive path derived from \`planningHome.changesDir\`// -**Specs:** Sync skipped (user chose to skip) +**Specs:** Application skipped (user chose to skip) **Warnings:** - Archived with 2 incomplete artifacts - Archived with 3 incomplete tasks -- Delta spec sync was skipped (user chose to skip) +- Applying the delta specs was skipped (user chose to skip) Review the archive if this was not intentional. \`\`\` diff --git a/test/core/templates/skill-templates-parity.test.ts b/test/core/templates/skill-templates-parity.test.ts index decad7b0b..a85146c88 100644 --- a/test/core/templates/skill-templates-parity.test.ts +++ b/test/core/templates/skill-templates-parity.test.ts @@ -50,11 +50,11 @@ const EXPECTED_FUNCTION_HASHES: Record = { getOpsxContinueCommandTemplate: 'e50e50266efa1b8e64ff9b6274ee8254f0a240d6adc1b862d126e2f1c9d3a559', getOpsxApplyCommandTemplate: 'e3579ac78f2e2c75fa3d3a7ac7dc3e49c395e96f7323398f0f041d94f8de9bb0', getOpsxFfCommandTemplate: 'e603bc0996604e6c17a3140943ea642a32d0fc65565e25424bf956e124c55772', - getArchiveChangeSkillTemplate: '56bfada1a5f35a127791b70de9d428a75b5aedd1584d6c9803a1ecb1fd1b4a23', + getArchiveChangeSkillTemplate: 'cefd6665fd123400e5067cee53f44646f8b376f9ec5b8f0d2c7c0c5a3f0df9b0', getBulkArchiveChangeSkillTemplate: '93875998cade5322d95b43299fba794bc1da754e917dd63a770406386a6d295d', getOpsxSyncCommandTemplate: '0d2427efb79986e8fff3f96bd075a739c80d45eb29159fae717e950030da8202', getVerifyChangeSkillTemplate: '223b7ffd99299a7d430e13092b9a0a3421b39f0d3217232f46c39d79b5f619ff', - getOpsxArchiveCommandTemplate: '9f973c819b11620985b03322945f0e0a92a02a2ef455b94e74482f5e6292ac5d', + getOpsxArchiveCommandTemplate: '897ff416ef125bd31fc5ff2a3d8903ae0e292699833f1073e72dddcd427e5612', getOpsxOnboardCommandTemplate: '7e251da66e2fdf539a09326463ee3ed0d01fe665ecb1d8f36f941fed00a01891', getOpsxBulkArchiveCommandTemplate: '9fa8cdebe2f5667ebfc37bdc023396762c59d5b038c771dac2d8fd2c19e2627b', getOpsxVerifyCommandTemplate: '1efcf7eff0671f48e9d9420f50865c563dd3079ee60f8c380bb7a90dd0102696', @@ -72,7 +72,7 @@ const EXPECTED_GENERATED_SKILL_CONTENT_HASHES: Record = { 'openspec-apply-change': '81ea96d9fa6ec8536cd23c1fe561ed28e1cc1cad0a8ceb700588e08974cc0e49', 'openspec-ff-change': '217c78da2b6e8358f609ac57dcd02266aaec3354ce26dc6ec2fc9c2174673ab4', 'openspec-sync-specs': 'd933d8856584d6c1253de91e652e7aee9e85c77ad4d3531f6476f79d84e6e5e8', - 'openspec-archive-change': '7c65053d674ba4e1e20e2bf73ba7e5a7f94baef2eaa9b33cee48d4cadea51b7a', + 'openspec-archive-change': '107de7724860233426a7d5ecb11fa1ad426cd32fac9a2fd48138479339ab9fcf', 'openspec-bulk-archive-change': '2039b9ecf6e64339dffe0e16272507a386d9fe326f419ff758315aa736fdd96c', 'openspec-verify-change': 'af9be013dcbe8c6d8f6d9ab10c893fbd03f4c62933c384d82f63894dd0ceb84f', 'openspec-onboard': 'd53403b4910ab64307862ccf97e70bd8f7174ee44508088fb239c880f0939331',