timsquad 3.4.0 → 3.6.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/README.ko.md +4 -0
- package/README.md +4 -0
- package/dist/commands/audit.d.ts +22 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +233 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/compile.d.ts.map +1 -1
- package/dist/commands/compile.js +84 -3
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/daemon.d.ts.map +1 -1
- package/dist/commands/daemon.js +50 -3
- package/dist/commands/daemon.js.map +1 -1
- package/dist/commands/full.js +1 -0
- package/dist/commands/full.js.map +1 -1
- package/dist/commands/git/pr.js +6 -5
- package/dist/commands/git/pr.js.map +1 -1
- package/dist/commands/git/release.js +2 -7
- package/dist/commands/git/release.js.map +1 -1
- package/dist/commands/improve.js +2 -2
- package/dist/commands/improve.js.map +1 -1
- package/dist/commands/init.js +42 -6
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/log.d.ts.map +1 -1
- package/dist/commands/log.js +34 -2
- package/dist/commands/log.js.map +1 -1
- package/dist/commands/meta-index.d.ts.map +1 -1
- package/dist/commands/meta-index.js +30 -0
- package/dist/commands/meta-index.js.map +1 -1
- package/dist/commands/metrics.d.ts.map +1 -1
- package/dist/commands/metrics.js +6 -2
- package/dist/commands/metrics.js.map +1 -1
- package/dist/commands/retro.d.ts.map +1 -1
- package/dist/commands/retro.js +71 -14
- package/dist/commands/retro.js.map +1 -1
- package/dist/commands/session.js +3 -3
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/skills.js +4 -7
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/status.js +1 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +18 -1
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/commands/workflow.d.ts +2 -0
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +180 -6
- package/dist/commands/workflow.js.map +1 -1
- package/dist/daemon/context-writer.d.ts +14 -0
- package/dist/daemon/context-writer.d.ts.map +1 -1
- package/dist/daemon/context-writer.js +29 -0
- package/dist/daemon/context-writer.js.map +1 -1
- package/dist/daemon/event-queue.d.ts +4 -0
- package/dist/daemon/event-queue.d.ts.map +1 -1
- package/dist/daemon/event-queue.js +107 -6
- package/dist/daemon/event-queue.js.map +1 -1
- package/dist/daemon/file-watcher.d.ts +14 -8
- package/dist/daemon/file-watcher.d.ts.map +1 -1
- package/dist/daemon/file-watcher.js +78 -41
- package/dist/daemon/file-watcher.js.map +1 -1
- package/dist/daemon/index.d.ts +1 -0
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +129 -53
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/jsonl-watcher.d.ts +1 -0
- package/dist/daemon/jsonl-watcher.d.ts.map +1 -1
- package/dist/daemon/jsonl-watcher.js.map +1 -1
- package/dist/daemon/session-notes.d.ts +33 -0
- package/dist/daemon/session-notes.d.ts.map +1 -0
- package/dist/daemon/session-notes.js +74 -0
- package/dist/daemon/session-notes.js.map +1 -0
- package/dist/daemon/session-state.d.ts +8 -0
- package/dist/daemon/session-state.d.ts.map +1 -1
- package/dist/daemon/session-state.js +33 -0
- package/dist/daemon/session-state.js.map +1 -1
- package/dist/daemon/shutdown.d.ts.map +1 -1
- package/dist/daemon/shutdown.js +3 -1
- package/dist/daemon/shutdown.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-generator.d.ts +4 -0
- package/dist/lib/agent-generator.d.ts.map +1 -1
- package/dist/lib/agent-generator.js +63 -3
- package/dist/lib/agent-generator.js.map +1 -1
- package/dist/lib/compile-rules.d.ts +2 -0
- package/dist/lib/compile-rules.d.ts.map +1 -1
- package/dist/lib/compile-rules.js +2 -0
- package/dist/lib/compile-rules.js.map +1 -1
- package/dist/lib/compiler.d.ts +21 -1
- package/dist/lib/compiler.d.ts.map +1 -1
- package/dist/lib/compiler.js +113 -3
- package/dist/lib/compiler.js.map +1 -1
- package/dist/lib/config.d.ts +3 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +17 -2
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/project.d.ts.map +1 -1
- package/dist/lib/project.js +8 -3
- package/dist/lib/project.js.map +1 -1
- package/dist/lib/skill-generator.d.ts +1 -1
- package/dist/lib/skill-generator.d.ts.map +1 -1
- package/dist/lib/skill-generator.js +39 -3
- package/dist/lib/skill-generator.js.map +1 -1
- package/dist/lib/ssot-map.d.ts +31 -0
- package/dist/lib/ssot-map.d.ts.map +1 -0
- package/dist/lib/ssot-map.js +76 -0
- package/dist/lib/ssot-map.js.map +1 -0
- package/dist/lib/template.js +1 -0
- package/dist/lib/template.js.map +1 -1
- package/dist/lib/workflow-state.d.ts +1 -1
- package/dist/lib/workflow-state.d.ts.map +1 -1
- package/dist/lib/workflow-state.js +1 -1
- package/dist/lib/workflow-state.js.map +1 -1
- package/dist/types/config.d.ts +10 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +22 -17
- package/dist/types/config.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/meta-index.d.ts +8 -0
- package/dist/types/meta-index.d.ts.map +1 -1
- package/dist/types/project.d.ts +1 -1
- package/dist/types/project.d.ts.map +1 -1
- package/dist/types/project.js.map +1 -1
- package/dist/types/ssot-map.d.ts +28 -0
- package/dist/types/ssot-map.d.ts.map +1 -0
- package/dist/types/ssot-map.js +6 -0
- package/dist/types/ssot-map.js.map +1 -0
- package/package.json +4 -4
- package/templates/base/agents/base/tsq-architect.md +2 -2
- package/templates/base/agents/base/tsq-librarian.md +45 -0
- package/templates/base/knowledge/checklists/plan-quality.md +31 -0
- package/templates/base/knowledge/checklists/stability-verification.md +14 -0
- package/templates/base/skills/_shared/naming-conventions.md +49 -0
- package/templates/base/skills/_template/SKILL.md +33 -17
- package/templates/base/skills/audit/SKILL.md +66 -0
- package/templates/base/skills/coding/SKILL.md +49 -29
- package/templates/base/skills/coding/rules/async-patterns.md +81 -0
- package/templates/base/skills/coding/rules/code-organization.md +80 -0
- package/templates/base/skills/coding/rules/error-handling.md +76 -0
- package/templates/base/skills/coding/rules/type-safety.md +85 -0
- package/templates/base/skills/controller/SKILL.md +50 -84
- package/templates/base/skills/controller/delegation/developer.md +25 -0
- package/templates/base/skills/controller/delegation/librarian.md +33 -0
- package/templates/base/skills/controller/delegation/reviewer.md +19 -0
- package/templates/base/skills/controller/memory/.gitkeep +0 -0
- package/templates/base/skills/controller/triggers/phase-complete.md +25 -0
- package/templates/base/skills/controller/triggers/sequence-complete.md +15 -0
- package/templates/base/skills/controller/triggers/ssot-changed.md +14 -0
- package/templates/base/skills/controller/triggers/task-complete.md +14 -0
- package/templates/base/skills/database/SKILL.md +8 -25
- package/templates/base/skills/database/rules/query-optimization.md +32 -0
- package/templates/base/skills/database/rules/supabase-patterns.md +94 -0
- package/templates/base/skills/librarian/SKILL.md +53 -0
- package/templates/base/skills/main-session-constraints/SKILL.md +62 -0
- package/templates/base/skills/methodology/tdd/SKILL.md +6 -0
- package/templates/base/skills/product-audit/SKILL.md +115 -0
- package/templates/base/skills/product-audit/checklists/01-security.md +86 -0
- package/templates/base/skills/product-audit/checklists/02-performance.md +67 -0
- package/templates/base/skills/product-audit/checklists/03-seo.md +46 -0
- package/templates/base/skills/product-audit/checklists/04-accessibility.md +66 -0
- package/templates/base/skills/product-audit/checklists/05-ui-ux.md +50 -0
- package/templates/base/skills/product-audit/checklists/06-architecture.md +53 -0
- package/templates/base/skills/product-audit/checklists/07-functional-requirements.md +55 -0
- package/templates/base/skills/product-audit/rules/audit-protocol.md +136 -0
- package/templates/base/skills/product-audit/rules/false-positive-guard.md +81 -0
- package/templates/base/skills/product-audit/rules/scoring-criteria.md +113 -0
- package/templates/base/skills/product-audit/templates/improvement-plan-template.md +60 -0
- package/templates/base/skills/product-audit/templates/report-template.md +88 -0
- package/templates/base/skills/prompt-engineering/SKILL.md +54 -73
- package/templates/base/skills/retrospective/SKILL.md +70 -95
- package/templates/base/skills/retrospective/references/improvement-template.md +26 -0
- package/templates/base/skills/review/SKILL.md +72 -0
- package/templates/base/skills/security/SKILL.md +50 -37
- package/templates/base/skills/security/rules/auth-patterns.md +62 -0
- package/templates/base/skills/security/rules/dependency-security.md +69 -0
- package/templates/base/skills/security/rules/input-validation.md +68 -0
- package/templates/base/skills/security/rules/secrets-management.md +65 -0
- package/templates/base/skills/spec/SKILL.md +60 -0
- package/templates/base/skills/stability-verification/SKILL.md +64 -0
- package/templates/base/skills/stability-verification/references/release-checklist.md +34 -0
- package/templates/base/skills/stability-verification/references/security-fix-patterns.md +112 -0
- package/templates/base/skills/stability-verification/rules/verification-layers.md +67 -0
- package/templates/base/skills/stability-verification/rules/verification-workflow.md +69 -0
- package/templates/base/skills/stability-verification/scripts/verify.sh +294 -0
- package/templates/base/skills/testing/SKILL.md +33 -25
- package/templates/base/skills/testing/references/e2e-stability.md +33 -0
- package/templates/base/skills/tsq-cli/SKILL.md +73 -0
- package/templates/base/skills/tsq-cli/references/cli-reference.md +92 -0
- package/templates/base/skills/tsq-protocol/SKILL.md +41 -25
- package/templates/base/skills/typescript/SKILL.md +3 -9
- package/templates/base/timsquad/ssot/test-spec.template.md +11 -1
- package/templates/base/timsquad/ssot-map.template.yaml +41 -0
- package/templates/platforms/claude-code/rules/api-conventions.md +12 -0
- package/templates/platforms/claude-code/rules/build-gate.md +28 -0
- package/templates/platforms/claude-code/rules/completion-verification.md +30 -0
- package/templates/platforms/claude-code/rules/context-monitor.md +23 -0
- package/templates/platforms/claude-code/rules/librarian-constraints.md +11 -0
- package/templates/platforms/claude-code/rules/plan-review.md +45 -0
- package/templates/platforms/claude-code/rules/quality-guards.md +43 -0
- package/templates/platforms/claude-code/rules/session-notes.md +18 -0
- package/templates/platforms/claude-code/rules/skill-suggest.md +27 -0
- package/templates/platforms/claude-code/rules/test-conventions.md +13 -0
- package/templates/platforms/claude-code/scripts/build-gate.sh +73 -0
- package/templates/platforms/claude-code/scripts/change-scope-guard.sh +113 -0
- package/templates/platforms/claude-code/scripts/completion-guard.sh +122 -24
- package/templates/platforms/claude-code/scripts/context-restore.sh +68 -0
- package/templates/platforms/claude-code/scripts/e2e-commit-gate.sh +70 -0
- package/templates/platforms/claude-code/scripts/e2e-marker.sh +51 -0
- package/templates/platforms/claude-code/scripts/phase-guard.sh +5 -5
- package/templates/platforms/claude-code/scripts/pre-compact.sh +70 -0
- package/templates/platforms/claude-code/scripts/safe-guard.sh +83 -0
- package/templates/platforms/claude-code/scripts/skill-inject.sh +216 -0
- package/templates/platforms/claude-code/scripts/skill-rules.json +95 -0
- package/templates/platforms/claude-code/scripts/skill-suggest.sh +105 -0
- package/templates/platforms/claude-code/scripts/subagent-inject.sh +53 -0
- package/templates/platforms/claude-code/settings.json +71 -9
|
@@ -178,7 +178,17 @@ describe('UserService', () => {
|
|
|
178
178
|
|
|
179
179
|
---
|
|
180
180
|
|
|
181
|
-
## 5. 테스트
|
|
181
|
+
## 5. 테스트 게이트
|
|
182
|
+
|
|
183
|
+
TimSquad 워크플로우에서 자동 실행되는 테스트 게이트 설정.
|
|
184
|
+
|
|
185
|
+
### 5.0 게이트별 실행 명령
|
|
186
|
+
|
|
187
|
+
| 게이트 | 실행 시점 | 명령 | 타임아웃 |
|
|
188
|
+
|--------|----------|------|---------|
|
|
189
|
+
| Task (Unit) | Task 완료 시 | `npm run test:unit` | 120s |
|
|
190
|
+
| Sequence (Integration + Build) | Sequence 완료 시 | `npm run test:integration` + `tsc --noEmit` | 300s |
|
|
191
|
+
| Phase (E2E) | Phase 완료 시 | `npm run test:e2e` | 300s |
|
|
182
192
|
|
|
183
193
|
### 5.1 CI 파이프라인
|
|
184
194
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# SSOT Map — 티어별 문서 주입 기준
|
|
2
|
+
# Tier 0: 모든 작업에 항상 주입 (Hook → systemMessage)
|
|
3
|
+
# Tier 1: Phase 시작 시 Controller가 주입
|
|
4
|
+
# Tier 2: Sequence 범위 문서 (Controller가 선택 주입)
|
|
5
|
+
# Tier 3: 개별 Task에 필요한 구체 spec (Controller가 선택 주입)
|
|
6
|
+
|
|
7
|
+
tier-0-always:
|
|
8
|
+
description: "모든 작업에 항상 주입되는 제약 문서"
|
|
9
|
+
inject_via: hook
|
|
10
|
+
documents:
|
|
11
|
+
- compiled: rules/security-constraints.md
|
|
12
|
+
source: security-spec.md
|
|
13
|
+
- compiled: rules/completion-criteria.md
|
|
14
|
+
source: requirements.md
|
|
15
|
+
|
|
16
|
+
tier-1-phase:
|
|
17
|
+
description: "Phase 시작 시 controller가 주입하는 방향성 문서"
|
|
18
|
+
inject_via: controller
|
|
19
|
+
documents:
|
|
20
|
+
- compiled: references/prd-summary.spec.md
|
|
21
|
+
source: prd.md
|
|
22
|
+
- compiled: references/architecture.spec.md
|
|
23
|
+
source: planning.md
|
|
24
|
+
|
|
25
|
+
tier-2-sequence:
|
|
26
|
+
description: "Sequence 범위의 기능별 문서"
|
|
27
|
+
inject_via: controller
|
|
28
|
+
documents:
|
|
29
|
+
- compiled: references/service.spec.md
|
|
30
|
+
source: service-spec.md
|
|
31
|
+
- compiled: references/data-design.spec.md
|
|
32
|
+
source: data-design.md
|
|
33
|
+
|
|
34
|
+
tier-3-task:
|
|
35
|
+
description: "개별 Task에 필요한 구체 spec"
|
|
36
|
+
inject_via: controller
|
|
37
|
+
documents:
|
|
38
|
+
- compiled: references/error-codes.spec.md
|
|
39
|
+
source: error-codes.md
|
|
40
|
+
- compiled: references/functional.spec.md
|
|
41
|
+
source: functional-spec.md
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "src/api/**/*.ts"
|
|
4
|
+
- "src/routes/**/*.ts"
|
|
5
|
+
- "src/controllers/**/*.ts"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
- RESTful 네이밍 사용 (복수형 리소스, kebab-case)
|
|
9
|
+
- 에러 응답 표준 형식: `{ code: string, message: string, details?: unknown }`
|
|
10
|
+
- HTTP 상태 코드 정확히 매핑 (200/201/400/401/403/404/500)
|
|
11
|
+
- 요청 validation은 엔드포인트 진입 시점에서 수행
|
|
12
|
+
- 비즈니스 로직은 서비스 레이어에 위치 (컨트롤러에 직접 작성 금지)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 빌드 게이트. 변경 파일의 TypeScript 에러를 자동 감지하여 완료 차단.
|
|
3
|
+
globs:
|
|
4
|
+
- "src/**/*.ts"
|
|
5
|
+
- "src/**/*.tsx"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 빌드 게이트 (Build Gate)
|
|
9
|
+
|
|
10
|
+
## 자동 검증
|
|
11
|
+
|
|
12
|
+
매 턴 종료 시 변경된 TypeScript 파일에 대해 `tsc --noEmit`을 실행합니다.
|
|
13
|
+
- 변경 파일에 에러가 있으면 **완료를 차단**하고 에러 목록을 제공
|
|
14
|
+
- 기존 파일의 pre-existing 에러는 무시 (변경 파일만 필터링)
|
|
15
|
+
- `stop_hook_active` 플래그로 1회만 차단 (무한루프 방지)
|
|
16
|
+
|
|
17
|
+
## 블로킹 수신 시 대응
|
|
18
|
+
|
|
19
|
+
`[Build Gate]` 블로킹 메시지를 받으면:
|
|
20
|
+
1. 제시된 TypeScript 에러를 확인하세요
|
|
21
|
+
2. 해당 파일을 열어 에러를 수정하세요
|
|
22
|
+
3. 수정 후 작업을 마무리하세요
|
|
23
|
+
|
|
24
|
+
## 참고
|
|
25
|
+
|
|
26
|
+
- 전체 `tsc --noEmit` 실행 (incremental 가능)
|
|
27
|
+
- 변경 파일 감지: `git diff --name-only HEAD -- '*.ts' '*.tsx'`
|
|
28
|
+
- 타임아웃: 30초
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 완료 검증 루프. 자기 보고 금지, exit code로 완료 판정.
|
|
3
|
+
globs:
|
|
4
|
+
- "**/*"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 완료 검증 루프 (Completion Verification)
|
|
8
|
+
|
|
9
|
+
## 원칙: 자기 보고 금지
|
|
10
|
+
|
|
11
|
+
"작업을 완료했습니다"라고 자체 판단하지 마세요. 객관적 증거(테스트 exit code)가 완료를 판정합니다.
|
|
12
|
+
|
|
13
|
+
## 자동 검증 (Stop Hook)
|
|
14
|
+
|
|
15
|
+
Implementation phase에서 턴이 종료될 때:
|
|
16
|
+
1. 세션 내 Bash 명령 실행 이력 확인
|
|
17
|
+
2. 테스트가 한 번도 실행되지 않았으면 **블로킹** — 강제로 테스트 실행 요구
|
|
18
|
+
3. `stop_hook_active` 플래그로 1회만 블로킹 (무한루프 방지)
|
|
19
|
+
|
|
20
|
+
## 블로킹 수신 시 대응
|
|
21
|
+
|
|
22
|
+
`[Completion Guard]` 블로킹 메시지를 받으면:
|
|
23
|
+
1. 프로젝트의 테스트 명령을 실행하세요 (`npm test`, `pytest` 등)
|
|
24
|
+
2. 실패한 테스트가 있으면 수정하세요
|
|
25
|
+
3. 모든 테스트 통과 후 작업을 마무리하세요
|
|
26
|
+
|
|
27
|
+
## 참고
|
|
28
|
+
|
|
29
|
+
- Planning/Design phase에서는 블로킹하지 않음 (코드 변경이 없으므로)
|
|
30
|
+
- 세션 컨텍스트(`[Session]`)는 블로킹 여부와 무관하게 항상 주입됨
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 컨텍스트 윈도우 모니터. 85% 임계값 도달 시 사전 대응.
|
|
3
|
+
globs:
|
|
4
|
+
- ".timsquad/.daemon/**"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 컨텍스트 윈도우 모니터 (Context Window Monitor)
|
|
8
|
+
|
|
9
|
+
## 자동 감지
|
|
10
|
+
매 턴 종료 시 `[Session]` 메시지에 컨텍스트 사용률이 포함됩니다.
|
|
11
|
+
- 70% 이상: `Ctx: XX%` 표시
|
|
12
|
+
- 85% 이상: 경고 메시지 발생
|
|
13
|
+
|
|
14
|
+
## 85% 경고 수신 시 대응 절차
|
|
15
|
+
1. **현재 태스크 상태 기록**: 진행 중인 작업, 결정사항, 다음 단계를 정리
|
|
16
|
+
2. **서브에이전트 완료 대기**: 활성 서브에이전트가 있으면 완료 후 정리
|
|
17
|
+
3. **태스크 마무리**: 현재 태스크를 가능한 완료 지점까지 진행
|
|
18
|
+
4. **컨텍스트 압축 대비**: 자동 압축 후에도 `[Session]` 메시지로 상태 복원 가능
|
|
19
|
+
|
|
20
|
+
## 참고
|
|
21
|
+
- 기본 컨텍스트 윈도우: 200K 토큰 (Sonnet 기준)
|
|
22
|
+
- 자동 압축은 75-95% 사이에서 발생 (Claude Code 내부 휴리스틱)
|
|
23
|
+
- 사용률은 최신 턴의 input 토큰 기준 (누적 아님)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 계획 품질 검증 루프. Full Mode에서 구현 전 필수 수행.
|
|
3
|
+
globs:
|
|
4
|
+
- ".timsquad/ssot/**"
|
|
5
|
+
- ".timsquad/state/**"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 계획 품질 검증 (Plan Review Protocol)
|
|
9
|
+
|
|
10
|
+
## 언제 수행하나
|
|
11
|
+
`tsq f`로 Full Mode 진입 시, SSOT 체크 후 / 에이전트 위임 전.
|
|
12
|
+
|
|
13
|
+
## 검증 축 (3-Axis Plan Review)
|
|
14
|
+
|
|
15
|
+
### Axis P1: 요구사항 명확성
|
|
16
|
+
- 태스크가 구체적 행동(what)과 완료 조건(done-when)을 포함하는가
|
|
17
|
+
- 모호한 용어 없이 검증 가능한 기준이 있는가
|
|
18
|
+
- SSOT 문서(requirements.md, functional-spec.md)에 근거가 있는가
|
|
19
|
+
|
|
20
|
+
### Axis P2: 기술 분해 품질
|
|
21
|
+
- 단일 시퀀스로 완료 가능한 크기인가 (아니면 분할 필요)
|
|
22
|
+
- 에이전트 위임이 명확한가 (developer/dba/qa 중 누구에게)
|
|
23
|
+
- 의존성 순서가 올바른가 (DB 먼저 → API → 프론트 등)
|
|
24
|
+
|
|
25
|
+
### Axis P3: 리스크 & 빠진 것
|
|
26
|
+
- 기존 코드에 영향을 주는 부분이 식별되었는가
|
|
27
|
+
- 에러/엣지 케이스 대응이 계획에 포함되었는가
|
|
28
|
+
- 보안/성능 고려사항이 누락되지 않았는가
|
|
29
|
+
|
|
30
|
+
## 검증 결과 분류
|
|
31
|
+
|
|
32
|
+
| 결과 | 조건 | 액션 |
|
|
33
|
+
|------|------|------|
|
|
34
|
+
| ✅ PASS | 3축 모두 충족 | 구현 진행 |
|
|
35
|
+
| 🔄 REVISE (1/2) | 1-2축 미충족, 자체 보완 가능 | PM이 계획 보완 후 재검증 |
|
|
36
|
+
| ❌ ESCALATE | 3축 미충족 or 2회 재검토 후에도 미충족 | 사용자에게 확인 요청 (L3) |
|
|
37
|
+
|
|
38
|
+
## 재검토 규칙
|
|
39
|
+
- 최대 2회 재검토 (iteration 1 → 2 → 실패 시 ESCALATE)
|
|
40
|
+
- 매 재검토마다 어떤 축이 미충족인지 명시
|
|
41
|
+
- REVISE 시 SSOT 보완이 필요하면 먼저 SSOT 수정 후 재검증
|
|
42
|
+
- 2회 이내 PASS 시 "Plan Review: PASS (iteration N)" 기록 후 진행
|
|
43
|
+
|
|
44
|
+
## 상세 체크 항목
|
|
45
|
+
knowledge/checklists/plan-quality.md 참조.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 품질 가드 시스템. 파괴적 명령 차단, 페이즈 제한, 완료 검증.
|
|
3
|
+
globs:
|
|
4
|
+
- "**/*"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 품질 가드 시스템 (Quality Guards)
|
|
8
|
+
|
|
9
|
+
## 가드 목록
|
|
10
|
+
|
|
11
|
+
### 1. Safe Guard (PreToolUse/Bash)
|
|
12
|
+
Bash 명령 실행 전 파괴적 명령을 차단합니다.
|
|
13
|
+
|
|
14
|
+
**차단 (DENY)**:
|
|
15
|
+
- `rm -rf /` — 루트 삭제
|
|
16
|
+
- `git push --force` (main/master) — force push
|
|
17
|
+
- `git reset --hard` — 커밋되지 않은 변경 유실
|
|
18
|
+
- `DROP TABLE`, `TRUNCATE TABLE` — 데이터 파괴
|
|
19
|
+
- `chmod 777` — 보안 위반
|
|
20
|
+
|
|
21
|
+
**확인 요청 (ASK)**:
|
|
22
|
+
- `npm publish` — 패키지 배포
|
|
23
|
+
- `git push` (main/master) — 메인 브랜치 push
|
|
24
|
+
- `rm -rf` (일반) — 재귀 삭제
|
|
25
|
+
|
|
26
|
+
### 2. Phase Guard (PreToolUse/Write|Edit)
|
|
27
|
+
페이즈에 따라 파일 수정을 제한합니다.
|
|
28
|
+
|
|
29
|
+
- **planning/design**: `src/`, `lib/`, `app/` 등 코드 수정 차단
|
|
30
|
+
- **implementation**: `.timsquad/ssot/` 직접 수정 차단
|
|
31
|
+
|
|
32
|
+
### 3. Completion Guard (Stop)
|
|
33
|
+
매 턴 종료 시 세션 컨텍스트를 주입하고, 필요 시 경고합니다.
|
|
34
|
+
|
|
35
|
+
- 세션 상태 (턴, 도구, 에이전트, 파일) 주입
|
|
36
|
+
- implementation phase에서 테스트 미실행 경고
|
|
37
|
+
- 컨텍스트 윈도우 85% 이상 시 경고
|
|
38
|
+
|
|
39
|
+
## 가드가 차단한 경우
|
|
40
|
+
|
|
41
|
+
1. **DENY된 경우**: 차단 사유를 확인하고 안전한 대안을 사용하세요
|
|
42
|
+
2. **ASK로 에스컬레이션된 경우**: 사용자에게 확인을 요청합니다
|
|
43
|
+
3. **Phase 제한인 경우**: 현재 페이즈에 맞는 작업을 수행하세요
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 컨텍스트 생존 메모. 세션 압축 후 작업 연속성 유지.
|
|
3
|
+
globs:
|
|
4
|
+
- ".timsquad/.daemon/**"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 세션 컨텍스트 복원 (Session Notes)
|
|
8
|
+
|
|
9
|
+
## 자동 주입
|
|
10
|
+
매 턴 종료 시 `[Session]` 시스템 메시지가 자동 주입됩니다.
|
|
11
|
+
- 현재 턴 번호, 도구 사용 횟수, 활성 서브에이전트, 최근 수정 파일
|
|
12
|
+
|
|
13
|
+
## 압축 감지 후 대응
|
|
14
|
+
컨텍스트가 압축된 것 같으면 (이전 대화 내용이 요약되어 있으면):
|
|
15
|
+
1. `[Session]` 메시지의 턴/도구/에이전트 정보로 현재 진행 상태 파악
|
|
16
|
+
2. 필요 시 `.timsquad/.daemon/session-notes.jsonl`을 직접 읽어 이전 턴 이력 확인
|
|
17
|
+
3. 최근 수정 파일들을 Read로 다시 확인하여 작업 컨텍스트 복원
|
|
18
|
+
4. `.timsquad/logs/sessions/` 하위 세션 로그에서 상세 이벤트 확인 가능
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 런타임 스킬 제안. 프롬프트 분석 후 관련 스킬 자동 추천.
|
|
3
|
+
globs:
|
|
4
|
+
- "**/*"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 런타임 스킬 제안 (Skill Suggest)
|
|
8
|
+
|
|
9
|
+
## 자동 감지
|
|
10
|
+
|
|
11
|
+
매 프롬프트 제출 시 `[Skill Suggest]` 메시지가 주입될 수 있습니다.
|
|
12
|
+
- 사용자 프롬프트의 키워드/패턴을 분석하여 관련 스킬 추천
|
|
13
|
+
- 배포된 스킬만 추천 (프로젝트에 없는 스킬은 무시)
|
|
14
|
+
|
|
15
|
+
## 제안 수신 시 대응
|
|
16
|
+
|
|
17
|
+
`[Skill Suggest] 관련 스킬이 감지되었습니다: ...` 메시지를 받으면:
|
|
18
|
+
1. 추천된 스킬의 `rules/` 디렉토리를 확인하세요
|
|
19
|
+
2. 현재 태스크에 관련된 규칙을 참조하여 품질을 높이세요
|
|
20
|
+
3. 스킬이 현재 작업과 무관하면 무시해도 됩니다
|
|
21
|
+
|
|
22
|
+
## 스킬 규칙 위치
|
|
23
|
+
|
|
24
|
+
배포된 스킬: `.claude/skills/{skill-name}/`
|
|
25
|
+
- `SKILL.md` — 스킬 개요
|
|
26
|
+
- `rules/` — 구체적 규칙 (on-demand 참조)
|
|
27
|
+
- `references/` — 참고 자료
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "tests/**/*.test.ts"
|
|
4
|
+
- "tests/**/*.spec.ts"
|
|
5
|
+
- "**/*.test.ts"
|
|
6
|
+
- "**/*.spec.ts"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
- describe/it 중첩 3단계 이하 유지
|
|
10
|
+
- 테스트 데이터는 인라인 또는 fixtures/ 디렉토리 사용
|
|
11
|
+
- 각 테스트는 독립적 (공유 상태 금지, beforeEach에서 초기화)
|
|
12
|
+
- 테스트 이름은 "should + 기대 동작" 형식
|
|
13
|
+
- mock은 최소 범위로 사용 (외부 의존성만 mock)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Build Gate — Stop Hook
|
|
3
|
+
# 변경된 TypeScript 파일에 tsc 에러가 있으면 완료를 차단한다.
|
|
4
|
+
# 변경 파일만 필터링하여 기존 에러는 무시.
|
|
5
|
+
#
|
|
6
|
+
# Input: JSON via stdin (Claude Code hook protocol)
|
|
7
|
+
# Output: JSON with decision (block) or empty
|
|
8
|
+
|
|
9
|
+
set -e
|
|
10
|
+
|
|
11
|
+
# ── 0. Stop hook loop prevention ──
|
|
12
|
+
INPUT=$(cat 2>/dev/null || echo "")
|
|
13
|
+
STOP_HOOK_ACTIVE=$(echo "$INPUT" | jq -r '.stop_hook_active // false' 2>/dev/null || echo "false")
|
|
14
|
+
if [ "$STOP_HOOK_ACTIVE" = "true" ]; then
|
|
15
|
+
exit 0
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
# Find project root
|
|
19
|
+
PROJECT_ROOT="$(pwd)"
|
|
20
|
+
while [ "$PROJECT_ROOT" != "/" ]; do
|
|
21
|
+
if [ -d "$PROJECT_ROOT/.timsquad" ]; then
|
|
22
|
+
break
|
|
23
|
+
fi
|
|
24
|
+
PROJECT_ROOT="$(dirname "$PROJECT_ROOT")"
|
|
25
|
+
done
|
|
26
|
+
|
|
27
|
+
if [ ! -d "$PROJECT_ROOT/.timsquad" ]; then
|
|
28
|
+
exit 0
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# ── 1. Get changed TypeScript files ──
|
|
32
|
+
cd "$PROJECT_ROOT"
|
|
33
|
+
CHANGED_TS=$(git diff --name-only --diff-filter=ACMR HEAD -- '*.ts' '*.tsx' 2>/dev/null || echo "")
|
|
34
|
+
|
|
35
|
+
# No TypeScript files changed → pass
|
|
36
|
+
if [ -z "$CHANGED_TS" ]; then
|
|
37
|
+
exit 0
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# ── 2. Run tsc --noEmit ──
|
|
41
|
+
TSC_OUTPUT=$(npx tsc --noEmit 2>&1 || true)
|
|
42
|
+
|
|
43
|
+
# tsc passed → allow stop
|
|
44
|
+
if [ -z "$TSC_OUTPUT" ]; then
|
|
45
|
+
exit 0
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# ── 3. Filter errors to changed files only ──
|
|
49
|
+
RELEVANT_ERRORS=""
|
|
50
|
+
while IFS= read -r file; do
|
|
51
|
+
# tsc 에러 형식: src/foo.ts(12,5): error TS2345: ...
|
|
52
|
+
FILE_ERRORS=$(echo "$TSC_OUTPUT" | grep -F -- "$file" 2>/dev/null || true)
|
|
53
|
+
if [ -n "$FILE_ERRORS" ]; then
|
|
54
|
+
RELEVANT_ERRORS="${RELEVANT_ERRORS}${FILE_ERRORS}
|
|
55
|
+
"
|
|
56
|
+
fi
|
|
57
|
+
done <<< "$CHANGED_TS"
|
|
58
|
+
|
|
59
|
+
# No errors in changed files → pre-existing errors, ignore
|
|
60
|
+
if [ -z "$RELEVANT_ERRORS" ]; then
|
|
61
|
+
exit 0
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
# ── 4. Block with error details ──
|
|
65
|
+
# 에러 수 계산
|
|
66
|
+
ERROR_COUNT=$(echo "$RELEVANT_ERRORS" | grep -c "error TS" 2>/dev/null || echo "0")
|
|
67
|
+
|
|
68
|
+
REASON="[Build Gate] 변경된 파일에 TypeScript 에러 ${ERROR_COUNT}개가 있습니다. 수정 후 완료하세요.
|
|
69
|
+
|
|
70
|
+
${RELEVANT_ERRORS}"
|
|
71
|
+
|
|
72
|
+
jq -n --arg reason "$REASON" '{"decision": "block", "reason": $reason}'
|
|
73
|
+
exit 0
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# change-scope-guard.sh — PreToolUse Hook (Edit/Write)
|
|
3
|
+
# Tracks cumulative file changes and enforces SCR (Single Change Rule).
|
|
4
|
+
# 3 files: warning, 6 files: block, >100 lines total: warning
|
|
5
|
+
#
|
|
6
|
+
# Input: JSON via stdin (Claude Code hook protocol)
|
|
7
|
+
# Output: JSON with permissionDecision (allow/deny/ask)
|
|
8
|
+
#
|
|
9
|
+
# State file: /tmp/tsq-scope-guard-${SESSION_ID:-default}.json
|
|
10
|
+
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
WARN_FILES=3
|
|
14
|
+
BLOCK_FILES=6
|
|
15
|
+
WARN_LINES=100
|
|
16
|
+
|
|
17
|
+
# Session-scoped state file
|
|
18
|
+
SESSION_ID="${CLAUDE_SESSION_ID:-default}"
|
|
19
|
+
STATE_FILE="/tmp/tsq-scope-guard-${SESSION_ID}.json"
|
|
20
|
+
|
|
21
|
+
# Read hook input from stdin
|
|
22
|
+
INPUT=""
|
|
23
|
+
if read -t 1 -r line; then
|
|
24
|
+
INPUT="$line"
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# Fail-open: no input → allow
|
|
28
|
+
if [ -z "$INPUT" ]; then
|
|
29
|
+
echo '{"hookSpecificOutput":{"permissionDecision":"allow"}}'
|
|
30
|
+
exit 0
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Extract tool name
|
|
34
|
+
TOOL_NAME=""
|
|
35
|
+
if command -v jq >/dev/null 2>&1; then
|
|
36
|
+
TOOL_NAME=$(echo "$INPUT" | jq -r '.toolName // empty' 2>/dev/null || true)
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# Only track Edit and Write tools
|
|
40
|
+
if [ "$TOOL_NAME" != "Edit" ] && [ "$TOOL_NAME" != "Write" ]; then
|
|
41
|
+
echo '{"hookSpecificOutput":{"permissionDecision":"allow"}}'
|
|
42
|
+
exit 0
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Extract file path from tool input
|
|
46
|
+
FILE_PATH=""
|
|
47
|
+
if command -v jq >/dev/null 2>&1; then
|
|
48
|
+
FILE_PATH=$(echo "$INPUT" | jq -r '.toolInput.file_path // empty' 2>/dev/null || true)
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
if [ -z "$FILE_PATH" ]; then
|
|
52
|
+
echo '{"hookSpecificOutput":{"permissionDecision":"allow"}}'
|
|
53
|
+
exit 0
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# Initialize state file if needed
|
|
57
|
+
if [ ! -f "$STATE_FILE" ]; then
|
|
58
|
+
echo '{"files":[],"total_lines":0}' > "$STATE_FILE"
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# Read current state
|
|
62
|
+
if command -v jq >/dev/null 2>&1; then
|
|
63
|
+
CURRENT_FILES=$(jq -r '.files[]' "$STATE_FILE" 2>/dev/null || true)
|
|
64
|
+
TOTAL_LINES=$(jq -r '.total_lines // 0' "$STATE_FILE" 2>/dev/null || echo "0")
|
|
65
|
+
else
|
|
66
|
+
echo '{"hookSpecificOutput":{"permissionDecision":"allow"}}'
|
|
67
|
+
exit 0
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
# Check if file is already tracked
|
|
71
|
+
ALREADY_TRACKED=false
|
|
72
|
+
while IFS= read -r f; do
|
|
73
|
+
if [ "$f" = "$FILE_PATH" ]; then
|
|
74
|
+
ALREADY_TRACKED=true
|
|
75
|
+
break
|
|
76
|
+
fi
|
|
77
|
+
done <<< "$CURRENT_FILES"
|
|
78
|
+
|
|
79
|
+
# Add new file if not tracked
|
|
80
|
+
if [ "$ALREADY_TRACKED" = false ]; then
|
|
81
|
+
jq --arg fp "$FILE_PATH" '.files += [$fp]' "$STATE_FILE" > "${STATE_FILE}.tmp" && mv "${STATE_FILE}.tmp" "$STATE_FILE"
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
# Estimate line changes (for Edit: old_string length approximation)
|
|
85
|
+
if [ "$TOOL_NAME" = "Edit" ]; then
|
|
86
|
+
NEW_LINES=$(echo "$INPUT" | jq -r '.toolInput.new_string // ""' 2>/dev/null | wc -l || echo "0")
|
|
87
|
+
TOTAL_LINES=$((TOTAL_LINES + NEW_LINES))
|
|
88
|
+
jq --argjson tl "$TOTAL_LINES" '.total_lines = $tl' "$STATE_FILE" > "${STATE_FILE}.tmp" && mv "${STATE_FILE}.tmp" "$STATE_FILE"
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
# Count unique files
|
|
92
|
+
FILE_COUNT=$(jq '.files | length' "$STATE_FILE" 2>/dev/null || echo "0")
|
|
93
|
+
|
|
94
|
+
# Decision logic
|
|
95
|
+
if [ "$FILE_COUNT" -ge "$BLOCK_FILES" ]; then
|
|
96
|
+
MSG="SCR violation: ${FILE_COUNT} files modified (limit: ${BLOCK_FILES}). Split into smaller tasks."
|
|
97
|
+
echo "{\"hookSpecificOutput\":{\"permissionDecision\":\"deny\",\"message\":\"${MSG}\"}}"
|
|
98
|
+
exit 0
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
if [ "$FILE_COUNT" -ge "$WARN_FILES" ]; then
|
|
102
|
+
MSG="SCR warning: ${FILE_COUNT} files modified. Consider splitting this task."
|
|
103
|
+
echo "{\"hookSpecificOutput\":{\"permissionDecision\":\"allow\",\"message\":\"${MSG}\"}}"
|
|
104
|
+
exit 0
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
if [ "$TOTAL_LINES" -ge "$WARN_LINES" ]; then
|
|
108
|
+
MSG="Large change: ~${TOTAL_LINES} lines modified across ${FILE_COUNT} files."
|
|
109
|
+
echo "{\"hookSpecificOutput\":{\"permissionDecision\":\"allow\",\"message\":\"${MSG}\"}}"
|
|
110
|
+
exit 0
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
echo '{"hookSpecificOutput":{"permissionDecision":"allow"}}'
|