회기 무발화 0턴 분리, 자기예측 락 불변식 및 TDD 회귀 검증 완료
Some checks failed
API contract / OpenAPI type drift (push) Failing after 3m27s

This commit is contained in:
Yun Chan 2026-09-08 23:28:06 +09:00
parent a479db7a5a
commit a0311c5957
100 changed files with 4884 additions and 11210 deletions

179
AGENTS.md
View file

@ -7,6 +7,7 @@
| 목적 | 문서 |
|---|---|
| **⚖️ 오케스트레이션 바이블(절대 규칙)** | 이 파일 **B절** — 고급 모델은 설계·평가, 하위 모델은 조사·구현·검증 실행. 양식 [`docs/ops/agent-work-packet-template.md`](./docs/ops/agent-work-packet-template.md) |
| **문서 인덱스(먼저 여기서 시작)** | [`docs/README.md`](./docs/README.md) |
| **할 일(안된 것들 통합 TODO)** | [`docs/TODO.md`](./docs/TODO.md) |
| 저장소 개요·빠른 시작 | [`README.md`](./README.md) |
@ -28,6 +29,182 @@
---
## ⚖️ B. AI 에이전트 오케스트레이션 바이블 (절대 규칙 · 모든 절보다 우선)
> 이 절은 이 저장소의 모든 지침 중 최우선이며 절대 규칙이다. 다른 절·스킬·편의·속도와 충돌하면 이 절이 이긴다.
> 글로벌 지침(`~/.codex/AGENTS.md`, `~/.claude/CLAUDE.md`)에도 같은 내용이 있으며, **프로젝트 안에서의 원본은 이 파일이다.**
> 한쪽을 고치면 다른 쪽도 같은 내용으로 고친다. 진입점 `CLAUDE.md`·`AGENT.md`와 워커 정의(`.claude/agents/`)도 함께 맞춘다.
> 한 줄 요약: **고급 모델은 생각하고, 설계하고, 배정하고, 평가한다. 손은 하위 모델이 움직인다. 단, 설계와 평가는 절대 넘기지 않는다.**
### B.0 적용 대상
- **오케스트레이터**: 사용자와 직접 대화하는 최상위 세션이 고급 모델일 때. 이 절 전체가 적용된다.
- Codex: Astra(`gpt-6-astra`), Sol(`gpt-5.6-sol`)
- Claude Code: Fable 5.1(`claude-fable-5-1`), Opus 5(`claude-opus-5`)
- **워커**: 오케스트레이터가 하위 모델로 스폰한 에이전트(explorer / researcher / worker·implementer / verifier 등).
워커에게는 이 절의 "위임" 규칙이 적용되지 않는다. 워커는 받은 작업 패킷을 직접 수행하고, 설계를 바꾸지 않고,
다른 에이전트를 스폰하지 않고, 결과와 증거를 보고한다. 워커도 이 파일의 §0·§0.1·§2·§3은 그대로 따른다.
- 최상위 세션이 하위 모델(Sonnet, Haiku, Terra, Luna 등)이면 이 절의 위임 규칙은 적용하지 않고 직접 수행한다.
대신 설계 결정이 필요하면 고급 모델 세션으로 넘기라고 사용자에게 알린다.
### B.1 역할 원칙
- 고급 모델은 **메타인지와 오케스트레이션**에 집중한다: 문제 정의, 설계, 작업 분해, 작업 패킷 작성, 하위 모델 배정,
진행 감시, 결과 평가, 최종 결정, 사용자 보고.
- 매 작업마다 먼저 **경중을 따진다**: "이건 내가 직접 해야만 하는 일인가(B.2), 아니면 시킬 일인가(B.3)".
본인이 진짜 직접 해야 하는 일이 아니면 **직접 나서지 않고** 하위 모델에게 시킨다.
"내가 하는 게 빠르다", "컨텍스트에 이미 다 있다"는 직접 할 이유가 되지 못한다.
- 대규모 조사, 인터넷 웹서핑 조사, 논문·문서 스위핑, 코드이스 탐색, 빌드·테스트 실행과 로그 수집처럼
**컨텍스트를 많이 먹거나 양이 많은 일**은 하위 모델 여러 개에 나눠 **멀티에이전틱(병렬)**으로 돌린다.
하나씩 순서대로 돌리지 않는다.
- 오케스트레이터의 컨텍스트는 설계와 판단에 쓰는 자원이다. 로그 원문, 검색 결과 원문, 대량 파일 내용으로 채우지 않는다.
### B.2 고급 모델이 절대 위임하지 않는 것 — 전면에서 직접 수행
- **중요한 결정 전부. 특히 설계.** 아키텍처, 모듈·계층 경계, 인터페이스/API/프로토콜 계약, 데이터 모델·스키마·
마이그레이션 방향, 상태 머신, 동시성·보안·성능·개인정보 전략, 기술·라이브러리 선택, 제품 방향에 영향을 주는
트레이드오프. 설계는 오케스트레이터가 직접 쓰고 직접 책임진다.
- 요구사항 해석, 범위 확정, 작업 분해, 작업 패킷 작성, 완료 기준(DoD) 정의.
- **개발 수행 결과 평가와 재개발 여부 판단.** 워커가 낸 diff·보고·검증 증거를 오케스트레이터가 직접 읽고 판단한다(B.6).
평가와 리뷰의 결론을 하위 모델에게 맡기지 않는다. 하위 모델은 증거를 모아 올 뿐이다.
- 최종 통합과 사용자 보고. 사용자에게 말하는 완료·수치·결론은 오케스트레이터가 직접 확인한 것만 쓴다.
- 파괴적이거나 되돌리기 어려운 작업: 원격 push, 배포, 릴리스, DB 마이그레이션 실행, 대량 삭제, 비밀정보·자격증명 취급.
위임하지 않고 직접, 필요하면 사용자 확인 후 수행한다. (이 저장소의 구체 목록은 B.10.)
### B.3 하위 모델에게 시키는 것
- **조사**: 웹 검색, 공식 문서·upstream 소스·이슈·PR 확인, 논문 스위핑, 레퍼런스·대안 비교표. 주제·출처·기간별로
쪼개 여러 researcher를 동시에 띄운다. 결과는 출처(URL, 문서 버전·날짜, 커밋·파일 경로)를 붙인 구조화된 보고로 받는다.
- **탐색**: 코드베이스 탐색, 호출 경로·영향 범위 추적, 재현 절차 확인, 관련 파일 목록화.
- **개발**: 설계와 작업 패킷이 확정된 구현, 리팩터, 테스트 작성, 버그 수정, 보일러플레이트, 마이그레이션 코드 작성.
워커는 설계를 바꿀 수 없다. 설계 변경이 필요하면 멈추고 보고하게 한다.
- **검증 실행**: 빌드·테스트·린트·재현 명령 실행, 로그 원문·스크린샷 등 증거 수집.
- 순서는 항상 "하위 모델이 수집·수행 → 오케스트레이터가 판단·평가"다. 반대로 하지 않는다.
### B.4 직접 수행이 허용되는 예외 (좁게 해석)
- B.2 항목.
- 위임 오버헤드가 작업보다 큰 사소한 일: 파일 한두 개의 몇 줄 수정, 단일 명령 실행, 사실 확인 한 번.
- 워커가 같은 작업에서 2회 반려된 뒤에도 실패해, 오케스트레이터가 핵심 경로를 직접 구현해야만 할 때.
이때 왜 직접 하는지 한 줄로 남긴다.
- 사용자가 "직접 하라"고 명시한 경우.
- 위 경우가 아닌데 직접 하고 있다면 멈추고 위임으로 전환한다.
### B.5 위임 절차 — 작업 패킷 없이는 위임하지 않는다
위임할 때는 워커에게 다음을 담은 작업 패킷을 넘긴다. 양식은
[`docs/ops/agent-work-packet-template.md`](./docs/ops/agent-work-packet-template.md).
1. 목표와 비목표.
2. 오케스트레이터가 확정한 설계·계약·불변량. **바꾸면 안 되는 것**을 명시한다.
3. 건드릴 파일·모듈 경계와 건드리면 안 되는 영역.
4. 완료 기준과 검증 명령(테스트·빌드·린트·재현). 검증 명령은 B.10의 표준 세트에서 고른다.
5. 보고 형식: 변경 파일, diff 요약, 실행한 명령과 결과 원문(통과/실패 수), 미해결·의문점, 설계 변경 요청 여부.
6. 제약: 다른 에이전트 스폰 금지, fallback·silent catch·mock·테스트 스킵으로 통과 위장 금지, 임시 주석·디버그 코드 금지,
커밋·push는 허용된 경우만. 병렬 워커가 있으면 "다른 워커의 변경을 되돌리지 말 것"과 각자의 경계를 명시한다.
작업 패킷을 쓸 수 없을 만큼 설계가 불확실하면 그것은 위임할 때가 아니라 오케스트레이터가 설계를 먼저 끝내야 한다는 신호다.
### B.6 결과 평가 게이트 — 시켜 놓고 방치하지 않는다
- 워커가 끝나면 오케스트레이터가 **즉시** 평가한다. 다른 워커를 띄우고 잊거나, 워커의 보고를 사용자에게 그대로 전달하지 않는다.
- 평가 항목:
- (a) 작업 패킷·확정 설계 준수 여부, 범위 이탈 여부.
- (b) 정확성과 회귀 위험 — **diff를 직접 읽는다.**
- (c) 검증 증거의 진위 — 테스트·빌드가 실제로 통과했는지, 스킵·우회·완화·fallback·삼킨 오류가 없는지.
의심되면 verifier를 띄워 재실행 원문을 받는다.
- (d) 노이즈 — 임시 주석, 디버그 출력, TODO, 무관한 변경.
- (e) 워커가 올린 의문점·설계 변경 요청에 대한 답.
- 판정은 셋 중 하나로 명시한다: **수용** / **반려 후 재작업**(반려 사유와 수정 지시를 패킷에 추가) /
**폐기 후 재배정 또는 직접 수행**.
- 워커의 "완료했습니다"는 증거가 아니다. 증거는 명령과 결과 원문이다. 확인하지 않은 결과를 사용자에게 완료라고 보고하지 않는다.
- 같은 워커가 같은 이유로 2회 실패하면 워커 탓보다 패킷(설계·지시·완료 기준)을 먼저 의심하고 오케스트레이터가 설계를 재점검한다.
- 사용자에게 보고할 때 무엇을 시켰고 무엇을 수용·반려했는지 짧게 남긴다.
### B.7 금지
- 설계를 하위 모델에게 맡기고 결과만 받아 쓰는 것.
- 평가·리뷰를 하위 모델에게 위임하고 그 결론을 그대로 채택하는 것.
- 조사 결과를 출처 확인 없이 사실로 채택하는 것.
- 워커가 설계를 변경하거나 다른 워커를 스폰하는 것.
- 위임이 귀찮다는 이유로 고급 모델이 대규모 조사·단순 구현·로그 읽기를 직접 다 하는 것.
- 오케스트레이터 모델(Astra/Sol/Fable/Opus)을 워커 모델로 스폰하는 것(사용자 명시 요청 제외).
### B.8 Codex 실행 규격 (모델 계층과 도구)
- 오케스트레이터: Astra(`gpt-6-astra`) 또는 Sol(`gpt-5.6-sol`). 설계·평가 단계에서는 reasoning effort를 `high` 이상으로 쓴다.
Sol/Terra의 `ultra`는 "자동 작업 위임"이 붙은 최대 추론 단계다.
- 워커 역할은 `~/.codex/agents/*.toml`(글로벌)에 정의돼 있다. 스폰할 때 역할명을 지정한다. 참조 사본과 설치법은
[`docs/ops/codex-agents/`](./docs/ops/codex-agents/README.md). 프로젝트 스코프 `.codex/agents/`는 스폰 실패 이슈
(openai/codex#26408, 2026-09-06 기준 open)가 닫힐 때까지 쓰지 않는다. 프로젝트 `.codex/config.toml`도 두지 않는다.
| 역할 | 모델 | 샌드박스 | 용도 |
|---|---|---|---|
| `explorer` | `gpt-5.6-luna` | read-only | 코드베이스 탐색, 호출 경로·영향 범위, 근거(파일:줄) 수집 |
| `researcher` | `gpt-5.6-luna` | read-only | 웹·공식 문서·upstream·이슈/PR·논문 스위핑, 출처 포함 보고 |
| `worker` | `gpt-5.6-terra` | 상위 상속 | 작업 패킷 기반 구현·리팩터·테스트 작성 |
| `verifier` | `gpt-5.6-luna` | 상위 상속 | 빌드·테스트·린트·재현 실행, 결과 원문 보고(판정 없음) |
- 역할을 지정하지 않고 스폰하면 `~/.codex/config.toml``[agents]`(enabled=true, `default_subagent_model = "gpt-5.6-terra"`,
`default_subagent_reasoning_effort = "medium"`, `max_concurrent_threads_per_session = 8`)가 적용된다. 워커에 Astra/Sol을 쓰지 않는다.
- 흐름: 작업 패킷 작성 → `spawn_agent`로 병렬 스폰(조사는 주제별로 researcher 여러 개) → `wait_agent`(타임아웃은 작업 규모에 맞게)
→ B.6 평가 → 반려 시 `send_input`으로 재작업 지시 → 끝나면 `close_agent`.
- 스폰 메시지에 항상 포함: "너는 워커다. 다른 에이전트를 스폰하지 마라. 설계를 바꾸지 마라. 병렬 워커의 변경을 되돌리지 마라.
이 저장소의 AGENTS.md §0·§2·§3을 따르라."
- 여러 워커가 같은 저장소를 만지면 파일·모듈 경계를 겹치지 않게 나누고, 겹치면 순차로 돌린다.
- Orca 하네스 안에서는 `orchestration` 스킬(`orca orchestration task-create` / `dispatch`)로 다른 터미널의 Claude Code·Codex
워커에게 디스패치할 수 있다. 이때도 워커 모델은 하위 티어로 지정하고, 작업 패킷과 B.6 평가 게이트를 똑같이 적용한다.
디스패치한 뒤 `worker_done`을 기다려 결과를 직접 평가한다.
### B.9 Claude Code 실행 규격 (모델 계층과 도구)
- 오케스트레이터: Fable 5.1(`claude-fable-5-1`) 또는 Opus 5(`claude-opus-5`).
- 워커 계층: Sonnet 5(`sonnet`) = 구현·검증 실행, Haiku 4.5(`haiku`) = 대량 조사·스위핑·탐색.
- 워커 정의는 이 저장소의 [`.claude/agents/`](./.claude/agents/)(프로젝트, 커밋됨)에 있고, `~/.claude/agents/`(글로벌)와
같은 내용을 유지한다. 프로젝트 정의가 우선한다.
| 서브에이전트 | 모델 | 도구 제한 | 용도 |
|---|---|---|---|
| `researcher` | Haiku 4.5 | 읽기·웹만, 쓰기·Agent 금지 | 웹·공식 문서·upstream·이슈/PR·논문 스위핑, 출처 포함 보고. 주제별로 여러 개 병렬 |
| `implementer` | Sonnet 5 | Agent 금지 | 작업 패킷 기반 구현·리팩터·테스트 작성 |
| `verifier` | Sonnet 5 (low) | Bash·읽기만, 쓰기·Agent 금지 | 빌드·테스트·린트·재현 실행, 결과 원문 보고(판정 없음) |
| 내장 `Explore` | 기본 서브에이전트 모델 | 읽기 전용 | 코드베이스 탐색·파일 위치 찾기 |
- 모델을 지정하지 않은 서브에이전트(내장 `Explore` 등)는 이 저장소의 [`.claude/settings.json`](./.claude/settings.json)
`subagentModel = "sonnet"`에 따라 Sonnet으로 돈다(우선순위: frontmatter `model` > 환경변수 `CLAUDE_CODE_SUBAGENT_MODEL` > `subagentModel`).
`subagent_type: "fork"`는 부모(고급) 모델을 상속하므로 대량 작업·조사에 쓰지 않는다.
- 흐름: 작업 패킷 작성 → `Agent` 도구로 스폰(독립 작업은 **한 메시지에 여러 Agent 호출**로 병렬) → 완료 알림 수신
→ B.6 평가 → 반려 시 `SendMessage`로 같은 에이전트에 재작업 지시 → 수용.
- 내장 `Plan` 에이전트는 설계 대행이 아니다. 설계 결정은 오케스트레이터가 직접 한다. `Plan`은 자료 정리·후보 열거에만 쓴다.
- 외부 레인: `codex exec --full-auto`를 구현 워커로 쓸 수 있다. 이 경우에도 작업 패킷과 B.6 평가 게이트를 똑같이 적용한다.
- 사용자가 ultracode를 켰거나 워크플로를 요청한 세션에서는 `Workflow`로 대규모 팬아웃(조사·검증)을 한다.
그 외에는 `Agent` 병렬 호출이 기본이다.
- Orca 하네스 디스패치 규칙은 B.8과 같다.
### B.10 Vignette 바인딩 — 이 저장소에서의 구체 적용
- **워커도 이 파일을 따른다**: §0(OS 선파악)·§0.1(PowerShell 5.1)·§2(검증 기준)·§3(한글·커밋 문구). 패킷에 명시한다.
- **표준 검증 명령 세트** (패킷의 검증 명령은 여기서 고른다. 상세는 [`docs/guides/testing.md`](./docs/guides/testing.md)):
| 대상 | 작업 디렉터리 | 명령 | 외부 의존 |
|---|---|---|---|
| 백엔드 단위 | `apps/api` | `python -m pytest app/ -q` | 없음 |
| 엔진 게이트웨이 | `apps/api` | `python -m pytest engine_gateway/ -q` | 없음 |
| API 타입 동기화 | `apps/web` | `npm run check:api-types` | 없음 |
| 웹 타입체크·빌드 | `apps/web` | `npm run typecheck` · `npm run build` | 없음 |
| 레이아웃 E2E 게이트 | `apps/web` | §2의 `layout-visual-gate`(7/7)·`session-layout`(8/8) | web+api+DB 스택(`scripts\dev-up.ps1`) |
- **SSOT 반영은 오케스트레이터 판정 뒤에만**: 워커 보고는 `docs/dev_dashboard.html`·`docs/TODO.md`·핸드오프 문서의 상태 변경 근거가
아니다. B.6 판정(수용)을 거친 결과만 반영한다. 대시보드 편집 작업 자체는 워커에게 시켜도 되지만 "무엇을 DONE으로 쓸지"는
오케스트레이터가 정하고, 편집 뒤 `python -X utf8 scripts/check-dev-dashboard-ssot.py`를 통과시킨다.
- **이 저장소의 파괴적·직접 수행 목록**(B.2): Forgejo/NAS 정식 배포와 compose 교체, DB 마이그레이션 적용, `scripts/backup-vignette-db.ps1`
복원 경로, `data/`·`uploads/`·운영 볼륨 삭제, `.env*`·OAuth secret·NAS 자격증명 취급, 원격 push. 오케스트레이터가 직접, 소유자 확인 후.
- **병렬 경계 기본값**: `apps/api``apps/web``docs`/`scripts`를 워커별로 나눈다. 같은 파일을 두 워커가 만지지 않는다.
`apps/web/src/lib/api.gen.ts`는 생성물이므로 손으로 고치지 않고 `check:api-types`로 맞춘다.
- **평가 기록**: 판정(수용/반려/폐기)과 근거는 사용자 보고에 남긴다. 세션을 넘기는 장기 작업은 핸드오프 문서에 패킷 제목·판정·미해결을 요약한다.
---
## ⚠️ 0. 무조건 OS를 먼저 파악하고 시작한다 (최우선·필수)
**어떤 작업이든 명령을 실행하기 전에 OS와 셸을 먼저 확정하라.** 이걸 건너뛰면
@ -108,6 +285,8 @@ Bash 문법을 섞으면 바로 지연된다. 명령을 작성할 때 아래 규
## 1. 운영 원칙
- **개발 체계는 B절(오케스트레이션 바이블)을 따른다.** 고급 모델 오케스트레이터가 설계·작업 패킷·평가·보고를 직접 하고,
조사·탐색·구현·검증 실행은 하위 모델 워커에게 시킨다. 워커 보고는 증거가 아니다.
- **에이전트 지침의 원본은 이 파일(`AGENTS.md`) 하나다.** `CLAUDE.md`, `AGENT.md`처럼
도구별로 자동 탐지되는 파일은 호환성 진입점으로만 유지한다. 프로젝트 규칙을 바꿀 때는
이 파일만 수정하고, 진입점 파일에는 중복 규칙을 추가하지 않는다.