@ps-neko/nekowork 0.1.0-alpha.11 → 0.1.0-alpha.12
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/AGENTS.md +1 -1
- package/CLAUDE.md +3 -3
- package/README.ko.md +3 -3
- package/README.md +11 -3
- package/WORKING-CONTEXT.md +14 -4
- package/agent.yaml +5 -4
- package/agents/codex-challenger.md +1 -1
- package/agents/codex-reviewer.md +1 -1
- package/commands/nekowork-full-cycle.md +29 -0
- package/docs/ARCHITECTURE.md +2 -2
- package/docs/CHANGELOG.md +10 -1
- package/docs/DEMO.md +1 -1
- package/docs/GUIDED-MODE.md +1 -1
- package/docs/PORTING.md +1 -1
- package/docs/POST-RELEASE-CHECKLIST.md +35 -18
- package/docs/SCOPE-1.0.md +1 -1
- package/docs/SETUP.md +1 -1
- package/docs/VISION.md +76 -14
- package/docs/assets/demo-terminal.svg +1 -1
- package/docs/assets/hero.gif +0 -0
- package/manifests/install-components.json +6 -6
- package/manifests/install-modules.json +3 -3
- package/package.json +6 -2
- package/scripts/build-cursor.js +1 -1
- package/scripts/ci/security-hardening.js +27 -4
- package/scripts/cli.js +1 -1
- package/scripts/demo-review.js +2 -2
- package/scripts/lib/diff-parser.js +33 -2
- package/scripts/lib/project-detector.js +74 -11
- package/scripts/lib/router.js +1 -1
- package/scripts/orchestrators/review.js +1 -1
- package/scripts/orchestrators/verify-pr.js +12 -2
- package/scripts/sync-claude-md.js +1 -1
- package/skills/{claude-led-codex-review → nekowork-full-cycle}/SKILL.md +3 -3
- package/skills/plan-eng-review/SKILL.md +1 -1
- package/skills/ralph/SKILL.md +1 -1
- package/skills/review/SKILL.md +2 -2
- package/skills/ship/SKILL.md +1 -1
- package/skills/verified-gate/SKILL.md +47 -0
- package/LICENSE +0 -21
- package/commands/claude-led-codex-review.md +0 -29
package/AGENTS.md
CHANGED
|
@@ -28,7 +28,7 @@ fact_forcing: true|false # PreToolUse 사실 조사 강제 여부
|
|
|
28
28
|
- `commands/` 는 legacy slash-entry 호환 표면이다. 신규 추가 금지, 점진 마이그레이션.
|
|
29
29
|
- `agents/` 는 페르소나 카탈로그다. 워크플로우는 `skills/` 에서 정의하고 에이전트는 `skills/` 가 호출한다.
|
|
30
30
|
|
|
31
|
-
## 7단계 풀사이클 (
|
|
31
|
+
## 7단계 풀사이클 (nekowork-full-cycle)
|
|
32
32
|
|
|
33
33
|
| 단계 | 담당 | 입력 | 출력 |
|
|
34
34
|
|---|---|---|---|
|
package/CLAUDE.md
CHANGED
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
|
|
9
9
|
## 자동 갱신 영역
|
|
10
10
|
|
|
11
|
-
<!-- HARNESS:START version=0.1.0-alpha.
|
|
11
|
+
<!-- HARNESS:START version=0.1.0-alpha.12 -->
|
|
12
12
|
<!-- 이 영역은 scripts/sync-claude-md.js 가 자동 갱신한다. 직접 편집 금지. -->
|
|
13
13
|
|
|
14
14
|
## 카탈로그 요약
|
|
15
15
|
|
|
16
16
|
- agents: 11
|
|
17
|
-
- skills:
|
|
17
|
+
- skills: 11
|
|
18
18
|
- commands: 1 (legacy compat)
|
|
19
19
|
- hooks: 5 (gateguard-fact-force, config-protection, quality-gate, pre-bash-dispatcher, persistent-mode)
|
|
20
20
|
- packs: core, builder, productivity, team, debugging, maintenance, pr, catalog-plus, quality, security, frontend, testing, release, enterprise
|
|
@@ -93,7 +93,7 @@ nekowork costs --since=7d # 비용 추정
|
|
|
93
93
|
|
|
94
94
|
## 매직 키워드 → 스킬 (명시 옵트인만)
|
|
95
95
|
|
|
96
|
-
자동 활성 키워드 감지는 **사용**하지 않는다. 사용자 룰("확인 후 실행") 우선. 모든 스킬은 슬래시 명령(`/
|
|
96
|
+
자동 활성 키워드 감지는 **사용**하지 않는다. 사용자 룰("확인 후 실행") 우선. 모든 스킬은 슬래시 명령(`/nekowork-full-cycle`) 또는 CLI(`nekowork review`) 로 명시 호출.
|
|
97
97
|
|
|
98
98
|
## 핸드오프 5필드
|
|
99
99
|
|
package/README.ko.md
CHANGED
|
@@ -12,7 +12,7 @@ NEKOWORK 는 AI 가 생성한 코드를 위한 로컬 검증 게이트입니다.
|
|
|
12
12
|
|
|
13
13
|
여기서 "검증됨"은 정답을 수학적으로 보증한다는 뜻이 아닙니다. verdict 는 결정적 룰과 검증 결과만 결정합니다. 선택적 Codex 리뷰는 advisor 노트로만 기록되며 verdict 에 영향을 주지 않습니다.
|
|
14
14
|
|
|
15
|
-
> 1.0 scope 와 로드맵: [docs/SCOPE-1.0.md](docs/SCOPE-1.0.md). 장기 비전 (검증 우선 AI 개발
|
|
15
|
+
> 1.0 scope 와 로드맵: [docs/SCOPE-1.0.md](docs/SCOPE-1.0.md). 장기 비전 (검증 우선 AI 개발 공장): [docs/VISION.md](docs/VISION.md).
|
|
16
16
|
|
|
17
17
|
## 용어
|
|
18
18
|
|
|
@@ -189,10 +189,10 @@ NEKOWORK는 하나의 거대한 agent 묶음이 아니라, 일을 나누고 검
|
|
|
189
189
|
## 현재 alpha 상태
|
|
190
190
|
|
|
191
191
|
- Package: `@ps-neko/nekowork`
|
|
192
|
-
- Current alpha: `0.1.0-alpha.
|
|
192
|
+
- Current alpha: `0.1.0-alpha.11` (npm `@alpha` published 2026-05-16)
|
|
193
193
|
- CLI: `nekowork`
|
|
194
194
|
- Legacy/internal alias: `harness`
|
|
195
|
-
- Tests:
|
|
195
|
+
- Tests: 501 pass
|
|
196
196
|
- npm audit: 0 moderate+ issues
|
|
197
197
|
- Fresh `npx @alpha` smoke: pass
|
|
198
198
|
|
package/README.md
CHANGED
|
@@ -6,11 +6,19 @@
|
|
|
6
6
|
|
|
7
7
|
[](https://github.com/Ps-Neko/NEKOWORK/actions/workflows/harness-validate.yml)
|
|
8
8
|
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="https://ps-neko.github.io/NEKOWORK/?fixture=sample-pr-001">
|
|
11
|
+
<img src="docs/assets/hero.gif" alt="NEKOWORK Verification Factory — Claude advisor 가 LGTM 한 코드를 NEKOWORK 결정적 규칙이 BLOCK 하는 12-station 시연" width="800" />
|
|
12
|
+
</a>
|
|
13
|
+
<br/>
|
|
14
|
+
<em>Claude said LGTM. NEKOWORK blocked.</em> · <a href="https://ps-neko.github.io/NEKOWORK/?fixture=sample-pr-001"><strong>Live demo →</strong></a>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
9
17
|
NEKOWORK is a local verification gate for AI-generated code. It analyzes the diff, runs deterministic risk rules, collects evidence, and decides whether the change is safe to merge or apply — without auto-committing, auto-pushing, or trusting LLM verdicts.
|
|
10
18
|
|
|
11
19
|
Note: "Verified" means independently reviewed with recorded evidence — not mathematically proven correct. The verdict is decided by deterministic rules and check results. Optional Codex review is recorded as an advisor note only and never controls the verdict.
|
|
12
20
|
|
|
13
|
-
> 1.0 scope and roadmap: [docs/SCOPE-1.0.md](docs/SCOPE-1.0.md). Long-term vision (Verification-first AI development
|
|
21
|
+
> 1.0 scope and roadmap: [docs/SCOPE-1.0.md](docs/SCOPE-1.0.md). Long-term vision (Verification-first AI development factory): [docs/VISION.md](docs/VISION.md).
|
|
14
22
|
|
|
15
23
|
Note: "ship" in NEKOWORK is a **readiness decision** (`SHIP_READY` or `NO_SHIP`), not a deployment. The `ship` step decides whether `apply` is allowed; it never commits, pushes, deploys, or publishes by itself.
|
|
16
24
|
|
|
@@ -199,9 +207,9 @@ For comparison and positioning: [docs/WHY-NEKOWORK.md](docs/WHY-NEKOWORK.md).
|
|
|
199
207
|
|
|
200
208
|
## Status
|
|
201
209
|
|
|
202
|
-
Current repository version: `0.1.0-alpha.
|
|
210
|
+
Current repository version: `0.1.0-alpha.12` · Current npm alpha: `@ps-neko/nekowork@0.1.0-alpha.11` (published 2026-05-16, `@alpha` dist-tag). Package: `@ps-neko/nekowork`. CLI: `nekowork` (`harness` is a legacy alias). Default: mock providers, no API keys.
|
|
203
211
|
|
|
204
|
-
Verification: `npm run lint` pass · `npm test`
|
|
212
|
+
Verification: `npm run lint` pass · `npm test` 501 tests pass · `npm audit --audit-level=moderate` 0 vulns · `npm pack --dry-run --json` pass · `npx -y @ps-neko/nekowork@alpha check` pass with warnings only.
|
|
205
213
|
|
|
206
214
|
Live provider auth delegates to local CLI sessions (`claude auth status`, `codex login`, `gemini`); long-lived API key env vars (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY`, `GOOGLE_API_KEY`) are blocked unless `HARNESS_AUTH_ALLOW_ENV_OVERRIDE=1`. See [docs/SETUP.md](docs/SETUP.md).
|
|
207
215
|
|
package/WORKING-CONTEXT.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
## Current Truth
|
|
11
11
|
|
|
12
12
|
- 위치: `C:/Users/Mun/harness/` · 브랜치: `main`
|
|
13
|
-
- 버전: `0.1.0-alpha.
|
|
13
|
+
- 버전: `0.1.0-alpha.12` (repo; npm alpha 는 `0.1.0-alpha.11` published 2026-05-16, alpha.12 publish 진행 중)
|
|
14
14
|
- 카탈로그: 11 agents · 5 skills (+1 ralph) · 5 hooks · 6 modules · 5 profiles
|
|
15
15
|
- 5 빌더 모두 동작 (claude / codex / cursor / gemini / opencode) + codemaps
|
|
16
16
|
- `npm test`, `npm run lint`, `npm audit --audit-level=moderate`, provider live smoke, Rust release build 검증 경로 유지
|
|
@@ -26,14 +26,21 @@
|
|
|
26
26
|
## Active Queues
|
|
27
27
|
|
|
28
28
|
### In Progress
|
|
29
|
-
-
|
|
29
|
+
- 외부 알파 5명 모집 + 7일 피드백 수집 (POST-RELEASE-CHECKLIST §4-§5, **사용자 수동 social work**)
|
|
30
30
|
|
|
31
31
|
### Next
|
|
32
|
-
-
|
|
32
|
+
- 1.0 게이트 5조건 점검 (SCOPE-1.0 §13.2): recall ≥ 0.90, FP ≤ 0.10 (real-world corpus), 외부 알파 3/5 "다시 쓰겠다", CRITICAL 미탐 0, 치명적 오탐 0
|
|
33
|
+
- real-world fixture 추가 후 `npm run bench:rules` 재측정
|
|
34
|
+
- 코드 품질 핫스팟 3건 (cli.js 분해 / orchestrator 보일러플레이트 추출 / 미사용 export) — **publish 게이트 통과 이후**
|
|
35
|
+
|
|
36
|
+
### 절대 금지 (현 단계)
|
|
37
|
+
- 코드 추가 (외부 피드백 없이 추측으로 룰 늘리기 금지)
|
|
38
|
+
- scope 확장 (verify-skill / verify-release 등은 1.x)
|
|
39
|
+
- "1.0 곧 출시" 류 마케팅
|
|
33
40
|
|
|
34
41
|
## Open PR Classification
|
|
35
42
|
|
|
36
|
-
(
|
|
43
|
+
(이전 작업 — auth migration / harness.dev placeholder / 검증 게이트 cut 등은 main 머지 완료, 메모리 `nekowork-*` 참조)
|
|
37
44
|
|
|
38
45
|
## Interfaces
|
|
39
46
|
|
|
@@ -50,3 +57,6 @@
|
|
|
50
57
|
- 2026-04-29: P1 회수 세션 완료 (`docs/dev-log/2026-04-29-p1-recovery.md`). 빈 디렉터리 6 → 0, 미구현 스크립트 9 → 0, ARCHITECTURE 528줄, 73 테스트.
|
|
51
58
|
- 2026-04-29: 잡티 제거 배치 진행 중 — 본 파일 갱신 + Validator 경고 정합 + RUNBOOK/PORTING/Security Bar 보완.
|
|
52
59
|
- 2026-04-30: **auth migration 완료**. PR #1-#3 (3계층 인증 + GitHub OAuth + OS keychain) main 머지 (`60e9de9` → `7c4f2c8`, +4 commits, rebase merge). PR #2/#3 은 phase-1 옛 SHA 포함으로 force-push 1회씩(`--onto origin/main bf72841`/`b2b1bce` + `--force-with-lease`). Smoke 3/4 PASS (#1 `claude /status` Claude Max, #2 override 차단 3 케이스, #4 keychain Windows Credential Manager). #3 GitHub OAuth Device Flow 는 OAuth App 미등록으로 사용자 자율 보류 — 실제 GitHub automation 사용 시점에 수행. PR #4 (codex 0.125+ 호환) 는 본 작업과 무관 OPEN 잔존.
|
|
60
|
+
- 2026-05-14: **alpha.10 npm publish 완료**. dist-tag `@alpha`. 19개 CLI 명령 wide surface. 코드 품질 핫스팟 3건 진단 (cli.js 1543 LOC / orchestrator 보일러플레이트 / 미사용 export 3건) — publish 게이트 후 처리.
|
|
61
|
+
- 2026-05-15~16: **1.0 검증 게이트 cut + alpha.11 publish**. `feat(verify-pr)` 5 deterministic rules + Auto-Apply-Commit-Push + GitHub Actions PR comment + bench:rules. 정체성을 "verification-first AI development factory" 12-Station 으로 정제 (VISION.md). README hero 는 검증 게이트 카피 유지.
|
|
62
|
+
- 2026-05-16: **post-publish CI red 사고 복구** (`6a0e862`). `.gitignore *.pem` 룰이 secret-detection 룰 자체 fixture 까지 차단 → alpha.11 가 CI red 6 commit streak 상태로 publish. `!tests/fixtures/**/*.pem` 예외 + synthetic fixture 2개 commit 으로 복구. POST-RELEASE-CHECKLIST §0.2 에 CI green 3항목 게이트 추가 (`f6995ab`). 메모리 `nekowork-alpha11-verify-pr` 의 '자기모순' 섹션 참조.
|
package/agent.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
spec_version: gitagent/0.1.0
|
|
2
2
|
name: nekowork
|
|
3
3
|
runtime_name: harness
|
|
4
|
-
version: 0.1.0-alpha.
|
|
4
|
+
version: 0.1.0-alpha.12
|
|
5
5
|
description: "NEKOWORK - Verified autopilot for AI code changes with Codex verification, Human Gate, and explicit apply"
|
|
6
6
|
license: MIT
|
|
7
7
|
homepage: https://github.com/Ps-Neko/NEKOWORK
|
|
@@ -23,7 +23,7 @@ agents:
|
|
|
23
23
|
- doc-writer
|
|
24
24
|
|
|
25
25
|
skills:
|
|
26
|
-
-
|
|
26
|
+
- nekowork-full-cycle
|
|
27
27
|
- plan-eng-review
|
|
28
28
|
- tdd-workflow
|
|
29
29
|
- acceptance-coverage
|
|
@@ -33,10 +33,11 @@ skills:
|
|
|
33
33
|
- release-readiness
|
|
34
34
|
- porting
|
|
35
35
|
- ralph # 명시 옵트인 영속 루프. 자동 키워드 활성 OFF.
|
|
36
|
+
- verified-gate # strict 검증 게이트 진입점. 명시 옵트인, 자동 키워드 OFF.
|
|
36
37
|
|
|
37
38
|
commands:
|
|
38
39
|
# legacy compat (slash entry). 신규 추가 금지.
|
|
39
|
-
-
|
|
40
|
+
- nekowork-full-cycle
|
|
40
41
|
|
|
41
42
|
hooks:
|
|
42
43
|
file: hooks/hooks.json
|
|
@@ -200,7 +201,7 @@ auth:
|
|
|
200
201
|
deny_static_api_keys_in_repo: true
|
|
201
202
|
|
|
202
203
|
routing:
|
|
203
|
-
# 단계별 routing 표는 skills/
|
|
204
|
+
# 단계별 routing 표는 skills/nekowork-full-cycle/SKILL.md 가 정전(canon).
|
|
204
205
|
eco_mode_floor: sonnet
|
|
205
206
|
human_gate_triggers:
|
|
206
207
|
severity: critical
|
|
@@ -5,7 +5,7 @@ provider: codex
|
|
|
5
5
|
model: gpt-5-codex
|
|
6
6
|
level: 3
|
|
7
7
|
disallowedTools: [Write, Edit, Bash, Network]
|
|
8
|
-
trigger: ["codex challenge", "--secure", "
|
|
8
|
+
trigger: ["codex challenge", "--secure", "nekowork-full-cycle:6"]
|
|
9
9
|
hand_off_to: []
|
|
10
10
|
sandbox: read-only
|
|
11
11
|
network_access: false
|
package/agents/codex-reviewer.md
CHANGED
|
@@ -5,7 +5,7 @@ provider: codex
|
|
|
5
5
|
model: gpt-5-codex
|
|
6
6
|
level: 3
|
|
7
7
|
disallowedTools: [Write, Edit, Bash, Network]
|
|
8
|
-
trigger: ["codex review", "
|
|
8
|
+
trigger: ["codex review", "nekowork-full-cycle:5"]
|
|
9
9
|
hand_off_to: []
|
|
10
10
|
sandbox: read-only
|
|
11
11
|
network_access: false
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Claude 주도 + Codex 위임 7단계 풀사이클. nekowork-full-cycle 스킬 호출."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /nekowork-full-cycle
|
|
6
|
+
|
|
7
|
+
이 슬래시 명령은 `nekowork-full-cycle` 스킬의 legacy compat 진입점이다. 신규 워크플로우는 스킬에서 정의되지만 슬래시 호출 호환성을 위해 보존.
|
|
8
|
+
|
|
9
|
+
## 동작
|
|
10
|
+
|
|
11
|
+
`Skill` 도구로 `nekowork-full-cycle` 를 즉시 호출. 인자가 있으면 작업 요약으로 전달, 없으면 사용자에게 한 줄 요약을 요청.
|
|
12
|
+
|
|
13
|
+
## 인자
|
|
14
|
+
|
|
15
|
+
- `$ARGUMENTS` — 작업 요약 한 줄
|
|
16
|
+
- `--fast` — 단계 1·6 스킵
|
|
17
|
+
- `--secure` — 단계 6 강제
|
|
18
|
+
- `--no-ship` — 단계 7 생략
|
|
19
|
+
|
|
20
|
+
## 예시
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
/nekowork-full-cycle JWT 검증 미들웨어 추가 --secure
|
|
24
|
+
/nekowork-full-cycle 결제 환불 로직 버그 수정
|
|
25
|
+
/nekowork-full-cycle --fast 사소한 리팩토링
|
|
26
|
+
/nekowork-full-cycle 새 API 엔드포인트 --no-ship
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
전체 명세는 `skills/nekowork-full-cycle/SKILL.md` 참조.
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -207,8 +207,8 @@ Builders project the catalog into tool-specific files:
|
|
|
207
207
|
|
|
208
208
|
## Release State
|
|
209
209
|
|
|
210
|
-
The current repository release line is `0.1.0-alpha.
|
|
210
|
+
The current repository release line is `0.1.0-alpha.12`:
|
|
211
211
|
|
|
212
212
|
- Repository and GitHub tarball release are available.
|
|
213
|
-
- Public npm alpha is published as `@ps-neko/nekowork@alpha` and currently points at `0.1.0-alpha.
|
|
213
|
+
- Public npm alpha is published as `@ps-neko/nekowork@alpha` and currently points at `0.1.0-alpha.11` (published 2026-05-16).
|
|
214
214
|
- Clone, submodule, and local checkout integration remain supported for repository-pinned workflows.
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
-
## [0.1.0-alpha.
|
|
7
|
+
## [0.1.0-alpha.12] - TBD
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- `verify-pr --full-scan` (alias `--full`): scans all tracked files as a synthetic added-diff via the shared `synthesizeFilesAsDiff` helper, so first-time onboarding no longer requires a throwaway repo with a fake diff. (First external-user feedback.)
|
|
11
|
+
- `INSUFFICIENT_EVIDENCE` verdict now explains itself: its reason/summary clarify "not a failure — risk checks passed; add a test command to verify, or use `--ci-exit-soft`," instead of reading like a hard block. Verdict logic is unchanged — an unverified source change still does not auto-pass (SCOPE-1.0 §7).
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
- Language detection now finds project markers (`go.mod`, `package.json`, `Cargo.toml`, …) in subdirectories, not just the repo root. A Go project with `go.mod` in a subfolder (e.g. `backend/`) was misdetected as `unknown` and reported `INSUFFICIENT_EVIDENCE` for source changes; it is now detected with its test command available. Root markers still take precedence, and excluded dirs (`node_modules`, `vendor`, build output) are skipped — no behavior change for root-level projects. (First external-user feedback.)
|
|
15
|
+
|
|
16
|
+
## [0.1.0-alpha.11] - 2026-05-16
|
|
8
17
|
|
|
9
18
|
### Added
|
|
10
19
|
- Add `nekowork verify-pr` 1.0 entrypoint: scans diff (working tree / staged / range / patch file) with deterministic risk rules, writes evidence to `.nekowork/evidence/`, decides verdict from rule findings + check availability, renders `REPORT.md`.
|
package/docs/DEMO.md
CHANGED
|
@@ -143,7 +143,7 @@ project root : C:\path\to\harness
|
|
|
143
143
|
|
|
144
144
|
STATUS CHECK MESSAGE
|
|
145
145
|
PASS node Node 24.x
|
|
146
|
-
PASS package metadata @ps-neko/nekowork@0.1.0-alpha.
|
|
146
|
+
PASS package metadata @ps-neko/nekowork@0.1.0-alpha.11; public alpha package
|
|
147
147
|
PASS git worktree project root is inside a git worktree
|
|
148
148
|
WARN gemini cli installed, auth status is not checked non-interactively
|
|
149
149
|
|
package/docs/GUIDED-MODE.md
CHANGED
package/docs/PORTING.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Porting NEKOWORK Into Another Project
|
|
2
2
|
|
|
3
|
-
NEKOWORK `0.1.0-alpha.
|
|
3
|
+
NEKOWORK `0.1.0-alpha.12` is the current repository version (npm `@ps-neko/nekowork@alpha` currently published at `0.1.0-alpha.11`, 2026-05-16). Use npm alpha for the shortest published install path, or use a submodule/local checkout for repository-pinned workflows and examples.
|
|
4
4
|
|
|
5
5
|
## Local Demo First
|
|
6
6
|
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
## 0. 사전 확인 (publish 전)
|
|
8
8
|
|
|
9
|
+
### 0.1 로컬 검증
|
|
10
|
+
|
|
9
11
|
- [x] git tag `v0.1.0-alpha.11` 로컬 생성 (커밋 `c8f55bd`)
|
|
10
12
|
- [ ] `npm test` 통과 (494/494)
|
|
11
13
|
- [ ] `npm run bench:rules` 5/5 PASS
|
|
@@ -13,6 +15,16 @@
|
|
|
13
15
|
- [ ] `npm audit --audit-level=moderate` 0 vulns
|
|
14
16
|
- [ ] `npm pack --dry-run --json` 정상
|
|
15
17
|
|
|
18
|
+
### 0.2 CI green 게이트 (publish 차단)
|
|
19
|
+
|
|
20
|
+
**로컬 PASS ≠ CI PASS.** `.gitignore` / 환경 변수 / fixture 경로 차이로 환경이 갈릴 수 있음. publish 전 다음 3개를 모두 확인:
|
|
21
|
+
|
|
22
|
+
- [ ] **마지막 1 commit CI 성공** — `gh run list --branch main --limit 1 --json conclusion --jq '.[0].conclusion'` 가 `success`
|
|
23
|
+
- [ ] **최근 5 commit CI 추세** — `gh run list --branch main --limit 5 --json conclusion --jq '[.[] | .conclusion] | join(",")'` 결과에 `failure` 가 1개라도 있으면 publish 금지. red streak 의 근본 원인을 먼저 잡고 다음 commit 으로 green 회복 확인 후 진행
|
|
24
|
+
- [ ] **fixture / `.gitignore` 변경이 있었다면 충돌 검토** — 새 fixture 가 시크릿 룰 (`*.pem` / `*.key` / `*.crt` / `*.p12` / `*.pfx` / `credentials*.json`) 에 차단되지 않는지 `git check-ignore <fixture-path>` 로 확인. 차단되면 `!tests/fixtures/**/<pattern>` 예외 룰 추가
|
|
25
|
+
|
|
26
|
+
> **2026-05-16 사고 (이 게이트의 도출 근거):** alpha.11 가 **CI red 6 commit streak** 상태에서 publish 됨. 원인: `.gitignore` 의 `*.pem` 룰이 secret-detection 룰 자체의 fixture (`positive/004-private-key.pem`, `negative/005-public-key.pem`) 까지 차단. 로컬 `npm test` 는 fixture 가 존재하므로 PASS, CI 체크아웃은 fixture 가 없어서 FAIL. **NEKOWORK 가 NEKOWORK 자신의 CI 를 깨뜨린 자기모순.** commit `6a0e862` 로 `.gitignore` 예외 + 두 synthetic fixture commit 으로 복구. 위 3개 게이트가 이 사고에서 도출됨. 다음 alpha 에서는 0.1 → 0.2 순서로 검증 후 publish.
|
|
27
|
+
|
|
16
28
|
## 1. Publish (사용자 수동)
|
|
17
29
|
|
|
18
30
|
```bash
|
|
@@ -33,37 +45,42 @@ npx -y @ps-neko/nekowork@alpha --version
|
|
|
33
45
|
|
|
34
46
|
## 2. README 즉시 갱신 (publish 직후 1 commit)
|
|
35
47
|
|
|
36
|
-
|
|
48
|
+
> ✅ alpha.11 (2026-05-16) 에서 이미 완료. 다음 alpha publish 시 동일 패턴.
|
|
37
49
|
|
|
38
|
-
|
|
39
|
-
- Current repository version: `0.1.0-alpha.11` · Current npm alpha: `@ps-neko/nekowork@0.1.0-alpha.10` (published 2026-05-14, `@alpha` dist-tag).
|
|
40
|
-
+ Current repository version: `0.1.0-alpha.11` · Current npm alpha: `@ps-neko/nekowork@0.1.0-alpha.11` (published <YYYY-MM-DD>, `@alpha` dist-tag).
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
`docs/SETUP.md` 와 `docs/PORTING.md` 의 첫 문단도 같이 갱신:
|
|
50
|
+
publish 직후 update 가 필요한 파일들:
|
|
44
51
|
|
|
45
|
-
|
|
46
|
-
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
`docs/
|
|
52
|
+
- `README.md` Status 섹션: `Current npm alpha: ...` 라인 + `npm test N tests pass` 라인
|
|
53
|
+
- `README.ko.md` "현재 alpha 상태" 섹션: Current alpha + Tests 라인
|
|
54
|
+
- `docs/SETUP.md`: 첫 문단 published alpha 핀
|
|
55
|
+
- `docs/PORTING.md`: 첫 문단 published alpha 핀
|
|
56
|
+
- `docs/CHANGELOG.md`: `[0.1.0-alpha.X] - TBD` → `- YYYY-MM-DD`
|
|
57
|
+
- `docs/DEMO.md`: doctor example 의 alpha 버전 라인 (version-consistency.test.js 가 SVG + README 와 교차 검증)
|
|
58
|
+
- `docs/assets/demo-terminal.svg`: package metadata 의 alpha 버전 (version-consistency.test.js 가 README 의 npmAlpha 와 일치 강제)
|
|
59
|
+
- `WORKING-CONTEXT.md`: 버전 라인 ("repo + npm alpha 동기" 표현으로)
|
|
60
|
+
- `tests/unit/version-consistency.test.js`: `Tests: N` assertion 의 N 갱신
|
|
51
61
|
|
|
52
62
|
## 3. Smoke test (publish 직후)
|
|
53
63
|
|
|
54
|
-
새 임시
|
|
64
|
+
새 임시 디렉토리에서. **중요**: 베이스 파일만 먼저 commit 하고, AI 가 만들었을 법한
|
|
65
|
+
위험 변경은 untracked / unstaged 로 남겨야 verify-pr 의 working-tree 모드가
|
|
66
|
+
그 변경을 잡습니다 (diff-parser 가 ls-files --others 로 untracked 도 흡수).
|
|
67
|
+
전부 한 번에 `git add -A` 하면 diff 가 비어서 ALLOW 가 됩니다.
|
|
55
68
|
|
|
56
69
|
```bash
|
|
57
|
-
|
|
70
|
+
TMP=$(mktemp -d) && cd "$TMP"
|
|
71
|
+
git init -q && git config user.email t@t && git config user.name t
|
|
72
|
+
|
|
73
|
+
# 1. 베이스만 commit (untracked 가 working-tree diff 에 들어가도록)
|
|
58
74
|
echo '{"name":"smoke","scripts":{"test":"echo ok"}}' > package.json
|
|
59
|
-
git add
|
|
75
|
+
git add package.json && git commit -q -m init
|
|
60
76
|
|
|
61
|
-
#
|
|
77
|
+
# 2. AI 가 만들었을 법한 위험 변경 — untracked 로 둠
|
|
78
|
+
mkdir -p src
|
|
62
79
|
cat > src/auth.ts <<'EOF'
|
|
63
80
|
export const k = process.env.API_KEY || "sk-leaked-fallback-test";
|
|
64
81
|
EOF
|
|
65
82
|
|
|
66
|
-
#
|
|
83
|
+
# 3. verify-pr 실행
|
|
67
84
|
npx -y @ps-neko/nekowork@alpha verify-pr
|
|
68
85
|
|
|
69
86
|
# 3. 기대: verdict BLOCK, exit 2, REPORT.md 와 decision.json 생성
|
package/docs/SCOPE-1.0.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
## 1. 결정 요약
|
|
6
6
|
|
|
7
7
|
NEKOWORK 1.0 은 **AI 가 만든 PR/diff 를 머지해도 되는지 판정하는 검증 게이트** 로 포지셔닝한다.
|
|
8
|
-
장기 비전 ("Verification-first AI development
|
|
8
|
+
장기 비전 ("Verification-first AI development factory") 은 `docs/VISION.md` 에만 남기고, 1.0 의 README/CLI hero/마케팅에는 노출하지 않는다.
|
|
9
9
|
|
|
10
10
|
알파.10 의 wide surface (19개 명령) 는 **Phased Cut** 으로 좁힌다 — 1.0 에서는 hero 강등만, 실제 breaking 은 2.0.
|
|
11
11
|
|
package/docs/SETUP.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Start with [QUICKSTART.md](QUICKSTART.md) if this is your first run. This page is the deeper contributor setup guide.
|
|
4
4
|
|
|
5
|
-
NEKOWORK `0.1.0-alpha.
|
|
5
|
+
NEKOWORK `0.1.0-alpha.12` is the current repository version (npm `@ps-neko/nekowork@alpha` currently published at `0.1.0-alpha.11`, 2026-05-16). Use npm alpha for the shortest first-run path, or use a source checkout, submodule, or local repository integration when you need examples, tests, or repository-pinned workflows.
|
|
6
6
|
|
|
7
7
|
## Requirements
|
|
8
8
|
|
package/docs/VISION.md
CHANGED
|
@@ -7,13 +7,19 @@
|
|
|
7
7
|
## One-liner
|
|
8
8
|
|
|
9
9
|
```text
|
|
10
|
-
Verification-first AI development
|
|
10
|
+
Verification-first AI development factory.
|
|
11
|
+
AI builds. NEKOWORK verifies. Humans decide.
|
|
12
|
+
Nothing ships without evidence.
|
|
11
13
|
```
|
|
12
14
|
|
|
13
15
|
```text
|
|
14
|
-
검증 우선 AI 개발
|
|
16
|
+
검증 우선 AI 개발 공장.
|
|
17
|
+
AI 가 만들고, NEKOWORK 가 검증하고, 사람이 결정한다.
|
|
18
|
+
증거 없이는 출고하지 않는다.
|
|
15
19
|
```
|
|
16
20
|
|
|
21
|
+
> 비유: NEKOWORK 는 검증관이 붙은 AI 개발 공장. 입력은 아이디어, 출력은 증거가 첨부된 변경. 검사 없이는 출고하지 않는다.
|
|
22
|
+
|
|
17
23
|
## 핵심 원칙
|
|
18
24
|
|
|
19
25
|
NEKOWORK 의 모든 장기 확장은 단 하나의 원칙에 묶입니다.
|
|
@@ -28,19 +34,75 @@ AI 생성물은 신뢰하지 않고 검증한다.
|
|
|
28
34
|
|
|
29
35
|
이 원칙이 6개 레이어 전체를 묶습니다.
|
|
30
36
|
|
|
31
|
-
##
|
|
37
|
+
## 12-Station Factory Model (long-term)
|
|
38
|
+
|
|
39
|
+
> **주의:** 12 patterns ≠ 12 sequential steps. **12 patterns = 공장 운영에 필요한 12개 설계 블록**.
|
|
40
|
+
> 작업 유형에 따라 일부 station 만 거친다. 모든 작업이 12 station 을 순차적으로 도는 것은 아니다.
|
|
32
41
|
|
|
33
42
|
```text
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
43
|
+
[입고]
|
|
44
|
+
1. Intake 사용자 요청 접수
|
|
45
|
+
2. Clarify 제품 질문 / 요구사항 흔들기
|
|
46
|
+
|
|
47
|
+
[기획]
|
|
48
|
+
3. Route 작업 유형 분류: bug / feature / refactor / release / docs
|
|
49
|
+
4. Context 도메인 문서 / 기존 구조 / 제약 확인
|
|
50
|
+
5. Spec acceptance criteria 작성
|
|
51
|
+
6. Plan 실행 계획과 작업 단위 분해
|
|
52
|
+
|
|
53
|
+
[제조]
|
|
54
|
+
7. Team read-only 전문가 handoff 생성
|
|
55
|
+
8. Work 단일 executor 가 코드 변경
|
|
56
|
+
|
|
57
|
+
[검사] ← 1.0 의 칼날
|
|
58
|
+
9. Self-Review 작성자 1차 검토
|
|
59
|
+
10. Independent Review Codex / 별도 모델 교차 검토
|
|
60
|
+
|
|
61
|
+
[출고]
|
|
62
|
+
11. Human Gate / Apply 위험 작업은 사람 승인 후 적용
|
|
63
|
+
|
|
64
|
+
[학습]
|
|
65
|
+
12. Memory / Evolution 결과·실패·규칙·개선점을 다음 작업에 반영
|
|
40
66
|
```
|
|
41
67
|
|
|
42
|
-
NEKOWORK 의 **차별 핵심은
|
|
43
|
-
1
|
|
68
|
+
NEKOWORK 의 **차별 핵심은 station 9–11** ([검사] + [출고]).
|
|
69
|
+
1–8 은 외부 AI (Claude Code / Codex / Cursor / Gemini / 사람) 가 채울 수 있으며, NEKOWORK 는 그 출력을 **입력 소스로 흡수**합니다.
|
|
70
|
+
station 12 는 검사·출고 결과를 다음 작업에 되먹이는 닫힌 루프 — 1.x 의 rule learning, 2.x 의 자동 룰 제안으로 이어집니다.
|
|
71
|
+
|
|
72
|
+
### 기존 6-layer 와의 매핑
|
|
73
|
+
|
|
74
|
+
> 참고용. 2026-05-16 이전 문서가 6-layer (Discover / Spec / Plan / Build / Verify / Decide) 로 작성되어 있음. 12-station 은 그것을 더 정밀하게 분해한 것이며 정체성 변경이 아닙니다.
|
|
75
|
+
|
|
76
|
+
| 6-layer | 12-station |
|
|
77
|
+
|---|---|
|
|
78
|
+
| 1. Discover | 1 Intake · 2 Clarify |
|
|
79
|
+
| 2. Spec | 3 Route · 4 Context · 5 Spec |
|
|
80
|
+
| 3. Plan | 6 Plan · 7 Team |
|
|
81
|
+
| 4. Build | 8 Work |
|
|
82
|
+
| 5. Verify | 9 Self-Review · 10 Independent Review |
|
|
83
|
+
| 6. Decide | 11 Human Gate / Apply |
|
|
84
|
+
| — | 12 Memory / Evolution (신규) |
|
|
85
|
+
|
|
86
|
+
### 각 station 의 현재 상태
|
|
87
|
+
|
|
88
|
+
> alpha.11 기준 (2026-05-16). 자세한 1.0 scope 는 [SCOPE-1.0.md](SCOPE-1.0.md). 이 표는 **약속이 아니라 현재 그림** — CLI 명령 추가는 별도 alpha 결정 사항.
|
|
89
|
+
|
|
90
|
+
| Station | 1.0 (현재) | 1.x | 2.x |
|
|
91
|
+
|---|---|---|---|
|
|
92
|
+
| 1 Intake | 외부 (사람 / Cursor / Claude Code) | upstream file 자동 수집 확장 | NEKOWORK 진입점 |
|
|
93
|
+
| 2 Clarify | 외부 | — | NEKOWORK 진입점 |
|
|
94
|
+
| 3 Route | 결정적 룰이 diff 에서 자동 추론 | task type label | 진입점 분기 |
|
|
95
|
+
| 4 Context | upstream file (`context.md` / `DOMAIN.md`) 자동 픽업 | — | NEKOWORK 진입점 |
|
|
96
|
+
| 5 Spec | upstream file (`SPEC.md`) 자동 픽업 | acceptance coverage 측정 | NEKOWORK 진입점 |
|
|
97
|
+
| 6 Plan | upstream file (`PLAN.md`) 자동 픽업 | plan 검증 룰 | NEKOWORK 진입점 |
|
|
98
|
+
| 7 Team | read-only handoff (legacy `team`) | — | 검증 게이트 강제 |
|
|
99
|
+
| 8 Work | 외부 executor (Claude Code / Cursor / Codex) | — | 검증 게이트 강제 |
|
|
100
|
+
| **9 Self-Review** | `verify-pr` 결정적 룰 + 증거 수집 | check 자동 실행 (test / lint / typecheck / audit) | check 매트릭스 확장 |
|
|
101
|
+
| **10 Independent Review** | Codex review (advisor 노트, verdict 영향 없음) | `verify-skill` / `verify-release` family | 멀티 reviewer 가중치 |
|
|
102
|
+
| **11 Human Gate / Apply** | `decision.json` + 명시적 `apply` | policy profiles + team approval flow | apply 범위 확장 (patch → workflow) |
|
|
103
|
+
| 12 Memory / Evolution | session evidence + `bench:rules` rule efficacy | rule learning | 자동 룰 제안 |
|
|
104
|
+
|
|
105
|
+
**진한 station (9 · 10 · 11) 이 NEKOWORK 의 칼날** — 1.0 의 출하 기준은 이 세 station 의 신뢰도입니다.
|
|
44
106
|
|
|
45
107
|
## 외부 AI 의 정의
|
|
46
108
|
|
|
@@ -76,9 +138,9 @@ OMC / ECC / Cursor / Claude Code / Codex / Gemini 는 NEKOWORK 의 경쟁자가
|
|
|
76
138
|
|
|
77
139
|
단, **모든 위쪽 레이어는 검증 게이트에 묶여야 합니다.** 검증되지 않은 산출물은 다음 단계로 가지 못합니다. 이게 OMC/ECC 식 자유로운 multi-agent runtime 과의 차이입니다.
|
|
78
140
|
|
|
79
|
-
### 3.x 이후 — Verification-first AI development
|
|
80
|
-
-
|
|
81
|
-
- 외부 AI 는 입력 소스 또는
|
|
141
|
+
### 3.x 이후 — Verification-first AI development factory
|
|
142
|
+
- 12 station 이 모두 검증으로 묶임
|
|
143
|
+
- 외부 AI 는 입력 소스 또는 어시스턴트 ("공장 안 작업자 또는 외부 납품원") 로 사용됨
|
|
82
144
|
- 사용자는 "NEKOWORK 안에서 작업하면 절대 검증 없이 머지·apply 되지 않는다" 를 신뢰
|
|
83
145
|
|
|
84
146
|
## 무엇이 NEKOWORK 가 아닌가
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<text x="72" y="147" fill="#d7e3ec">NEKOWORK doctor</text>
|
|
26
26
|
<text x="72" y="179" fill="#8fb3c8">STATUS CHECK MESSAGE</text>
|
|
27
27
|
<text x="72" y="211" fill="#9be9a8">PASS node Node 22+</text>
|
|
28
|
-
<text x="72" y="243" fill="#9be9a8">PASS package metadata @ps-neko/nekowork@0.1.0-alpha.
|
|
28
|
+
<text x="72" y="243" fill="#9be9a8">PASS package metadata @ps-neko/nekowork@0.1.0-alpha.11</text>
|
|
29
29
|
<text x="72" y="275" fill="#9be9a8">PASS api key env no delegated-provider API key overrides</text>
|
|
30
30
|
<text x="72" y="307" fill="#ffd166">WARN gemini cli auth status is not checked non-interactively</text>
|
|
31
31
|
<text x="72" y="339" fill="#d7e3ec">summary: WARN (5 pass, 2 warn, 0 fail)</text>
|
|
Binary file
|
|
@@ -106,10 +106,10 @@
|
|
|
106
106
|
"target": { "claude": ".claude/agents/doc-writer.md" }
|
|
107
107
|
},
|
|
108
108
|
|
|
109
|
-
"skill:
|
|
109
|
+
"skill:nekowork-full-cycle": {
|
|
110
110
|
"type": "skill",
|
|
111
|
-
"source": "skills/
|
|
112
|
-
"target": { "claude": ".claude/skills/
|
|
111
|
+
"source": "skills/nekowork-full-cycle/",
|
|
112
|
+
"target": { "claude": ".claude/skills/nekowork-full-cycle/" }
|
|
113
113
|
},
|
|
114
114
|
"skill:plan-eng-review": {
|
|
115
115
|
"type": "skill",
|
|
@@ -152,10 +152,10 @@
|
|
|
152
152
|
"target": { "claude": ".claude/skills/porting/" }
|
|
153
153
|
},
|
|
154
154
|
|
|
155
|
-
"command:
|
|
155
|
+
"command:nekowork-full-cycle": {
|
|
156
156
|
"type": "command",
|
|
157
|
-
"source": "commands/
|
|
158
|
-
"target": { "claude": ".claude/commands/
|
|
157
|
+
"source": "commands/nekowork-full-cycle.md",
|
|
158
|
+
"target": { "claude": ".claude/commands/nekowork-full-cycle.md" }
|
|
159
159
|
},
|
|
160
160
|
|
|
161
161
|
"hook:gateguard-fact-force": {
|
|
@@ -76,12 +76,12 @@
|
|
|
76
76
|
"required": false
|
|
77
77
|
},
|
|
78
78
|
"codex-loop": {
|
|
79
|
-
"description": "
|
|
79
|
+
"description": "nekowork-full-cycle 7단계 풀사이클 + Codex 검증 루프",
|
|
80
80
|
"components": [
|
|
81
|
-
"skill:
|
|
81
|
+
"skill:nekowork-full-cycle",
|
|
82
82
|
"agent:codex-reviewer",
|
|
83
83
|
"agent:codex-challenger",
|
|
84
|
-
"command:
|
|
84
|
+
"command:nekowork-full-cycle"
|
|
85
85
|
],
|
|
86
86
|
"level": 3,
|
|
87
87
|
"required": false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ps-neko/nekowork",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.12",
|
|
4
4
|
"description": "Verifies AI-made code changes before apply with Codex verification, Human Gate, and explicit apply",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
@@ -50,7 +50,11 @@
|
|
|
50
50
|
"scripts/",
|
|
51
51
|
"bridge/",
|
|
52
52
|
"examples/",
|
|
53
|
-
"docs
|
|
53
|
+
"docs/*.md",
|
|
54
|
+
"docs/assets/**",
|
|
55
|
+
"docs/case-studies/**",
|
|
56
|
+
"docs/dev-log/**",
|
|
57
|
+
"docs/examples/**",
|
|
54
58
|
"SOUL.md",
|
|
55
59
|
"RULES.md",
|
|
56
60
|
"CLAUDE.md",
|
package/scripts/build-cursor.js
CHANGED
|
@@ -113,7 +113,7 @@ const cursorrules = `# Auto-generated. agent.yaml + agents/*.md 가 원본.
|
|
|
113
113
|
|
|
114
114
|
이 워크스페이스는 HARNESS 카탈로그를 기반으로 한다.
|
|
115
115
|
.cursor/rules/agents/ : 11개 에이전트 (provider/model 메타데이터 포함)
|
|
116
|
-
.cursor/rules/skills/ : ${manifest.skills?.length || 0}개 스킬 (
|
|
116
|
+
.cursor/rules/skills/ : ${manifest.skills?.length || 0}개 스킬 (nekowork-full-cycle 등)
|
|
117
117
|
.cursor/hooks.json : Cursor 이벤트 (beforeTool/afterTool/...) 어댑터
|
|
118
118
|
|
|
119
119
|
직접 편집 금지. 변경은 정규 카탈로그(agents/, skills/, agent.yaml)에서 하고
|
|
@@ -45,7 +45,17 @@ export function isSemverMcpPin(pin) {
|
|
|
45
45
|
return /@\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(pin);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
export function
|
|
48
|
+
export function resolveEffectiveRoot(start) {
|
|
49
|
+
// Monorepo 자동 감지: packages/<x>/ 에서 호출되면 워크스페이스 루트로 폴백.
|
|
50
|
+
const candidate = path.resolve(start, '..', '..');
|
|
51
|
+
if (fs.existsSync(path.join(candidate, 'pnpm-workspace.yaml'))) {
|
|
52
|
+
return candidate;
|
|
53
|
+
}
|
|
54
|
+
return start;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function checkSecurityHardening(rawRoot = ROOT) {
|
|
58
|
+
const root = resolveEffectiveRoot(rawRoot);
|
|
49
59
|
const errors = [];
|
|
50
60
|
const warnings = [];
|
|
51
61
|
const stats = {
|
|
@@ -56,7 +66,7 @@ export function checkSecurityHardening(root = ROOT) {
|
|
|
56
66
|
packageSpecs: 0,
|
|
57
67
|
};
|
|
58
68
|
|
|
59
|
-
const manifest =
|
|
69
|
+
const manifest = readAgentManifest(root, errors);
|
|
60
70
|
const security = manifest?.security || {};
|
|
61
71
|
|
|
62
72
|
checkDeadManConfig(security, errors);
|
|
@@ -171,8 +181,10 @@ function checkMcpPins(servers, security, errors, stats) {
|
|
|
171
181
|
|
|
172
182
|
function checkPackageSupplyChain(root, security, errors, stats) {
|
|
173
183
|
if (security.supply_chain?.package_lock_required !== false) {
|
|
174
|
-
|
|
175
|
-
|
|
184
|
+
const hasNpmLock = fs.existsSync(path.join(root, 'package-lock.json'));
|
|
185
|
+
const hasPnpmLock = fs.existsSync(path.join(root, 'pnpm-lock.yaml'));
|
|
186
|
+
if (!hasNpmLock && !hasPnpmLock) {
|
|
187
|
+
errors.push('package-lock.json or pnpm-lock.yaml is required for supply-chain reproducibility');
|
|
176
188
|
}
|
|
177
189
|
}
|
|
178
190
|
|
|
@@ -227,6 +239,17 @@ function readYaml(root, rel, errors) {
|
|
|
227
239
|
}
|
|
228
240
|
}
|
|
229
241
|
|
|
242
|
+
function readAgentManifest(root, errors) {
|
|
243
|
+
if (fs.existsSync(path.join(root, 'agent.yaml'))) {
|
|
244
|
+
return readYaml(root, 'agent.yaml', errors);
|
|
245
|
+
}
|
|
246
|
+
const monorepoCandidate = path.join(root, 'packages', 'nekowork-cli', 'agent.yaml');
|
|
247
|
+
if (fs.existsSync(monorepoCandidate)) {
|
|
248
|
+
return readYaml(path.dirname(monorepoCandidate), 'agent.yaml', errors);
|
|
249
|
+
}
|
|
250
|
+
return readYaml(root, 'agent.yaml', errors);
|
|
251
|
+
}
|
|
252
|
+
|
|
230
253
|
function readJson(root, rel, errors) {
|
|
231
254
|
try {
|
|
232
255
|
return JSON.parse(fs.readFileSync(path.join(root, rel), 'utf8'));
|
package/scripts/cli.js
CHANGED
|
@@ -166,7 +166,7 @@ Review loop
|
|
|
166
166
|
pr-prep ["task"] [--session <id>] [--project-root <dir>] [--json]
|
|
167
167
|
generate PR_SUMMARY/RISK_NOTES/TEST_EVIDENCE/CHANGELOG_DRAFT without branch, commit, push, or PR creation
|
|
168
168
|
review "<task>" [--secure] [--fast] [--no-ship] [--no-codex] [--live] [--session <id>] [--project-root <dir>]
|
|
169
|
-
legacy full
|
|
169
|
+
legacy full nekowork-full-cycle workflow
|
|
170
170
|
review-cycle "<task>" [--secure] [--fast] [--no-ship] [--no-codex] [--live] [--session <id>] [--project-root <dir>]
|
|
171
171
|
explicit compatibility alias for the legacy full workflow
|
|
172
172
|
plan "<task>" [--project-root <dir>] ideate + plan only
|
package/scripts/demo-review.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
//
|
|
2
|
+
// nekowork-full-cycle 풀사이클 시뮬레이션 (Week 1 데모).
|
|
3
3
|
// 실제 LLM 호출은 안 함 — 7단계의 핸드오프 파일 / 상태 / round 카운터가 잘 흐르는지만 검증.
|
|
4
4
|
// 사용자 룰("git push 사용자 확인") 우선이라 실 ship 은 안 함.
|
|
5
5
|
|
|
@@ -19,7 +19,7 @@ const NO_SHIP = process.argv.includes('--no-ship');
|
|
|
19
19
|
const SESSION_DIR = path.join(ROOT, '.harness', 'state', 'sessions', SESSION_ID);
|
|
20
20
|
fs.mkdirSync(path.join(SESSION_DIR, 'handoffs'), { recursive: true });
|
|
21
21
|
|
|
22
|
-
console.log(`\n===
|
|
22
|
+
console.log(`\n=== nekowork-full-cycle demo ===`);
|
|
23
23
|
console.log(`session : ${SESSION_ID}`);
|
|
24
24
|
console.log(`task : ${TASK}`);
|
|
25
25
|
console.log(`flags : ${SECURE ? '--secure ' : ''}${NO_SHIP ? '--no-ship' : ''}`);
|
|
@@ -179,7 +179,7 @@ export function addedLines(parsed) {
|
|
|
179
179
|
*
|
|
180
180
|
* @param {object} opts
|
|
181
181
|
* @param {string} [opts.cwd] git working directory
|
|
182
|
-
* @param {'working' | 'staged' | 'range'} [opts.mode='working']
|
|
182
|
+
* @param {'working' | 'staged' | 'range' | 'full'} [opts.mode='working']
|
|
183
183
|
* @param {string} [opts.range] required when mode='range', e.g. 'main...HEAD'
|
|
184
184
|
* @param {string[]} [opts.extraArgs] extra args appended after the mode args
|
|
185
185
|
* @param {boolean} [opts.includeUntracked=true] for mode='working', synthesize
|
|
@@ -189,6 +189,23 @@ export function getGitDiff(opts = {}) {
|
|
|
189
189
|
const cwd = opts.cwd || process.cwd();
|
|
190
190
|
const mode = opts.mode || 'working';
|
|
191
191
|
const includeUntracked = opts.includeUntracked !== false;
|
|
192
|
+
|
|
193
|
+
// full-scan: treat the entire tracked file set (plus untracked, unless
|
|
194
|
+
// disabled) as an all-added diff, so risk rules see every line rather than
|
|
195
|
+
// only a git delta. This is the onboarding path — run verify-pr on a repo
|
|
196
|
+
// that has no PR/diff yet, without fabricating a fake change.
|
|
197
|
+
if (mode === 'full') {
|
|
198
|
+
const ls = spawnSync('git', ['ls-files'], { cwd, encoding: 'utf8', windowsHide: true });
|
|
199
|
+
if (ls.error) throw ls.error;
|
|
200
|
+
if (ls.status !== 0) {
|
|
201
|
+
throw new Error(`git ls-files exited ${ls.status}: ${ls.stderr || ''}`);
|
|
202
|
+
}
|
|
203
|
+
const tracked = (ls.stdout || '').split('\n').map(s => s.trim()).filter(Boolean);
|
|
204
|
+
let stdout = synthesizeFilesAsDiff(cwd, tracked);
|
|
205
|
+
if (includeUntracked) stdout += synthesizeUntrackedDiff(cwd);
|
|
206
|
+
return parseDiff(stdout);
|
|
207
|
+
}
|
|
208
|
+
|
|
192
209
|
const args = ['diff', '--no-color', '--no-ext-diff'];
|
|
193
210
|
if (mode === 'staged') args.push('--cached');
|
|
194
211
|
else if (mode === 'range') {
|
|
@@ -227,8 +244,22 @@ function synthesizeUntrackedDiff(cwd) {
|
|
|
227
244
|
const ls = spawnSync('git', ['ls-files', '--others', '--exclude-standard'], { cwd, encoding: 'utf8', windowsHide: true });
|
|
228
245
|
if (ls.status !== 0 || !ls.stdout) return '';
|
|
229
246
|
const files = ls.stdout.split('\n').map(s => s.trim()).filter(Boolean);
|
|
247
|
+
return synthesizeFilesAsDiff(cwd, files);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Render a list of repo-relative file paths as an all-added unified diff
|
|
252
|
+
* (every line prefixed `+`). Shared by untracked-file synthesis (working mode)
|
|
253
|
+
* and whole-tree synthesis (full-scan mode). Non-files and unreadable paths
|
|
254
|
+
* are skipped silently.
|
|
255
|
+
*
|
|
256
|
+
* @param {string} cwd
|
|
257
|
+
* @param {string[]} relPaths repo-relative paths
|
|
258
|
+
* @returns {string} concatenated unified-diff chunks
|
|
259
|
+
*/
|
|
260
|
+
function synthesizeFilesAsDiff(cwd, relPaths) {
|
|
230
261
|
let chunks = '';
|
|
231
|
-
for (const rel of
|
|
262
|
+
for (const rel of relPaths) {
|
|
232
263
|
const full = path.join(cwd, rel);
|
|
233
264
|
let content;
|
|
234
265
|
try {
|
|
@@ -47,6 +47,16 @@ const LOCKFILE_TO_PM = {
|
|
|
47
47
|
'bun.lockb': 'bun',
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
+
// 하위 탐색 시 들어가지 않을 디렉토리 (의존성 / 빌드 산출물 / 캐시).
|
|
51
|
+
// 이 안의 언어 마커는 프로젝트 본체의 것이 아니므로 무시한다.
|
|
52
|
+
const EXCLUDED_DIRS = new Set([
|
|
53
|
+
'node_modules', 'vendor', 'dist', 'build', 'out', 'target',
|
|
54
|
+
'coverage', 'venv', '.venv', '__pycache__', 'tmp',
|
|
55
|
+
]);
|
|
56
|
+
|
|
57
|
+
// 하위 탐색 최대 깊이 (root 의 직계 자식이 depth 1).
|
|
58
|
+
const SUBTREE_MAX_DEPTH = 4;
|
|
59
|
+
|
|
50
60
|
/**
|
|
51
61
|
* Detect what verifications make sense for `root`.
|
|
52
62
|
*
|
|
@@ -88,24 +98,34 @@ export function detectProject(root = process.cwd()) {
|
|
|
88
98
|
baselineAt: new Date().toISOString(),
|
|
89
99
|
};
|
|
90
100
|
|
|
91
|
-
|
|
101
|
+
// 언어 마커는 root 를 우선 검사한다. root 에서 아무 언어도 못 찾았을 때만
|
|
102
|
+
// (모노레포 / backend 서브디렉토리 등) 제한된 깊이로 하위를 탐색한다.
|
|
103
|
+
// root 에 마커가 있으면 하위는 보지 않으므로 기존 동작이 그대로 보존된다.
|
|
104
|
+
const langDirs = new Map(); // type -> 마커가 발견된 디렉토리
|
|
92
105
|
for (const marker of LANGUAGE_MARKERS) {
|
|
93
|
-
if (exists(path.join(root, marker.file))
|
|
106
|
+
if (exists(path.join(root, marker.file)) && !langDirs.has(marker.type)) {
|
|
107
|
+
langDirs.set(marker.type, root);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (langDirs.size === 0) {
|
|
111
|
+
for (const { type, dir } of findLanguageMarkersInSubtree(root)) {
|
|
112
|
+
if (!langDirs.has(type)) langDirs.set(type, dir);
|
|
113
|
+
}
|
|
94
114
|
}
|
|
95
|
-
out.languages = [...
|
|
115
|
+
out.languages = [...langDirs.keys()];
|
|
96
116
|
out.projectType = pickPrimaryLanguage(out.languages);
|
|
97
117
|
|
|
98
|
-
if (
|
|
99
|
-
Object.assign(out, detectNode(
|
|
118
|
+
if (langDirs.has('node')) {
|
|
119
|
+
Object.assign(out, detectNode(langDirs.get('node')));
|
|
100
120
|
}
|
|
101
|
-
if (
|
|
102
|
-
mergeCommands(out, detectRust(
|
|
121
|
+
if (langDirs.has('rust')) {
|
|
122
|
+
mergeCommands(out, detectRust(langDirs.get('rust')));
|
|
103
123
|
}
|
|
104
|
-
if (
|
|
105
|
-
mergeCommands(out, detectPython(
|
|
124
|
+
if (langDirs.has('python')) {
|
|
125
|
+
mergeCommands(out, detectPython(langDirs.get('python')));
|
|
106
126
|
}
|
|
107
|
-
if (
|
|
108
|
-
mergeCommands(out, detectGo(
|
|
127
|
+
if (langDirs.has('go')) {
|
|
128
|
+
mergeCommands(out, detectGo(langDirs.get('go')));
|
|
109
129
|
}
|
|
110
130
|
|
|
111
131
|
for (const file of CI_FILES) {
|
|
@@ -131,6 +151,49 @@ function pickPrimaryLanguage(languages) {
|
|
|
131
151
|
return languages[0];
|
|
132
152
|
}
|
|
133
153
|
|
|
154
|
+
// root 에서 언어 마커를 못 찾았을 때, 제한된 깊이로 하위 디렉토리를 탐색한다.
|
|
155
|
+
// node_modules / vendor / 빌드 산출물 / 숨김(.) 디렉토리는 건너뛴다.
|
|
156
|
+
// 같은 언어가 여러 곳이면 가장 먼저 만난 디렉토리를 쓴다.
|
|
157
|
+
function findLanguageMarkersInSubtree(root, maxDepth = SUBTREE_MAX_DEPTH) {
|
|
158
|
+
const found = [];
|
|
159
|
+
const markerByFile = new Map(LANGUAGE_MARKERS.map(m => [m.file, m.type]));
|
|
160
|
+
|
|
161
|
+
const skipDir = (name) => name.startsWith('.') || EXCLUDED_DIRS.has(name);
|
|
162
|
+
|
|
163
|
+
const walk = (dir, depth) => {
|
|
164
|
+
let entries;
|
|
165
|
+
try {
|
|
166
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
167
|
+
} catch {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
for (const entry of entries) {
|
|
171
|
+
if (entry.isFile() && markerByFile.has(entry.name)) {
|
|
172
|
+
found.push({ type: markerByFile.get(entry.name), dir });
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (depth >= maxDepth) return;
|
|
176
|
+
for (const entry of entries) {
|
|
177
|
+
if (entry.isDirectory() && !skipDir(entry.name)) {
|
|
178
|
+
walk(path.join(dir, entry.name), depth + 1);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
let rootEntries;
|
|
184
|
+
try {
|
|
185
|
+
rootEntries = fs.readdirSync(root, { withFileTypes: true });
|
|
186
|
+
} catch {
|
|
187
|
+
return found;
|
|
188
|
+
}
|
|
189
|
+
for (const entry of rootEntries) {
|
|
190
|
+
if (entry.isDirectory() && !skipDir(entry.name)) {
|
|
191
|
+
walk(path.join(root, entry.name), 1);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return found;
|
|
195
|
+
}
|
|
196
|
+
|
|
134
197
|
function detectNode(root) {
|
|
135
198
|
const pkgPath = path.join(root, 'package.json');
|
|
136
199
|
const out = {
|
package/scripts/lib/router.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// 입력: stage, task, files, ecoMode, riskLevel
|
|
3
3
|
// 출력: { agent, model, provider, rationale, alternatives }
|
|
4
4
|
//
|
|
5
|
-
// SKILL
|
|
5
|
+
// SKILL nekowork-full-cycle 의 Stage Routing 표 + AGENTS.md 의
|
|
6
6
|
// 권한 매트릭스를 코드로 구현.
|
|
7
7
|
|
|
8
8
|
import fs from 'node:fs';
|
|
@@ -50,7 +50,7 @@ export const EXIT_CODE = Object.freeze({
|
|
|
50
50
|
/**
|
|
51
51
|
* @param {object} opts
|
|
52
52
|
* @param {string} [opts.projectRoot] default process.cwd()
|
|
53
|
-
* @param {'working' | 'staged' | 'patch' | 'range'} [opts.mode='working']
|
|
53
|
+
* @param {'working' | 'staged' | 'patch' | 'range' | 'full'} [opts.mode='working']
|
|
54
54
|
* @param {string} [opts.patchPath] required when mode='patch'
|
|
55
55
|
* @param {string} [opts.range] required when mode='range'
|
|
56
56
|
* @param {boolean} [opts.write=true] write evidence + REPORT.md to disk
|
|
@@ -155,6 +155,9 @@ function loadDiff({ mode, projectRoot, opts }) {
|
|
|
155
155
|
if (mode === 'staged') {
|
|
156
156
|
return getGitDiff({ cwd: projectRoot, mode: 'staged' });
|
|
157
157
|
}
|
|
158
|
+
if (mode === 'full') {
|
|
159
|
+
return getGitDiff({ cwd: projectRoot, mode: 'full' });
|
|
160
|
+
}
|
|
158
161
|
return getGitDiff({ cwd: projectRoot, mode: 'working' });
|
|
159
162
|
}
|
|
160
163
|
|
|
@@ -221,7 +224,7 @@ function deriveVerdict({ findings, parsedDiff, checksAvailable }) {
|
|
|
221
224
|
if (sourceOnly && !checksAvailable.test) {
|
|
222
225
|
return {
|
|
223
226
|
verdict: VERDICT.INSUFFICIENT_EVIDENCE,
|
|
224
|
-
reason: '
|
|
227
|
+
reason: 'risk scan passed (no blocking findings), but this project has no test command — full verification needs one. This is "not enough evidence", not a failure.',
|
|
225
228
|
apply_allowed: false,
|
|
226
229
|
};
|
|
227
230
|
}
|
|
@@ -422,6 +425,7 @@ export function parseVerifyPrArgs(rest = []) {
|
|
|
422
425
|
const a = rest[i];
|
|
423
426
|
if (a === '--from-working-tree') opts.mode = 'working';
|
|
424
427
|
else if (a === '--from-staged' || a === '--staged') opts.mode = 'staged';
|
|
428
|
+
else if (a === '--full-scan' || a === '--full') opts.mode = 'full';
|
|
425
429
|
else if (a === '--from-patch') { opts.mode = 'patch'; opts.patchPath = rest[++i]; }
|
|
426
430
|
else if (a === '--range') { opts.mode = 'range'; opts.range = rest[++i]; }
|
|
427
431
|
else if (a === '--project-root') opts.projectRoot = rest[++i];
|
|
@@ -449,6 +453,12 @@ export function printVerifyPrSummary(result) {
|
|
|
449
453
|
console.log(` - [${f.severity.toUpperCase()}] ${f.title} (${f.file}:${f.line})`);
|
|
450
454
|
}
|
|
451
455
|
}
|
|
456
|
+
if (decision.verdict === VERDICT.INSUFFICIENT_EVIDENCE) {
|
|
457
|
+
console.log('');
|
|
458
|
+
console.log(' i not a failure — the risk scan passed with no blocking findings.');
|
|
459
|
+
console.log(' verify-pr just has no test command to fully verify this change.');
|
|
460
|
+
console.log(' -> add a test script for full verification, or pass --ci-exit-soft to avoid blocking CI.');
|
|
461
|
+
}
|
|
452
462
|
if (writtenPaths) {
|
|
453
463
|
console.log(` report : ${path.relative(process.cwd(), writtenPaths.report).replace(/\\/g, '/')}`);
|
|
454
464
|
console.log(` decision : ${path.relative(process.cwd(), writtenPaths.decision).replace(/\\/g, '/')}`);
|
|
@@ -166,7 +166,7 @@ function buildAutoSection() {
|
|
|
166
166
|
|
|
167
167
|
lines.push('## 매직 키워드 → 스킬 (명시 옵트인만)');
|
|
168
168
|
lines.push('');
|
|
169
|
-
lines.push('자동 활성 키워드 감지는 **사용**하지 않는다. 사용자 룰("확인 후 실행") 우선. 모든 스킬은 슬래시 명령(`/
|
|
169
|
+
lines.push('자동 활성 키워드 감지는 **사용**하지 않는다. 사용자 룰("확인 후 실행") 우선. 모든 스킬은 슬래시 명령(`/nekowork-full-cycle`) 또는 CLI(`nekowork review`) 로 명시 호출.');
|
|
170
170
|
lines.push('');
|
|
171
171
|
|
|
172
172
|
lines.push('## 핸드오프 5필드');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: nekowork-full-cycle
|
|
3
3
|
description: "Claude 주도 + Codex 위임 7단계 풀사이클 (idea → ship). Week 1 데모 정전(canon)."
|
|
4
4
|
origin: harness-core
|
|
5
5
|
level: 3
|
|
@@ -9,7 +9,7 @@ auto_inject_keywords: []
|
|
|
9
9
|
tags: [workflow, review, codex, primary]
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
#
|
|
12
|
+
# nekowork-full-cycle
|
|
13
13
|
|
|
14
14
|
Claude 가 구현하고 Codex 가 의심하는 7단계 풀사이클. **HARNESS 의 정전 워크플로우.** 자동 활성 키워드는 비워두고 명시 호출만 받는다 (사용자 환경의 "확인 후 실행" 류 룰을 우회하지 않기 위함).
|
|
15
15
|
|
|
@@ -23,7 +23,7 @@ nekowork review "<task>" --no-ship # 단계 7 생략 (리뷰까지만)
|
|
|
23
23
|
nekowork review "<task>" --no-codex # 단계 5·6 스킵 (Codex 검증 생략)
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
또는 슬래시: `/
|
|
26
|
+
또는 슬래시: `/nekowork-full-cycle <task> [--flags]`
|
|
27
27
|
|
|
28
28
|
## 7단계
|
|
29
29
|
|
package/skills/ralph/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: ralph
|
|
|
3
3
|
description: "PRD AC 가 모두 passes:true 될 때까지 반복 실행. 명시 옵트인만 (사용자 룰: 자동 활성 금지)."
|
|
4
4
|
origin: harness-core
|
|
5
5
|
level: 3
|
|
6
|
-
prerequisites: [tdd-workflow,
|
|
6
|
+
prerequisites: [tdd-workflow, nekowork-full-cycle]
|
|
7
7
|
conflicts: [auto-merge]
|
|
8
8
|
auto_inject_keywords: []
|
|
9
9
|
tags: [persistent, loop]
|
package/skills/review/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: review
|
|
3
|
-
description: "
|
|
3
|
+
description: "nekowork-full-cycle 단계 4 (self-review) 실행. critical / high 만 잡는다."
|
|
4
4
|
origin: harness-core
|
|
5
5
|
level: 2
|
|
6
6
|
prerequisites: [tdd-workflow]
|
|
@@ -16,7 +16,7 @@ Claude self-review 단계. code-reviewer 에이전트(opus, ro)를 호출해 git
|
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
nekowork self-review # 단독
|
|
19
|
-
#
|
|
19
|
+
# nekowork-full-cycle 의 단계 4 로 자동 호출됨
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
## 입력
|
package/skills/ship/SKILL.md
CHANGED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: verified-gate
|
|
3
|
+
description: "독립 검증 게이트를 strict 모드로 실행해 review 미실행/경고/위험을 non-zero exit 으로 차단하고, verdict 카드로 ship/no-ship 을 제시한다."
|
|
4
|
+
origin: harness-core
|
|
5
|
+
level: 1
|
|
6
|
+
prerequisites: []
|
|
7
|
+
conflicts: []
|
|
8
|
+
auto_inject_keywords: []
|
|
9
|
+
tags: [gate, verification, strict, ci]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# verified-gate
|
|
13
|
+
|
|
14
|
+
현재 워킹트리 변경을 **strict 검증 게이트**에 통과시킨다. 일반 `gate` 와 달리 세 가지를 강제한다:
|
|
15
|
+
|
|
16
|
+
- review 미실행(`not_run`)·실패(`failed`)를 PASS 로 묻지 않고 `PASS_WITH_WARNINGS` 로 가시화한다 (미검증 = 미통과).
|
|
17
|
+
- `--strict` 는 그 경고·위험을 **non-zero exit 으로 차단**한다 — CI 에서 게이트 자체가 빨갛게 빠진다.
|
|
18
|
+
- `decision.json` 은 content-hash 로 `audit.jsonl` 에 결박되어, gate 이후 사후 변조 시 `apply` 가 거부한다.
|
|
19
|
+
|
|
20
|
+
## 사용 시점
|
|
21
|
+
|
|
22
|
+
- PR/커밋 직전 ship/no-ship 을 한 번에 판정하고 싶을 때.
|
|
23
|
+
- CI 에서 "검증 안 함"이 "통과"로 새지 않도록 강제하고 싶을 때.
|
|
24
|
+
- 명시 옵트인 전용 — 자동 키워드 활성은 하지 않는다(프로젝트 정책).
|
|
25
|
+
|
|
26
|
+
## 동작
|
|
27
|
+
|
|
28
|
+
1. 프로젝트 harness CLI 로 strict 게이트를 실행한다 (`nekoforge` 우선, 없으면 `harness` / `nekowork` 폴백):
|
|
29
|
+
```bash
|
|
30
|
+
nekoforge gate --strict --task "<task-id, 기본 TASK-001>"
|
|
31
|
+
```
|
|
32
|
+
2. **exit code 를 신뢰해** 판정하고(verdict 텍스트만 보고 통과시키지 않는다), `.harness/decision.json` 과 `REPORT.md` 를 읽어 **verdict 카드**로 제시한다:
|
|
33
|
+
|
|
34
|
+
| exit | verdict | 카드 | 의미 |
|
|
35
|
+
|---|---|---|---|
|
|
36
|
+
| 0 | PASS | ✅ | clean. apply 가능 |
|
|
37
|
+
| 3 | NEEDS_HUMAN_REVIEW / PASS_WITH_WARNINGS | ⚠️ | 사람 검토 필요 (경고·미검증 포함) |
|
|
38
|
+
| 4 | BLOCK / INSUFFICIENT_EVIDENCE | 🚫 | 차단 (critical / 증거 부족) |
|
|
39
|
+
|
|
40
|
+
3. no-ship(⚠️/🚫)이면 `REPORT.md` 의 triggered rules·reasons 를 요약하고 다음 행동을 안내한다.
|
|
41
|
+
4. ship-ready(✅)면 `nekoforge apply --approved` 를 **안내만** 한다.
|
|
42
|
+
|
|
43
|
+
## 원칙
|
|
44
|
+
|
|
45
|
+
- **apply 를 자동 실행하지 않는다.** 게이트는 판정만, apply 는 사용자의 명시적 승인으로만.
|
|
46
|
+
- 차단은 exit code 로 강제된다(권고가 아니다).
|
|
47
|
+
- 이 스킬은 슬래시 명령이 아니라 스킬+CLI 로 호출한다 (프로젝트의 "슬래시 신규 금지" 정책 준수).
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 HARNESS contributors
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: "Claude 주도 + Codex 위임 7단계 풀사이클. claude-led-codex-review 스킬 호출."
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# /claude-led-codex-review
|
|
6
|
-
|
|
7
|
-
이 슬래시 명령은 `claude-led-codex-review` 스킬의 legacy compat 진입점이다. 신규 워크플로우는 스킬에서 정의되지만 슬래시 호출 호환성을 위해 보존.
|
|
8
|
-
|
|
9
|
-
## 동작
|
|
10
|
-
|
|
11
|
-
`Skill` 도구로 `claude-led-codex-review` 를 즉시 호출. 인자가 있으면 작업 요약으로 전달, 없으면 사용자에게 한 줄 요약을 요청.
|
|
12
|
-
|
|
13
|
-
## 인자
|
|
14
|
-
|
|
15
|
-
- `$ARGUMENTS` — 작업 요약 한 줄
|
|
16
|
-
- `--fast` — 단계 1·6 스킵
|
|
17
|
-
- `--secure` — 단계 6 강제
|
|
18
|
-
- `--no-ship` — 단계 7 생략
|
|
19
|
-
|
|
20
|
-
## 예시
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
/claude-led-codex-review JWT 검증 미들웨어 추가 --secure
|
|
24
|
-
/claude-led-codex-review 결제 환불 로직 버그 수정
|
|
25
|
-
/claude-led-codex-review --fast 사소한 리팩토링
|
|
26
|
-
/claude-led-codex-review 새 API 엔드포인트 --no-ship
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
전체 명세는 `skills/claude-led-codex-review/SKILL.md` 참조.
|