@ps-neko/nekowork 0.1.0-alpha.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 (203) hide show
  1. package/AGENTS.md +112 -0
  2. package/CLAUDE.md +81 -0
  3. package/LICENSE +21 -0
  4. package/README.md +283 -0
  5. package/REVIEW.md +96 -0
  6. package/RULES.md +51 -0
  7. package/SOUL.md +21 -0
  8. package/WORKING-CONTEXT.md +52 -0
  9. package/agent.yaml +219 -0
  10. package/agents/architect.md +57 -0
  11. package/agents/code-reviewer.md +60 -0
  12. package/agents/codex-challenger.md +53 -0
  13. package/agents/codex-reviewer.md +56 -0
  14. package/agents/debugger.md +33 -0
  15. package/agents/doc-writer.md +51 -0
  16. package/agents/executor.md +41 -0
  17. package/agents/planner.md +49 -0
  18. package/agents/research.md +50 -0
  19. package/agents/security-reviewer.md +47 -0
  20. package/agents/test-engineer.md +41 -0
  21. package/bridge/mcp-server.js +301 -0
  22. package/commands/claude-led-codex-review.md +29 -0
  23. package/docs/ADVANCED.md +321 -0
  24. package/docs/AI-DEVELOPMENT-LIFECYCLE.md +105 -0
  25. package/docs/ARCHITECTURE.md +205 -0
  26. package/docs/AUDIT.md +114 -0
  27. package/docs/AUTH-MIGRATION.md +282 -0
  28. package/docs/CHANGELOG.md +97 -0
  29. package/docs/CLI-STAGES.md +89 -0
  30. package/docs/CODEMAPS/README.md +15 -0
  31. package/docs/CODEMAPS/agents.md +22 -0
  32. package/docs/CODEMAPS/bridge.md +18 -0
  33. package/docs/CODEMAPS/hooks.md +28 -0
  34. package/docs/CODEMAPS/manifests.md +14 -0
  35. package/docs/CODEMAPS/rules.md +22 -0
  36. package/docs/CODEMAPS/schemas.md +21 -0
  37. package/docs/CODEMAPS/scripts.md +158 -0
  38. package/docs/CODEMAPS/skills.md +29 -0
  39. package/docs/CODEMAPS/tests.md +98 -0
  40. package/docs/CORE-INVARIANTS.md +38 -0
  41. package/docs/DEMO.md +110 -0
  42. package/docs/EXAMPLE-PROJECT.md +92 -0
  43. package/docs/PORTING.md +154 -0
  44. package/docs/PRODUCT-PRINCIPLES.md +303 -0
  45. package/docs/PUBLISH-ALPHA.md +106 -0
  46. package/docs/QUICKSTART.md +344 -0
  47. package/docs/RELEASE-READINESS.md +140 -0
  48. package/docs/RISK-CLASSIFIER.md +50 -0
  49. package/docs/RUNBOOK.md +146 -0
  50. package/docs/SECURITY.md +79 -0
  51. package/docs/SETUP.md +142 -0
  52. package/docs/WHY-NEKOWORK.md +64 -0
  53. package/docs/case-studies/README.md +16 -0
  54. package/docs/case-studies/SINDRESORHUS-IS-PLAIN-OBJ.md +141 -0
  55. package/docs/dev-log/2026-04-29-p1-recovery.md +142 -0
  56. package/docs/dev-log/2026-04-29-week1-4.md +81 -0
  57. package/docs/examples/GITHUB-ACTIONS-HARDENING.md +86 -0
  58. package/docs/examples/QUALITY-LIFECYCLE-SMOKE.md +32 -0
  59. package/docs/examples/TRADING-DASHBOARD-MOCK.md +65 -0
  60. package/docs/workflows-stash/README.md +32 -0
  61. package/docs/workflows-stash/harness-review.yml +166 -0
  62. package/docs/workflows-stash/harness-validate.yml +48 -0
  63. package/examples/github-actions-hardening/.github/workflows/hardened-validate.yml +38 -0
  64. package/examples/github-actions-hardening/README.md +31 -0
  65. package/examples/github-actions-hardening/case-study/ASK.md +26 -0
  66. package/examples/github-actions-hardening/case-study/GATE_STATUS.md +28 -0
  67. package/examples/github-actions-hardening/case-study/PLAN.md +25 -0
  68. package/examples/github-actions-hardening/case-study/SHIP_READY.md +21 -0
  69. package/examples/github-actions-hardening/case-study/TASK.md +30 -0
  70. package/examples/github-actions-hardening/case-study/TEAM_HANDOFFS.md +37 -0
  71. package/examples/github-actions-hardening/case-study/VERIFY_SUMMARY.md +35 -0
  72. package/examples/github-actions-hardening/case-study/WORK_SUMMARY.md +24 -0
  73. package/examples/github-actions-hardening/package.json +12 -0
  74. package/examples/github-actions-hardening/scripts/check.mjs +43 -0
  75. package/examples/quality-lifecycle-smoke/README.md +30 -0
  76. package/examples/quality-lifecycle-smoke/case-study/ASK.md +24 -0
  77. package/examples/quality-lifecycle-smoke/case-study/GATE_STATUS.md +10 -0
  78. package/examples/quality-lifecycle-smoke/case-study/PLAN.md +19 -0
  79. package/examples/quality-lifecycle-smoke/case-study/SHIP_READY.md +11 -0
  80. package/examples/quality-lifecycle-smoke/case-study/TASK.md +19 -0
  81. package/examples/quality-lifecycle-smoke/case-study/TEAM_HANDOFFS.md +21 -0
  82. package/examples/quality-lifecycle-smoke/case-study/VERIFY_SUMMARY.md +44 -0
  83. package/examples/quality-lifecycle-smoke/case-study/WORK_SUMMARY.md +19 -0
  84. package/examples/quality-lifecycle-smoke/package.json +8 -0
  85. package/examples/quality-lifecycle-smoke/scripts/check.mjs +44 -0
  86. package/examples/trading-dashboard-mock/README.md +33 -0
  87. package/examples/trading-dashboard-mock/case-study/ASK.md +24 -0
  88. package/examples/trading-dashboard-mock/case-study/GATE_STATUS.md +28 -0
  89. package/examples/trading-dashboard-mock/case-study/PLAN.md +23 -0
  90. package/examples/trading-dashboard-mock/case-study/SHIP_READY.md +21 -0
  91. package/examples/trading-dashboard-mock/case-study/TASK.md +29 -0
  92. package/examples/trading-dashboard-mock/case-study/TEAM_HANDOFFS.md +49 -0
  93. package/examples/trading-dashboard-mock/case-study/VERIFY_SUMMARY.md +35 -0
  94. package/examples/trading-dashboard-mock/case-study/WORK_SUMMARY.md +27 -0
  95. package/examples/trading-dashboard-mock/fixtures/market.json +9 -0
  96. package/examples/trading-dashboard-mock/index.html +76 -0
  97. package/examples/trading-dashboard-mock/package.json +9 -0
  98. package/examples/trading-dashboard-mock/scripts/check.mjs +54 -0
  99. package/examples/trading-dashboard-mock/src/app.js +83 -0
  100. package/examples/trading-dashboard-mock/src/styles.css +227 -0
  101. package/hooks/hooks.json +44 -0
  102. package/hooks/scripts/config-protection.js +34 -0
  103. package/hooks/scripts/gateguard-fact-force.js +146 -0
  104. package/hooks/scripts/persistent-mode.mjs +27 -0
  105. package/hooks/scripts/pre-bash-dispatcher.js +63 -0
  106. package/hooks/scripts/quality-gate.js +106 -0
  107. package/manifests/install-components.json +195 -0
  108. package/manifests/install-modules.json +101 -0
  109. package/manifests/install-profiles.json +134 -0
  110. package/package.json +96 -0
  111. package/rules/common/coding-style.md +71 -0
  112. package/rules/common/security.md +69 -0
  113. package/rules/common/testing.md +58 -0
  114. package/rules/python/coding-style.md +80 -0
  115. package/rules/python/testing.md +86 -0
  116. package/rules/typescript/coding-style.md +97 -0
  117. package/rules/typescript/security.md +67 -0
  118. package/rules/typescript/testing.md +78 -0
  119. package/schemas/agent-yaml.schema.json +168 -0
  120. package/schemas/agent.schema.json +32 -0
  121. package/schemas/handoff.schema.json +105 -0
  122. package/schemas/hooks.schema.json +35 -0
  123. package/schemas/install-components.schema.json +46 -0
  124. package/schemas/install-modules.schema.json +39 -0
  125. package/schemas/install-profiles.schema.json +32 -0
  126. package/schemas/install-state.schema.json +42 -0
  127. package/schemas/routing.schema.json +42 -0
  128. package/schemas/skill.schema.json +19 -0
  129. package/scripts/agents/dispatch.js +144 -0
  130. package/scripts/agents/runners/claude.js +214 -0
  131. package/scripts/agents/runners/codex.js +233 -0
  132. package/scripts/agents/runners/gemini.js +92 -0
  133. package/scripts/agents/runners/mock.js +107 -0
  134. package/scripts/auth/github-import-gh.js +52 -0
  135. package/scripts/auth/github-login.js +79 -0
  136. package/scripts/auth/github-logout.js +21 -0
  137. package/scripts/auth/github-status.js +46 -0
  138. package/scripts/build-claude.js +101 -0
  139. package/scripts/build-codemaps.js +286 -0
  140. package/scripts/build-codex.js +93 -0
  141. package/scripts/build-cursor.js +132 -0
  142. package/scripts/build-gemini.js +117 -0
  143. package/scripts/build-opencode.js +117 -0
  144. package/scripts/ci/catalog.js +120 -0
  145. package/scripts/ci/check-markers.js +48 -0
  146. package/scripts/ci/security-hardening.js +270 -0
  147. package/scripts/ci/validate-agents.js +88 -0
  148. package/scripts/ci/validate-hooks.js +99 -0
  149. package/scripts/ci/validate-manifests.js +128 -0
  150. package/scripts/ci/validate-skills.js +93 -0
  151. package/scripts/cli.js +1134 -0
  152. package/scripts/core/auth-guard.js +22 -0
  153. package/scripts/core/build-roots.js +11 -0
  154. package/scripts/core/cli-resolver.js +64 -0
  155. package/scripts/core/execution-workspace.js +84 -0
  156. package/scripts/core/git-mutation-guard.js +79 -0
  157. package/scripts/core/install-state.js +125 -0
  158. package/scripts/core/json-extractor.js +32 -0
  159. package/scripts/core/subprocess.js +74 -0
  160. package/scripts/daemon/wait.js +278 -0
  161. package/scripts/demo-external-project.js +222 -0
  162. package/scripts/demo-quick-run.js +193 -0
  163. package/scripts/demo-review.js +204 -0
  164. package/scripts/doctor.js +296 -0
  165. package/scripts/install-apply.js +185 -0
  166. package/scripts/install-plan.js +411 -0
  167. package/scripts/lib/acceptance-criteria.js +105 -0
  168. package/scripts/lib/costs.js +82 -0
  169. package/scripts/lib/instincts.js +194 -0
  170. package/scripts/lib/keychain.js +85 -0
  171. package/scripts/lib/profile-policy.js +134 -0
  172. package/scripts/lib/profile-safety.js +81 -0
  173. package/scripts/lib/risk-classifier.js +145 -0
  174. package/scripts/lib/router.js +138 -0
  175. package/scripts/lib/severity.js +99 -0
  176. package/scripts/lib/token-vault.js +136 -0
  177. package/scripts/orchestrators/apply.js +225 -0
  178. package/scripts/orchestrators/ask.js +143 -0
  179. package/scripts/orchestrators/gate.js +179 -0
  180. package/scripts/orchestrators/ralph.js +179 -0
  181. package/scripts/orchestrators/review.js +452 -0
  182. package/scripts/orchestrators/run.js +151 -0
  183. package/scripts/orchestrators/ship.js +339 -0
  184. package/scripts/orchestrators/team-lite.js +270 -0
  185. package/scripts/orchestrators/team.js +244 -0
  186. package/scripts/orchestrators/verify.js +306 -0
  187. package/scripts/orchestrators/work.js +207 -0
  188. package/scripts/portability/simulate-port.js +220 -0
  189. package/scripts/repair.js +184 -0
  190. package/scripts/sync-claude-md.js +220 -0
  191. package/scripts/verify/claude-live.js +30 -0
  192. package/scripts/verify/codex-live.js +60 -0
  193. package/scripts/verify/gemini-live.js +48 -0
  194. package/scripts/verify/runtime.js +105 -0
  195. package/skills/claude-led-codex-review/SKILL.md +133 -0
  196. package/skills/plan-eng-review/SKILL.md +51 -0
  197. package/skills/porting/SKILL.md +69 -0
  198. package/skills/ralph/SKILL.md +48 -0
  199. package/skills/release-readiness/SKILL.md +62 -0
  200. package/skills/review/SKILL.md +42 -0
  201. package/skills/security-hardening/SKILL.md +59 -0
  202. package/skills/ship/SKILL.md +44 -0
  203. package/skills/tdd-workflow/SKILL.md +42 -0
package/package.json ADDED
@@ -0,0 +1,96 @@
1
+ {
2
+ "name": "@ps-neko/nekowork",
3
+ "version": "0.1.0-alpha.0",
4
+ "description": "Local-first AI development harness for Claude Code, Codex CLI, and Gemini CLI",
5
+ "keywords": [
6
+ "claude",
7
+ "claude-code",
8
+ "codex",
9
+ "ai-agent",
10
+ "code-review",
11
+ "second-opinion",
12
+ "mcp",
13
+ "harness",
14
+ "multi-agent"
15
+ ],
16
+ "license": "MIT",
17
+ "private": false,
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/Ps-Neko/NEKOWORK.git"
21
+ },
22
+ "type": "module",
23
+ "engines": {
24
+ "node": ">=22.0.0"
25
+ },
26
+ "bin": {
27
+ "harness": "scripts/cli.js"
28
+ },
29
+ "files": [
30
+ "agent.yaml",
31
+ "agents/",
32
+ "skills/",
33
+ "commands/",
34
+ "hooks/",
35
+ "rules/",
36
+ "manifests/",
37
+ "schemas/",
38
+ "scripts/",
39
+ "bridge/",
40
+ "examples/",
41
+ "docs/",
42
+ "SOUL.md",
43
+ "RULES.md",
44
+ "CLAUDE.md",
45
+ "AGENTS.md",
46
+ "WORKING-CONTEXT.md",
47
+ "REVIEW.md"
48
+ ],
49
+ "scripts": {
50
+ "build": "echo 'build: harness-specific projection scripts run via prepack' && exit 0",
51
+ "build:claude": "node scripts/build-claude.js",
52
+ "build:codex": "node scripts/build-codex.js",
53
+ "build:cursor": "node scripts/build-cursor.js",
54
+ "build:gemini": "node scripts/build-gemini.js",
55
+ "build:codemaps": "node scripts/build-codemaps.js",
56
+ "lint": "node scripts/ci/catalog.js && npm run validate:all && npm run security:hardening",
57
+ "test": "node --test tests/unit/*.test.js tests/integration/*.test.js tests/e2e/*.test.js",
58
+ "test:unit": "node --test tests/unit/*.test.js",
59
+ "test:integration": "node --test tests/integration/*.test.js",
60
+ "test:e2e": "node --test tests/e2e/*.test.js",
61
+ "test:catalog": "node scripts/ci/catalog.js",
62
+ "security:hardening": "node scripts/ci/security-hardening.js",
63
+ "validate:agents": "node scripts/ci/validate-agents.js",
64
+ "validate:skills": "node scripts/ci/validate-skills.js",
65
+ "validate:hooks": "node scripts/ci/validate-hooks.js",
66
+ "validate:manifests": "node scripts/ci/validate-manifests.js",
67
+ "validate:all": "npm run validate:agents && npm run validate:skills && npm run validate:hooks && npm run validate:manifests",
68
+ "install:plan": "node scripts/install-plan.js",
69
+ "install:apply": "node scripts/install-apply.js",
70
+ "demo:quick": "node scripts/demo-quick-run.js",
71
+ "demo:external": "node scripts/demo-external-project.js",
72
+ "verify:claude": "node scripts/verify/claude-live.js",
73
+ "verify:codex": "node scripts/verify/codex-live.js",
74
+ "verify:gemini": "node scripts/verify/gemini-live.js",
75
+ "verify:runtime": "node scripts/verify/runtime.js",
76
+ "auth:github:login": "node scripts/auth/github-login.js",
77
+ "auth:github:status": "node scripts/auth/github-status.js",
78
+ "auth:github:logout": "node scripts/auth/github-logout.js",
79
+ "test:keychain": "node --test tests/optional/keychain-smoke.test.js",
80
+ "auth:github:import-gh": "node scripts/auth/github-import-gh.js"
81
+ },
82
+ "dependencies": {
83
+ "@modelcontextprotocol/sdk": "^1.29.0",
84
+ "@napi-rs/keyring": "^1.2.0",
85
+ "ajv": "^8.17.1",
86
+ "ajv-formats": "^3.0.1",
87
+ "yaml": "^2.6.1"
88
+ },
89
+ "devDependencies": {
90
+ "@types/node": "^22.10.0",
91
+ "typescript": "^5.7.2"
92
+ },
93
+ "optionalDependencies": {
94
+ "@anthropic-ai/sdk": "^0.92.0"
95
+ }
96
+ }
@@ -0,0 +1,71 @@
1
+ # common/coding-style — 언어 무관 공통 규칙
2
+
3
+ > 이 문서는 모든 언어 룰의 베이스. 언어별 디렉터리(`typescript/`, `python/`)가 이 룰을 확장한다.
4
+ > 본 룰의 위반은 `quality-gate` → `code-reviewer` → `codex-reviewer` 단계에서 차단된다.
5
+
6
+ ## 1. 불변성 우선
7
+
8
+ 원본 객체는 변경하지 않는다. 새 객체를 만들어 돌려준다.
9
+
10
+ ```
11
+ // 잘못됨 (mutation)
12
+ modify(original, "field", value) // original 자체가 바뀜
13
+
14
+ // 올바름 (immutable)
15
+ new = update(original, "field", value) // original 보존, 새 객체 반환
16
+ ```
17
+
18
+ 근거: side effect 격리, 디버깅 단순화, 동시성 안전.
19
+
20
+ > **언어 노트**: Go·Rust 처럼 mutation 이 관용적인 언어는 해당 언어 룰이 이 원칙을 재정의할 수 있다.
21
+
22
+ ## 2. 파일 조직
23
+
24
+ 작은 파일 다수 > 큰 파일 소수.
25
+
26
+ - 보통 200~400 줄, 800줄을 넘으면 분할 후보.
27
+ - 응집도(cohesion) 높게, 결합도(coupling) 낮게.
28
+ - 도메인 / 기능 단위로 묶고, 타입(`utils.ts`, `helpers.ts` 같은 잡동사니) 으로 묶지 않는다.
29
+
30
+ ## 3. 함수
31
+
32
+ - 1 함수 1 책임. 50줄 넘으면 분할 후보.
33
+ - 부정 조건은 early-return 으로 거두고 nesting 4단계 초과 금지.
34
+ - 인자 4개 초과 시 객체로 묶거나 빌더 패턴 검토.
35
+
36
+ ## 4. 네이밍
37
+
38
+ - 가독성 > 짧음. `r`, `tmp`, `data2` 금지.
39
+ - 부울 변수·함수는 `is`, `has`, `can`, `should` 접두사.
40
+ - 상수는 SCREAMING_SNAKE_CASE.
41
+ - 약어는 단어 취급(파스칼/카멜 케이스에서 `Url`, `Api` — 모두 대문자 금지).
42
+
43
+ ## 5. 에러 처리
44
+
45
+ - 모든 레벨에서 명시적으로 처리한다.
46
+ - UI 표면에는 사용자 친화적 메시지, 서버 로그에는 풀 컨텍스트.
47
+ - 절대 silent swallow 금지(빈 catch / `except: pass`).
48
+ - 시스템 경계(외부 API, 사용자 입력, 파일 입력)에서만 검증·차단.
49
+
50
+ ## 6. 입력 검증
51
+
52
+ - 시스템 경계에서 schema 검증 (TS: zod / ajv, Python: pydantic).
53
+ - 외부에서 들어온 데이터는 신뢰하지 않는다.
54
+ - fail-fast: 잘못된 입력은 즉시 명확한 메시지로 거부.
55
+
56
+ ## 7. 부수 효과 명시
57
+
58
+ - 네트워크 / 디스크 / 글로벌 상태 변경은 함수 시그니처와 이름에 드러난다.
59
+ - 순수 함수는 순수하게 두고, side-effect 가 있는 호출은 한 곳으로 모은다(orchestrator 패턴).
60
+
61
+ ## 8. 코드 리뷰 체크리스트
62
+
63
+ 작업을 끝났다고 표시하기 전 확인:
64
+
65
+ - [ ] 모든 새 함수 50줄 이하, nesting 4단계 이하.
66
+ - [ ] 외부 입력 검증 있음.
67
+ - [ ] 에러는 처리되거나 명시적으로 throw.
68
+ - [ ] 하드코딩된 값 없음 (상수 / 환경 변수 / 설정 사용).
69
+ - [ ] mutation 없음 (또는 mutation 이 의도적이고 주석 있음).
70
+ - [ ] 공개 API 의 타입 / 시그니처 명시.
71
+ - [ ] 단위 테스트 추가, 80% 커버리지 유지 (`common/testing.md`).
@@ -0,0 +1,69 @@
1
+ # common/security — 보안 공통 규칙
2
+
3
+ > 본 룰은 `gateguard-fact-force`, `config-protection`, `audit log` 훅과
4
+ > `security-reviewer` 에이전트가 강제한다. 위반 시 자동 차단.
5
+
6
+ ## 1. 시크릿
7
+
8
+ - 코드에 하드코딩 금지 (API key, password, token).
9
+ - 환경 변수 또는 시크릿 매니저 사용.
10
+ - 시작 시 필수 변수 존재 확인 — 없으면 명시적 에러로 종료.
11
+ - 노출된 시크릿은 즉시 rotate.
12
+
13
+ ## 2. 입력 검증
14
+
15
+ - 모든 외부 입력(HTTP 요청, 파일, 환경 변수, 외부 API 응답)은 schema 로 검증.
16
+ - SQL injection: parameterized query 만 사용. string concat 금지.
17
+ - XSS: HTML 출력은 escape. raw html 삽입은 명시적 sanitize 후만.
18
+ - 경로 traversal: `..` 와 절대 경로 차단.
19
+
20
+ ## 3. 인증·인가
21
+
22
+ - 인증 없는 엔드포인트는 명시적으로 표시 (`@public`).
23
+ - 인가는 리소스 단위로 매번 확인 (역할 기반만으로 부족).
24
+ - 세션 토큰은 `httpOnly` + `secure` + `sameSite=strict`.
25
+
26
+ ## 4. Rate Limiting
27
+
28
+ - 모든 외부 노출 엔드포인트에 rate limit 적용.
29
+ - 인증 실패 / 회원가입 / 비밀번호 재설정은 더 엄격하게.
30
+
31
+ ## 5. 에러 메시지
32
+
33
+ - 사용자 표면: 일반적인 메시지 ("요청을 처리하지 못했습니다").
34
+ - 서버 로그: 풀 컨텍스트 (스택, 입력값 — 단 시크릿은 redact).
35
+ - 에러 메시지로 시스템 내부 구조(파일 경로, 스택, DB 컬럼명) 노출 금지.
36
+
37
+ ## 6. 의존성
38
+
39
+ - 모든 npm / pip / cargo 의존성은 SemVer 핀.
40
+ - `@latest` 금지.
41
+ - 정기적으로 `npm audit` / `pip-audit` / `cargo audit` 실행.
42
+ - `lockfile` 은 커밋한다.
43
+
44
+ ## 7. MCP / 외부 서비스
45
+
46
+ - `agent.yaml` 의 `mcp.external_servers` 는 SemVer 핀 필수 (`mcp_pin_required: true`).
47
+ - 새 MCP 서버 추가 시 `security-reviewer` 검토 후 머지.
48
+
49
+ ## 8. 커밋 전 체크리스트
50
+
51
+ - [ ] 하드코딩된 시크릿 / API 키 없음.
52
+ - [ ] 모든 입력 검증.
53
+ - [ ] SQL parameterized.
54
+ - [ ] XSS / CSRF 방어 활성.
55
+ - [ ] 인증·인가 검증.
56
+ - [ ] Rate limit 설정.
57
+ - [ ] 에러 메시지에 민감 정보 없음.
58
+ - [ ] 의존성 SemVer 핀.
59
+
60
+ ## 9. 사고 대응
61
+
62
+ 문제 발견 시:
63
+
64
+ 1. **STOP** — 즉시 작업 중단.
65
+ 2. `security-reviewer` 에이전트로 영향 범위 분석.
66
+ 3. CRITICAL 은 다른 작업보다 우선.
67
+ 4. 노출된 시크릿 rotate.
68
+ 5. 같은 패턴이 다른 코드에 있는지 grep.
69
+ 6. 사후: `docs/dev-log/` 에 incident note 추가.
@@ -0,0 +1,58 @@
1
+ # common/testing — 테스트 공통 규칙
2
+
3
+ > 본 룰은 `verification.required_coverage_pct: 80` 와 `quality-gate` 훅이 강제한다.
4
+
5
+ ## 1. 테스트 종류
6
+
7
+ 3가지 모두 필수:
8
+
9
+ 1. **Unit Tests** — `tests/unit/<area>.test.<ext>`. 함수·유틸·컴포넌트 단위.
10
+ 2. **Integration Tests** — `tests/integration/<scenario>.test.<ext>`. API 엔드포인트, DB 트랜잭션, 파일 IO.
11
+ 3. **E2E Tests** — `tests/e2e/<flow>.test.<ext>`. 핵심 사용자 흐름.
12
+
13
+ ## 2. 커버리지 하한
14
+
15
+ - 라인 커버리지 80% 이상 유지.
16
+ - 새 PR 의 라인 커버리지가 베이스 브랜치 대비 떨어지면 `quality-gate` 차단.
17
+ - 핵심 도메인(보안 / 결제 / 데이터 일관성)은 90% 이상 권장.
18
+
19
+ ## 3. TDD 워크플로우
20
+
21
+ `skills/tdd-workflow/SKILL.md` 와 정합:
22
+
23
+ 1. **RED** — 실패하는 테스트 먼저 작성.
24
+ 2. **GREEN** — 통과시킬 최소 구현.
25
+ 3. **REFACTOR** — 중복 제거, 네이밍 정리.
26
+ 4. **VERIFY** — 커버리지·린트 확인.
27
+
28
+ ## 4. 테스트 격리
29
+
30
+ - 각 테스트는 독립적으로 실행 가능해야 한다 (실행 순서 의존 금지).
31
+ - 글로벌 상태 변경은 `setup` / `teardown` 으로 복구.
32
+ - 외부 시스템(DB, 네트워크)은 통합 테스트에서만 사용. 단위 테스트는 mock.
33
+
34
+ ## 5. 결정성
35
+
36
+ - `Date.now()`, `Math.random()`, UUID 같은 비결정 소스는 주입(injection)으로 대체.
37
+ - 테스트가 가끔 실패하면 즉시 격리(`.skip`)하고 원인 추적 — 무시하지 않는다.
38
+
39
+ ## 6. 데이터
40
+
41
+ - 픽스처는 `tests/fixtures/<area>/` 에 둔다.
42
+ - 가능한 한 작고 의미가 명확한 데이터.
43
+ - 실 운영 데이터를 그대로 가져오지 않는다 (PII 위험).
44
+
45
+ ## 7. 실패 분석 순서
46
+
47
+ `tdd-workflow` 와 동일:
48
+
49
+ 1. 격리: 다른 테스트와 독립적으로 실패하는가?
50
+ 2. 결정성: 같은 입력에 같은 결과인가?
51
+ 3. 모킹: mock 이 실 구현과 합치하는가?
52
+ 4. 구현 vs 테스트: 어느 쪽이 잘못됐는가? — 보통 구현. 테스트가 잘못이면 명시적으로 그 근거를 PR 설명에.
53
+
54
+ ## 8. CI 게이트
55
+
56
+ - `npm run test` (또는 언어별 등가) 가 PR 단계에서 통과해야 한다.
57
+ - `npm run validate:all` 도 함께 통과해야 한다.
58
+ - `harness review --no-ship` 으로 로컬 풀체인 미리 돌려볼 수 있다.
@@ -0,0 +1,80 @@
1
+ # python/coding-style — Python 룰
2
+
3
+ > [common/coding-style.md](../common/coding-style.md) 의 Python 확장.
4
+
5
+ ## 1. PEP 8 + 타입
6
+
7
+ - PEP 8 + PEP 484 (타입 힌트) 기본.
8
+ - 포매터: `ruff format` (이전 black). 라인 100자.
9
+ - 린터: `ruff check`. 추가로 `mypy --strict` 또는 `pyright`.
10
+
11
+ ## 2. 타입 힌트
12
+
13
+ - 공개 함수·메서드는 인자·반환 타입 명시.
14
+ - `Any` 는 외부 데이터 진입점만, 즉시 narrow.
15
+ - `from __future__ import annotations` 로 forward reference 부담 제거.
16
+
17
+ ```python
18
+ from __future__ import annotations
19
+
20
+ def format_user(user: User) -> str:
21
+ return f"{user.first_name} {user.last_name}"
22
+ ```
23
+
24
+ ## 3. 데이터 모델
25
+
26
+ - 단순 값 묶음: `dataclass` (`frozen=True` 우선).
27
+ - 검증 + 직렬화 필요: `pydantic.BaseModel`.
28
+ - `Enum` 보다 `Literal["a", "b"]` 권장 (직렬화 단순).
29
+
30
+ ## 4. 불변성
31
+
32
+ - `dataclass(frozen=True)` 또는 `tuple` / `frozenset`.
33
+ - 리스트 mutation 보다 컴프리헨션·`+` 로 새 객체.
34
+
35
+ ```python
36
+ # 잘못됨
37
+ def add(items, x):
38
+ items.append(x)
39
+ return items
40
+
41
+ # 올바름
42
+ def add(items: list[int], x: int) -> list[int]:
43
+ return [*items, x]
44
+ ```
45
+
46
+ ## 5. 에러 처리
47
+
48
+ - 도메인 에러 클래스 (`class NotFoundError(Exception): ...`).
49
+ - `except Exception:` 광범위 catch 금지. 좁게.
50
+ - `try/except/else/finally` 의 `else` 는 성공 경로 분리에 활용.
51
+ - 절대 `except: pass` 금지.
52
+
53
+ ## 6. 컨텍스트 매니저
54
+
55
+ - 파일·DB·락 등 자원은 `with` 로. 수동 close 금지.
56
+ - 사용자 정의는 `contextlib.contextmanager` 또는 `__enter__/__exit__`.
57
+
58
+ ## 7. 비동기
59
+
60
+ - `async def` + `await` 기본. blocking IO 는 `asyncio.to_thread`.
61
+ - 병렬: `asyncio.gather` (실패 전파) / `return_exceptions=True` (모아 처리).
62
+ - 사용 안 하는 동기 / 비동기 혼합 주의 — `nest_asyncio` 같은 hack 금지.
63
+
64
+ ## 8. 입력 검증
65
+
66
+ - `pydantic.BaseModel` 으로 schema 검증.
67
+ - `parse_obj` / `model_validate` 의 ValidationError 를 catch 후 사용자 메시지로 변환.
68
+
69
+ ## 9. 모듈 구조
70
+
71
+ - 패키지: 작은 모듈 다수.
72
+ - `__init__.py` 는 공개 API 만 re-export (`__all__` 명시).
73
+ - circular import 가 보이면 구조 재설계 (lazy import 회피책 X).
74
+
75
+ ## 10. 도구 체인
76
+
77
+ - 의존성: `uv` (또는 pip + `requirements.txt` + `requirements-dev.txt`).
78
+ - 가상환경: `uv venv` / `python -m venv`.
79
+ - 테스트: `pytest`.
80
+ - 타입 체크: `mypy` (PR 게이트).
@@ -0,0 +1,86 @@
1
+ # python/testing — Python 테스트 룰
2
+
3
+ > [common/testing.md](../common/testing.md) 의 Python 확장.
4
+
5
+ ## 1. 프레임워크
6
+
7
+ - 단위 / 통합: **pytest**.
8
+ - E2E: pytest + playwright (`pytest-playwright`) 또는 별도 시나리오 러너.
9
+ - 커버리지: **pytest-cov** (`coverage[toml]` 백엔드).
10
+
11
+ ## 2. 파일 위치
12
+
13
+ - `tests/unit/test_<area>.py`.
14
+ - `tests/integration/test_<scenario>.py`.
15
+ - `tests/e2e/test_<flow>.py`.
16
+ - 픽스처: `tests/conftest.py` 또는 `tests/<area>/conftest.py`.
17
+
18
+ ## 3. pytest 패턴
19
+
20
+ ```python
21
+ import pytest
22
+ from harness.router import route
23
+
24
+ @pytest.mark.parametrize("severity, expected", [
25
+ ("critical", "opus"),
26
+ ("high", "sonnet"),
27
+ ])
28
+ def test_route(severity, expected):
29
+ assert route(severity=severity) == expected
30
+ ```
31
+
32
+ - `@pytest.mark.parametrize` 로 테이블 케이스.
33
+ - `pytest.fixture` 로 setup, `yield` 로 teardown.
34
+
35
+ ## 4. 모킹
36
+
37
+ - `pytest-mock` (`mocker` fixture) 또는 `unittest.mock`.
38
+ - 외부 의존만 mock. 자체 모듈은 실 구현.
39
+ - HTTP: `httpx_mock` / `responses`.
40
+ - DB: 통합 테스트는 실 DB (테스트 DB 격리). 단위 테스트는 repository 인터페이스 mock.
41
+
42
+ ## 5. 비동기
43
+
44
+ ```python
45
+ import pytest
46
+ import asyncio
47
+
48
+ @pytest.mark.asyncio
49
+ async def test_async_route():
50
+ result = await route_async(severity="critical")
51
+ assert result == "opus"
52
+ ```
53
+
54
+ - `pytest-asyncio` 의 `mode = "auto"` 설정 권장 (`pyproject.toml`).
55
+
56
+ ## 6. 픽스처 스코프
57
+
58
+ - `function` (기본): 매 테스트.
59
+ - `module`: 모듈 단위 (DB 연결 등 비싼 자원).
60
+ - `session`: 전체 세션 (잘 안 씀, 격리 위험).
61
+
62
+ ## 7. 단언(assertion)
63
+
64
+ - pytest 의 plain `assert` 사용. `unittest` 스타일 `assertEqual` 불필요.
65
+ - `pytest.approx(x, rel=1e-6)` 로 부동소수.
66
+ - `with pytest.raises(MyError, match=r"..."):` 로 예외 검증.
67
+
68
+ ## 8. 커버리지
69
+
70
+ ```bash
71
+ pytest --cov=harness --cov-report=term-missing --cov-fail-under=80
72
+ ```
73
+
74
+ - `pyproject.toml` 의 `[tool.coverage.run]` 으로 omit 설정.
75
+ - HTML 리포트는 `htmlcov/`, CI 아티팩트로.
76
+
77
+ ## 9. CI 게이트
78
+
79
+ - `pytest -q` 가 PR 단계에서 통과.
80
+ - `mypy --strict` 추가 게이트.
81
+ - `ruff check` 린트 게이트.
82
+
83
+ ## 10. 에이전트 지원
84
+
85
+ - TDD: `tdd-guide` (skills/tdd-workflow).
86
+ - Python 코드 리뷰: `python-reviewer` 에이전트 (글로벌 룰의 reviewer 매트릭스 참조).
@@ -0,0 +1,97 @@
1
+ # typescript/coding-style — TS/JS 룰
2
+
3
+ > 이 문서는 [common/coding-style.md](../common/coding-style.md) 를 TypeScript / JavaScript 관용에 맞춰 확장한다.
4
+
5
+ ## 1. 타입
6
+
7
+ ### 공개 API
8
+
9
+ - export 되는 함수·클래스 메서드는 인자·반환 타입을 명시한다.
10
+ - 로컬 변수의 명백한 타입은 추론에 맡긴다.
11
+ - 반복되는 inline object 형태는 `interface` / `type` 으로 추출.
12
+
13
+ ```ts
14
+ // 잘못됨
15
+ export function formatUser(user) { return `${user.firstName} ${user.lastName}`; }
16
+
17
+ // 올바름
18
+ interface User { firstName: string; lastName: string; }
19
+ export function formatUser(user: User): string {
20
+ return `${user.firstName} ${user.lastName}`;
21
+ }
22
+ ```
23
+
24
+ ### `interface` vs `type`
25
+
26
+ - 객체 형태 + 확장 가능성: `interface`.
27
+ - 유니온 / 교차 / 튜플 / 매핑 타입: `type`.
28
+ - `enum` 보다 string literal union (`type Role = 'admin' | 'member'`) 선호.
29
+
30
+ ### `any` 금지
31
+
32
+ - 어플리케이션 코드에서 `any` 사용 금지.
33
+ - 외부·신뢰 못 하는 입력은 `unknown` 으로 받고 narrow.
34
+ - 캐스팅(`as`) 은 시스템 경계 한 곳에서만, 그 즉시 검증.
35
+
36
+ ```ts
37
+ function getErrorMessage(err: unknown): string {
38
+ if (err instanceof Error) return err.message;
39
+ return 'Unexpected error';
40
+ }
41
+ ```
42
+
43
+ ### React props
44
+
45
+ - `interface XxxProps { ... }` 로 정의. 콜백 prop 시그니처 명시.
46
+ - `React.FC` 사용 안 함 (불필요한 제네릭 + children 암묵 주입).
47
+
48
+ ### `.js` 파일
49
+
50
+ - TS 마이그가 어려운 곳은 JSDoc 으로 타입 표현. 런타임 동작과 동기화.
51
+
52
+ ## 2. 비동기
53
+
54
+ - `async / await` + `try / catch` 기본.
55
+ - Promise chain (`.then().catch()`) 보다 `await`.
56
+ - 병렬 실행은 `Promise.all`. 단일 실패가 다른 호출을 막아도 OK 면 `Promise.allSettled`.
57
+ - top-level await 은 ES module 안에서만 사용.
58
+
59
+ ## 3. 불변성
60
+
61
+ - spread / `Readonly<T>` / `as const` 활용.
62
+ - mutation 이 필요하면 그 함수 안에서만, 반환 값은 새 객체.
63
+
64
+ ```ts
65
+ function rename(user: Readonly<User>, name: string): User {
66
+ return { ...user, name };
67
+ }
68
+ ```
69
+
70
+ ## 4. 에러
71
+
72
+ - `Error` 를 직접 던지지 말고 도메인 에러 클래스 (`class NotFoundError extends Error`) 사용.
73
+ - catch 의 `err: unknown` 을 narrow 후 처리.
74
+ - `console.error` 직접 사용 안 함 — 로거(pino / winston) 경유.
75
+
76
+ ## 5. 입력 검증
77
+
78
+ - 외부 경계는 zod / ajv 로 schema 검증.
79
+ - 검증된 타입은 `z.infer<typeof schema>` 로 추론해서 단일 진실.
80
+
81
+ ## 6. import
82
+
83
+ - 상대 경로 `../../..` 가 3단 이상이면 alias (`@/`) 도입 검토.
84
+ - side-effect import 는 파일 최상단 한 곳에 모은다.
85
+ - 미사용 import 는 `eslint-plugin-unused-imports` 로 제거.
86
+
87
+ ## 7. console.log
88
+
89
+ - 운영 코드에 `console.log` 금지. PostToolUse hook 이 경고.
90
+ - 디버깅 출력은 `debug` 패키지 또는 로거의 `debug` 레벨.
91
+
92
+ ## 8. 도구
93
+
94
+ - 포매터: Prettier. PostToolUse hook 으로 자동.
95
+ - 린터: ESLint (`@typescript-eslint`).
96
+ - 타입 체크: `tsc --noEmit` PR 게이트.
97
+ - 테스트: node:test (repo default). Vitest 는 프로젝트별 필요 시 opt-in.
@@ -0,0 +1,67 @@
1
+ # typescript/security — TS/JS 보안 룰
2
+
3
+ > [common/security.md](../common/security.md) 의 TS/JS 확장.
4
+
5
+ ## 1. 시크릿
6
+
7
+ ```ts
8
+ // 잘못됨
9
+ const apiKey = "sk-proj-xxxxx";
10
+
11
+ // 올바름
12
+ const apiKey = process.env.OPENAI_API_KEY;
13
+ if (!apiKey) throw new Error('OPENAI_API_KEY 미설정');
14
+ ```
15
+
16
+ - 시작 시 검증. 부재 시 기동 실패.
17
+ - `dotenv` 사용 시 `.env` 는 `.gitignore`.
18
+
19
+ ## 2. 입력 검증
20
+
21
+ - HTTP body / query / params 는 zod 로 schema 검증:
22
+
23
+ ```ts
24
+ import { z } from 'zod';
25
+ const Body = z.object({ email: z.string().email(), age: z.number().int().min(0) });
26
+ const parsed = Body.parse(req.body); // 실패 시 ZodError 던짐
27
+ ```
28
+
29
+ - `parse` (throw) vs `safeParse` (`{success, data | error}`) 용도에 맞게.
30
+
31
+ ## 3. SQL / DB
32
+
33
+ - `pg` / `postgres` / Prisma — 모두 parameterized.
34
+ - raw SQL 작성 시 `${value}` 보간 절대 금지. `$1`, `$2` 자리표시자 사용.
35
+ - ORM 의 `raw` API 는 검토 후만.
36
+
37
+ ## 4. XSS
38
+
39
+ - React 의 `dangerouslySetInnerHTML` 사용 시 sanitize (`dompurify`) 필수.
40
+ - 사용자 입력 → URL 로 사용 시 `encodeURIComponent`.
41
+
42
+ ## 5. CSRF
43
+
44
+ - SameSite cookie + CSRF token 둘 다.
45
+ - API only 면 토큰 인증 (Bearer) + CORS allowlist.
46
+
47
+ ## 6. JWT
48
+
49
+ - 검증 시 `algorithms: ['RS256']` 명시. `none` 차단.
50
+ - `iat` / `exp` 둘 다 확인.
51
+ - secret 은 환경 변수.
52
+
53
+ ## 7. 의존성
54
+
55
+ - `npm audit --omit=dev` 정기 실행.
56
+ - 새 의존성 추가 전 `npmjs.com` 의 weekly downloads, last publish 확인.
57
+ - typosquatting 주의 (`color` vs `colors`, `lodash` vs `lodash-utils`).
58
+
59
+ ## 8. SSR / 서버 액션
60
+
61
+ - Next.js server action 의 입력은 클라이언트가 임의 조작 가능 — 반드시 재검증.
62
+ - 인가는 매 액션마다 확인.
63
+
64
+ ## 9. 에이전트 지원
65
+
66
+ - 보안 변경: `security-reviewer` 에이전트로 사전 검토.
67
+ - 인증 / 결제 / PII 다루는 PR 은 `harness review --secure` 로 codex-challenge 단계 강제.