spec은 스톡 정보인가, 플로우 정보인가?
요약
본 문서는 소프트웨어 개발 과정에서 생성되는 '사양(spec)' 문서를 어떻게 관리할지 논의합니다. 사양을 현재 상태를 나타내는 스톡 정보로 볼지, 특정 작업에 한정된 플로우 정보로 볼지에 따라 관리 방식이 달라집니다. 핵심은 기능 단위로 '현재 사양'(스톡)과 변경 이력을 분리하는 두 계층 구조를 갖는 것입니다.
핵심 포인트
- 사양(spec)을 스톡(Stock)과 플로우(Flow) 정보로 구분하여 관리해야 합니다.
- 스톡 정보는 항상 최신 상태로 유지하고, 플로우 정보는 참조하지 않도록 해야 합니다.
- AI 에이전트는 문서의 '오래됨'보다 '정확성'에 기반해 정보를 신뢰합니다.
- spec-kit 사용 시 사양 변경 이력을 명확히 분리하는 것이 중요합니다.
원문: Spec Kit: Spec Persistence Models / spec-driven.md
저자: GitHub(spec-kit), Birgitta Böckeler(Thoughtworks)ほか
공개일: 불명 (참조는 2026-10-06 시점)
TL;DR
spec-kit으로 생성한 spec을 리포지토리에 남겨야 하는지, 사양 변경 때마다 업데이트해야 하는지에 대한 문제입니다. spec-kit 공식은 하나의 답을 정해두지 않았으며, **'None is the default'**로 3가지 운영 모델을 제시하고 있습니다.
판단 기준은 '그 spec을 스톡(stock)으로 다룰 것인지 플로우(flow)로 다룰 것인지'입니다. 다만, 어느 한쪽에 치우치는 것은 적절하지 않습니다. 기능 단위로 '현재의 사양'을 가진 스톡 계층과, 변경할 때마다 분리하여 끝내면 동결하는 플로우 계층의 두 층으로 나누는 것이 해결책이 됩니다.
동결된 기록을 남겨도 되는 경우는 그것이 '오래되었지만 올바른(old but correct)' 경우입니다. ADR(Architecture Decision Record)가 남길 수 있는 것과 같은 이치로, 남아도 되는지 여부는 오래되었다는 것이 아니라 정확성으로 결정됩니다.
specs/에 쌓여가는 것들
spec-kit에서 /specify
→ /plan
→ /tasks
순서로 진행하면, specs/001-user-login/와 같은 디렉토리가 하나 생기고, 그 안에 spec.md, plan.md, tasks.md가 나열됩니다. 기능을 하나 만들 때마다 002-, 003- 등으로 늘어납니다.
구현하고 머지(merge)한 시점에서 이것들은 역할을 다한 것일까요?
반년 후에 '로그인에 싱글 사인온(SSO)을 추가한다'는 변경이 왔다고 가정해 봅시다. 014-sso-login/를 새로 분리할지, 아니면 001-user-login/spec.md를 수정할까요? 새로 분리한다면, 001에 적힌 '로그인은 이메일과 비밀번호만'이라는 설명은 어떻게 되는 걸까요? 방치하면, 다음에 이 디렉토리를 읽는 AI 에이전트는 001과 014 중 무엇을 신뢰해야 할지 알 수 없습니다.
핵심은 spec의 내용 자체가 아니라, spec을 어떤 종류의 문서로 작성했는지에 있습니다.
스톡이라면 최신으로, 플로우라면 읽게 하지 마라
정보에는 두 가지 종류가 있습니다. **스톡 정보(Stock information)**는 언제 읽어도 '현재 상태'를 나타내는 전제 조건의 문서입니다. **플로우 정보(Flow information)**는 특정 시점의 작업을 위해 작성되었고, 그 작업과 함께 흘러가는 문서입니다.
spec을 스톡 정보로 간주한다면, 리포지토리에 남겨서 항상 최신 상태로 유지해야 합니다. 사양 변경이 있으면 관련 spec도 모두 동시에 수정합니다. 수정하지 않으면, 스톡으로서의 전제가 무너집니다.
spec을 플로우 정보로 간주한다면, 업데이트할 필요가 없습니다. 대신 참조하지 않습니다. 참조하지 않는다면, 남겨둘 이유도 많지 않습니다.
어느 쪽으로 처리하든 논리는 통합니다. 위험한 것은 처리를 결정하지 않은 채 계속 남아있는 것입니다. 플로우로 작성된 것이 스톡의 모습으로 읽힙니다. 인간이라면 날짜나 커밋 히스토리를 보고 '이건 오래됐네'라고 알아차릴 수 있지만, 에이전트는 리포지토리 안에 있는 문서를 동등한 맥락으로 가져옵니다. 오래된 의도 그대로 구현하고, 한 번 고친 버그를 되돌립니다.
그렇다면 spec-kit은 어떤 의도로 spec을 만들고 있을까요?
spec-kit 공식의 혼란
공식 문서를 읽어보면, 두 가지 답이 나옵니다.
이념은 스톡(Stock)에 기울어져 있다
spec-kit의 사상을 정리한 spec-driven.md는 spec을 명확하게 스톡으로 취급합니다.
Maintaining software means evolving specifications.
The specification becomes the primary artifact. Code becomes its expression in a particular language and framework.
요구사항이 바뀌면 PRD(Product Requirements Document, 제품 요구 사양서)를 수정하고, 거기에서 구현 계획을 다시 세웁니다. 운영상의 메트릭이나 인시던트도 핫픽스(hotfix)로 끝내지 않고 spec으로 되돌립니다. spec이 유일한 진실이며, 코드는 거기에서 파생된다는 세계관입니다.
제작 방식은 플로우(Flow)에 기울어져 있다
하지만 실제 툴의 동작은 다릅니다. spec은 브랜치와 쌍을 이루어 기능별로 번호가 매겨 잘리며, 하나의 변경 요청이 끝나면 다음 번호로 넘어갑니다. Thoughtworks의 Birgitta Böckeler는 martinfowler.com의 SDD 툴 비교에서 다음과 같이 지적했습니다.
spec-kit은 생성되는 모든 spec마다 브랜치를 만드는데, 이는 그들이 spec을 기능의 수명 주기(lifetime)가 아닌 변경 요청의 생애물(living artifact)로 본다는 것을 시사합니다.
Böckeler는 SDD를 3단계로 나누었습니다. spec을 먼저 작성하여 구현에 사용하는 spec-first, 구현 후에도 spec을 남겨 가꾸어 나가는 spec-anchored, spec만 사람이 편집하고 코드에는 손대지 않는 spec-as-source입니다. Böckeler의 견해로는, spec-kit의 철학은 spec-anchored 이상을 이야기하고 있지만, 툴의 제작 방식은 spec-first에 머물러 있다는 것이었습니다.
그리고 공식은 '결정하지 않음'을 선택했다
이 차이는 커뮤니티에서도 반복적으로 질문되었고, spec-kit은 현재 문서에 Spec Persistence Models라는 장을 마련하고 있습니다. 나열된 것은 3가지 모델입니다.
| 모델 | 완료된 디렉터리의 처리 방식 | 공식이 제시하는 위험성 |
|---|---|---|
| Flow-Forward | 변경하지 않는 이력으로 남김. 새로운 요청은 새로운 디렉터리로 처리 | 관련된 판단이 여러 디렉터리에 흩어짐 |
| Living Spec | spec.md를 진실로 간주하고, plan과 tasks는 거기서 재작성함 | 재작성 과정에서 구현 시의 이유 설명(reasoning)이 사라짐 |
| Flow-Back | 어떤 결과물로부터 수정해도 좋으며, 나중에 전체를 맞춰봄 | 하류 변경 사항이 spec으로 돌아오지 않고 조용히 어긋나감 |
그리고 무엇을 지향해야 하는지에 대해서는 다음과 같이 적혀 있습니다.
None is the default, and none is required by Spec Kit. (기본값은 없으며, Spec Kit에 의해 요구되는 것도 없습니다.)
팀 차원에서 '완료된 디렉터리는 이력인가, 편집 가능한 작업장인가', 'spec.md가 유일한 진실인가'를 결정하여 프로젝트의 헌법(constitution)에 기록해 두는 것이 공식적인 지침입니다.
Flow-Forward는 흐름(flow)의 처리에 관한 것이고, Living Spec은 스톡(stock)의 처리에 관한 것입니다. Flow-Back도 스톡 측에 속하지만, spec을 최신 상태로 유지하는 것을 'spec.md부터 먼저 수정한다'는 절차를 따르기보다는 나중에 다시 기록하는 규율에 맡깁니다 (Living Spec이 반드시 spec에서 수정해야 하는 것과 달리, Flow-Back은 구현 중에 발견된 tasks나 plan에서 수정해도 좋습니다). 빠르게 진행할 수 있는 대신, 스톡으로서의 신뢰도는 떨어지기 쉽습니다.
spec-kit은 어떤 것을 선택하든 좋다고 결정했습니다. 3가지 모델을 명명한 유지보자(maintainer)의 제안에 따르면, 이는 의도적인 것인 듯합니다.
Spec Kit today is intentionally unopinionated about what happens to spec.md, plan.md, and tasks.md once requirements start changing — and I think that's the right design choice. (오늘날 Spec Kit은 요구사항이 변경하기 시작했을 때 spec.md, plan.md, tasks.md에 어떤 일이 일어나는지에 대해 의도적으로 의견을 제시하지 않으며—그리고 저는 그것이 올바른 설계 선택이라고 생각합니다.)
선택하게 하는 것 자체는 문제가 없습니다. 다만, 선택한 모델을 구동하는 도구는 본체(core)에 포함되어 있지 않습니다. analyze는 하나의 기능 디렉터리 안을 비교하며 읽을 뿐 파일에는 손대지 않습니다. converge는 spec을 진실로 간주하고 부족한 tasks를 추가하지만, spec 자체는 수정하지 않습니다. 기존 spec을 수정할 방법이 없다는 요청은 2025년 가을부터 여러 번 올라왔으며, #1191에는 'Critical feature omission.'이라는 의견들이 나열되어 있습니다. 기능 단위로 남는 spec을 요구한 #1100에 대해 유지보자는 확장(extension)이나 프리셋(preset)으로 처리해 달라고 답했습니다. 도구는 커뮤니티 확장의 카탈로그에 맡겨졌으며, 그 카탈로그에 대해서만 유지보자는 형식 확인만 하고 코드는 리뷰하지 않을 것이라고 명시했습니다.
같은 제안 안에서, 유지보수자(멘테나) 자신이 이렇게 질문했습니다.
Does the "three models, no preferred default" framing resonate, or does it feel like a cop-out?
이 질문에 대해서는 댓글이 단 하나도 없습니다. 용어를 배치하고 선택의 책임을 팀에게 넘기고, 선택한 후의 도구는 외부에 둡니다. '보류'라고 부르기에는 너무 많은 것을 놓아버린 상태입니다.
다른 도구들은 어떤가요
spec-kit이 결정하지 않았다면, 다른 SDD(Software Design Document) 도구들은 어떻게 하고 있을까요? 완료된 spec/계획/태스크를 그 이후에 어떻게 처리하는지 각 도구의 공식 문서와 리포지토리를 통해 확인했습니다 (2026-10-06 시점).
| 도구 | 저장 위치 | 완료 후 처리 방식 | '현재 상태'를 유지하는 계층 | spec을 스톡으로 관리하는 방침 |
|---|---|---|---|
| spec-kit | specs/NNN-<feature>/ | 세 가지 모델을 나열하고, 기본값은 두지 않음 | constitution | 결정하지 않음 |
| Kiro | .kiro/specs/<feature>/ | 아카이브나 삭제 메커니즘이 없습니다. 리포지토리에 두고 프로젝트에 맞춰 계속 업데이트하는 것으로 간주함 | .kiro/steering/ | 있음 |
| OpenSpec | openspec/specs/ 와 openspec/changes/ | 차이점(diff)을 specs/에 가져온 후, changes/archive/에 날짜와 함께 동결시킴 | openspec/specs/ | 있음 (변경 기록은 동결하여 남김) |
| BMAD-Method | _bmad-output/ 하위 디렉터리에 PRD・epic・story 계획
| 완료된 story의 계획은 증거로 남긴다. PRD는 계속 수정한다 | PRD・architecture | 있음 (계획은 동결하여 남김) |
| Tessl | spec과 구현 파일이 1 대 1 | spec을 기준으로 유지하는 구상이었으나, 현재 문서에는 보이지 않음 | spec 자체 | 현재는 불명확함 |
| Agent OS | agent-os/specs/<날짜>-<slug>/ | 기술되어 있지 않음. 날짜가 붙은 폴더들이 쌓여감 | product/ standards/ | 명시되지 않음 |
| cc-sdd | .kiro/specs/<feature>/ | 기술되어 있지 않음. 정답(正)은 코딩이라고 명확히 밝힘 | .kiro/steering/ | 명시되지 않음 |
| Spec Workflow MCP | .spec-workflow/specs/ | archive/로 통째로 옮김. 현재 사양에는 포함하지 않음 | .spec-workflow/steering/ | 명시되지 않음 |
| Claude Code의 플랜 모드 | ~/.claude/plans/ | 기본적으로 30일 후에 자동 삭제됨 | CLAUDE.md | 명시되지 않음 |
| Cursor의 플랜 모드 | 홈 디렉터리 | "Save to workspace"를 통해 리포지토리로 옮길지는 사용자에게 맡김 | rules・AGENTS.md | 명시되지 않음 |
| AGENTS.md | 리포지토리 직하위 | spec이 아님. 그것 자체를 계속 업데이트함 | AGENTS.md 자체 | 대상 외 |
완료 후 처리 방식에 대해 명확하게 적어 놓은 도구는 거의 없습니다.
방침을 알 수 있는 것은 세 가지입니다. Kiro는 spec을 기능별로 나누어 리포지토리에 두고, "프로젝트의 진화에 맞춰 업데이트하는" 방식을 취하고 있습니다. Böckeler의 비교에서는 spec-first로 판정되었지만, 현재 문서는 spec을 키우는 쪽에 가깝습니다. OpenSpec은 현재 사양(spec)을 놓는 specs/와 변경 사항별(changes/) 것을 다른 디렉터리로 분리하고 있습니다. BMAD는 PRD를 계속 수정하는 한편, 완료된 story의 계획은 "나중 검토나 회고가 읽을 증거"이므로 지우지 말라고 적어 놓았습니다. 이 세 가지 모두 spec을 스톡(stock)으로 보유할 목적으로 만들어졌습니다.
남아있는 툴들 중에서는 spec을 스톡(stock)으로 키우는 방식을 찾기 어렵습니다. Agent OS와 cc-sdd는 자리를 정해 놓았을 뿐, 끝난 후에는 건드리지 않았습니다. 잊어버린 것이라기보다는 포기한 것에 가깝다고 생각합니다. cc-sdd는 'Code remains the source of truth'라고 단언하며 spec을 작업용 계약으로 위치시킵니다. Spec Workflow MCP는 완료된 spec 전체를 archive로 옮길 뿐, 현재 사양에는 통합하지 않습니다. Claude Code의 플랜 모드는 계획을 30일 후에 삭제합니다. spec-as-source에 가장 가까웠던 Tessl은 지금 문서에서 그 기능이 사라졌습니다.
'현재 상태'를 가진 계층 자체는 거의 모든 툴에 있습니다. steering, product/, CLAUDE.md, AGENTS.md입니다. 다만, 거기에 적혀 있는 것은 제품의 목적이나 기술 스택 같은 전반적인 방침이지, 기능별 사양이 아닙니다. 기능의 사양까지 최신으로 유지하려고 노력하는 곳은 앞서 언급한 세 군데뿐입니다.
spec-kit의 'None is the default'는 많은 툴이 적지 않고 있는 공백을 스스로 글로 채운 점에서 이례적인 경우입니다. 단순히 적었을 뿐, 채워 넣지는 않았습니다. 어떤 모델을 선택하든, 서두에 나오는 싱글 사인온(Single Sign-On) 질문은 아직 해결되지 않습니다.
기능 번호로 나눈 spec은 본래 플로우의 형태를 띠고 있다
Living Spec을 선택하여 spec을 스톡으로 다루기로 한다고 가정해 봅시다. 싱글 사인온을 추가할 때, 001-user-login/spec.md만 수정하면 될 것 같습니다.
정말로 그것으로 끝날까요?
싱글 사인온을 추가하면 로그인 화면뿐 아니라 세션 관리(003-session-timeout)와 감사 로그(009-audit-log)에도 손이 갑니다. 스톡으로서 정확성을 유지하려면 이 3개의 spec를 동시에 찾아 수정해야 합니다. 어느 것에 영향을 미치는지 알려면 과거의 spec을 전부 읽지 않으면 알 수 없습니다.
이것은 스톡이라는 개념의 문제가 아닙니다. '001을 만들었을 때', '014를 만들었을 때'와 같은 작업 단위로 나뉜 spec은 구조적으로 플로우의 형태를 띠고 있습니다. 플로우의 형태로 계속 스톡으로 다루려고 하기 때문에, 과거의 spec을 파헤치는 고행이 생기는 것입니다.
스톡으로 하려면, 자르는 방식을 바꿉니다. 작업 단위가 아니라, 기능 단위로 '현재 사양'을 한 장씩 갖는 것입니다. auth/login.md, auth/session.md, audit/log.md처럼 나열해 놓으면, 싱글 사인온을 추가할 때 수정해야 할 곳은 기능 이름에서 파악할 수 있습니다.
표에 제시된 OpenSpec은 이 두 계층의 구분 방식을 처음부터 내장하고 있습니다. openspec/specs/에 기능 단위의 '현재 정답'을 두고, 변경 사항은 openspec/changes/에 분리합니다. 변경 spec에는 차이점(ADDED / MODIFIED / REMOVED)만 작성하고, 끝나면 그 차이점을 specs/에 통합하고, 변경 폴더는 날짜가 붙어 changes/archive/로 옮깁니다.
스톡 계층(specs/)은 항상 최신 상태. 플로우 계층(changes/)은 끝나면 동결하여 archive로 이동
스톡은 계속 업데이트하고, 플로우는 동결합니다. 싱글 사인온을 어디에 적을지는 이것으로 결정됩니다. 아직 결정되지 않은 것은, 동결된 changes/archive/를 버릴지 남길지입니다.
오래되었지만 정확하다면, 남겨도 좋다
플로우는 참조하지 않으니 바로 지워버리면 됩니다. 그렇게 생각할 수도 있습니다. 다만, 설계 판단 기록으로 ADR(Architecture Decision Record)을 남기는 습관은 널리 정착되어 있습니다. ADR 역시 시간이 지나면 오래되는 문서입니다. 오래된 spec은 삭제하고, 오래된 ADR은 보존합니다. 이 차이는 어디에서 오는 것일까요?
차이는 오래됨이 아니라, 정확성에 있습니다.
오래된 spec이 위험한 것은 오래되어서가 아닙니다. '현재 시스템은 이렇게 작동한다'고 쓰여 있는데, 현재 시스템이 그렇게 작동하지 않기 때문입니다. 오래되었으면서도 틀린 경우입니다. 스톡으로 작성된 문서는 업데이트가 멈추는 순간부터 오류로 변해갑니다.
ADR은 그렇지 않습니다. ADR에 적혀 있는 것은 '2026년 7월에, 이런 이유로 A가 아닌 B를 선택했다'라는 과거의 의사결정입니다. 최신 상태를 반영하는 것이 아니라, 과거의 기록(snapshot)이기 때문에 영원히 올바른 상태입니다. 시간 여행으로 역사를 바꿀 때만 아니면 절대적으로 옳습니다. 나중에 판단이 뒤집혀도 그 ADR은 틀리지 않습니다. '뒤집힌 판단의 기록'으로서 계속 올바르게 남게 됩니다.
그러므로, 동결된 플로우 역시 같은 조건으로 남겨두어도 무방합니다. changes/archive/2026-10-06-sso-login/
여기에 적혀 있는 것은 '이 날, 싱글 사인온을 이렇게 넣으려고 했다'는 기록이며, 이것은 수정하지 않는 한 올바릅니다.
다만, 이 올바름에는 조건이 붙습니다. snapshot으로서 읽힐 때라는 조건입니다. 날짜도 상태도 없는 spec이 리포지토리 중앙에 놓여 있다면, 독자는 그것을 '현재의 사양'으로 읽게 됩니다. 그 순간, 올바른 기록은 잘못된 사양으로 변해버립니다. ADR이 오래되었더라도 안전한 이유는 번호와 날짜와 status
를 가지고 있으며, '이것은 과거의 판단이다'라고 명시하고 있기 때문입니다.
남겨두어도 좋은 조건은 이로써 두 가지가 됩니다.
- 내용을 수정하지 않는다 (수정하면 snapshot으로서의 올바름을 잃게 된다)
- snapshot임을 독자에게도 에이전트에게도 알 수 있다 (날짜, 상태, 위치 등으로 알 수 있게 한다)
두 가지를 충족할 수 없는 기록은 남겨두는 것이 해가 더 큽니다. 만약 충족시킬 수 있다면, 왜 현재의 사양이 이렇게 되었는지 추적하는 단서로서 가치가 있습니다.
하나의 방안: 기능 단위로 사양을 갖는 docs/ 구성
기능 단위의 스톡 정보와 동결된 기록을 실제로 어떻게 배치할지. 필자가 개발 중인 macOS용 AI 워크스페이스 Aidea(GitHub에서 공개 중)의 docs/를 예로 소개합니다. spec-kit이나 OpenSpec을 사용하지 않고, 수동으로 운영해 온 구성입니다. spec이 56개 파일, ADR이 42건 있습니다.
docs/
├── LAYOUT.md # 배치 규칙 그 자체. 어디에 무엇을 쓸지 유일한 참조처
├── foundation/ # 만들 동기와 원칙 (거의 변하지 않음)
...
계층은 '변경되는 계기'로 나눈다
이 구성의 핵심은 문서를 내용의 종류가 아니라, 언제 변경되는지에 따라 나누고 있다는 점입니다.
| 계층 | 작성하는 내용 | 변경되는 계기 | 성질 |
|---|---|---|---|
foundation/ | 가치관・목적 | 가치관이 변했을 때 (거의 변하지 않음) | 스톡 |
| GitHub Issues | 요구사항 (~하고 싶다) | 구현되면 소모됨 | 플로우 |
specs/ | 시스템 동작 (~한다 / 항상 ~가 성립한다) | 동작을 바꿀 때 (코드와 동시에) | 스톡 |
conventions/ | 어떻게 쓸지 | 구현 방법을 바꿀 때 | 스톡 |
decisions/ | 왜 A가 아닌 B인가 | 변경하지 않음 (대체만) | snapshot |
plans/ | 이번 구현 계획 | 작업이 끝나면 소용없어짐 | 플로우 |
모든 계층에 공통되는 원칙은 하나뿐이며, 변경의 계기가 다른 것을 같은 파일에 쓰지 않는 것입니다. spec-kit의 specs/001-xxx/는 요구사항(플로우), 동작 사양(스톡), 구현 계획(플로우), 판단 이유(snapshot)를 하나의 디렉터리에 모아 놓았습니다. 나중에 다루기 어려워지는 것은 이 동거가 원인이라고 생각합니다.
스톡 계층을 최신으로 유지하기 위한 약속
- specs/에는 스톡 정보만 쓴다. 범위(scope), MVP, 일정, 미구현 아이디어는 적지 않고 Issue 쪽에 둔다 -
- 대체된 spec은 삭제한다. specs/에는 '폐지'도 '대체'도 상태로 존재하지 않는다. 거기에 있는 문서는 모두 현재의 사양이다 -
- 요구사항은 spec 시작 부분에 1~2문장으로 요구 자체는 Issue와 함께 닫아서 흘린다
issue #NN
링크만 남긴다 -
- 문서 간 의존성을 frontmatter에 쓴다.
derived_from(상대방이 바뀌면 자신을 고친다),syncs_with(어느 쪽을 바꿔도 상대방을 고친다),impacts
(自分を変えたら相手を直す)의 3가지 유형으로, 특정 spec을 수정했을 때 함께 봐야 할 문서를 에이전트가 기계적으로 추적할 수 있습니다 -
코드를 변경했지만 specs/를 변경하지 않은 커밋에는 경고를 표시합니다. post-commit hook에서 감지하여 커밋은 막지 않고 알려줍니다.
플로우(Flow) 계층과 스냅샷(Snapshot) 계층의 처리
- 구현 계획은 진부화가 빠르기 때문에 스냅샷으로 남길 가치가 없습니다. 계획 과정에서 나온 중요한 판단만 ADR에 승격시킵니다 (
plans/).
plans/는 git 관리 대상에서 제외합니다. 다만, Claude Code를 클라우드에서 구동하는 경우 리포지토리에 push한 것만 볼 수 있으므로, plans/도 git에 포함해야 합니다. 그 경우에는 'plans/는 참조하지 않는다'고 에이전트용 규칙에 명시하거나, 과거의 계획이 현재 사양으로 읽히는 것을 방지하는 방법도 생각해볼 수 있습니다 -
ADR은 작성 후에 본문을 수정하지 않습니다. 바뀌는 것은 status와 replaces/replaced_by뿐입니다. 판단이 뒤집되면 새로운 ADR을 작성하여 오래된 것을 대체합니다 -
ADR의。「ADR이 바뀌면 spec을 고친다」라는 관계는, ADR이 변하지 않는 전제에서는 성립할 수 없습니다. 의존성은 spec 측의 impacts와 syncs_with은 항상 비워두고, derived_from에 ADR을 작성하여 표기합니다. 새로운 spec이 오래된 ADR을 참조하더라도, ADR 쪽은 일절 건드릴 필요가 없습니다.
싱글 사인온(Single Sign-On)의 예에 적용하면 다음과 같습니다. 요구사항은 Issue에 작성하고, 구현 계획은 plans/에 작성 후 버립니다. '왜 SAML이 아니라 OIDC를 사용했는지'는 ADR에 남깁니다. specs/에서는 로그인과 세션 기능군 spec을 수정합니다. 어떤 spec을 수정할지는 기능군의 이름과 frontmatter에서 파악할 수 있으므로, 과거 작업 디렉토리를 뒤질 필요가 없습니다.
함정(落とし穴)
archive로 옮겼다고 해서 에이전트가 안 읽는 것은 아니다
동결된 기록을 archive/로 옮겨도, 에이전트가 grep이나 전체 검색을 하면 평범하게 걸립니다. '읽게 하지 않기'는 디렉토리를 나눈 것만으로는 실현할 수 없습니다. 에이전트의 지시 파일에 'archive와 decisions는 경위 참조에만 사용하고, 현재 사양은 specs/를 정답으로 한다'고 명시하거나, 검색 대상에서 제외하는 설정까지 넣어둡니다.
기능 단위로 하면, 기능을 가로지르는 사양을 둘 곳이 없다
키 조작, 영속화, 목록의 정렬 순서처럼 여러 기능에 동일한 규칙이 적용되는 사양은 어느 기능군에도 들어갈 수 없습니다. 각 기능군마다 같은 내용을 쓰면 스톡(stock)이 중복되어 한쪽만 오래되게 됩니다. Aidea에서는 specs/aspects/를 가로지르는 관심사(cross-cutting concerns)의 장소로 마련하고, 개별 기능군의 spec과 syncs_with으로 연결합니다.
ADR을 '조금만' 고치고 싶어진다
ADR의 서술이 현재 구현과 맞지 않으면, 무심코 본문을 수정하고 싶어집니다. 수정한 순간, 그 ADR은 '당시 판단 기록'도 '현재 사양'도 아닌 애매한 문서가 됩니다. 현재 사양은 specs/에 작성하고, ADR에는 손대지 않습니다. Aidea의 42개 ADR은 현시점 모두 '채택(採用)' 상태 그대로이며, 대체하는 연쇄는 아직 한 번도 일어나지 않았습니다. 운영에서 시험받을 것은 앞으로입니다.
spec-kit으로 시작한다면
spec-kit의 specs/NNN-xxx/는 그 자체로 Flow-Forward의 플로우 계층으로 사용할 수 있습니다. 병합하는 시점에 동결하고 수정하지 않습니다. 그 위에 기능 단위의 '현재 사양'을 둘 스톡 계층을 별도로 가집니다. 병합할 때마다, 차이점을 스톡 계층으로 가져오는 절차를 하나 추가합니다.
이 운영 방식은 constitution에 작성해둡니다. 공식적으로 'None is the default'라고 말하고 있는 이상, 정하지 않으면 아무도 정해주지 않습니다. 정하지 않은 채 번호가 매겨진 디렉토리가 30개 쌓이면, 에이전트는 그것을 전부 '현재 사양'으로 읽어버립니다.
참고
- Spec Kit: Spec Persistence Models — 세 가지 모델과 'None이 기본값'
- Spec Kit: 기존 프로젝트에 Spec Kit 도입하기 — 완성된 결과물의 유지보수 방침을 팀으로 결정하기
- spec-kit / spec-driven.md — '소프트웨어를 유지보수한다는 것은 명세(specifications)를 진화시킨다는 것을 의미한다'
- spec-kit Discussion #2831: Spec Kit 사용 세 가지 방법 — 3개 모델의 명명과 '회피하는 것?'에 대한 질문
- spec-kit #1191 / #1100 — 기존 spec 수정 방법, 기능 단위로 남는 spec에 대한 요청
- Spec Kit Extensions — 커뮤니티 확장 카탈로그와 리뷰 방침
- Understanding Spec-Driven-Development: Kiro, spec-kit, and Tessl (Birgitta Böckeler) — spec-first / spec-anchored / spec-as-source
- OpenSpec overview — specs/ 와 changes/ 의 분리, 차이점 통합 및 아카이브
- Kiro: Specs best practices — spec을 리포지토리에 두고 지속적으로 업데이트하기
- BMAD-Method: Break work into stories and track it — '완료된 계획 유지하기'
Agent OS —
product/
standards/
그리고 날짜가 찍힌 specs/
- cc-sdd — '코드가 진실의 원천으로 남는다' (Code remains the source of truth)
- Spec Workflow MCP — 완료된 spec 아카이브 및 복원
Claude Code: The .claude directory —
plans/
은 cleanupPeriodDays
AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기