jinhak-ai-standard 2.7.1 → 3.7.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.
Files changed (86) hide show
  1. package/.claude/scripts/cleanup-nul.cjs +20 -0
  2. package/.claude/scripts/commit-guard.cjs +82 -0
  3. package/.claude/scripts/npm-tag-guard.cjs +85 -0
  4. package/.claude/scripts/session-briefing.cjs +2 -0
  5. package/.claude/settings.json +20 -2
  6. package/.claude/skills/code-garden/SKILL.md +112 -0
  7. package/.claude/skills/debug/SKILL.md +5 -0
  8. package/.claude/skills/deep-plan/SKILL.md +36 -21
  9. package/.claude/skills/dependency-guardian/SKILL.md +97 -0
  10. package/.claude/skills/dependency-guardian/assets/ALLOWLIST_STRICT.md +72 -0
  11. package/.claude/skills/dependency-guardian/assets/BLOCKLIST.md +32 -0
  12. package/.claude/skills/dependency-guardian/references/audit-lockfile.md +47 -0
  13. package/.claude/skills/dependency-guardian/references/check-package.md +56 -0
  14. package/.claude/skills/dependency-guardian/references/jabis-api-guide.md +42 -0
  15. package/.claude/skills/dependency-guardian/references/scoring-criteria.md +37 -0
  16. package/.claude/skills/dependency-guardian/scripts/check-npm-meta.sh +36 -0
  17. package/.claude/skills/dependency-guardian/scripts/sync-jabis-cache.sh +60 -0
  18. package/.claude/skills/doc-garden/SKILL.md +80 -0
  19. package/.claude/skills/lint-check/SKILL.md +57 -0
  20. package/.claude/skills/metrics-report/SKILL.md +59 -0
  21. package/.claude/skills/session-end/SKILL.md +78 -2
  22. package/CHANGELOG.md +218 -16
  23. package/CLAUDE.md +80 -1150
  24. package/PROMPT-LIBRARY.md +15 -5
  25. package/QUICK_START_PROMPT.md +2 -2
  26. package/README.md +155 -60
  27. package/SECURITY_ISMS.md +3 -4
  28. package/VIBE_CODING_GUIDE.md +4 -5
  29. package/docs/api/EXECUTION_RECORD_API_SPEC.md +206 -0
  30. package/docs/architecture/dependencies.md +148 -0
  31. package/docs/architecture/domain-map.md +127 -0
  32. package/{ARCHITECTURE.md → docs/architecture/layers.md} +37 -184
  33. package/docs/concepts/AI_WORK_PATTERN.md +172 -0
  34. package/docs/concepts/HARNESS_ENGINEERING.md +285 -0
  35. package/docs/concepts/V3_FULL_TECHNICAL_SPEC.md +717 -0
  36. package/docs/domain/domain-template.md +43 -0
  37. package/docs/plans/decision-context-pack-consolidation.md +52 -0
  38. package/docs/plans/decision-log-template.md +34 -0
  39. package/docs/plans/plan-template.md +72 -0
  40. package/docs/quality/daily-report-template.md +33 -0
  41. package/docs/quality/execution-record.md +170 -0
  42. package/docs/quality/grades-template.md +27 -0
  43. package/docs/quality/session-metrics.md +119 -0
  44. package/docs/quality/tech-debt-template.md +31 -0
  45. package/docs/security/AI_SECURITY_GUARDRAILS.md +377 -0
  46. package/docs/security/DATA_CLASSIFICATION.md +242 -0
  47. package/docs/security/FORBIDDEN_PATTERNS.md +485 -0
  48. package/docs/security/INCIDENT_RESPONSE.md +300 -0
  49. package/docs/security/OWASP_LLM_CHECKLIST.md +229 -0
  50. package/docs/standards/api-patterns.md +222 -0
  51. package/docs/standards/clarification-protocol.md +130 -0
  52. package/{CODING_CONVENTIONS.md → docs/standards/coding.md} +36 -76
  53. package/docs/standards/difficulty-guide.md +132 -0
  54. package/docs/standards/lint-architecture-rules.md +425 -0
  55. package/docs/standards/lint-architecture-technical-spec.md +604 -0
  56. package/docs/standards/naming.md +148 -0
  57. package/docs/standards/phase-gates.md +175 -0
  58. package/{PROJECT_STRUCTURE.md → docs/standards/project-structure.md} +30 -9
  59. package/docs/standards/prompt-structure.md +119 -0
  60. package/package.json +3 -1
  61. package/prompts/_template/metadata.json +20 -1
  62. package/prompts/code-review/security-review/metadata.json +30 -3
  63. package/prompts/testing/unit-test-gen/metadata.json +29 -3
  64. package/scripts/doc-coverage-check.cjs +236 -0
  65. package/scripts/doc-freshness-check.cjs +157 -0
  66. package/scripts/execution-record-collect.cjs +197 -0
  67. package/scripts/install-global-hook.cjs +34 -12
  68. package/scripts/retry-pending-records.cjs +127 -0
  69. package/scripts/security-check-hook.cjs +16 -3
  70. package/security/AI_SECURITY_GUARDRAILS.md +5 -6
  71. package/security/FORBIDDEN_PATTERNS.md +1 -1
  72. package/security/INCIDENT_RESPONSE.md +3 -4
  73. package/security/OWASP_LLM_CHECKLIST.md +3 -4
  74. package/templates/ai-folder-templates.md +1 -1
  75. package/templates/ci-architecture-lint.yml +55 -0
  76. package/templates/project-claude.md +1 -1
  77. package/tracking/TRACKING_SETUP.md +123 -0
  78. package/tracking/grade-history-collector.cjs +86 -0
  79. package/tracking/lint-metrics-collector.cjs +121 -0
  80. package/tracking/prompt-usage-tracker.cjs +210 -0
  81. package/tracking/schemas/lint-metrics.schema.json +18 -0
  82. package/tracking/schemas/usage-event.schema.json +52 -0
  83. package/tracking/test-fixtures/generate-sample.cjs +39 -0
  84. package/tracking/test-fixtures/sample-usage.jsonl +20 -0
  85. package/.claude/skills/orchestrate/SKILL.md +0 -220
  86. package/security/NIGHTBUILDER_SECURITY.md +0 -234
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * PostToolUse Hook — Windows nul 파일 자동 삭제
5
+ *
6
+ * Windows에서 `> nul` 리다이렉션 사용 시 예약 디바이스 이름 충돌로
7
+ * 실제 `nul` 파일이 생성되는 문제를 방지합니다.
8
+ * \\?\ prefix로 Windows 예약어를 우회하여 삭제합니다.
9
+ */
10
+
11
+ const fs = require('fs');
12
+ const path = require('path');
13
+
14
+ const nulPath = '\\\\?\\' + path.resolve('nul');
15
+
16
+ try {
17
+ fs.unlinkSync(nulPath);
18
+ } catch {
19
+ // 파일이 없으면 무시
20
+ }
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * commit-guard.cjs
4
+ *
5
+ * PreToolUse Hook — git commit 실행 시 JINHAK 표준 커밋 형식을 검증합니다.
6
+ *
7
+ * 검증 항목:
8
+ * 1. 커밋 메시지가 <type>: <한글 설명> 형식인가
9
+ * 2. Co-Authored-By 태그가 포함되어 있는가
10
+ * 3. /commit 스킬을 통하지 않은 직접 커밋이면 경고
11
+ *
12
+ * Hook 결과:
13
+ * - exit 0 + stdout 비어있음 → 통과 (아무 출력도 안 하면 통과)
14
+ * - exit 0 + stdout에 메시지 → 경고 표시 (진행은 됨)
15
+ * - exit 2 → 차단 (커밋 실행 불가)
16
+ */
17
+ 'use strict';
18
+
19
+ const VALID_TYPES = ['feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore'];
20
+ const TYPE_PATTERN = new RegExp(`^(${VALID_TYPES.join('|')}):\\s*.+`);
21
+ const CO_AUTHOR_PATTERN = /Co-Authored-By:/i;
22
+
23
+ // Hook에서 전달받는 환경변수/인자에서 커밋 메시지 추출
24
+ const input = process.env.CLAUDE_TOOL_INPUT || process.argv.slice(2).join(' ');
25
+
26
+ // git commit 명령인지 확인
27
+ if (!input.includes('git commit') && !input.includes('git -c') ) {
28
+ // git commit이 아니면 무시
29
+ process.exit(0);
30
+ }
31
+
32
+ // 커밋 메시지 추출 시도
33
+ let commitMsg = '';
34
+
35
+ // -m "메시지" 또는 -m '메시지' 패턴
36
+ const mFlag = input.match(/-m\s+["']([\s\S]*?)["']/);
37
+ if (mFlag) {
38
+ commitMsg = mFlag[1];
39
+ }
40
+
41
+ // HEREDOC 패턴: -m "$(cat <<'EOF' ... EOF )"
42
+ const heredoc = input.match(/cat\s*<<['"]?EOF['"]?\n([\s\S]*?)\nEOF/);
43
+ if (heredoc) {
44
+ commitMsg = heredoc[1];
45
+ }
46
+
47
+ if (!commitMsg) {
48
+ // 메시지를 파싱할 수 없으면 경고만
49
+ console.log('⚠️ [commit-guard] 커밋 메시지를 파싱할 수 없습니다. /commit 스킬 사용을 권장합니다.');
50
+ process.exit(0);
51
+ }
52
+
53
+ // 첫 줄(subject) 추출
54
+ const subject = commitMsg.split('\n')[0].trim();
55
+ const errors = [];
56
+
57
+ // 1. type: 한글 형식 검증
58
+ if (!TYPE_PATTERN.test(subject)) {
59
+ errors.push(`커밋 메시지 형식 위반: "${subject}"`);
60
+ errors.push(` 필수 형식: <type>: <한글 설명>`);
61
+ errors.push(` 유효 type: ${VALID_TYPES.join(', ')}`);
62
+ }
63
+
64
+ // 2. Co-Authored-By 검증
65
+ if (!CO_AUTHOR_PATTERN.test(commitMsg)) {
66
+ errors.push(`Co-Authored-By 태그 누락`);
67
+ errors.push(` 필수: Co-Authored-By: Claude <noreply@anthropic.com>`);
68
+ }
69
+
70
+ if (errors.length > 0) {
71
+ console.log('');
72
+ console.log('❌ [commit-guard] JINHAK 커밋 표준 위반:');
73
+ errors.forEach(e => console.log(` ${e}`));
74
+ console.log('');
75
+ console.log('💡 /commit 스킬을 사용하면 자동으로 표준에 맞는 커밋이 생성됩니다.');
76
+ console.log('');
77
+ // exit 2 = 차단
78
+ process.exit(2);
79
+ }
80
+
81
+ // 통과 — 아무것도 출력하지 않음
82
+ process.exit(0);
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * npm Tag Guard Hook
4
+ *
5
+ * git push 시점에 package.json 버전이 변경되었는데
6
+ * 해당 버전의 git tag가 없으면 push를 차단합니다.
7
+ *
8
+ * 이 프로젝트는 npm 패키지(jinhak-ai-standard)이므로
9
+ * 버전 변경 시 반드시 태그를 생성해야 npm publish가 트리거됩니다.
10
+ */
11
+
12
+ const { execSync } = require('child_process');
13
+
14
+ // push 명령이 아니면 무시
15
+ const command = process.env.command || '';
16
+ if (!command.includes('push')) {
17
+ process.exit(0);
18
+ }
19
+
20
+ try {
21
+ const pkg = require('../../package.json');
22
+ const version = pkg.version;
23
+ const tagName = `v${version}`;
24
+
25
+ // 해당 버전의 태그가 존재하는지 확인
26
+ let tagExists = false;
27
+ try {
28
+ execSync(`git tag -l "${tagName}"`, { encoding: 'utf-8' }).trim();
29
+ const result = execSync(`git tag -l "${tagName}"`, { encoding: 'utf-8' }).trim();
30
+ tagExists = result === tagName;
31
+ } catch {
32
+ tagExists = false;
33
+ }
34
+
35
+ if (tagExists) {
36
+ // 태그가 이미 push되었는지 확인
37
+ let tagPushed = false;
38
+ try {
39
+ const remoteTag = execSync(`git ls-remote --tags origin "refs/tags/${tagName}"`, { encoding: 'utf-8' }).trim();
40
+ tagPushed = remoteTag.length > 0;
41
+ } catch {
42
+ tagPushed = false;
43
+ }
44
+
45
+ if (!tagPushed) {
46
+ console.log(`[npm Guard] ⚠️ 태그 ${tagName}가 로컬에 있지만 원격에 push되지 않았습니다.
47
+
48
+ 이 프로젝트는 npm 패키지이므로 태그를 push해야 npm publish가 트리거됩니다.
49
+ 코드 push 후 반드시 실행하세요:
50
+ git push origin ${tagName}`);
51
+ }
52
+ process.exit(0);
53
+ }
54
+
55
+ // 태그가 없음 — 버전이 원격의 최신 태그와 다른지 확인
56
+ let latestRemoteTag = '';
57
+ try {
58
+ latestRemoteTag = execSync('git describe --tags --abbrev=0 2>/dev/null', { encoding: 'utf-8' }).trim();
59
+ } catch {
60
+ // 태그가 하나도 없는 경우
61
+ latestRemoteTag = '';
62
+ }
63
+
64
+ const latestVersion = latestRemoteTag.replace(/^v/, '');
65
+
66
+ if (version !== latestVersion) {
67
+ // 버전이 변경되었는데 태그가 없음 → 차단
68
+ console.log(`[npm Guard] 🚫 PUSH 차단 — package.json 버전(${version})에 대한 태그(${tagName})가 없습니다!
69
+
70
+ 이 프로젝트는 npm 패키지(jinhak-ai-standard)입니다.
71
+ 버전을 올렸으면 반드시 태그를 생성하고 함께 push해야 합니다.
72
+
73
+ 필요한 명령:
74
+ git tag ${tagName}
75
+ git push origin master ${tagName}
76
+
77
+ 태그 없이 push하면 npm에 새 버전이 배포되지 않습니다.
78
+ 반드시 태그를 먼저 생성한 후 push를 진행하세요.`);
79
+ process.exit(1);
80
+ }
81
+
82
+ } catch (e) {
83
+ // 스크립트 오류 시 push를 막지 않음
84
+ process.exit(0);
85
+ }
@@ -126,3 +126,5 @@ output.push('');
126
126
  output.push('위 컨텍스트를 참고하여 이전 작업 맥락을 이어서 진행하세요.');
127
127
 
128
128
  console.log(output.join('\n'));
129
+
130
+ try { require(require('path').join(require('os').homedir(), '.claude', 'scripts', 'retry-pending-records.cjs')); } catch(e) { /* 글로벌 스크립트 미설치 시 무시 */ }
@@ -68,7 +68,7 @@
68
68
  "hooks": [
69
69
  {
70
70
  "type": "command",
71
- "command": "node scripts/security-check-hook.cjs"
71
+ "command": "node \"$(git rev-parse --show-toplevel)/scripts/security-check-hook.cjs\""
72
72
  }
73
73
  ]
74
74
  },
@@ -80,6 +80,24 @@
80
80
  "command": "node .claude/scripts/readme-guard.cjs"
81
81
  }
82
82
  ]
83
+ },
84
+ {
85
+ "matcher": "Bash(git*commit*)",
86
+ "hooks": [
87
+ {
88
+ "type": "command",
89
+ "command": "node .claude/scripts/commit-guard.cjs"
90
+ }
91
+ ]
92
+ },
93
+ {
94
+ "matcher": "Bash",
95
+ "hooks": [
96
+ {
97
+ "type": "command",
98
+ "command": "node .claude/scripts/npm-tag-guard.cjs"
99
+ }
100
+ ]
83
101
  }
84
102
  ],
85
103
  "PostToolUse": [
@@ -110,7 +128,7 @@
110
128
  "hooks": [
111
129
  {
112
130
  "type": "command",
113
- "command": "node scripts/session-end-reminder.cjs"
131
+ "command": "node \"$(git rev-parse --show-toplevel)/scripts/session-end-reminder.cjs\""
114
132
  }
115
133
  ]
116
134
  }
@@ -0,0 +1,112 @@
1
+ ---
2
+ name: code-garden
3
+ description: 코드 품질 점검 및 엔트로피 관리 — 아키텍처 린트, 중복 코드, 복잡도 급증, 미사용 코드 탐지
4
+ ---
5
+
6
+ # /code-garden
7
+
8
+ 코드 품질을 종합 점검하고 엔트로피(코드 복잡도 증가)를 관리합니다.
9
+
10
+ ## 사용법
11
+
12
+ ```
13
+ /code-garden [옵션]
14
+ ```
15
+
16
+ **옵션:**
17
+ - `--check <type>`: 특정 검사만 실행 (`duplicates`, `complexity`, `unused`, `grade`, `all`)
18
+ - `--dir <path>`: 대상 디렉토리 지정
19
+ - `--auto-fix`: 자동 수정 안내 포함
20
+ - (기본: 전체 검사 + 리포트 출력)
21
+
22
+ ## 절차
23
+
24
+ ### 1단계: 도구 실행
25
+
26
+ `tools/code-garden/` 도구를 실행하여 코드 품질 지표를 수집합니다.
27
+
28
+ ```bash
29
+ # 전체 검사
30
+ cd tools/code-garden && node dist/index.js --check all --dir <프로젝트_루트>
31
+
32
+ # 개별 검사
33
+ node dist/index.js --check duplicates --dir <프로젝트_루트>
34
+ node dist/index.js --check complexity --dir <프로젝트_루트>
35
+ node dist/index.js --check unused --dir <프로젝트_루트>
36
+ node dist/index.js --check grade --dir <프로젝트_루트>
37
+ ```
38
+
39
+ 수집 항목:
40
+ 1. **중복 코드 탐지** — 10줄 이상, 85%+ 유사도 코드 블록 탐지
41
+ 2. **복잡도 급증 감지** — 최근 7일 대비 50%+ 복잡도 증가 파일
42
+ 3. **미사용 코드 탐지** — export 했지만 다른 파일에서 import하지 않는 심볼
43
+ 4. **품질 등급 산정** — 도메인(디렉토리)별 A~D 등급
44
+
45
+ ### 2단계: 결과 분석 + 등급 산정
46
+
47
+ 도구 출력 결과를 분석하여 도메인별 등급을 확인합니다.
48
+
49
+ | 등급 | 기준 |
50
+ |------|------|
51
+ | A | 린트 에러 0, 복잡도 낮음, 중복 코드 없음 |
52
+ | B | 린트 에러 5개 미만, 복잡도 중간 이하 |
53
+ | C | 린트 에러 10개 미만 |
54
+ | D | 위 기준 미달 |
55
+
56
+ 분석 포인트:
57
+ - 등급이 하락한 도메인이 있는지 확인
58
+ - 복잡도 급증 파일의 원인 파악 (대규모 기능 추가? 리팩토링 필요?)
59
+ - 중복 코드가 공통 모듈로 추출 가능한지 검토
60
+ - 미사용 export가 의도적인지(향후 사용 예정) 확인
61
+
62
+ ### 3단계: 리포트 출력
63
+
64
+ 결과를 사용자에게 보고합니다. 형식:
65
+
66
+ ```
67
+ ## 코드 품질 리포트 (YYYY-MM-DD)
68
+
69
+ ### 전체 요약
70
+ - 전체 등급: X
71
+ - 총 파일 수: N
72
+ - 중복 코드: N건
73
+ - 복잡도 급증: N건
74
+ - 미사용 export: N건
75
+
76
+ ### 도메인별 등급
77
+ | 도메인 | 등급 | 상세 |
78
+ |--------|------|------|
79
+ | ... | ... | ... |
80
+
81
+ ### 주요 이슈
82
+ 1. ...
83
+ 2. ...
84
+
85
+ ### 권장 조치
86
+ - ...
87
+ ```
88
+
89
+ `docs/quality/grades.md`를 도구 출력의 Markdown 리포트로 업데이트합니다.
90
+
91
+ ### 4단계: 자동 수정 (--auto-fix 옵션 시)
92
+
93
+ `--auto-fix` 옵션이 지정된 경우, 자동 수정 가능한 항목을 안내합니다:
94
+
95
+ - **중복 코드**: 공통 함수/유틸로 추출할 위치 제안
96
+ - **미사용 export**: `export` 키워드 제거 또는 파일 삭제 제안
97
+ - **복잡도 급증**: 함수 분리, 조건문 단순화 등 리팩토링 제안
98
+
99
+ 자동 수정은 직접 코드를 변경하며, 변경 전 확인을 요청합니다.
100
+
101
+ ## 도구 경로
102
+
103
+ - **도구 위치**: `tools/code-garden/`
104
+ - **빌드**: `cd tools/code-garden && npm run build`
105
+ - **테스트**: `cd tools/code-garden && npm test`
106
+ - **CLI**: `node tools/code-garden/dist/index.js`
107
+
108
+ ## 참고
109
+
110
+ - `docs/quality/grades-template.md` — 등급 문서 템플릿
111
+ - `docs/quality/tech-debt-template.md` — 기술 부채 추적 템플릿
112
+ - `docs/quality/daily-report-template.md` — 일일 리포트 템플릿
@@ -24,6 +24,11 @@ $ARGUMENTS - 버그 증상 또는 에러 메시지 (필수)
24
24
 
25
25
  ---
26
26
 
27
+ ## 사전 참조
28
+
29
+ - `docs/standards/clarification-protocol.md` — 에러 정보가 부족하면 HIGH/MEDIUM 판정 후 질문
30
+ - `docs/standards/difficulty-guide.md` — 버그 복잡도에 따라 Phase 깊이 조절 (Simple 버그는 Phase 2에서 바로 수정 가능)
31
+
27
32
  ## 실행 절차 (4단계, 순서 엄수)
28
33
 
29
34
  ### Phase 1: 증상 수집 (Observe)
@@ -26,14 +26,47 @@ $ARGUMENTS - 구현할 기능/작업에 대한 설명 (필수)
26
26
 
27
27
  > 간단한 작업은 Plan 모드(`EnterPlanMode`)로 충분합니다. `/deep-plan`은 **계획 자체의 품질 검증**이 필요할 때 사용합니다.
28
28
 
29
+ ## 적응적 추천 (Auto-Suggest)
30
+
31
+ Plan 모드(`EnterPlanMode`) 진입 후 코드베이스를 탐색하면서 다음 조건 중 2개 이상 해당되면 `/deep-plan` 사용을 **추천**합니다. 최종 결정은 사용자에게 맡깁니다.
32
+
33
+ **복잡도 판정 기준:**
34
+ - 수정 대상 파일 5개 이상
35
+ - 2가지 이상 구현 방식 선택이 필요
36
+ - Human-in-the-Loop 필수 영역 해당 (인증/인가, 결제/정산, 개인정보, 암호화, 인프라, 마이그레이션)
37
+ - 신규 모듈/서비스 생성 포함
38
+
39
+ **추천 흐름:**
40
+ ```
41
+ EnterPlanMode → 코드베이스 탐색 (Glob, Grep, Read)
42
+
43
+ [복잡도 판정: 위 기준 2개+ 해당?]
44
+ ├─ 예 → "이 작업은 L3 이상 복잡도입니다. `/deep-plan`으로 심층 계획을 수립하시겠습니까?"
45
+ │ → 사용자 승인 → `/deep-plan` 전환
46
+ │ → 사용자 거절 → 일반 Plan 모드 계속
47
+ └─ 아니오 → 일반 Plan 모드 진행
48
+ ```
49
+
50
+ **핵심: 추천은 하되 강제하지 않는다.** 사용자가 거절하면 일반 Plan 모드로 진행한다.
51
+
29
52
  ---
30
53
 
31
54
  ## 실행 절차
32
55
 
33
56
  ### 0단계: 사전 분석 및 요구사항 정제
34
57
 
35
- 1. 사용자의 요청(`$ARGUMENTS`)을 분석하여 **명시적 요구사항**과 **암묵적 요구사항** 분리
36
- 2. **작업 유형 태그 자동 분류:**
58
+ > **필수 참조**: 단계에서 `docs/standards/prompt-structure.md`(4요소 구조), `docs/standards/clarification-protocol.md`(불확실성 대응)를 적용합니다.
59
+
60
+ 1. 사용자의 요청(`$ARGUMENTS`)을 **4요소 프레임워크**로 분석:
61
+ - **Goal**: 명시적 요구사항과 암묵적 요구사항 분리
62
+ - **Context**: 관련 코드베이스 탐색 (Glob, Grep, Read)
63
+ - **Constraints**: CLAUDE.md 절대 규칙 + 작업 유형별 제약
64
+ - **Done When**: 검증 가능한 완료 기준 도출
65
+ 2. **불확실성 판정** (`docs/standards/clarification-protocol.md`):
66
+ - LOW → 가정 기록 후 진행
67
+ - MEDIUM → 옵션 제시 + 사용자 선택
68
+ - HIGH → 질문 후 답변 받을 때까지 대기
69
+ 3. **작업 유형 태그 자동 분류:**
37
70
 
38
71
  | 태그 | 해당 조건 | Critic 가중치 영향 |
39
72
  |------|----------|-------------------|
@@ -44,10 +77,6 @@ $ARGUMENTS - 구현할 기능/작업에 대한 설명 (필수)
44
77
  | `비즈니스` | 핵심 도메인 로직, 결제/정산 | C6 가중 ×1.5, C4 가중 ×1.5 |
45
78
  | `일반` | 위에 해당하지 않는 경우 | 기본 가중치 (모두 ×1.0) |
46
79
 
47
- 3. 모호하거나 결정이 필요한 부분이 있으면 `AskUserQuestion`으로 먼저 확인:
48
- - 기술적 선택지 (예: JWT vs 세션, Redis vs 인메모리)
49
- - 범위 확인 (어디까지 포함하는가)
50
- - 우선순위 (성능 vs 구현 속도 vs 유지보수성)
51
80
  4. 관련 코드베이스 탐색 (Glob, Grep, Read)으로 현재 상태 파악
52
81
 
53
82
  ### 1단계: 팀 구성
@@ -217,20 +246,6 @@ Task({
217
246
  - 라운드 간 가중 비율 개선이 **+5%p 미만**이면 → 정체로 판단, 사용자 위임
218
247
  - 3라운드 초과 시 → 전체 계획 + 비평 이력을 사용자에게 제시하고 판단 위임
219
248
 
220
- **NightBuilder 환경 분기:**
221
-
222
- NightBuilder(무인 자동 개발) 환경에서 3라운드 내 미수렴 시:
223
- 1. 현재까지의 계획서 + 비평 이력을 `.ai/PENDING_PLANS.md`에 저장:
224
- ```markdown
225
- ## [보류] YYYY-MM-DD HH:mm - [작업요약]
226
- - 상태: 미수렴 (라운드 N, 가중 비율 NN.N%)
227
- - C6 Hard Gate: 통과/실패/해당없음
228
- - 저장된 계획서: `.ai/plans/YYYY-MM-DD_HHmm_[작업요약].md`
229
- - 사유: [정체/라운드 초과/C6 Hard Gate 실패]
230
- ```
231
- 2. 다음 태스크로 진행 (교착 방지)
232
- 3. 다음 세션(사람 참여) 시 `session-briefing.cjs`가 보류 건을 감지하여 안내
233
-
234
249
  **재작성 지시 시:**
235
250
  ```
236
251
  SendMessage({
@@ -452,7 +467,7 @@ TeamDelete()
452
467
  - Planner와 Critic은 **읽기 전용** 에이전트 (Plan 타입) — 코드를 직접 수정하지 않음
453
468
  - Plan 타입이 사용 불가능한 경우 Explore → general-purpose(파일 수정 금지 지시) 순으로 폴백
454
469
  - 비평은 냉혹하게 하되, **건설적인 대안**을 반드시 제시
455
- - 3라운드 내 수렴하지 않으면 무한 반복하지 않고 사용자에게 위임 (NightBuilder는 PENDING_PLANS.md 저장)
470
+ - 3라운드 내 수렴하지 않으면 무한 반복하지 않고 사용자에게 위임
456
471
  - C6 Hard Gate는 보안/비즈니스 유형에서만 적용 — 일반 작업에 과도한 보안 검증을 강제하지 않음
457
472
 
458
473
  ---
@@ -0,0 +1,97 @@
1
+ # dependency-guardian
2
+
3
+ npm 패키지 설치 안전성을 검증합니다.
4
+
5
+ ## 트리거
6
+
7
+ 사용자가 새로운 npm 패키지를 설치하려 할 때, 또는 `npm install`, `pnpm add` 등 패키지 추가 명령 실행 전에 이 스킬을 실행합니다.
8
+
9
+ ## 데이터 소스 우선순위
10
+
11
+ 패키지 상태 조회 시 아래 순서로 시도합니다:
12
+
13
+ ### 1순위: JABIS API 실시간 조회
14
+ - URL: `{JABIS_API_URL}/api/v1/packages/check/{packageName}?mode={mode}`
15
+ - JABIS_API_URL은 프로젝트 CLAUDE.md의 `jabis_api_url` 설정에서 읽음
16
+ - 타임아웃: 3초
17
+ - 인증: JABIS JWT 토큰 (환경변수 `JABIS_API_TOKEN`)
18
+
19
+ ### 2순위: 로컬 캐시 (assets/cache/*.json)
20
+ - `scripts/sync-jabis-cache.sh`로 주기적 동기화 (1일 1회 권장)
21
+ - 캐시 유효기간: 24시간 (파일 수정 시간 기준)
22
+ - 캐시 만료 시: "⚠️ JABIS 캐시가 24시간 이상 경과. sync-jabis-cache.sh 실행을 권장합니다."
23
+
24
+ ### 3순위: 정적 파일 fallback
25
+ - `assets/BLOCKLIST.md`, `assets/ALLOWLIST_STRICT.md`
26
+ - API와 캐시 모두 실패 시 최종 fallback
27
+ - "⚠️ JABIS API 연결 불가. 정적 파일 기반 검사. 결과가 최신이 아닐 수 있습니다."
28
+
29
+ ### 자동 모드 감지
30
+ - CLAUDE.md에 `jabis_api_url`이 없으면 → 정적 파일 모드로 동작 (기존 호환)
31
+ - `dependency_guard_mode: strict` 또는 `standard` (기본: standard)
32
+
33
+ ## 실행 절차
34
+
35
+ ### Step 0: JABIS 레지스트리 조회
36
+ 1. JABIS API 호출 (또는 캐시/정적 파일 조회)
37
+ 2. 응답 status에 따른 판정:
38
+ - **BLOCKED** → 즉시 ❌ BLOCK. reason과 alternative 표시. 이후 Step 스킵.
39
+ - **RECOMMENDED/ALLOWED** → 즉시 ✅ PASS. 이후 Step 스킵.
40
+ - **CAUTION** → ⚠️ WARN 후 Step 1~3 추가 검증 진행.
41
+ - **UNREGISTERED** → Step 1~3 일반 검사 플로우 진행.
42
+ - API 실패 → fallback 후 Step 1~3 진행.
43
+ 3. STRICT 모드 + UNREGISTERED → 즉시 ❌ BLOCK:
44
+ "STRICT 모드에서 미등록 패키지는 설치 불가. JABIS 패키지 레지스트리에서 승인 요청을 먼저 진행하세요."
45
+
46
+ ### Step 1: npm 메타데이터 검사
47
+ 패키지의 npm 레지스트리 메타데이터를 확인합니다:
48
+ - 주간 다운로드 수 (1,000 미만 → 위험)
49
+ - 최종 발행일 (2년 초과 → 위험)
50
+ - 메인테이너 수 (1명 → 위험)
51
+ - install 스크립트 존재 여부
52
+
53
+ `references/check-package.md` 참조.
54
+
55
+ ### Step 2: 취약점 검사
56
+ - `npm audit` 결과 확인
57
+ - Critical/High 취약점 → BLOCK
58
+ - Moderate → WARN
59
+
60
+ ### Step 3: risk_score 계산
61
+ `references/scoring-criteria.md`의 기준으로 0~100 점수 산출.
62
+
63
+ ## 결과 출력 형식
64
+
65
+ ```
66
+ 📦 패키지: {name}@{version}
67
+ 🔒 모드: STRICT | STANDARD
68
+ 📡 소스: JABIS API | 로컬 캐시 ({N}시간 전) | 정적 파일 (fallback)
69
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━
70
+ ✅ PASS | ⚠️ WARN | ❌ BLOCK
71
+
72
+ 📊 위험도: {score}/100
73
+ 📋 사유: {reason}
74
+ 🔄 대안: {alternative} (BLOCK/CAUTION 시)
75
+ ```
76
+
77
+ ## Lock 파일 전수 검사
78
+
79
+ `/dependency-guardian audit` 명령으로 package-lock.json 전체 패키지를 검사합니다.
80
+ - JABIS bulk-check API 활용 (가능한 경우)
81
+ - `references/audit-lockfile.md` 참조.
82
+
83
+
84
+ ## CLAUDE.md 설정 예시
85
+
86
+ ```markdown
87
+ ## Dependency Guardian 설정
88
+ dependency_guard_mode: strict
89
+ jabis_api_url: https://jabis.jinhakapply.com
90
+ jabis_api_token: ${JABIS_API_TOKEN}
91
+ ```
92
+
93
+ ## 참조 문서
94
+ - `references/check-package.md` — 단일 패키지 검사 상세
95
+ - `references/audit-lockfile.md` — Lock 파일 전수 검사
96
+ - `references/scoring-criteria.md` — risk_score 계산 기준
97
+ - `references/jabis-api-guide.md` — JABIS API 연동 가이드
@@ -0,0 +1,72 @@
1
+ # STRICT 모드 허용 목록 (정적 Fallback)
2
+
3
+ > STRICT 모드에서는 이 목록에 있는 패키지만 설치 가능합니다.
4
+ > 최신 목록은 JABIS 패키지 레지스트리를 참조하세요.
5
+
6
+ ## 허용 패키지
7
+
8
+ ### 프레임워크
9
+ | 패키지명 | 버전 제약 | 카테고리 |
10
+ |----------|----------|---------|
11
+ | react | >= 18.0.0 | frontend |
12
+ | react-dom | >= 18.0.0 | frontend |
13
+ | next | >= 14.0.0 | frontend |
14
+ | express | >= 4.18.0 | backend |
15
+ | fastify | >= 4.0.0 | backend |
16
+ | @nestjs/core | >= 10.0.0 | backend |
17
+
18
+ ### ORM / DB
19
+ | 패키지명 | 버전 제약 | 카테고리 |
20
+ |----------|----------|---------|
21
+ | @prisma/client | >= 5.0.0 | backend |
22
+ | prisma | >= 5.0.0 | devtool |
23
+ | mssql | >= 10.0.0 | backend |
24
+ | pg | >= 8.0.0 | backend |
25
+ | ioredis | >= 5.0.0 | backend |
26
+
27
+ ### UI
28
+ | 패키지명 | 버전 제약 | 카테고리 |
29
+ |----------|----------|---------|
30
+ | tailwindcss | >= 3.0.0 | frontend |
31
+ | @radix-ui/* | any | frontend |
32
+ | class-variance-authority | any | frontend |
33
+ | clsx | any | frontend |
34
+ | lucide-react | any | frontend |
35
+
36
+ ### 상태 관리
37
+ | 패키지명 | 버전 제약 | 카테고리 |
38
+ |----------|----------|---------|
39
+ | zustand | >= 4.0.0 | frontend |
40
+ | @tanstack/react-query | >= 5.0.0 | frontend |
41
+ | jotai | >= 2.0.0 | frontend |
42
+
43
+ ### 유틸리티
44
+ | 패키지명 | 버전 제약 | 카테고리 |
45
+ |----------|----------|---------|
46
+ | zod | >= 3.0.0 | utility |
47
+ | date-fns | >= 3.0.0 | utility |
48
+ | dayjs | >= 1.11.0 | utility |
49
+ | lodash | >= 4.17.21 | utility |
50
+ | axios | >= 1.0.0 | utility |
51
+ | pino | >= 8.0.0 | backend |
52
+ | bcrypt | >= 5.0.0 | security |
53
+ | jsonwebtoken | >= 9.0.0 | security |
54
+ | helmet | >= 7.0.0 | security |
55
+
56
+ ### 테스팅
57
+ | 패키지명 | 버전 제약 | 카테고리 |
58
+ |----------|----------|---------|
59
+ | vitest | >= 1.0.0 | testing |
60
+ | @testing-library/react | >= 14.0.0 | testing |
61
+ | playwright | >= 1.40.0 | testing |
62
+ | msw | >= 2.0.0 | testing |
63
+
64
+ ### 빌드 도구
65
+ | 패키지명 | 버전 제약 | 카테고리 |
66
+ |----------|----------|---------|
67
+ | typescript | >= 5.0.0 | devtool |
68
+ | vite | >= 5.0.0 | devtool |
69
+ | eslint | >= 8.0.0 | devtool |
70
+ | prettier | >= 3.0.0 | devtool |
71
+
72
+ > 마지막 업데이트: 2026-03-16
@@ -0,0 +1,32 @@
1
+ # 패키지 차단 목록 (정적 Fallback)
2
+
3
+ > 이 파일은 JABIS API에 접근할 수 없을 때 사용하는 최종 fallback입니다.
4
+ > 최신 목록은 JABIS 패키지 레지스트리를 참조하세요.
5
+
6
+ ## 차단 패키지
7
+
8
+ | 패키지명 | 사유 | 대안 |
9
+ |----------|------|------|
10
+ | event-stream | 2018년 악성코드 삽입 | readable-stream, through2 |
11
+ | flatmap-stream | event-stream 의존성 공격 | Array.prototype.flatMap |
12
+ | ua-parser-js (< 0.7.33) | 크립토마이너 삽입 | ua-parser-js >= 1.0.33 |
13
+ | colors (> 1.4.0) | 의도적 파괴 코드 | chalk, picocolors |
14
+ | faker (> 5.5.3) | 의도적 파괴 코드 | @faker-js/faker |
15
+ | node-ipc (> 10.1.0) | 의도적 파괴 코드 | 이전 안전 버전 사용 |
16
+ | rc (< 1.2.7) | 프로토타입 오염 | rc >= 1.2.8 |
17
+ | minimist (< 1.2.6) | 프로토타입 오염 | minimist >= 1.2.6 |
18
+ | lodash (< 4.17.21) | 프로토타입 오염 | lodash >= 4.17.21 |
19
+ | xmlhttprequest-ssl | 폐기됨, 취약점 | axios, node-fetch |
20
+ | request | 폐기됨, 미유지보수 | axios, got, node-fetch |
21
+ | moment | 폐기됨, 큰 번들 | dayjs, date-fns |
22
+
23
+ ## Typosquatting 주의 패키지
24
+
25
+ | 정상 패키지 | Typosquatting 시도 |
26
+ |------------|-------------------|
27
+ | lodash | lodashs, lodash-es (정상), lodahs |
28
+ | express | expresss, expres |
29
+ | react | reacct, reactt |
30
+ | chalk | chalks, chalkk |
31
+
32
+ > 마지막 업데이트: 2026-03-16