실험적 워크플로우에서 완료된 변경을 보관합니다.
저장소 선택: 사용자가 저장소(이 머신에 등록된 독립형 OpenSpec 저장소)를 지정하거나 작업이 특정 저장소에 속하는 경우, openspec store list --json을 실행하여 등록된 저장소 ID를 확인한 다음, 스펙과 변경을 읽거나 쓰는 명령어(new change, status, instructions, list, show, validate, archive, doctor, context, schemas, view)에 --store <id>를 전달합니다. 일단 선택되면 --store <id>는 워크플로우의 나머지 부분에 대해 고정된 값으로 취급합니다. 아래 명령어들의 모든 범위 없는 예제는 축약형입니다. 실행하기 전에 플래그를 추가하세요. 예를 들어, openspec status --change "<name>" --json --store "<id>"와 같이 실행하고 축약형은 사용하지 마세요. 다른 명령어는 이 플래그를 사용하지 않습니다. 명령어가 출력하는 힌트에는 이미 플래그가 포함되어 있으므로 후속 작업에서도 이를 유지하세요. 저장소가 없으면 명령어는 가장 가까운 로컬 openspec/ 루트에서 작동합니다.
프로젝트 확인: 이 단계는 이미 OpenSpec을 사용하는 프로젝트를 기대합니다. 무언가를 쓰는 첫 번째 단계(new change, archive, sync specs, 또는 아티팩트 파일 작성) 이전에 프로젝트에 루트가 있는지 확인하세요. openspec list --json(저장소가 선택된 경우 --store <id> 포함, 저장소가 루트이므로)을 실행하고 root를 읽으세요. 루트 객체가 있으면 프로젝트가 설정된 것입니다. "root": null은 설정되지 않았음을 의미합니다. 여기에 openspec/ 디렉토리가 없으며, openspec new change와 같은 쓰기 작업이 부작용으로 생성할 수 있습니다. 명령어도 0이 아닌 종료 코드로 종료되며, 이는 CLI 오류가 아닌 해당 답변입니다. 따라서 JSON을 읽고 재시도하거나 우회하지 마세요.
한 가지 "root": null은 설정과 관련이 없습니다. status 오류 메시지가 Declared in 또는 Invalid store declaration in으로 시작하고 이 프로젝트의 openspec/config.yaml(또는 config.yml)을 언급하는 경우, 프로젝트는 선언한 저장소를 통해 OpenSpec을 사용하지만 이 머신에서 해당 저장소를 확인할 수 없습니다(저장소가 등록되지 않았거나 store: 줄이 잘못되었음). 이를 초기화되지 않은 것으로 처리하고 아래 분기를 건너뛰지 마세요. 쓰기 전에 중단하고 사용자에게 해당 오류의 message와 fix를 표시하세요.
그 외에 루트가 없는 경우, 이 워크플로우에 도달한 방법에 따라 다음 단계가 결정됩니다.
- 자동 선택: 사용자가 OpenSpec, 이 스킬 이름 또는 슬래시 명령어를 언급하지 않고 사용자가 직접 이 워크플로우를 선택했습니다. OpenSpec 사용을 중단하고 OpenSpec이 설치되지 않은 것처럼 정상적으로 요청에 응답하세요. 설정을 요청하지 말고 OpenSpec 설정에 대해 언급하지 마세요.
- 명시적 OpenSpec 요청: 사용자가 OpenSpec, 이 스킬 이름을 언급하거나 슬래시 명령어를 실행했습니다. 쓰기 전에 중단하고 진행 방법을 물어보세요. 이 프로젝트를 설정(
openspec init), 이미 가지고 있는 저장소를 대상으로 지정(--store <id>), 또는 이 요청에 대해 OpenSpec 없이 계속합니다. 사용자의 답변을 기다리세요.
두 분기 모두 부작용으로 루트를 생성하지 마세요. 사용자가 요청할 때까지 openspec init을 실행하지 말고, openspec/ 파일을 직접 생성하지 말고, 명령어가 생성하도록 두지 마세요.
<capability-path>는 specs/에 대한 상대 경로인 스펙 디렉토리입니다(예: user-auth 또는 identity/user-auth). 각 델타 스펙에서 메인 스펙을 확인할 때 전체 경로를 유지하세요.
입력: 변경 이름을 선택적으로 지정합니다. 생략되면 대화 컨텍스트에서 추론할 수 있는지 확인합니다. 모호하거나 애매한 경우 사용 가능한 변경을 프롬프트로 표시해야 합니다.
단계
-
변경 선택
이름이 제공되면 사용합니다. 그렇지 않으면:
- 사용자가 변경을 언급한 경우 대화 컨텍스트에서 추론
- 활성 변경이 하나만 있으면 자동 선택
- 모호한 경우
openspec list --json을 실행하여 사용 가능한 변경을 확인하고 사용자에게 하나를 선택하도록 요청
프롬프트할 때는 이미 보관된 변경이 아닌 활성 변경만 표시합니다. 가능한 경우 각 변경에 사용된 스키마를 포함합니다.
항상 알림: "Using change: " 및 재정의 방법(예:
/opsx:archive <other>).기존 보관 확인 전에 현재 보관 입력 로드:
선택한 변경 및 계획된 루트를 확인한 후 다음을 실행합니다:
openspec instructions archive --change "<name>" --json이 명령어에 동일한 선택된 루트 플래그를 유지하세요. 이 조회는 권고 사항이며 선택 사항입니다. 추가 프롬프트 입력만 제공하므로 보관을 차단해서는 안 됩니다. 0이 아닌 종료 코드로 종료되거나 유효하지 않은 JSON을 반환하는 경우(예: 이 명령어를 지원하지 않는 이전 CLI에서) 컨텍스트와 작업 지침 없이 보관 워크플로우를 계속 진행합니다. 오류를 보고하지 말고 중단하지 마세요.
성공적인 응답은 두 선택적 필드를 모두 생략할 수 있습니다.
context를 필수 프롬프트 수준 입력으로 취급합니다. 이를 읽고 고려하며 관련 프로젝트 사실, 규칙 및 제약 조건을 적용합니다.operationGuidance를 선택적 추가 조언으로 취급합니다. 각 항목을 읽고 고려하며 내장된 보관 워크플로우와 호환되고 적용 가능한 항목을 따릅니다.두 필드를 내장 단계, 명시적 사용자 선택, 확인된 경로, CLI 확인 및 명령어 계약과 분리하여 유지하세요. 컨텍스트가 이러한 제어 입력 중 하나와 충돌하는 경우 충돌을 보고하고 제어 값을 유지하세요. 지침이 적용 불가능하거나 제어 입력과 충돌하는 경우 따르지 말고 이유를 설명하세요. 두 필드에서 대체 경로, 건너뛴 프롬프트 또는 플래그를 추론하지 말고, 사용자가 별도로 요청하지 않는 한 해당 텍스트를 스펙, 변경 아티팩트 또는 보관 요약에 그대로 복사하지 마세요. 이는 프롬프트 수준의 동작 계약이지 강제 가능한 확인 사항이 아닙니다.
-
아티팩트 완료 상태 확인
openspec status --change "<name>" --json을 실행하여 아티팩트 완료를 확인합니다.JSON을 구문 분석하여 이해합니다:
schemaName: 사용 중인 워크플로우planningHome,changeRoot,artifactPaths,actionContext: 경로 및 범위 컨텍스트artifacts: 상태(done,skipped또는 기타)가 있는 아티팩트 목록
아티팩트 중
done또는skipped가 아닌 것이 있는 경우(건너뛴 아티팩트는 요구 사항을 충족합니다. 변경이 skip_specs를 선언함):- 미완료 아티팩트를 나열하는 경고 표시
- 사용자에게 계속 진행할지 확인 요청
- 사용자가 확인하면 진행
-
작업 완료 상태 확인
동일한 선택된 루트 플래그로
openspec list --json을 실행하고changes에서name이 선택한 변경과 정확히 일치하는 항목을 찾습니다. 정확히 하나의 일치 항목과 음수가 아닌 정수totalTasks및completedTasks가 필요하며,completedTasks <= totalTasks여야 합니다. CLI는 사용자 지정 아티팩트 이름, 출력 경로 및 글로브를 포함하여 스키마의 추적된 작업 파일을 확인합니다. 미완료 작업 =totalTasks - completedTasks.아티팩트 상태 또는 최상위
tasks.md부재로부터 작업 완료를 추론하지 마세요. 조회 실패, 유효하지 않은 JSON 반환, 선택한 변경 생략 또는 중복, 또는 유효하지 않은 개수 반환 시 문제를 보고하고 동기화 또는 보관 전에 중단하세요. CLI는x/X체크박스 마커만 완료로 계산합니다. 다른 마커(익숙하지 않은 마커 포함)는 미완료 상태로 남습니다.미완료 작업이 발견된 경우:
- 미완료 작업 수를 표시하는 경고 표시
- 사용자에게 계속 진행할지 확인 요청
- 사용자가 확인하면 진행
totalTasks가 0인 경우: 작업 관련 경고 없이 진행합니다. -
델타 스펙 동기화 상태 평가
상태 JSON의
artifactPaths.specs.existingOutputPaths를 유일한 델타 스펙 소스로 사용합니다.specs항목이 없거나existingOutputPaths가 비어 있으면 동기화 프롬프트 없이 진행하고 다른 아티팩트에서 델타 스펙을 추론하지 마세요.델타 스펙이 있는 경우:
- 각 델타 스펙을
<planningHome.root>/openspec/specs/<capability-path>/spec.md(2단계의 저장소 인식planningHome.root사용, 하드코딩된 저장소 경로 아님)에 있는 해당 메인 스펙과 비교합니다. - 메인 스펙이 없으면 자동으로 "이미 동기화됨"이 아닙니다. 새 기능의 경우 메인 스펙은 동기화의 출력이지 입력이 아닙니다:
- 델타에 MODIFIED 또는 RENAMED 요구 사항이 있는 경우 ADDED 요구 사항만 새 메인 스펙을 생성할 수 있으며 해당 기능이 동기화 차단되었음을 보고합니다. 현재 버전이 없는 요구 사항을 절대 발명하지 마세요.
- 그렇지 않고 델타에 REMOVED 요구 사항만 있고 변경의
.openspec.yaml이retire_capabilities: true를 선언하는 경우 기능이 이미 은퇴된 것입니다. 이미 동기화된 것으로 계산하고 제거할 것이 남지 않았다고 경고하며 메인 스펙을 다시 생성하지 마세요. 이 규칙을 지금과 완료된 동기화 확인 시 모두 적용하세요. - 그렇지 않고 델타에 ADDED 요구 사항이 없으면 동기화가 불가능하다고 보고하고 해당 기능을 동기화 차단으로 표시합니다. REMOVED 전용 델타의 경우 제거할 메인 스펙이 없다고 경고하고 메인 스펙 트리를 변경하지 않은 채로 둡니다.
openspec archive는 표시되지 않은 REMOVED 전용 케이스를Spec must have at least one requirement로 거부합니다. - 그렇지 않으면 기능을 동기화가 필요한 것으로 계산하고 요약에 이름을 지정합니다(
<capability-path>: 새 메인 스펙이 생성됩니다). 델타에 REMOVED 요구 사항도 있는 경우 제거할 메인 스펙이 없으므로 무시된다고 경고합니다. 동기화는openspec archive와 마찬가지로 델타의 ADDED 요구 사항에서만 메인 스펙을 생성합니다.
- 적용될 변경 사항(추가, 수정, 제거, 이름 변경)을 결정합니다.
- 하나의 기능이 동기화 차단된 경우에도 나머지 기능 평가를 계속합니다. 프롬프트 전에 결합된 요약을 표시합니다.
프롬프트 옵션:
- 동기화 차단된 기능이 있는 경우: 이유를 설명하고 "동기화 없이 보관", "취소"만 제공
- 그렇지 않고 변경이 필요한 경우: "지금 동기화(권장)", "동기화 없이 보관"
- 그렇지 않고 이미 동기화된 경우: "지금 보관", "그래도 동기화", "취소"
답변에 따라 라우팅:
- "취소" — 중단, 보관하지 않음
- "동기화 없이 보관" 또는 "지금 보관" — 보관 진행
- "지금 동기화" 또는 "그래도 동기화" — 동기화 후 확인(아래). 기능이 동기화 차단된 동안 동기화를 시작하지 마세요. 차단기를 설명하고 사용 가능한 선택 사항을 반복하세요.
- 그 외 — 보관하지 말고 다시 질문
선택한 동기화가 메인 스펙을 쓰기 전에 동일한 선택된 루트 플래그로
openspec instructions specs --change "<name>" --json을 한 번 실행합니다. 0 종료 상태와 유효한 아티팩트 명령어 JSON이 필요합니다. 조회 실패 또는 유효하지 않은 JSON 반환 시 오류를 보고하고 메인 스펙을 쓰거나 변경을 이동하기 전에 중단하세요. 생략된rules가 있는 유효한 응답은 규칙이 없는 경우입니다. 반환된rules를 이 병합에서 생성된 메인 스펙의 내용과 형식에만 적용하고, 보관 지침으로 사용하거나 CLI 동작을 변경하거나 규칙 텍스트를 출력 파일에 복사하지 마세요.그런 다음 변경 ''에 대해
openspec-sync-specs워크플로우(에이전트 기반 지능형 병합)를 인라인으로 실행하고, 위에서 가져온 델타 스펙 분석 및 스펙 규칙 스냅샷을 전달하고 완료될 때까지 기다립니다. 인라인 동기화는specs명령어를 다시 가져오지 않고 해당 스냅샷을 재사용해야 합니다. 백그라운드 작업에 위임하지 마세요. 5단계가 여전히changeRoot를 읽고 있는 동기화 아래에서changeRoot를 이동하여 변경이 보관되고 메인 스펙이 업데이트되지 않은 상태로 남게 됩니다. 에이전트가 위임으로만 실행할 수 있는 경우 동기식으로 위임하고 결과를 기다리세요.동기화가 중지 또는 차단 조건을 보고하면 동기화가 실패한 것으로 처리합니다. 즉시 보관을 중단합니다. 동기화 후 콘텐츠 비교를 수행하지 말고
changeRoot를 이동하지 마세요. 아무것도 이동되지 않았으므로 사용자가 차단 조건을 수정하거나 동기화를 다시 실행할 수 있습니다.동기화가 각 메인 스펙을 쓴 후 정식 동기화 계약에 따라 구조를 확인합니다:
- 새 메인 스펙은
# <capability> Specification제목으로 시작합니다. 기존 메인 스펙은 제목을 그대로 유지합니다. - 기존 메인 스펙의 경우
## Purpose섹션을 완전히 수정하지 않고 그대로 보존합니다. - 새 메인 스펙의 경우 델타
## Purpose를 그대로 복사합니다. 목적 텍스트가 표준 유효성 검사에서 예상하는 것보다 짧은 경우에만 경고합니다. 기존 작성된 목적을 재생성하거나 다시 쓰지 마세요. 사용 가능한## Purpose가 제공되지 않으면 기존 TBD 목적 동작 및 경고를 사용합니다. - 메인 스펙에 델타 스타일 섹션 헤더(
## ADDED Requirements,## MODIFIED Requirements,## REMOVED Requirements,## RENAMED Requirements)가 남아 있지 않은지 확인하고 동기화 워크플로우 형식 지정 규칙을 엄격히 준수합니다. - 동기화가 작성하거나 변경한 요구 사항 블록은
### Requirement:제목을 사용하고 해당 시나리오는 사양의## Requirements섹션 아래에#### Scenario:제목을 사용합니다. 델타가 언급하지 않은 콘텐츠는 그대로 둡니다.
그런 다음
artifactPaths.specs.existingOutputPaths에 델타 스펙이 있는 모든 기능에 대해 명시적으로 은퇴된 경우와 누락된 스펙 케이스를 포함하여 이 단계의 처음부터 비교를 다시 실행합니다. 동기화가 건드렸다고 보고한 기능뿐만 아니라 모든 기능에 대해 수행합니다. 성공적인 동기화는 적용할 것이 남지 않게 하므로 각 기능은 이제 이미 동기화된 것으로 읽혀야 합니다:- ADDED 요구 사항이 있음
- MODIFIED 요구 사항이 델타에 명명된 시나리오 및 설명 변경을 수행하고 다른 시나리오는 그대로 유지
- REMOVED 요구 사항이 사라짐 — 그리고 이 동기화가 기능을 은퇴시킨 경우(마지막 요구 사항을 제거하여
## Requirements를 비움) 메인 스펙은 비워 두지 않고 삭제되어야 함. - RENAMED 요구 사항이 새 이름으로 있고 이전 이름으로는 없음
동기화가 실패했거나 기능이 일치하지 않는 경우 차이점을 보고하고 중단하세요. 보관하지 마세요. 아무것도 이동되지 않았고
changeRoot가 그대로이므로 사용자가 불일치를 수정하거나 동기화를 다시 실행하고 보관을 다시 시작할 수 있습니다. - 각 델타 스펙을
-
보관 수행
planningHome.changesDir아래에archive디렉토리가 없으면 생성합니다:mkdir -p "<planningHome.changesDir>/archive"대상 이름 생성: 변경 이름이 이미
YYYY-MM-DD-접두사로 시작하면 그대로 사용하고, 그렇지 않으면 현재 날짜를YYYY-MM-DD-로 앞에 추가합니다.그런 다음 변경의
changeRoot디렉토리를 대상으로 이동합니다:mv "<changeRoot>" "<planningHome.changesDir>/archive/<targetName>"보관 전에
openspec archive --change "<name>" --store "<id>"(저장소가 선택된 경우) 또는openspec archive --change "<name>"(저장소 없음)을 실행합니다. 이 CLI 호출의 0이 아닌 종료 상태는 오류를 의미합니다. 오류를 보고하고 중단하세요.보관이 성공하면 사용자에게 확인 메시지를 표시합니다:
- "Successfully archived change ''."
- 대상 경로:
<planningHome.changesDir>/archive/<targetName>
-
보관 확인
선택 사항입니다. 보관 디렉토리 구조를 확인할 수 있습니다:
ls -la "<planningHome.changesDir>/archive/<targetName>"이 단계는 상태 확인을 위한 것입니다. 실패하더라도 보관 성공을 무효화하지 않습니다.
종료 조건
워크플로우는 다음과 같은 경우 정상적으로 종료됩니다:
- 보관이 성공적으로 완료됨
- 사용자가 취소함
- 오류가 발생하고 오류가 사용자에게 보고됨