Skip to content

스토어 (베타) ​

여러 리포지토리에 걸친 변경 사항을 계획하세요: 하나의 스토어, 여러 리포지토리.

OpenSpec은 일반적으로 하나의 리포지토리 안에 있습니다. OpenSpec이 계획하는 코드 옆에 있는 openspec/ 폴더입니다. 스토어는 이 폴더를 자체 리포지토리로 옮기며, 여러 코드 리포지토리가 이를 공유할 수 있습니다.

각 머신에서 한 번만 설정하면 status, new change, archive 같은 명령을 어느 디렉터리에서든 스토어에서 사용할 수 있습니다.

         team-plans  (a store: OpenSpec in its own repo)
         ├── .openspec-store/store.yaml   the store's name
         └── openspec/
             ├── specs/
             └── changes/
                   ▲
                   │ set up once on each machine,
                   │ shared by pushing and cloning like any repo
     ┌─────────────┼─────────────┐
     │             │             │
 web-app       api-server     mobile-app
(code repo)   (code repo)    (code repo)

스토어는 코드를 공유하는 것과 같은 방식으로 git을 통해 공유합니다. 직접 commit, push, pull하고 리뷰하세요. 스펙과 변경 사항도 코드와 마찬가지로 브랜치와 풀 리퀘스트를 갖습니다.

스토어가 필요한 경우 ​

스토어를 사용하는 일반적인 이유는 두 가지입니다:

  • 프론트엔드와 백엔드가 별도 리포지토리에 있는 경우: 하나의 기능이 둘 모두에 영향을 주므로, 계획을 두 갈래로 나누지 않고 한곳에서 관리해야 합니다.

          shop-plans  (store)
          └── openspec/changes/add-discounts/    one plan for the feature
                    ▲
          ┌─────────┴─────────┐
          │                   │
      storefront             api
    (frontend repo)     (backend repo)
  • 하나의 제품, 여러 클라이언트 리포지토리: Android, iOS, 웹은 각자의 리포지토리에서 출시되지만 하나의 기대 동작을 공유합니다. 스펙은 구현이 아니라 동작을 설명하므로, 하나의 스펙이 세 클라이언트 모두에 적용됩니다.

            product-specs  (store)
            └── openspec/specs/checkout/spec.md    the expected behavior
                      ▲
        ┌─────────────┼─────────────┐
        │             │             │
    android-app    ios-app       web-app
    (code repo)   (code repo)   (code repo)

스토어를 여러 개 보유할 수 있지만, 개수는 적게 유지하는 것이 좋습니다.

스토어 설정하기 ​

한 명이 스토어를 생성한 다음, 나머지 모두가 참여합니다.

  1. 스토어 생성 (한 명, 팀당 한 번). openspec store setup을 실행하고 프롬프트에 답합니다:

    bash
    # 어디서든 실행 가능; 무엇을 생성할지와 어디에 생성할지 물어봅니다
    openspec store setup

    세 가지 질문을 합니다:

    • 스토어 이름: team-plans
    • 이 스토어를 어디에 저장할까요?: ~/openspec/<name>으로 미리 채워져 있으며, Enter를 눌러 수락하거나 다른 경로를 입력합니다
    • 이 스토어를 생성할까요?: 생성할 내용을 보여주며, Yes로 답합니다

    그런 다음 생성된 내용을 보고합니다:

    yaml
    Store ready: team-plans
    Location: ~/openspec/team-plans
    OpenSpec root: ready
    Registry: registered
    
    Next: run normal OpenSpec commands against this store, for example:
      openspec new change <change-id> --store team-plans
    Share this store by committing and pushing it like any Git repo.
  2. Git 호스트에 푸시합니다. 먼저 호스트에 빈 team-plans 저장소를 생성하세요. 설정은 git 원격을 추가하지 않으므로, 스토어를 해당 저장소에 연결한 다음 푸시합니다:

    bash
    # git 호스트의 빈 저장소에 스토어 연결
    cd ~/openspec/team-plans
    git remote add origin git@github.com:acme/team-plans.git
    
    # 게시
    git push -u origin main
  3. 스토어 참여 (모든 팀원, 기계당 한 번):

    bash
    # 스토어를 내 기계로 가져오기
    git clone git@github.com:acme/team-plans.git ~/openspec/team-plans
    
    # OpenSpec에게 위치를 알려주기
    openspec store register ~/openspec/team-plans
    yaml
    Store registered: team-plans
    Location: /Users/you/openspec/team-plans
    OpenSpec root: ready
    Registry: registered

    등록하면 내 기계에 이 스토어의 위치를 알려줍니다. 스토어의 이름은 이미 그 안의 .openspec-store/store.yaml에 커밋되어 있습니다. 설정 시 생성자의 사본이 등록되므로, 복제된 사본만 이 단계가 필요합니다.

  4. 정상 작동 확인, 임의의 디렉터리에서:

    bash
    # 어떤 OpenSpec 명령이든 이름으로 스토어에 접근합니다
    openspec status --store team-plans
    yaml
    Using OpenSpec root: team-plans (/Users/you/openspec/team-plans)
    No active changes. Create one with: openspec new change <name> --store team-plans

설정 유형 ​

OpenSpec에는 세 가지 설정이 있습니다. 이 페이지의 나머지 부분에서는 다음 이름을 사용합니다:

  • repo-local: 저장소 내부의 OpenSpec, 스토어 없음. 기본값.
  • store-only: 저장소가 자체 스펙이나 변경사항을 유지하지 않습니다. 모든 것이 스토어에 있습니다.
  • store-optional: 프로젝트가 자체 openspec/ 폴더를 가지고 있으며, 요청 시 스토어에도 접근합니다.

기본값: 저장소 내부의 OpenSpec (repo-local) ​

openspec init은 코드 옆에 openspec/ 폴더를 생성하고, 해당 저장소의 스펙과 변경사항이 거기에 저장됩니다. 스토어는 관여하지 않습니다. 프로젝트 설정에서 가르치는 설정이며, 대부분의 프로젝트는 다른 설정이 필요 없습니다.

web-app  (code repo)
└── openspec/
    ├── specs/
    └── changes/

저장소 외부, 스토어에 있는 OpenSpec (store-only) ​

저장소가 자체 스펙이나 변경사항을 유지하지 않습니다. 계획하는 모든 것이 스토어에 있고, 저장소 설정의 한 줄이 둘을 연결합니다.

한 팀이 모든 저장소와 계획을 한 곳에서 구축할 때 일반적입니다. 위의 예시가 모두 이 형태입니다.

team-plans  (store)
└── openspec/
    ├── specs/       저장소의 스펙이 여기에 있습니다
    └── changes/     변경사항도 마찬가지입니다
          ▲
          │ store: team-plans   (연결 줄)
web-app  (code repo)
└── openspec/
    └── config.yaml    그 외에는 아무것도 없습니다

저장소 내부와 스토어에 모두 있는 OpenSpec (store-optional) ​

저장소는 자체 작업을 위해 repo-local로 유지되는 동안, 스토어가 공유 스펙과 변경사항을 보유합니다. 저장소 내부에서 OpenSpec은 프로젝트의 openspec/ 폴더를 사용하고, --store를 전달할 때만 스토어에 접근합니다.

스토어가 생기기 전에 OpenSpec을 사용한 저장소이거나, 대부분 독립적인 저장소가 공유 작업에 가끔만 접근할 때 일반적입니다.

team-plans  (store)
└── openspec/          공유 스펙과 변경사항
          ▲
          │ --store team-plans를 전달할 때만
web-app  (code repo)
└── openspec/          이 저장소 자체 것
    ├── config.yaml
    ├── specs/
    └── changes/

저장소는 repo-local로 시작하여 나중에 스펙과 변경사항을 스토어로 옮길 수 있습니다. 저장소의 스펙과 변경사항을 스토어로 이동에서 방법을 보여줍니다.

스토어 사용 시 산출물이 생성되는 위치 ​

스토어를 사용할 때 OpenSpec은 산출물이 어디에 생성될지도 결정해야 합니다. 설정에 따라 다릅니다:

  • store-only (프로젝트가 스토어에만 기록): 모든 산출물이 스토어에 생성됩니다. 아래의 store: 줄이 이를 기록합니다.
  • store-optional (프로젝트가 자체 openspec/ 폴더를 가지고 있고 스토어도 사용): 요청 시 스토어를 지정하거나 해당 변경사항에 대해 --store를 전달하지 않는 한, 산출물이 프로젝트에 생성됩니다. 그러면 에이전트가 플래그를 워크플로 전체에 걸쳐 전달합니다.

OpenSpec은 산출물을 두 곳 중 하나에 기록합니다: 프로젝트의 openspec/ 폴더 또는 스토어. 다음 순서로 선택하며, 적용되는 첫 번째 옵션이 우선합니다:

  1. 명령의 --store <id>. 항상 우선하며, 어떤 디렉터리에서든 적용됩니다.
  2. 프로젝트의 openspec/ 폴더. 프로젝트에 자체 specs/ 또는 changes/ 폴더가 있으면 OpenSpec이 그것을 사용합니다.
  3. 프로젝트의 store: 줄. store-only 프로젝트가 스토어를 기록하는 방법.
  4. 기계의 defaultStore. 위의 어느 것도 적용되지 않을 때의 대체값.

이들 중 아무것도 적용되지 않고 등록된 스토어가 있으면, 명령이 실패하며 그 목록을 보여줍니다. 한 스토어의 id가 origin 원격에서 저장소 이름과 일치하면, 오류는 해당 스토어와 이를 선택하는 store: 줄을 알려줍니다. OpenSpec은 이름으로 스토어를 독자적으로 선택하지 않습니다. 왜냐하면 서로 다른 조직의 저장소가 같은 이름을 공유할 수 있기 때문입니다.

OpenSpec이 스토어를 선택하면, 명령 출력 전에 Using OpenSpec root: ...를 출력합니다.

store: 줄 (store-only 프로젝트) ​

프로젝트의 openspec/config.yaml에 한 줄을 추가하세요:

yaml
# web-app/openspec/config.yaml
store: team-plans

이제 프로젝트 내부에서 실행하는 모든 명령(본인 또는 에이전트)에 스토어가 사용되며, 입력할 플래그가 없습니다:

bash
# web-app 내부, 연결됨
openspec status
yaml
Using OpenSpec root: team-plans (/Users/you/openspec/team-plans)
No active changes. Create one with: openspec new change <name> --store team-plans
  • 줄이 없으면: store-only 프로젝트에서 일반 명령을 실행하면 OpenSpec이 등록된 스토어를 나열하는 오류와 함께 멈춥니다.
  • 커밋하세요: 프로젝트를 복제한 팀원도 그 줄을 받습니다. 여전히 그들의 기계에 스토어를 등록해야 하며(스토어 설정하기의 3단계), 그렇지 않으면 OpenSpec이 오류를 내고 등록하라고 알려줍니다.
  • 실제 폴더 옆에: 프로젝트에 specs/ 또는 changes/ 폴더도 있으면, OpenSpec은 그것을 사용하고 줄을 무시하며 경고를 표시합니다.

store-only 저장소에서 통합 설치 ​

계획을 해당 저장소로 되돌리지 않고 AI 도구 통합 파일을 설치하려면 코드 저장소 루트에서 init을 실행합니다:

bash
# web-app 내부, 저장소 루트에서
openspec init --tools claude
  • 통합 파일: 코드 저장소에 기록됩니다.
  • openspec/config.yaml: store: 줄을 포함하여 바이트 단위로 보존됩니다.
  • openspec/specs/와 openspec/changes/: 코드 저장소에 생성되지 않습니다.

OpenSpec은 코드 저장소의 하위 디렉터리에서 이 명령을 거부합니다. 저장소 루트에서 실행하세요.

OpenSpec은 언어가 외부 스토어 설정에 속하므로 여기서 --language도 거부합니다. 스토어 루트에서 init을 실행하거나 해당 설정을 직접 편집하세요.

기계의 defaultStore ​

작업하는 모든 프로젝트가 같은 스토어를 사용한다면 한 번 설정하세요. OpenSpec은 플래그도, 로컬 openspec/ 폴더도, store: 줄도 찾지 못할 때 이를 대체값으로 사용합니다:

bash
# 다른 것이 스토어를 지정하지 않을 때마다 team-plans 사용
openspec config set defaultStore team-plans

# 실행 취소
openspec config unset defaultStore

로컬로 유지되는 명령. init, update, templates, schemas, 그리고 openspec schema 하위 명령은 현재 디렉터리에만 작용하며 --store를 받지 않습니다.

저장소의 스펙과 변경사항을 스토어로 이동 ​

저장소를 repo-local에서 store-only로 전환하려면:

  1. 저장소의 openspec/specs/와 openspec/changes/에 있는 모든 것을 스토어의 같은 폴더로 이동합니다.
  2. 이제 빈 폴더를 삭제하여 저장소의 openspec/ 폴더에 config.yaml만 남깁니다.
  3. 해당 config.yaml에 store: 줄을 추가합니다.

이제 저장소 내부에서 openspec status를 실행하면 Using OpenSpec root: team-plans로 시작합니다.

스토어에서 작업 ​

워크플로는 본인이나 에이전트에게 변하지 않습니다. 제안, 적용, 보관이 언제나 그래왔듯 진행됩니다. 유일한 차이점은 산출물이 생성되는 위치이며, 위 섹션에서 다룹니다.

store-only 저장소 내부에서 변경사항을 생성하면 스토어에 들어갑니다:

bash
# web-app 내부; store: 줄이 이를 team-plans로 라우팅합니다
openspec new change add-login
yaml
Using OpenSpec root: team-plans (/Users/you/openspec/team-plans)
Created change 'add-login' at /Users/you/openspec/team-plans/openspec/changes/add-login/
Schema: spec-driven
Next: openspec status --change add-login --store team-plans
  • 위치: 코드 옆이 아니라 스토어 저장소에 들어갑니다.
  • 공유: 스토어 저장소를 커밋하고 푸시할 때까지 변경사항은 내 체크아웃에만 존재합니다. 팀원은 풀할 때 이를 볼 수 있습니다. 워크플로가 기록하는 모든 산출물도 마찬가지입니다.
  • 문서의 경로: 문서가 openspec/ 경로를 보여주는 곳마다, 스토어 설정에서 그 폴더는 스토어의 것입니다.

산출물이 예상치 못한 곳에 생성될 때, openspec doctor는 아무것도 변경하지 않고 설정을 점검하며 각 발견 사항에 대한 수정 방법을 출력합니다:

bash
# 현재 루트와 해당 스토어 점검
openspec doctor
yaml
Doctor

Root
  Location: /Users/you/openspec/team-plans
  OpenSpec root: ok
  Store: team-plans (metadata ok)

References
  (none declared)

openspec context는 점검 없이 같은 그림이 필요할 때 현재 디렉터리가 작업하는 루트와 스토어를 나열합니다.

스토어와 저장소를 한 편집기 창에서 열어 에이전트가 둘 다 읽을 수 있게 하려면 워크셋 (베타)를 참조하세요.

다른 스토어에서 스펙 읽기 ​

저장소는 자체 openspec/ 폴더를 유지하면서도 에이전트가 다른 스토어의 스펙을 읽을 수 있도록 할 수 있습니다. 저장소의 openspec/config.yaml에 있는 references: 항목 아래에 해당 스토어를 선언하세요:

yaml
# api-server/openspec/config.yaml
references:
  - team-plans

참조는 읽기 전용입니다. 작업 내용은 저장소에 그대로 유지되며, 참조는 에이전트에 전달되는 정보만 변경합니다.

워크플로우가 아티팩트를 생성할 때, 해당 지침에는 참조 스토어의 스펙 색인이 추가되며, 각 스펙에는 한 줄 요약과 이를 가져오는 정확한 명령이 함께 제공됩니다:

xml
<referenced_stores>
<!-- 읽기 전용 업스트림 컨텍스트. 필요한 것을 가져오고, 사용한 것을 인용하세요. -->
스토어 team-plans (/Users/you/openspec/team-plans):
  - payments: 고객에게 요금을 부과하고 환불하는 규칙.
  가져오기: openspec show <spec-id> --type spec --store team-plans
</referenced_stores>

참조에는 아직 해당 스토어가 없는 머신을 위해 스토어의 clone URL을 포함할 수도 있습니다:

yaml
references:
  - team-plans
  - { id: design-system, remote: "git@github.com:acme/design-system.git" }

URL을 선언하면 openspec doctor가 누락된 스토어를 붙여넣기 가능한 수정 방법으로 바꿔줍니다:

yaml
# 출력이 맞게 줄바꿈됨
참조
  - team-plans: ok (/Users/you/openspec/team-plans)
  - design-system: 참조된 스토어 'design-system'가 이 머신에 등록되어 있지 않습니다.
    수정: git clone -- git@github.com:acme/design-system.git '/Users/you/openspec/design-system' &&
         openspec store register '/Users/you/openspec/design-system' --id design-system

베타 제한 사항 ​

  • 형태가 변경될 수 있음: 명령 이름, 플래그, 파일 형식은 릴리스 간에 변경될 수 있습니다. 업그레이드 후 이 페이지를 다시 읽어보세요.
  • 동기화 없음, 의도된 설계: OpenSpec은 절대 clone, pull, push를 수행하지 않습니다. pull하기 전까지 오래된 체크아웃은 오래된 스펙을 보여주며, 참조는 디스크에 있는 내용 기준으로 읽힙니다.
  • 스토어 이름당 하나의 체크아웃: 이미 등록된 이름으로 두 번째 폴더를 등록하면 실패하며, 먼저 openspec store unregister를 실행하라는 힌트가 제공됩니다.