AGENTS.md · diff

git:20260918.89f2481 to git:20260918.b6f9e43

29 added, 23 removed. Audit A to A.

- # jev-gate 구현 지침 (V4)
+ # jev-gate 구현 지침 (V5)
- 명세는 GitHub 이슈가 소유한다: [#9 PRD](https://github.com/MongLong0214/jev-gate/issues/9) → [#10 ADR](https://github.com/MongLong0214/jev-gate/issues/10) → [#11](https://github.com/MongLong0214/jev-gate/issues/11)~[#18](https://github.com/MongLong0214/jev-gate/issues/18). #1–#8은 역사 기록이다. 추가 PRD 사본·승인 JSON·문서 validator·review ledger·오케스트레이션 프레임워크를 만들지 않는다.
+ 명세는 GitHub 이슈가 소유한다: [#21 PRD](https://github.com/MongLong0214/jev-gate/issues/21) → [#22 ADR](https://github.com/MongLong0214/jev-gate/issues/22) → [#23](https://github.com/MongLong0214/jev-gate/issues/23)~[#31](https://github.com/MongLong0214/jev-gate/issues/31). ADR 본문의 r2 개정(A1–A16)이 그보다 앞선 문장을 덮어쓴다. #1–#18은 V3·V4 역사 기록이다. 추가 PRD 사본·승인 JSON·문서 validator·review ledger·오케스트레이션 프레임워크를 만들지 않는다.
## 구조
- | 경로 | 역할 |
- | --- | --- |
- | `.claude-plugin/plugin.json`, `hooks/hooks.json` | 매니페스트; `UserPromptSubmit` 1개 + `^Agent$`에 `PreToolUse`/`PostToolUse`/`PostToolUseFailure` 각 1개, 모두 `node "${CLAUDE_PLUGIN_ROOT}/dist/hook.js"` timeout 5 |
- | `agents/worker.md`, `agents/planner.md` | `jev-gate:worker`(sonnet, Read/Grep/Glob/Edit/Write/Bash), `jev-gate:planner`(opus, Read/Grep/Glob); 둘 다 Agent·SendMessage 금지 |
- | `src/hook.ts` | 이벤트 디스패치. `JEV_GATE_MODE=off`는 config 읽기 전에 종료. UserPromptSubmit=고정 지침(Jev 0), PreToolUse:Agent=적격성→Jev 최대 1회→전체 입력 패치 또는 보존, Post*=관측만 |
- | `src/brief.ts` | `checkEligibility`(#10 §4), `patchAgentInput`(원문이 정확한 prefix, model/prompt만 변경), suffix ≤1 KiB, 출력 ≤512 KiB |
- | `src/jev.ts` | 고정 endpoint POST 1회, headers+body 단일 deadline, retry 0, Choice 엄격 검증, `decideTask`(context 우선, abstain/동률/floor 미달=보존) |
- | `src/coordinator.ts` | 공통 지침 + 모드 문장. `JEV_GATE_EXPERIMENT_ALLOCATION`은 벤치 고정 역할 control 전용 |
- | `src/config.ts` | ConfigV4(version 4, off/native/auto 기본 off). V3 레이아웃은 거부 + 마이그레이션 샘플 |
- | `src/trace.ts` | opt-in 로컬 기록: phase별 파일, 0700/0600, 원자적 쓰기, symlink 거부, 조인 키는 파일 안에 |
- | `src/auth.ts` | 엄격한 `claude auth status` 파서(정상 종료+JSON 객체), SUBAGENT_MODEL override 분류 |
- | `src/cli.ts` | `doctor`만. 추론 0 |
- | `src/bench/{run,report,paths,checker,usage}.ts` | 5 arm 실행기(계획=stdout만, 실행=배타적 새 out+입력 동결+dispatch intent), 계획 우선 보고, 안전 경로/스냅샷, checker 프로토콜, 엄격 숫자 |
- | `bench/v4/` | V4 평가 job 4개(fixture·checker·reference). `bench/` 루트의 4개는 V3 개발 fixture |
- | `bench/results/` | run-1(V3)·v4-host 관측 등 공개 가능한 집계만. 원자료는 저장소 밖 |
+ 호스트 중립 코어와 Claude Code 어댑터를 구분한다. 코어에는 벤더 모델 이름이 들어가지 않는다(V6 Codex 어댑터가 같은 정책을 그대로 쓴다).
+ | 경로 | 층 | 역할 |
+ | --- | --- | --- |
+ | `src/types.ts` | 코어 | tier(fast/standard/deep/frontier), 6개 owned agent 매핑, ConfigV5, PlannedTask/PlannerReply/WorkerReply, JobState, 닫힌 코드 유니온 |
+ | `src/config.ts` | 코어 | ConfigV5(version 5, 기본 off). V3·V4 레이아웃은 거부 + 마이그레이션 샘플 |
+ | `src/jev.ts` | 코어 | 고정 endpoint POST 1회, headers+body 단일 deadline, retry 0, Choice 엄격 검증, tier 설명 텍스트 |
+ | `src/admission.ts` | 코어 | Gate A 질문과 판정(direct/orchestrated/needs_context/abstain, floor 미달은 direct 보존) |
+ | `src/allocation.ts` | 코어 | Gate B(planner tier, worker tier + upgrade_basis), Gate C(result, advisory) 질문과 판정 |
+ | `src/plan.ts` | 코어 | JSON 추출·검증, `contract_hash`, `[JEV_TASK rev=<n> id=<id> attempt=<n>]` 마커, 계약 합성, 결정적 수락 판정 |
+ | `src/job.ts` | 코어 | `(session_id, prompt_id)` 세대별 상태 파일, 예약, 상한, 히스토리. 0700/0600, 원자적 쓰기, symlink 거부, pid 기반 stale lock |
+ | `src/coordinator.ts` | 코어 | 고정 지침·거부 사유·컨텍스트 문구. `JEV_GATE_EXPERIMENT_ADMISSION`은 벤치 강제 오케스트레이션 전용 |
+ | `src/hook.ts` | 어댑터 | 이벤트 디스패치. `JEV_GATE_MODE=off`는 상태·config 읽기 전에 종료 |
+ | `src/brief.ts` | 어댑터 | 적격성, allow-list 가드, 입력 패치(원문이 정확한 prefix), 출력 ≤512 KiB |
+ | `src/cli.ts` | 어댑터 | `doctor`만. 추론 0 |
+ | `hooks/hooks.json`, `agents/*.md` | 어댑터 | UserPromptSubmit·PreToolUse(matcher 없음)·PostToolUse/Failure(`^Agent$`)·Stop; worker 4종 + planner 2종, 모두 Agent·SendMessage 금지 |
+ | `src/bench/{run,report,paths,checker,usage}.ts` | 도구 | 7 arm 실행기(계획=stdout만, 실행=배타적 새 out + 입력 동결 + 셀별 state dir + 부모 환경 차단), 계획 우선 보고, checker 프로토콜 |
+ | `bench/v5/`, `bench/v4/` | 도구 | 평가 job·checker·reference. V4는 개발 데이터로 보존 |
+ | `bench/results/` | 기록 | 공개 가능한 집계만. 원자료는 저장소 밖 |
+
## 규칙
- - hook는 exit 0만. `permissionDecision`/`decision:block`/`continue:false`/exit 2 금지. 패치는 `updatedInput`로 전체 입력을 돌려주고 권한을 승인하지 않는다.
- - 적격 조건 전부 충족 시에만 Jev 1회. 명시 model(null/빈 문자열 포함)·resume/name/team/isolation·child 호출·다른 agent·background·구체적 `CLAUDE_CODE_SUBAGENT_MODEL`/FORCE·fork 강제는 무조건 보존. `run_in_background` 부재는 `CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1`일 때만 foreground로 본다(2.1.275 관측).
- - 불확실·invalid·timeout·키 없음은 **원래 입력 보존**. 낮은 confidence를 Fable로 올리지 않는다.
- - TypeSafe로 가는 것은 위임 prompt/description과 고정 criteria다(코드·이전 제약 포함 가능). 저장소·transcript·credential을 훅이 스스로 읽지 않는다. 키는 Authorization 헤더 외 어디에도 없다.
- - 회계: intent 기록이 없으면 "안 보냄"이 아니라 "모름". 실패 후에도 소비는 가능. 빈 usage는 0이 아니다. Fable 0은 완전한 모델 식별이 있을 때만.
- - 벤치: 계획 행이 분모. 누락 파일은 not_started가 아니다. 유리한 결과 선택·checker 사후 조정 금지(결함은 기록하고 전원 재채점, 이력 보존).
+ - hook는 언제나 exit 0. 오케스트레이션이 활성일 때의 root 가드만 `permissionDecision: "deny"`를 반환하고, `allow`는 절대 반환하지 않는다. 패치는 `updatedInput`으로 전체 입력을 돌려주며 권한을 승인하지 않는다.
+ - 가드는 allow-list다. 목록 밖 도구는 고정 사유로 거부하고, 한 프롬프트에서 예산을 소진하면 `continue:false`로 끝낸다. child 호출(`agent_id` 있음)은 절대 가드하지 않는다.
+ - 수락은 코드가 소유한다. `done` + blockers 없음 + 모든 required check가 정확히 한 번 `pass`여야 의존 작업이 열린다. Gate C는 자문이며 readiness를 바꾸지 못한다.
+ - 불확실·invalid·timeout·키 없음은 **원래 호출 보존**. 낮은 confidence를 상위 tier로 올리지 않는다. deep/frontier는 구체적 upgrade basis가 있어야 한다. abstain은 호출된 프로필을 유지한다.
+ - `prompt_id`가 없으면 오케스트레이션도 가드도 없다. 새 프롬프트는 이전 세대를 히스토리로 밀어내고, 늦게 도착한 결과는 기록만 하며 현재 계획을 진행시키지 않는다. HTTP 후에는 세대와 rev를 다시 확인한 뒤 적용한다.
+ - TypeSafe로 가는 것: auto에서 사용자 요청(Gate A), 합성된 task 계약과 선행 결과 요약(Gate B), worker 구조화 응답(Gate C). 저장소·transcript·credential을 훅이 스스로 읽지 않는다. 키는 Authorization 헤더 외 어디에도 없다. 신뢰 순서는 사용자 제약·네이티브 권한 > 계약 > worker 보고 사실 > route note.
+ - 회계: intent 기록이 없으면 "안 보냄"이 아니라 "모름". 실패 후에도 소비는 가능. 빈 usage는 0이 아니다. 요청한 프로필·실제 모델·실제 effort는 서로 다른 사실이다. haiku는 frontmatter effort가 적용되지 않는다(2026-09-18 관측).
+ - 벤치: 계획 행이 분모. 누락 파일은 not_started가 아니다. 측정 세션은 부모 환경을 상속하지 않는다(`CLAUDE_*` 제거). 유리한 결과 선택·checker 사후 조정 금지(결함은 기록하고 전원 재채점, 이력 보존). arm을 뺄 때는 결과를 보기 전에 근거를 기록한다.
- 변경 후 `npm run typecheck && npm test && npm run build && claude plugin validate . --strict`를 실제 실행하고 결과를 그대로 보고한다. 테스트는 fake HTTP·fake CLI만 사용하며 키/로그인이 필요 없다.
- 구현 완료 / 설치 호스트 관측 / 측정된 제품 효과는 서로 다른 완료다. 요청 없이 release/npm publish/marketplace/홍보를 하지 않는다.