. 내 패턴
7. 내 패턴
한 줄 요약
Claude는 기획·검사·적대검증하는 “머리”, Codex는 정해진 규칙 안에서만 글을 쓰는 “손”으로 나누고, 손이 만든 결과물을 컴퓨터가 결정적 규칙으로 다시 검사·재조립하는 이중모델 하네스다. 왜 배우나 — 내가 실제로 쓰는 작업 방식을 한 장으로 정리하면, “LLM을 어떻게 길들여 신뢰할 수 있는 파이프라인으로 만드는가”라는 이 교재 전체의 질문에 내 패턴이 어떤 답을 내놓는지 스스로 평가할 수 있기 때문이다.
그림
flowchart TD
subgraph 머리["Claude · 오케스트레이터/게이트/적대검증"]
H1["헌법 SSoT<br/>CLAUDE.md / AGENTS.md"]
H2["큐·체크포인트<br/>디스크 영속"]
end
subgraph 손["Codex · 제한된 변환기"]
W1[격리된 쓰기 워커]
end
H1 --> P1
subgraph 파이프라인[결정적 파이프라인]
P1["prepare<br/>관계 타깃 사전 주입"] --> P2["runner<br/>타깃 변경 금지"]
P2 --> W1
W1 --> P3["admit<br/>본문 무결성±15%"]
P3 --> P4["validate<br/>파생값 금지 코드 강제"]
P4 --> P5["build<br/>canonical 재구축"]
end
P5 --> G{"gate<br/>물리 게이트 exit 2"}
G -->|통과| OUT["정본 + Vercel 배포"]
G -->|실패| Q["quarantine<br/>사람이 직접 확인"]
H2 -. 세션 단절 시 완전 재개 .-> P1
쉽게 풀기
회사로 비유하면 이렇다.
- 머리와 손을 분리한다. Claude(머리)는 “무엇을, 어떤 순서로, 합격 기준은 무엇인지”를 정하고 검사만 한다. Codex(손)는 실제로 글을 쓴다. 머리가 손이 쓴 글을 자기 머릿속(컨텍스트)에 통째로 담지 않기 때문에, 손의 실수가 머리를 오염시키지 못한다.
- 손에게 “창작”을 안 시키고 “변환”만 시킨다. 자유롭게 쓰라고 하면 LLM은 없는 내용을 지어낸다. 그래서 미리
prepare단계에서 “이 글이 연결될 대상”을 정규화해 못 박아 두고(edge-map), 손에게는 “이 목록을 추가/삭제/변경하지 마라”고 명령한다. 손은 빈칸을 채우는 변환기일 뿐이다. - 손이 낸 결과물은 컴퓨터가 다시 검사한다. 사람 눈이 아니라 코드가 검사한다. 본문 길이가 원래보다 ±15% 넘게 변하면 거부(admit), 계산으로 만들 수 있는 값(점수·ID)을 글에 박아 넣으면 거부(validate). 마지막 관문(gate)은 통과 못 하면 프로그램이
exit 2로 멈춘다 — 차단막이 문서가 아니라 코드다. - 일이 끊겨도 처음부터 안 한다. 큐·시도횟수·진행 단계가 전부 파일로 저장돼 있어서, 컴퓨터가 꺼졌다 켜져도 멈춘 지점부터 이어간다.
- 배운 것을 세션 너머로 쌓는다. MEMORY.md 인덱스와 프로젝트 노트(LLM Wiki)에 “함정·결정”을 압축해 두어, 다음 대화의 Claude가 같은 실수를 반복하지 않는다.
핵심 한 문장: LLM의 비결정성(제멋대로 굴음)을 파이프라인의 양 끝에서 봉인한다.
핵심 정리
| 기둥 | 무엇 | 근거 파일 |
|---|---|---|
| 이중모델 분업 | Claude=머리, Codex=손 | /mnt/d/akh2/CLAUDE.md |
| 제한된 변환기 | 타깃 사전주입 + 변경금지 | prepare.mjs / runner.mjs |
| 코드화된 검증 | admit·validate·gate | admit.mjs/validate.mjs/gate.mjs |
| 영속 상태 | 디스크 큐로 완전 재개 | runtime-state·attempts.jsonl |
[!note] 10축 점수 (종합 평균 4.2)
- 컨텍스트엔지니어링 5 · 오케스트레이션 5 · 검증루프 5 · 철학/차별점 5
- 아키텍처 4 · 툴/확장 4 · 가드레일 4 · 상태/영속 4
- 자기개선 3 · 배포/DX 3
- 보정 사연: Claude 초안 4.6 → Codex 교차검증으로 아키텍처·가드레일·상태영속(5→4)·자기개선·배포DX(4→3) 하향. “운영 안전/배포 완성도”를 과대평가했던 부분을 코드 대조로 깎았다.
[!note] 독창적 아이디어 7가지
- 이중모델 비대칭 분업 — 컨텍스트 오염을 모델 경계로 차단
- LLM = 제한된 변환기 — edge-map 주입 + 타깃 변경 금지(Codex가 꼽은 진짜 핵심)
- 파생값 추방 — 계산 가능한 값은 저장 금지, build가 매번 재생성해 drift 차단
- codex_d.sh 격리 래퍼 — XDG/TMPDIR/npm/Playwright를 D로 리다이렉트, C드라이브 무흔적(단 akh2 러너는 미경유, 아래 tip 참조)
- 9p 병목을 설계 제약으로 — ext4 스테이징 후 admit 통과분만 D로 이동
- supersedes 보존 lifecycle — 틀린 내용도 덮지 않고 valid_to 기록, ‘변화 서사’를 강의 자산으로
- 로그 채널 물리 분리 — Claude가 직접 읽는 채널을 quarantine 하나로 제한
[!note] 강점 ↔ 약점 (균형 보기) 강점 — 검증 독립성이 코드로 제도화(자체승인 금지) · 4계층 장애복원(timeout/재시도/quarantine/lease·watchdog) · 컨텍스트 예산이 1급 제약 · 결정적 파이프라인 · 회고 주도 재설계. 약점 — 하네스 레벨 자동강제(커스텀 hooks) 부재 · 전역 안전설정 느슨(approval_policy on-failure, system32 trusted, skipDangerous=true) · Codex 단일계정 단일장애점 · 자동화 트리거 약함(수작업 의존) · 배포 문서/코드 불일치 · 헌법 문서 거대화 · 비밀정보 평문 기록.
실제 예시
언어 구성: Markdown(헌법·SCHEMA) · JavaScript/Node(.mjs 파이프라인) · Python(_scripts) · Bash(codex_d.sh) · TypeScript(Next.js 앱) · TOML(.codex/config.toml) · JSON/JSONL(상태·샤드·메모리).
# 결정적 파이프라인 단계 (akh2)
prepare → runner → admit → validate → build → gate
# 핵심 강제 지점
prepare.mjs : 관계 타깃을 build/edge-map.json에 사전 정규화 (워커 자유생성 금지)
runner.mjs : spawn('codex','exec',...) 직접 호출, 기본 gpt-5.4-mini,
프롬프트에 "타깃 추가/삭제/변경 절대 금지"
admit.mjs : 본문 단어수 무결성 ±15% 벗어나면 차단
validate.mjs : forbidden-derived-field — 파생값(quality_score 등) 박으면 FAIL
gate.mjs : 물리 게이트, 미통과 시 exit 2
# 4계층 장애처리 (akh2 §7)
1) timeout 480s → SIGKILL → 재시도
2) lease TTL 5분 + watchdog (죽은 러너 회수)
3) 429 → 병렬도 강하(백오프)
4) 2회 실패 → quarantine (사람 검토)
# 영속 상태 (세션 단절 시 완전 재개)
큐 · attempts.jsonl · runtime-state.json · phase 체크포인트 → 전부 디스크
# /home/seunghyeong/.codex/config.toml ← 전역 설정(느슨함, 약점 지점)
approval_policy = "on-failure"
# trusted: /tmp · /home · C:\WINDOWS\system32 (광범위)
// /home/seunghyeong/.claude/settings.json
{ "skipDangerousModePermissionPrompt": true } // 안전 훅 부재 지점
// settings.local.json 에는 sudo npm 허용
요약 & 셀프체크
3줄 요약
- 머리(Claude)와 손(Codex)을 모델 경계로 분리해 컨텍스트 오염을 막는다.
- 손에게 창작이 아닌 “정해진 변환”만 시키고, 결과는 코드(admit/validate/gate)가 검사한다.
- 모든 상태를 디스크에 영속해 세션이 끊겨도 완전 재개하고, LLM Wiki로 교훈을 누적한다.
셀프체크
- 이 하네스가 LLM의 비결정성을 봉인하는 두 지점(파이프라인 양 끝)은 각각 어디인가? (힌트: prepare / admit·validate·gate)
- “파생값 추방”이 막으려는 문제는 무엇이고, 코드로 어떻게 강제되는가?
- 점수가 5→4, 4→3으로 깎인 축들의 공통 원인은 무엇이었나? (힌트: 메모리가 아닌 코드를 1차 근거로)
연결
기능별 분해 — 하네스를 진입점부터 검증 게이트까지 9개 축으로 쪼갠 노트(번호순: 로딩→조립→확장점→도구→안전→상태→파이프라인).
- MINE_10_entrypoint-plugin-loading — 진입점과 플러그인 로딩: settings.json → 마켓플레이스 → 플러그인 활성화
- MINE_20_prompt-assembly-claudemd — 컨텍스트·프롬프트 조립: CLAUDE.md @-import 체인과 ‘헌법’ 구조
- MINE_30_hooks-lifecycle — 확장점 Hooks: 이벤트 라이프사이클과 system-reminder 주입(현재 미활용 약점)
- MINE_40_skills-and-slash-commands — 확장점 Skills/Slash-Commands: SKILL.md 프론트매터와 트리거 매칭
- MINE_50_subagents-format — 확장점 Subagents: 에이전트 .md 정의 형식과 모델 라우팅
- MINE_60_tool-system-mcp-bridge — 도구 시스템: MCP 브리지와 도구 정의·노출
- MINE_70_guardrails-permissions-sandbox — 가드레일: 권한·승인·샌드박스(codex_d.sh 봉인 ↔ 전역 설정 느슨함 충돌)
- MINE_80_state-memory-persistence — 상태·메모리 영속성: 다층 메모리(LLM Wiki)와 디스크 세션 상태
- MINE_90_pipeline-gates-receipts — 고유 기능: 파이프라인 검증 게이트와 영수증(admit/gate/claim-card)
분석 프레임 — _분석축_루브릭 · HOME · _비교매트릭스
핵심 파일
/home/seunghyeong/.claude/settings.json— skipDangerousModePermissionPrompt:true/home/seunghyeong/.claude/settings.local.json— sudo npm 허용/home/seunghyeong/.codex/config.toml— approval_policy on-failure, /tmp·/home·system32 trusted, 전역 gpt-5.5/home/seunghyeong/.claude/projects/-home-seunghyeong/memory/MEMORY.md— LLM Wiki 인덱스/mnt/d/akh2/CLAUDE.md— SSoT 헌법/mnt/d/akh2/pipeline/prepare.mjs— edge-map 사전 정규화(워커 자유생성 금지)/mnt/d/akh2/pipeline/runner.mjs— 직접 spawn(‘codex’), 기본 gpt-5.4-mini, 타깃 변경 금지 프롬프트/mnt/d/akh2/pipeline/admit.mjs— 본문 무결성(±15%) 차단/mnt/d/akh2/pipeline/validate.mjs— forbidden-derived-field 코드 강제/mnt/d/akh2/pipeline/gate.mjs— 물리 게이트(exit 2)/mnt/d/ai-knowledge-hub/CLAUDE.md·/mnt/d/ai-knowledge-hub/AGENTS.md·/mnt/d/ai-knowledge-hub/PROGRAM.md/mnt/d/ai-knowledge-hub/_scripts/codex_d.sh— C드라이브 무흔적 격리 래퍼(v1)/mnt/d/human-token-workflow/AGENTS.md— writer≠reviewer, 자체승인 금지/home/seunghyeong/projects/image-platform/DEPLOY.md— QStash 교체 대상, Hobby 60s/home/seunghyeong/projects/image-platform/src/lib/jobs/local.ts— LocalJobQueue 인메모리(실제 큐)
[!tip] Claude ↔ Codex 교차검증 (불일치가 곧 학습 포인트) Claude 초안은 큰 방향은 맞았으나 “운영 안전/배포 완성도”와 “모든 Codex 호출 격리”를 과대평가했고, 아래 Codex 지적은 직접 소스 대조로 전부 사실 확인됨. (1) 사실 오류 — conclave/image-platform의
AGENTS.md는 Next.js 주의문(<!-- nextjs-agent-rules -->)일 뿐, 아키텍처 근거는docs/SPEC.md다. “모든 Codex 호출은 codex_d.sh 경유”는 v1(ai-knowledge-hub)만 사실 — akh2 러너는spawn('codex',['exec',...])로 직접 호출(runner.mjs:160), 기본 모델도gpt-5.4-mini(runner.mjs:36)이지 gpt-5.5가 아니다(전역 config.toml과 혼동). “QStash 큐”는 과장 — 실제는LocalJobQueue(인메모리). Vercel 시간상한 충돌(Hobby 60s vs 300s). (2) 빠뜨린 핵심 — 진짜 강점은 문서 규율보다 결정적 파이프라인, 파생값 금지를 코드로 강제(validate/admit), 전역 Codex 설정 리스크, Claude 안전 훅 없음. (3) 점수 보정 — 아키텍처 5→4 / 가드레일 5→4 / 자기개선 4→3 / 상태영속 5→4 / 배포DX 4→3. 동결: 컨텍스트·오케스트레이션·검증루프·철학=5, 툴=4. (4) 가장 저평가됐던 핵심 — LLM을 “자유 작성자”가 아니라 결정적 파이프라인 안의 제한된 변환기로 쓴 점(prepare.mjs:3 관계 주입, runner.mjs:113 타깃 변경 금지). 이게 이 코드베이스의 진짜 정체성이다. 학습 포인트 — 메모리 노트는 “계획·의도”를 “구현 완료”처럼 압축 기록하는 경향이 있다(QStash, codex_d.sh 보편성, 300s 상한). 분석은 메모리가 아니라 코드를 1차 근거로. 프로젝트별 봉인이 강해도 전역 설정이 느슨하면 가드레일 점수가 떨어진다.