lee-spec-kit 0.8.7 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lee-spec-kit",
3
- "version": "0.8.7",
3
+ "version": "0.9.0",
4
4
  "description": "Document-centered harness engineering toolkit for AI agent development",
5
5
  "type": "module",
6
6
  "bin": {
@@ -30,13 +30,29 @@ npx lee-spec-kit docs get agents --json
30
30
 
31
31
  ## Directory Structure
32
32
 
33
- | Path | Purpose | Key Documents |
34
- | ----------------- | --------------------- | ------------- |
33
+ | Path | Purpose | Key Documents |
34
+ | ----------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------ |
35
35
  | `docs/agents/` | Agent operating rules | `custom.md`, `constitution.md` (engine-managed guides are fetched via `npx lee-spec-kit docs get <doc-id> --json`) |
36
- | `docs/prd/` | Product requirements | Project-specific |
37
- | `docs/designs/` | Design references | `README.md` (links/guidelines/references) |
38
- | `docs/ideas/` | Ideas / to-dos | `README.md` (Idea → Feature promotion rules) |
39
- | `{{featurePath}}` | Feature documentation | `{feature-id}/spec.md`, `plan.md`, `tasks.md`, `decisions.md` |
36
+ | `docs/prd/` | Product requirements | Project-specific |
37
+ | `docs/designs/` | Design references | `README.md` (links/guidelines/references) |
38
+ | `docs/ideas/` | Ideas / to-dos | `README.md` (Idea → Feature promotion rules) |
39
+ | `{{featurePath}}` | Feature documentation | `{feature-id}/spec.md`, `plan.md`, `tasks.md`, `decisions.md` |
40
+
41
+ ---
42
+
43
+ ## Document Routing
44
+
45
+ | Document content | Location |
46
+ | --------------------------------------------------------------------- | ----------------------------------- |
47
+ | Product requirements, user stories, and product roadmaps | `docs/prd/` |
48
+ | System architecture overviews shared by multiple Features | `docs/prd/*-overview.md` |
49
+ | Durable architecture principles | `docs/agents/constitution.md` |
50
+ | Technical research and candidate comparisons before Feature promotion | The relevant `docs/ideas/I###-*.md` |
51
+ | Implementation design for an active Feature | That Feature's `plan.md` |
52
+ | Technical choices, alternatives, and trade-offs | That Feature's `decisions.md` |
53
+ | Screens, Figma, design systems, and UI flows | `docs/designs/` |
54
+
55
+ Keep product roadmaps in `prd/`, but manage implementation sequencing and work plans in the active Feature's `plan.md` and `tasks.md`. The `designs/` directory is reserved for UX and visual design, not technical design.
40
56
 
41
57
  ---
42
58
 
@@ -114,6 +130,15 @@ When you run `lee-spec-kit init`, it creates `.lee-spec-kit.json` in the docs ro
114
130
  - `docsRepo` ("embedded" | "standalone"): How docs are managed
115
131
  - `pushDocs` (boolean, optional): Only written when `docsRepo: "standalone"` (whether to push to remote)
116
132
  - `docsRemote` (string, optional): Only written when `pushDocs: true` (remote repo URL)
133
+ - `workflow.prePrReview.reviewer` (object): Pre-PR subagent execution settings
134
+ - `type`: currently only `"subagent"` is supported
135
+ - `model`: `"inherit"` or a model name supported by the runtime
136
+ - `reasoningEffort`: `low | medium | high | xhigh | max | ultra`
137
+ - `onUnavailable`: `inherit | error` when the requested model is unavailable
138
+ - `workflow.baseBranch` (string): branch that receives a completed local Feature
139
+ - `workflow.completionStrategy` (`"local-ff" | "none"`): fast-forward and verify local Features before `done`, or explicitly finish without integration
140
+ - `workflow.deleteFeatureBranchAfterMerge` (boolean): delete the integrated local Feature branch after cleanup; remote branches are never deleted
141
+ - `workflow.postMergeChecks` (array): structured commands run from the base branch after local integration, for example `{ "command": "pnpm", "args": ["test"] }`
117
142
  - `approval` (object, optional): optional approval-checkpoint metadata for repo policy and custom validators
118
143
  - The Codex-native default path still asks at documented checkpoints and before remote/destructive actions first.
119
144
  - Legacy runtime consumed this field directly; keep it only when you intentionally want category-based checkpoint metadata.
@@ -121,6 +146,8 @@ When you run `lee-spec-kit init`, it creates `.lee-spec-kit.json` in the docs ro
121
146
  - `mode: "category"`
122
147
  - `default: "skip"`
123
148
  - `requireCheckCategories: ["spec_approve", "implementation_approve"]`
149
+ - In a `local-ff` workflow, `implementation_approve` explicitly authorizes the remaining fast-forward integration, post-merge checks, managed-worktree removal, and configured local Feature-branch deletion.
150
+ - Add `local_merge` to `requireCheckCategories` when a separate approval immediately before integration is required.
124
151
  - Approval token: `A`
125
152
  - Accepted replies: `A`, `A OK`
126
153
  - `allowedDocsEntries` (object, optional): Allowlist non-standard top-level docs entries so they are not treated as unmanaged docs
@@ -136,6 +163,22 @@ When you run `lee-spec-kit init`, it creates `.lee-spec-kit.json` in the docs ro
136
163
  "lang": "en",
137
164
  "createdAt": "{{date}}",
138
165
  "docsRepo": "embedded",
166
+ "workflow": {
167
+ "mode": "local",
168
+ "baseBranch": "main",
169
+ "completionStrategy": "local-ff",
170
+ "deleteFeatureBranchAfterMerge": true,
171
+ "postMergeChecks": [],
172
+ "prePrReview": {
173
+ "evidenceMode": "path_required",
174
+ "reviewer": {
175
+ "type": "subagent",
176
+ "model": "inherit",
177
+ "reasoningEffort": "high",
178
+ "onUnavailable": "inherit"
179
+ }
180
+ }
181
+ },
139
182
  "allowedDocsEntries": {
140
183
  "dirs": ["plans"]
141
184
  },
@@ -147,6 +190,8 @@ When you run `lee-spec-kit init`, it creates `.lee-spec-kit.json` in the docs ro
147
190
  }
148
191
  ```
149
192
 
193
+ New local projects use `local-ff`. During `update`, an existing local project with no explicit `completionStrategy` receives `none` so an upgrade does not unexpectedly merge its current branch. Set it to `local-ff` deliberately when ready.
194
+
150
195
  ```json
151
196
  {
152
197
  "projectName": "{{projectName}}",
@@ -27,23 +27,42 @@ This document defines workflow policy, not a custom runtime loop.
27
27
  - After reading the active feature docs, run `npx lee-spec-kit workflow-stage <featureRef> --json` and follow only that `nextAction`.
28
28
  - If `workflow-stage --json` also returns `primaryActionLabel` and `actionOptions`, treat `primaryActionLabel` as the default option label and present the exact `actionOptions[*].reply` tokens to the user.
29
29
 
30
+ ## Document Routing
31
+
32
+ | Content | SSOT location |
33
+ | --------------------------------------------------------- | ----------------------------------- |
34
+ | Product requirements, user stories, and product roadmaps | `docs/prd/` |
35
+ | System architecture overviews shared by multiple Features | `docs/prd/*-overview.md` |
36
+ | Durable architecture principles | `docs/agents/constitution.md` |
37
+ | Pre-Feature technical research and candidate comparison | The relevant `docs/ideas/I###-*.md` |
38
+ | Active Feature implementation design | That Feature's `plan.md` |
39
+ | Technical choices, alternatives, and trade-offs | That Feature's `decisions.md` |
40
+ | Screens, Figma, design systems, and UI flows | `docs/designs/` |
41
+
42
+ - Do not use `docs/designs/` for system architecture, data/API design, technical research, or implementation plans.
43
+ - Follow the detailed routing rules in `docs/README.md`.
44
+
30
45
  ## Execution Rules
31
46
 
32
47
  - lee-spec-kit owns docs structure, workflow stages, and validators.
33
48
  - Codex owns the execution loop, tool usage, and hook lifecycle.
34
49
  - Do not start implementation unless `workflow-stage --json` reports `stage === "implementation"` and `implementationAllowed === true`.
50
+ - When `workflow-stage --json` returns `nextAction.category: pre_pr_review` with `executor: subagent`, run a fresh, read-only subagent review using the returned `model`, `reasoningEffort`, and `onUnavailable` policy. Do not select or require a named review skill.
51
+ - The Pre-PR review subagent returns findings without modifying code. The main agent remediates findings and records reviewer metadata and the final decision as evidence.
35
52
  - Treat spec/plan/tasks approval, issue creation, and branch creation as hard gates before implementation.
36
53
  - In standalone mode, do not hand-write `git worktree add`; run the exact `nextAction.command` from `workflow-stage` so the managed workspace path, stale directory cleanup, and `.env`/`.env.*` copy step stay consistent.
54
+ - In local mode, do not stop after implementation approval. Follow the exact `local merge` and `local cleanup` commands returned by `workflow-stage` until verified integration and cleanup produce `done`.
55
+ - In a `local-ff` workflow, present the returned implementation-approval summary without weakening it: that checkpoint authorizes fast-forward integration, post-merge checks, and configured local cleanup. Ask again at `local_merge` only when that category is explicitly required.
37
56
  - Keep docs synced with code changes in the same turn whenever behavior or scope changes.
38
57
  - Use `npx lee-spec-kit commit-audit --json` before `git commit` when staged docs paths need validation.
39
58
  - Use `npx lee-spec-kit workflow-audit --json` as the default end-of-turn docs sync check.
40
59
 
41
60
  ## Approval Rules
42
61
 
43
- | Current action (examples) | What to share |
44
- | --- | --- |
45
- | Issue creation | Before `npx lee-spec-kit github issue <featureRef> --create` |
46
- | PR creation | Before `npx lee-spec-kit github pr <featureRef> --create` |
62
+ | Current action (examples) | What to share |
63
+ | ------------------------- | ------------------------------------------------------------ |
64
+ | Issue creation | Before `npx lee-spec-kit github issue <featureRef> --create` |
65
+ | PR creation | Before `npx lee-spec-kit github pr <featureRef> --create` |
47
66
 
48
67
  - Ask the user for approval at documented workflow checkpoints and before remote or destructive actions.
49
68
  - If `workflow-stage --json` says `approvalRequired === true`, stop and ask the user at that checkpoint.
@@ -17,7 +17,9 @@ Execution-state SSOT is the feature-local `pr.md`.
17
17
 
18
18
  ## Pre-PR Baseline Checklist (`builtin-checklist`)
19
19
 
20
- Always run this checklist in Pre-PR review. Treat it as the minimum baseline, then use review skills for deeper inspection when available.
20
+ The Pre-PR subagent must always run this minimum baseline. Do not depend on a named review skill.
21
+
22
+ When `workflow-stage --json` returns `nextAction.executor: subagent`, delegate the review to a fresh, read-only subagent. `model: inherit` means inheriting the current model; any other value is used as the subagent model override. If that model is unavailable, follow `onUnavailable` (`inherit` or `error`).
21
23
 
22
24
  1. Review alignment with `spec.md` / `plan.md` / `tasks.md` and confirm implementation still matches the original goal.
23
25
  2. Inspect regression, exception handling, critical/security risks, side effects, user flow impact, and release readiness.
@@ -31,6 +33,8 @@ Always run this checklist in Pre-PR review. Treat it as the minimum baseline, th
31
33
  10. `Pre-PR Decision` must use `decision: approve|changes_requested|blocked ...` (or `결정: ...`).
32
34
  11. Ensure the final decision is `approve` before moving to PR creation.
33
35
 
36
+ The review artifact must record the actual `executor`, `model`, `reasoningEffort`, reviewed commit/diff scope, findings, and final decision. The review subagent must not modify code; the main agent owns finding remediation and documentation updates.
37
+
34
38
  ---
35
39
 
36
40
  ## Steps
@@ -1,4 +1,4 @@
1
- # Designs
1
+ # UX / Visual Designs
2
2
 
3
3
  Store design references used by the project.
4
4
 
@@ -14,6 +14,18 @@ Store design references used by the project.
14
14
 
15
15
  ---
16
16
 
17
+ ## What does not belong here
18
+
19
+ - System/backend architecture (`docs/prd/*-overview.md` or the active Feature's `plan.md`)
20
+ - Data models and API design (an Idea before promotion, then the active Feature's `plan.md`)
21
+ - Open-source candidate research (an Idea or the active Feature's `decisions.md`)
22
+ - Technical decisions and alternative comparisons (an Idea before promotion, then the active Feature's `decisions.md`)
23
+ - Implementation roadmaps and work plans (the active Feature's `plan.md` and `tasks.md`)
24
+
25
+ In `designs/`, design means UX, screen, and visual design—not technical design.
26
+
27
+ ---
28
+
17
29
  ## Conventions
18
30
 
19
31
  - For external references, keep the **source URL + a short summary (or a snapshot)**.
@@ -57,6 +57,8 @@ npx lee-spec-kit workflow-stage <feature-ref> --json
57
57
 
58
58
  Use the returned `stage`, `nextAction`, and `implementationAllowed` values as the current workflow state.
59
59
 
60
+ In a local workflow with `completionStrategy: "local-ff"`, completion is `implementation_approve → local_merge → local_verify → local_cleanup → done`. Use the exact helper command returned for each stage; `done` means the base branch contains the Feature tip and cleanup is complete.
61
+
60
62
  ---
61
63
 
62
64
  ## PRD Requirement Traceability (Recommended)
@@ -129,9 +131,9 @@ Keeping the shared artifact for history is fine, but when it conflicts with feat
129
131
 
130
132
  ---
131
133
 
132
- ## Pre-PR Fallback Checklist
134
+ ## Pre-PR Subagent Checklist
133
135
 
134
- Use `agents/skills/create-pr.md` (`Pre-PR Baseline Checklist`) as the default baseline for every Pre-PR review. Use review skills additionally for deeper inspection.
136
+ Delegate every Pre-PR review to a fresh, read-only subagent using the model and reasoning effort returned by `workflow-stage --json`. The subagent follows `agents/skills/create-pr.md` (`Pre-PR Baseline Checklist`); the main agent owns finding remediation and evidence recording.
135
137
 
136
138
  ---
137
139
 
@@ -30,6 +30,36 @@
30
30
 
31
31
  ---
32
32
 
33
+ ## Research and Candidate Comparison
34
+
35
+ - Candidates:
36
+ - Advantages:
37
+ - Disadvantages:
38
+ - License:
39
+ - Validation Needed:
40
+
41
+ ---
42
+
43
+ ## Design Draft
44
+
45
+ - Data Contracts:
46
+ - Expected Components:
47
+ - External Dependencies:
48
+ - Open Questions:
49
+
50
+ ---
51
+
52
+ ## Feature Promotion Mapping
53
+
54
+ - Content for `spec.md`:
55
+ - Content for `plan.md`:
56
+ - Content for `decisions.md`:
57
+ - Content for `tasks.md`:
58
+
59
+ > This is a pre-promotion draft. After Feature creation, move unresolved material as Candidate or Pending and keep the Idea for history only.
60
+
61
+ ---
62
+
33
63
  ## Promotion Notes
34
64
 
35
65
  - What should stay true if this becomes a feature?
@@ -30,13 +30,29 @@ npx lee-spec-kit docs get agents --json
30
30
 
31
31
  ## 상위 구조 요약
32
32
 
33
- | 경로 | 목적 | 핵심 문서/역할 |
34
- | ---------------- | ------------------ | -------------- |
35
- | `docs/agents/` | 에이전트 운영 규칙 | `custom.md`, `constitution.md` (엔진 종속 가이드는 `npx lee-spec-kit docs get <doc-id> --json`으로 조회) |
36
- | `docs/prd/` | 제품 요구사항 | 프로젝트별 작성 |
37
- | `docs/designs/` | 디자인 참고 자료 | `README.md` (링크/가이드/레퍼런스) |
38
- | `docs/ideas/` | 아이디어/To-do | `README.md` (Idea → Feature 승격 규칙) |
39
- | `{{featurePath}}` | 기능별 문서 | `{feature-id}/spec.md`, `plan.md`, `tasks.md`, `decisions.md` |
33
+ | 경로 | 목적 | 핵심 문서/역할 |
34
+ | ----------------- | ------------------ | -------------------------------------------------------------------------------------------------------- |
35
+ | `docs/agents/` | 에이전트 운영 규칙 | `custom.md`, `constitution.md` (엔진 종속 가이드는 `npx lee-spec-kit docs get <doc-id> --json`으로 조회) |
36
+ | `docs/prd/` | 제품 요구사항 | 프로젝트별 작성 |
37
+ | `docs/designs/` | 디자인 참고 자료 | `README.md` (링크/가이드/레퍼런스) |
38
+ | `docs/ideas/` | 아이디어/To-do | `README.md` (Idea → Feature 승격 규칙) |
39
+ | `{{featurePath}}` | 기능별 문서 | `{feature-id}/spec.md`, `plan.md`, `tasks.md`, `decisions.md` |
40
+
41
+ ---
42
+
43
+ ## 문서 라우팅
44
+
45
+ | 문서 내용 | 위치 |
46
+ | -------------------------------------------- | ----------------------------- |
47
+ | 제품 요구사항·사용자 스토리·제품 로드맵 | `docs/prd/` |
48
+ | 여러 Feature가 공유하는 시스템 아키텍처 개요 | `docs/prd/*-overview.md` |
49
+ | 변경하기 어려운 아키텍처 원칙 | `docs/agents/constitution.md` |
50
+ | Feature 승격 전 기술 조사·후보 비교 | 해당 `docs/ideas/I###-*.md` |
51
+ | 활성 Feature의 구현 설계 | 해당 Feature의 `plan.md` |
52
+ | 기술 선택·대안·트레이드오프 | 해당 Feature의 `decisions.md` |
53
+ | 화면, Figma, 디자인 시스템, UI 플로우 | `docs/designs/` |
54
+
55
+ 제품 로드맵은 `prd/`에 두지만 구현 순서와 작업 계획은 활성 Feature의 `plan.md`와 `tasks.md`에서 관리합니다. `designs/`는 UX와 시각 디자인 전용이며 기술 설계 문서를 두지 않습니다.
40
56
 
41
57
  ---
42
58
 
@@ -114,6 +130,15 @@ npx lee-spec-kit docs get agents --json
114
130
  - `docsRepo` ("embedded" | "standalone"): Docs 관리 방식
115
131
  - `pushDocs` (boolean, optional): `docsRepo: "standalone"`일 때만 생성 (원격 push 여부)
116
132
  - `docsRemote` (string, optional): `pushDocs: true`일 때만 생성 (원격 레포 URL)
133
+ - `workflow.prePrReview.reviewer` (object): Pre-PR 서브에이전트 실행 설정
134
+ - `type`: 현재 `"subagent"`만 지원
135
+ - `model`: `"inherit"` 또는 런타임이 지원하는 모델명
136
+ - `reasoningEffort`: `low | medium | high | xhigh | max | ultra`
137
+ - `onUnavailable`: 지정 모델을 사용할 수 없을 때 `inherit | error`
138
+ - `workflow.baseBranch` (string): 완료된 local Feature를 통합할 기준 브랜치
139
+ - `workflow.completionStrategy` (`"local-ff" | "none"`): `done` 전에 local Feature를 fast-forward 병합·검증하거나, 명시적으로 통합 없이 종료
140
+ - `workflow.deleteFeatureBranchAfterMerge` (boolean): cleanup 후 통합된 local Feature 브랜치 삭제 여부. 원격 브랜치는 삭제하지 않음
141
+ - `workflow.postMergeChecks` (array): local 통합 뒤 기준 브랜치에서 실행할 구조화 명령. 예: `{ "command": "pnpm", "args": ["test"] }`
117
142
  - `approval` (object, optional): repo 정책/커스텀 validator용 승인 checkpoint 메타데이터
118
143
  - 기본 Codex-native 경로는 여전히 문서화된 checkpoint와 원격/파괴적 작업을 우선 기준으로 승인 요청합니다.
119
144
  - legacy runtime은 이 필드를 직접 소비했지만, 이제는 category 기반 checkpoint 메타데이터가 정말 필요할 때만 유지하세요.
@@ -121,6 +146,8 @@ npx lee-spec-kit docs get agents --json
121
146
  - `mode: "category"`
122
147
  - `default: "skip"`
123
148
  - `requireCheckCategories: ["spec_approve", "implementation_approve"]`
149
+ - `local-ff` workflow에서 `implementation_approve`는 이후의 fast-forward 통합, post-merge 검사, managed worktree 제거, 설정된 local Feature 브랜치 삭제까지 명시적으로 승인합니다.
150
+ - 통합 직전 별도 승인이 필요하면 `requireCheckCategories`에 `local_merge`를 추가하세요.
124
151
  - 승인 토큰: `A`
125
152
  - 허용 응답: `A`, `A OK`
126
153
  - `allowedDocsEntries` (object, optional): 비표준 `docs/` top-level 엔트리를 unmanaged docs로 보지 않도록 허용 목록에 추가
@@ -136,6 +163,22 @@ npx lee-spec-kit docs get agents --json
136
163
  "lang": "ko",
137
164
  "createdAt": "{{date}}",
138
165
  "docsRepo": "embedded",
166
+ "workflow": {
167
+ "mode": "local",
168
+ "baseBranch": "main",
169
+ "completionStrategy": "local-ff",
170
+ "deleteFeatureBranchAfterMerge": true,
171
+ "postMergeChecks": [],
172
+ "prePrReview": {
173
+ "evidenceMode": "path_required",
174
+ "reviewer": {
175
+ "type": "subagent",
176
+ "model": "inherit",
177
+ "reasoningEffort": "high",
178
+ "onUnavailable": "inherit"
179
+ }
180
+ }
181
+ },
139
182
  "allowedDocsEntries": {
140
183
  "dirs": ["plans"]
141
184
  },
@@ -147,6 +190,8 @@ npx lee-spec-kit docs get agents --json
147
190
  }
148
191
  ```
149
192
 
193
+ 새 local 프로젝트는 `local-ff`를 사용합니다. 기존 local 프로젝트에 명시적 `completionStrategy`가 없으면 `update`가 `none`을 넣어 업그레이드 도중 현재 브랜치를 갑자기 병합하지 않습니다. 준비가 끝난 뒤 `local-ff`로 명시적으로 전환하세요.
194
+
150
195
  ```json
151
196
  {
152
197
  "projectName": "{{projectName}}",
@@ -27,13 +27,32 @@
27
27
  - 활성 feature 문서를 읽은 뒤에는 `npx lee-spec-kit workflow-stage <featureRef> --json`를 실행하고, 그 `nextAction`만 따릅니다.
28
28
  - `workflow-stage --json`가 `primaryActionLabel`과 `actionOptions`를 같이 반환하면, `primaryActionLabel`은 기본 옵션 라벨로 보고 사용자에게는 `actionOptions[*].reply` 값을 그대로 보여줍니다.
29
29
 
30
+ ## 문서 라우팅
31
+
32
+ | 내용 | SSOT 위치 |
33
+ | -------------------------------------------- | ----------------------------- |
34
+ | 제품 요구사항·사용자 스토리·제품 로드맵 | `docs/prd/` |
35
+ | 여러 Feature가 공유하는 시스템 아키텍처 개요 | `docs/prd/*-overview.md` |
36
+ | 변경하기 어려운 아키텍처 원칙 | `docs/agents/constitution.md` |
37
+ | Feature 전 기술 조사·후보 비교 | 해당 `docs/ideas/I###-*.md` |
38
+ | 활성 Feature 구현 설계 | 해당 Feature의 `plan.md` |
39
+ | 기술 선택·대안·트레이드오프 | 해당 Feature의 `decisions.md` |
40
+ | 화면·Figma·디자인 시스템·UI 플로우 | `docs/designs/` |
41
+
42
+ - `docs/designs/`를 시스템 아키텍처, 데이터/API 설계, 기술 조사, 구현 계획의 목적지로 사용하지 않습니다.
43
+ - 세부 설명은 `docs/README.md`의 문서 라우팅 규칙을 따릅니다.
44
+
30
45
  ## 실행 규칙
31
46
 
32
47
  - lee-spec-kit은 문서 구조, workflow 단계, validator를 담당합니다.
33
48
  - Codex는 실행 루프, 도구 사용, hook lifecycle을 담당합니다.
34
49
  - `workflow-stage --json`가 `stage === "implementation"`이고 `implementationAllowed === true`를 반환하기 전에는 구현을 시작하지 않습니다.
50
+ - `workflow-stage --json`의 `nextAction.category`가 `pre_pr_review`이고 `executor`가 `subagent`이면, 반환된 `model`, `reasoningEffort`, `onUnavailable` 정책으로 fresh context의 읽기 전용 서브에이전트 리뷰를 실행합니다. 리뷰 스킬 이름을 선택하거나 요구하지 않습니다.
51
+ - Pre-PR 리뷰 서브에이전트는 finding만 반환하며 코드를 수정하지 않습니다. 메인 에이전트가 finding을 반영하고 reviewer metadata와 최종 decision을 evidence에 기록합니다.
35
52
  - spec / plan / tasks 승인, issue 생성, branch 생성은 구현 전 하드 게이트로 취급합니다.
36
53
  - standalone 모드에서는 `git worktree add`를 직접 만들지 말고 `workflow-stage`의 정확한 `nextAction.command`를 실행해 managed workspace 경로, stale 디렉터리 정리, `.env`/`.env.*` 복사 단계가 일관되게 유지되도록 합니다.
54
+ - local 모드에서는 구현 승인 직후 종료하지 않습니다. `workflow-stage`가 반환하는 정확한 `local merge`, `local cleanup` 명령을 따라 통합·검증·정리가 확인되어 `done`이 될 때까지 진행합니다.
55
+ - `local-ff` workflow에서는 반환된 구현 승인 설명을 축소하지 않고 그대로 제시합니다. 이 checkpoint는 fast-forward 통합, post-merge 검사, 설정된 local cleanup까지 승인하며, `local_merge` category가 명시적으로 승인 대상으로 설정된 경우에만 통합 직전 다시 요청합니다.
37
56
  - 동작이나 범위가 바뀌는 코드 변경이 있으면 같은 턴 안에서 feature 문서를 같이 동기화합니다.
38
57
  - staged된 docs 경로 검사가 필요하면 `git commit` 전에 `npx lee-spec-kit commit-audit --json`를 사용합니다.
39
58
  - 기본 docs sync 검사는 `npx lee-spec-kit workflow-audit --json`를 사용합니다.
@@ -42,10 +61,10 @@
42
61
 
43
62
  사용자 확인 필수 규칙을 항상 먼저 적용합니다.
44
63
 
45
- | 현재 액션 예시 | 공유 내용 |
46
- | --- | --- |
47
- | 이슈 생성 | `npx lee-spec-kit github issue <featureRef> --create` 전 |
48
- | PR 생성 | `npx lee-spec-kit github pr <featureRef> --create` 전 |
64
+ | 현재 액션 예시 | 공유 내용 |
65
+ | -------------- | -------------------------------------------------------- |
66
+ | 이슈 생성 | `npx lee-spec-kit github issue <featureRef> --create` 전 |
67
+ | PR 생성 | `npx lee-spec-kit github pr <featureRef> --create` 전 |
49
68
 
50
69
  - 문서화된 workflow checkpoint와 원격/파괴적 작업 전에만 사용자 승인을 요청합니다.
51
70
  - `workflow-stage --json`가 `approvalRequired === true`를 반환하면 그 checkpoint에서 멈추고 사용자 승인을 받습니다.
@@ -17,7 +17,9 @@ Pull Request를 생성할 때 따르는 가이드입니다.
17
17
 
18
18
  ## Pre-PR 기본 체크리스트(`builtin-checklist`)
19
19
 
20
- Pre-PR 리뷰에서 항상 수행하는 최소 기준입니다. 가능한 경우 리뷰 스킬을 추가로 사용해 심화 검토를 진행하세요.
20
+ Pre-PR 리뷰에서 서브에이전트가 항상 수행하는 최소 기준입니다. 리뷰 스킬 이름에 의존하지 않습니다.
21
+
22
+ `workflow-stage --json`의 `nextAction.executor`가 `subagent`이면 fresh context의 읽기 전용 서브에이전트에게 리뷰를 위임합니다. `model: inherit`은 현재 모델을 상속한다는 뜻이며, 그 외 값은 서브에이전트 생성 시 모델 override로 사용합니다. 지정 모델을 사용할 수 없으면 `onUnavailable` 정책(`inherit` 또는 `error`)을 따릅니다.
21
23
 
22
24
  1. `spec.md` / `plan.md` / `tasks.md` 기준으로 변경 범위 정합성을 확인하고, 구현이 원래 목적에 맞는지 점검합니다.
23
25
  2. 회귀/예외 처리, 크리티컬·보안 리스크, 사이드 이펙트, 사용자 흐름 영향, 배포 준비도를 점검합니다.
@@ -31,6 +33,8 @@ Pre-PR 리뷰에서 항상 수행하는 최소 기준입니다. 가능한 경우
31
33
  10. `PR 전 리뷰 Decision`은 `결정: approve|changes_requested|blocked ...` (또는 `decision: ...`) 형식을 사용합니다.
32
34
  11. PR 생성 단계로 이동하기 전 최종 Decision이 `approve`인지 확인합니다.
33
35
 
36
+ 리뷰 산출물에는 실제 사용한 `executor`, `model`, `reasoningEffort`, 검토한 commit/diff 범위, finding과 최종 decision을 기록합니다. 리뷰 서브에이전트는 코드를 수정하지 않으며, finding 반영과 문서 갱신은 메인 에이전트가 담당합니다.
37
+
34
38
  ---
35
39
 
36
40
  ## 단계
@@ -1,4 +1,4 @@
1
- # Designs
1
+ # UX / Visual Designs
2
2
 
3
3
  프로젝트에서 참고할 디자인 리소스를 모아두는 폴더입니다.
4
4
 
@@ -14,6 +14,18 @@
14
14
 
15
15
  ---
16
16
 
17
+ ## 포함하지 않는 문서
18
+
19
+ - 시스템/백엔드 아키텍처 (`docs/prd/*-overview.md` 또는 활성 Feature의 `plan.md`)
20
+ - 데이터 모델 및 API 설계 (Feature 전에는 `docs/ideas/I###-*.md`, 이후에는 활성 Feature의 `plan.md`)
21
+ - 오픈소스 후보 조사 (`docs/ideas/I###-*.md` 또는 활성 Feature의 `decisions.md`)
22
+ - 기술 결정과 대안 비교 (Feature 전에는 `docs/ideas/I###-*.md`, 이후에는 활성 Feature의 `decisions.md`)
23
+ - 구현 로드맵과 작업 계획 (활성 Feature의 `plan.md`와 `tasks.md`)
24
+
25
+ `designs/`의 design은 기술 설계가 아니라 UX, 화면, 시각 디자인을 뜻합니다.
26
+
27
+ ---
28
+
17
29
  ## 작성 규칙
18
30
 
19
31
  - 외부 링크는 가능한 한 **원본 URL + 요약(또는 캡처)**를 함께 남깁니다.
@@ -57,6 +57,8 @@ npx lee-spec-kit workflow-stage <feature-ref> --json
57
57
 
58
58
  반환되는 `stage`, `nextAction`, `implementationAllowed` 값을 현재 워크플로우 상태로 사용하세요.
59
59
 
60
+ `completionStrategy: "local-ff"`인 local workflow의 완료 흐름은 `implementation_approve → local_merge → local_verify → local_cleanup → done`입니다. 각 단계에서 반환된 helper 명령을 그대로 사용하며, `done`은 기준 브랜치가 Feature tip을 포함하고 cleanup까지 완료됐다는 뜻입니다.
61
+
60
62
  ---
61
63
 
62
64
  ## PRD 요구사항 추적 (권장)
@@ -129,9 +131,9 @@ Feature가 이미 진행 중이라면, 이 파일들은 활성 워크플로우 S
129
131
 
130
132
  ---
131
133
 
132
- ## Pre-PR 폴백 체크리스트
134
+ ## Pre-PR 서브에이전트 체크리스트
133
135
 
134
- 모든 Pre-PR 리뷰에서 `agents/skills/create-pr.md`의 `Pre-PR 기본 체크리스트`를 기본 베이스라인으로 사용하고, 리뷰 스킬은 심화 검토용으로 추가 사용하세요.
136
+ 모든 Pre-PR 리뷰는 `workflow-stage --json`이 반환한 모델·추론도 설정으로 fresh context의 읽기 전용 서브에이전트에게 맡깁니다. 서브에이전트는 `agents/skills/create-pr.md`의 `Pre-PR 기본 체크리스트`를 기준으로 리뷰하고, 메인 에이전트가 finding 반영과 evidence 기록을 담당합니다.
135
137
 
136
138
  ---
137
139
 
@@ -30,6 +30,36 @@
30
30
 
31
31
  ---
32
32
 
33
+ ## 조사 및 후보 비교
34
+
35
+ - 후보:
36
+ - 장점:
37
+ - 단점:
38
+ - 라이선스:
39
+ - 검증 필요 사항:
40
+
41
+ ---
42
+
43
+ ## 설계 초안
44
+
45
+ - 데이터 계약:
46
+ - 예상 컴포넌트:
47
+ - 외부 의존성:
48
+ - 미확정 사항:
49
+
50
+ ---
51
+
52
+ ## Feature 승격 매핑
53
+
54
+ - `spec.md`로 이동할 내용:
55
+ - `plan.md`로 이동할 내용:
56
+ - `decisions.md`로 이동할 내용:
57
+ - `tasks.md`로 이동할 내용:
58
+
59
+ > 승격 전 초안입니다. Feature 생성 후에는 확정되지 않은 내용을 Candidate 또는 Pending 상태로 옮기고, Idea는 이력으로만 유지합니다.
60
+
61
+ ---
62
+
33
63
  ## 승격 메모
34
64
 
35
65
  - Feature가 되어도 유지되어야 할 점은 무엇인가?
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/integrations/codex/bootstrap.ts"],"names":["next"],"mappings":"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","file":"chunk-LYFRLOFQ.js","sourcesContent":["import fs from 'fs-extra';\nimport os from 'node:os';\nimport path from 'node:path';\n\nexport const LEE_SPEC_KIT_CODEX_BOOTSTRAP_BEGIN =\n '# lee-spec-kit:codex-bootstrap:begin';\nexport const LEE_SPEC_KIT_CODEX_BOOTSTRAP_END =\n '# lee-spec-kit:codex-bootstrap:end';\n\nconst REQUIRED_HOOKS_FLAG_LINE = 'codex_hooks = true';\n\nfunction renderManagedSegment(): string {\n return [\n LEE_SPEC_KIT_CODEX_BOOTSTRAP_BEGIN,\n REQUIRED_HOOKS_FLAG_LINE,\n LEE_SPEC_KIT_CODEX_BOOTSTRAP_END,\n ].join('\\n');\n}\n\nfunction renderManagedBlock(): string {\n return `${renderManagedSegment()}\\n\\n`;\n}\n\nfunction sanitizeTomlScanContent(content: string): string {\n let result = '';\n let index = 0;\n let state: 'normal' | 'basic' | 'literal' | 'multibasic' | 'multiliteral' = 'normal';\n\n while (index < content.length) {\n const nextThree = content.slice(index, index + 3);\n const char = content[index] || '';\n\n if (state === 'normal') {\n if (nextThree === '\"\"\"') {\n result += ' ';\n index += 3;\n state = 'multibasic';\n continue;\n }\n if (nextThree === \"'''\") {\n result += ' ';\n index += 3;\n state = 'multiliteral';\n continue;\n }\n if (char === '\"') {\n result += ' ';\n index += 1;\n state = 'basic';\n continue;\n }\n if (char === \"'\") {\n result += ' ';\n index += 1;\n state = 'literal';\n continue;\n }\n result += char;\n index += 1;\n continue;\n }\n\n if (state === 'basic') {\n if (char === '\\\\') {\n result += ' ';\n index += 2;\n continue;\n }\n result += char === '\\n' ? '\\n' : ' ';\n index += 1;\n if (char === '\"') state = 'normal';\n continue;\n }\n\n if (state === 'literal') {\n result += char === '\\n' ? '\\n' : ' ';\n index += 1;\n if (char === \"'\") state = 'normal';\n continue;\n }\n\n if (state === 'multibasic') {\n if (nextThree === '\"\"\"') {\n result += ' ';\n index += 3;\n state = 'normal';\n continue;\n }\n result += char === '\\n' ? '\\n' : ' ';\n index += 1;\n continue;\n }\n\n if (nextThree === \"'''\") {\n result += ' ';\n index += 3;\n state = 'normal';\n continue;\n }\n result += char === '\\n' ? '\\n' : ' ';\n index += 1;\n }\n\n return result;\n}\n\nfunction stripManagedBlock(content: string): string {\n const beginIndex = content.indexOf(LEE_SPEC_KIT_CODEX_BOOTSTRAP_BEGIN);\n const endIndex = content.indexOf(LEE_SPEC_KIT_CODEX_BOOTSTRAP_END);\n if (beginIndex === -1 || endIndex === -1 || beginIndex > endIndex) {\n return content;\n }\n const replaceEnd = endIndex + LEE_SPEC_KIT_CODEX_BOOTSTRAP_END.length;\n return `${content.slice(0, beginIndex)}${content.slice(replaceEnd)}`;\n}\n\nfunction findFirstTableHeaderIndex(content: string): number {\n const sanitized = sanitizeTomlScanContent(content);\n const match = sanitized.match(/^\\s*\\[[^\\]]+\\](?:\\s*#.*)?$/m);\n return match?.index ?? -1;\n}\n\nfunction insertManagedBlockAtTopLevel(content: string, block: string): string {\n const normalizedBlock = block.trimEnd();\n const firstTableIndex = findFirstTableHeaderIndex(content);\n\n if (firstTableIndex === -1) {\n let next = content;\n if (next.length > 0 && !next.endsWith('\\n')) next += '\\n';\n if (next.trim().length > 0 && !next.endsWith('\\n\\n')) next += '\\n';\n next += `${normalizedBlock}\\n`;\n return next;\n }\n\n const before = content.slice(0, firstTableIndex).trimEnd();\n const after = content.slice(firstTableIndex).replace(/^\\n+/, '');\n\n let next = '';\n if (before.length > 0) {\n next += before;\n if (!next.endsWith('\\n\\n')) next += next.endsWith('\\n') ? '\\n' : '\\n\\n';\n }\n next += `${normalizedBlock}\\n\\n${after}`;\n return next;\n}\n\nexport function getCodexHome(): string {\n const explicit = String(process.env.CODEX_HOME || '').trim();\n if (explicit) return explicit;\n return path.join(os.homedir(), '.codex');\n}\n\nexport function getCodexConfigPath(): string {\n return path.join(getCodexHome(), 'config.toml');\n}\n\nfunction contentIncludesRequiredBootstrap(content: string): boolean {\n return (\n hasEnabledTopLevelCodexHooksKey(content) ||\n hasEnabledFeaturesTableCodexHooksKey(content) ||\n hasEnabledFeaturesInlineTableCodexHooksKey(content)\n );\n}\n\nfunction hasConflictingTopLevelKey(content: string, key: string): boolean {\n const sanitized = sanitizeTomlScanContent(content);\n const escaped = key.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const keyPattern = new RegExp(`^\\\\s*${escaped}\\\\s*=`, 'm');\n return keyPattern.test(sanitized);\n}\n\nfunction hasEnabledTopLevelCodexHooksKey(content: string): boolean {\n return /^\\s*codex_hooks\\s*=\\s*true\\b/m.test(\n sanitizeTomlScanContent(content)\n );\n}\n\nfunction hasConflictingFeaturesTableKey(content: string, key: string): boolean {\n const lines = sanitizeTomlScanContent(content).split('\\n');\n let inFeaturesTable = false;\n\n for (const rawLine of lines) {\n const line = rawLine.trim();\n if (!line || line.startsWith('#')) continue;\n\n const tableMatch = line.match(/^\\[([^\\]]+)\\](?:\\s*#.*)?$/);\n if (tableMatch) {\n inFeaturesTable = tableMatch[1]?.trim() === 'features';\n continue;\n }\n\n if (!inFeaturesTable) continue;\n if (new RegExp(`^${key.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}\\\\s*=`).test(line)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction hasEnabledFeaturesTableCodexHooksKey(content: string): boolean {\n const lines = sanitizeTomlScanContent(content).split('\\n');\n let inFeaturesTable = false;\n\n for (const rawLine of lines) {\n const line = rawLine.trim();\n if (!line || line.startsWith('#')) continue;\n\n const tableMatch = line.match(/^\\[([^\\]]+)\\](?:\\s*#.*)?$/);\n if (tableMatch) {\n inFeaturesTable = tableMatch[1]?.trim() === 'features';\n continue;\n }\n\n if (!inFeaturesTable) continue;\n if (/^codex_hooks\\s*=\\s*true\\b/.test(line)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction hasConflictingFeaturesInlineTableKey(content: string, key: string): boolean {\n const escapedKey = key.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const lines = sanitizeTomlScanContent(content).split('\\n');\n\n for (const rawLine of lines) {\n const line = rawLine.trim();\n if (!line || line.startsWith('#')) continue;\n if (!/^features\\s*=\\s*\\{/.test(line)) continue;\n if (new RegExp(`\\\\b${escapedKey}\\\\s*=`).test(line)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction hasEnabledFeaturesInlineTableCodexHooksKey(content: string): boolean {\n const lines = sanitizeTomlScanContent(content).split('\\n');\n\n for (const rawLine of lines) {\n const line = rawLine.trim();\n if (!line || line.startsWith('#')) continue;\n if (!/^features\\s*=\\s*\\{/.test(line)) continue;\n if (/\\bcodex_hooks\\s*=\\s*true\\b/.test(line)) {\n return true;\n }\n }\n\n return false;\n}\n\nexport async function hasLeeSpecKitCodexBootstrap(\n filePath = getCodexConfigPath()\n): Promise<boolean> {\n if (!(await fs.pathExists(filePath))) return false;\n const content = await fs.readFile(filePath, 'utf-8');\n return (\n (content.includes(LEE_SPEC_KIT_CODEX_BOOTSTRAP_BEGIN) &&\n content.includes(LEE_SPEC_KIT_CODEX_BOOTSTRAP_END)) ||\n contentIncludesRequiredBootstrap(content)\n );\n}\n\nexport async function upsertLeeSpecKitCodexBootstrap(\n filePath = getCodexConfigPath()\n): Promise<{\n changed: boolean;\n action: 'created' | 'appended' | 'updated' | 'noop';\n filePath: string;\n}> {\n const block = renderManagedBlock();\n const segment = renderManagedSegment();\n await fs.ensureDir(path.dirname(filePath));\n\n const exists = await fs.pathExists(filePath);\n if (!exists) {\n await fs.writeFile(filePath, block, 'utf-8');\n return { changed: true, action: 'created', filePath };\n }\n\n const current = await fs.readFile(filePath, 'utf-8');\n const externalContent = stripManagedBlock(current);\n const beginIndex = current.indexOf(LEE_SPEC_KIT_CODEX_BOOTSTRAP_BEGIN);\n const endIndex = current.indexOf(LEE_SPEC_KIT_CODEX_BOOTSTRAP_END);\n\n if (\n hasConflictingTopLevelKey(externalContent, 'codex_hooks') ||\n hasConflictingTopLevelKey(externalContent, 'features.codex_hooks') ||\n hasConflictingFeaturesTableKey(externalContent, 'codex_hooks') ||\n hasConflictingFeaturesInlineTableKey(externalContent, 'codex_hooks')\n ) {\n throw new Error(\n `Codex config already defines codex_hooks outside lee-spec-kit managed block: ${filePath}`\n );\n }\n\n if (beginIndex !== -1 && endIndex !== -1 && beginIndex <= endIndex) {\n const replaceEnd = endIndex + LEE_SPEC_KIT_CODEX_BOOTSTRAP_END.length;\n const next = `${current.slice(0, beginIndex)}${segment}${current.slice(replaceEnd)}`;\n if (next === current) {\n return { changed: false, action: 'noop', filePath };\n }\n await fs.writeFile(filePath, next, 'utf-8');\n return { changed: true, action: 'updated', filePath };\n }\n\n if (contentIncludesRequiredBootstrap(current)) {\n return { changed: false, action: 'noop', filePath };\n }\n\n const next = insertManagedBlockAtTopLevel(current, block);\n\n await fs.writeFile(filePath, next, 'utf-8');\n return { changed: true, action: 'appended', filePath };\n}\n\nexport async function removeLeeSpecKitCodexBootstrap(\n filePath = getCodexConfigPath()\n): Promise<{ changed: boolean; filePath: string }> {\n if (!(await fs.pathExists(filePath))) {\n return { changed: false, filePath };\n }\n\n const current = await fs.readFile(filePath, 'utf-8');\n const beginIndex = current.indexOf(LEE_SPEC_KIT_CODEX_BOOTSTRAP_BEGIN);\n const endIndex = current.indexOf(LEE_SPEC_KIT_CODEX_BOOTSTRAP_END);\n if (beginIndex === -1 || endIndex === -1 || beginIndex > endIndex) {\n return { changed: false, filePath };\n }\n\n const replaceEnd = endIndex + LEE_SPEC_KIT_CODEX_BOOTSTRAP_END.length;\n let next = `${current.slice(0, beginIndex)}${current.slice(replaceEnd)}`;\n next = next.replace(/\\n{3,}/g, '\\n\\n').trimEnd();\n if (next.length > 0) next += '\\n';\n await fs.writeFile(filePath, next, 'utf-8');\n return { changed: true, filePath };\n}\n"]}