. gajae-code
4. gajae-code
한 줄 요약
gajae-code(gjc)는 Codex·Claude Code “옆에서” 독립 실행되는 외부 코딩 에이전트 하네스로, “묻고(deep-interview)→합의해 계획하고(ralplan)→증거로 완료를 증명한다(ultragoal)“는 좁은 워크플로우를 강제한다. → 왜 배우나: “스킬을 늘리지 말고 방법론 자체를 좁혀 모델의 자유도를 줄인다”는 설계 철학과, 그 좁힘을 말이 아니라 게이트·영수증·원장으로 강제하는 구조를 배우기 위해서다.
그림
flowchart TD
U[사용자 의도] --> DI["deep-interview<br/>수학적 모호성 게이팅"]
DI -->|모호성 임계값 이하| RP["ralplan<br/>Planner·Architect·Critic 합의"]
RP -->|사람 승인| UG["ultragoal<br/>ledger 원장 + 병렬 executor"]
UG --> GATE{"완료 게이트<br/>영수증 sha256 검증"}
GATE -->|증거 충족| DONE[완료 fail-closed]
GATE -->|증거 부족| UG
subgraph 런타임 경계
TS["TS 코어<br/>CLI·에이전트루프·LLM클라이언트"]
RS["Rust 핫패스<br/>FFI·PTY·ast·diff"]
PY["Python 운영면<br/>RPC·robogjc 봇"]
end
UG -.실행.-> TS
TS -.성능경로.-> RS
TS -.서브프로세스.-> PY
쉽게 풀기
gajae-code를 **“까다로운 시공 감리관”**이라고 생각하면 쉽다. 일반적인 AI 코딩 도구가 “시키면 바로 일하는 직원”이라면, gjc는 일을 시작하기 전과 끝낸 후에 증거를 요구하는 감리다.
-
먼저 충분히 묻는다 (deep-interview) — 집을 짓기 전 “방은 몇 개? 예산은? 언제까지?”를 끝까지 캐묻는다. gjc는 이걸 감으로 하지 않고 “목표·제약·기준·맥락” 점수를 매겨서, 모호함이 정해진 선 아래로 떨어지기 전까지는 일을 시작하지 못하게 막는다. 게다가 나중 답변이 오히려 모호함을 키울 수도 있어서, 한 번 통과했다고 끝이 아니다.
-
혼자 정하지 않고 합의한다 (ralplan) — 계획가·설계자·비평가 세 역할이 모여 안을 다듬고, 최종안은 따로 떼어내 사람의 승인을 기다린다.
-
“다 했다”는 말을 믿지 않는다 (ultragoal) — 가장 중요한 부분이다. 작업이 끝나면 gjc는 화면용은 브라우저 자동화+스크린샷, 명령줄용은 로그, API는 블랙박스 테스트… 이렇게 종류별로 다른 증거를 강제로 제출시킨다. “내가 봤는데 잘 되더라”는 자기검증을 거부한다.
-
모든 흔적은 도장이 찍힌다 (영수증) — 작업 완료는 sha256 체크섬이 박힌 **영수증(receipt)**으로 증명한다. 위변조하면 어긋나서 통과 못 한다(fail-closed). 상태 폴더
.gjc/는 손으로 못 고치고 반드시 CLI를 거쳐야 한다.
[!warning] 지금은 베타다 README가 명시적으로 experimental/beta 단계라고 경고한다. 야심과 설계는 성숙하지만 실전 안정성은 아직 입증 전이다.
핵심 정리
| 영역 | 한 줄 | 근거 파일 |
|---|---|---|
| 정체성 | 패치 안 받는 외부 하네스 (플러그인 아님) | README.md |
| 좁은 표면 | 4 workflow + 4 role agent를 테스트로 못박음 | default-gjc-definitions.test.ts |
| 핵심 강제 | 영수증 sha256 + .gjc CLI 경유 강제 | receipts.ts |
런타임 3층 구조
- TS 코어 (Bun) —
packages/coding-agent(CLI),packages/agent(루프/컴팩션),packages/ai(멀티프로바이더) - Rust 핫패스 —
crates/의 pi-natives(FFI)·pi-shell(PTY)·pi-ast(ast-grep)·pi-iso(diff), 성능 민감 경로만 분리 - Python 운영면 —
gjc-rpc(타입드 바인딩)·robogjc(GitHub triage 봇),gjc --mode rpc를 서브프로세스로 구동하고--listen으로 영속 UDS 서버 가동
[!note] 10축 점수 (종합 평균 약 4.3) 컨텍스트엔지니어링·가드레일/안전·상태영속·철학 = 5 (근거 충분, 양측 합치) 아키텍처·툴/확장·오케스트레이션·검증루프·배포/DX = 4 (beta 단계·수치 보정 반영) 자기개선/반복 = 3 (메모리/반성 위주, 기본 OFF·opt-in)
[!tip] 이 노트의 독창적 아이디어 3가지
- 수학적 모호성 게이팅 — 가중 차원 점수가 임계값 이하로 떨어지기 전까지 실행 차단, 양방향·비단조 스코어링
- 영수증 제어면 — sha256 canonical-JSON으로 완료를 fail-closed 증명, state-machine의
nextAllowedActions가 “지금 가능한 동작/불가 사유”를 알려주는 강제 함수- surface별 증거 강제 — GUI/CLI/API/알고리즘마다 다른 증거 매트릭스로 happy-path 자기검증 거부
실제 예시
(1) 본문을 다시 토해내지 않는 영수증 — 토큰 누수 방지
// packages/coding-agent/src/gjc-runtime/cli-write-receipt.ts
export interface CliWriteReceipt {
ok: boolean;
[field: string]: unknown; // run_id, goal_id, state_path, sha256 등 라우팅/감사용
}
// 핵심 규약: state 봉투 전체·ultragoal plan·team task 본문을 절대 echo 하지 않는다
// (호출자가 이미 들고 있으므로 되돌려주면 토큰 누수)
(2) RPC가 설명보다 진전됨 — 영속 UDS 서버
# 세션을 registry에 기록하는 영속 서버 (cli/args.ts:149, rpc-mode.ts, session-registry.ts)
gjc --mode rpc --listen
(3) 좁은 표면을 테스트로 강제
// packages/coding-agent/src/defaults/gjc-defaults.ts
// 정확히 4 workflow + 4 role agent만 노출되는지 검사
// → default-gjc-definitions.test.ts / check-visible-definitions.ts
요약 & 셀프체크
- gjc는 외부 코딩 에이전트 하네스로, deep-interview→ralplan→ultragoal 워크플로우를 게이트·영수증·원장으로 강제한다.
- 핵심 철학은 “스킬을 늘리지 않고 방법론을 좁혀 모델의 자유도를 줄이는 것”이며, 좁은 표면 자체를 테스트로 못박는다.
- TS 코어 + Rust 핫패스 + Python 운영면의 깨끗한 멀티런타임 경계 위에서 fail-closed 검증 폐루프가 돈다 (단, 현재 beta).
스스로 답해보기
- ultragoal이 “다 했다”는 모델의 말을 믿지 않기 위해 요구하는 증거는 어떤 종류들인가? (힌트: surface별 매트릭스)
CliWriteReceipt와WorkflowStateReceipt는 이름은 비슷한데 역할이 정반대다. 무엇이 어떻게 다른가?- “툴 71개”가 왜 틀린 수치였고, 실제 공개 도구 수는 얼마인가?
기능별 분해
각 기능을 별도 노트로 분해했다(번호순).
- GJ_10_agent-loop — 모델의 “생각→도구호출→결과→재생각” 사이클을 도는 에이전트 실행 루프. 대화는 끝까지
AgentMessage로, LLM 전송 직전 한 경계에서만Message[]로 변환(steering/abort/Harmony leak 처리 + 영수증 집계). - GJ_20_context-and-prompt-assembly — 시스템 프롬프트를
.md템플릿(prompt.render)으로 조립하고, 조상 폴더의 AGENTS.md/CLAUDE.md/GEMINI.md를 deeper-overrides-higher로 긁어모아 합치며 oversized 컨텍스트를 prune. - GJ_30_extension-points-hooks-skills-commands — 코어를 안 건드리고 행동을 덧붙이는 세 확장 구멍: Hooks(좁힌 UI 권한 TS 콜백)·Skills(
SKILL.md점진 공개)·Slash-Commands(/명령). capability discovery로 자동 발견. - GJ_40_subagents-and-task-delegation — 역할 에이전트(executor/architect/planner/critic)를
prompts/agents/*.md프론트매터 계약으로 정의하고task도구로 격리 워크트리에 병렬 위임, 결과는 영수증 요약으로만 회수. - GJ_50_mcp-integration —
.mcp.json디스커버리→connect→MCPTool래핑으로 외부 도구 서버를 내부 커스텀 툴에 편입(mcp__서버_도구네이밍, 250ms 초과 시DeferredMCPTool로 지연 노출). - GJ_60_tool-system-definition-and-exposure — 도구 정의 형식(
AgentTool/BUILTIN_TOOLS팩토리)과 모델 노출 정책: essential 도구만 먼저 보이고 나머지는search_tool_bm25로 점진 공개, ToolChoice 강제 + capability degradation. - GJ_70_guardrails-sandbox-permission-gating — 4겹 잠금: read-only 역할 bash 화이트리스트·plan-mode 쓰기 잠금·spawn 게이트(5+ 시 정당화 영수증)·ACP 권한 팝업. “deny by default, gate by justification”.
- GJ_80_gajae-receipts-and-workflow-state — gajae 고유의 이중 영수증(
CliWriteReceipt본문 에코 금지 vsWorkflowStateReceiptsha256 위변조 도장)과.gjc/워크플로 상태, deep-interview의 수학적 모호성 단조 게이팅.
연결
핵심 파일
/mnt/d/6study/_소스레포/gajae-code/AGENTS.md/mnt/d/6study/_소스레포/gajae-code/README.md/mnt/d/6study/_소스레포/gajae-code/packages/coding-agent/src/defaults/gjc/skills/deep-interview/SKILL.md/mnt/d/6study/_소스레포/gajae-code/packages/coding-agent/src/defaults/gjc/skills/ultragoal/SKILL.md/mnt/d/6study/_소스레포/gajae-code/packages/coding-agent/src/defaults/gjc/skills/ralplan/SKILL.md/mnt/d/6study/_소스레포/gajae-code/packages/agent/src/append-only-context.ts/mnt/d/6study/_소스레포/gajae-code/packages/coding-agent/src/tools/index.ts(BUILTIN_TOOLS:315 / HIDDEN_TOOLS:354)/mnt/d/6study/_소스레포/gajae-code/packages/coding-agent/src/harness-control-plane/state-machine.ts/mnt/d/6study/_소스레포/gajae-code/packages/coding-agent/src/harness-control-plane/receipts.ts/mnt/d/6study/_소스레포/gajae-code/packages/coding-agent/src/tools/plan-mode-guard.ts/mnt/d/6study/_소스레포/gajae-code/packages/coding-agent/src/tools/bash-interceptor.ts/mnt/d/6study/_소스레포/gajae-code/packages/coding-agent/src/defaults/gjc-defaults.ts/mnt/d/6study/_소스레포/gajae-code/packages/coding-agent/src/cli/args.ts(—listen:149)/mnt/d/6study/_소스레포/gajae-code/packages/coding-agent/src/hindsight/mental-models.ts/mnt/d/6study/_소스레포/gajae-code/python/robogjc/README.md/mnt/d/6study/_소스레포/gajae-code/python/gjc-rpc/README.md/mnt/d/6study/_소스레포/gajae-code/docs/bridge.md
[!tip] Codex ↔ Claude 교차검증 (보존) 두 분석을 대조해 점수·사실을 보정했다. 불일치 지점이 곧 학습 포인트다.
- 사실 오류(Codex가 잡음): “툴 71개” → 실제 공개
BUILTIN_TOOLS약 35개 +HIDDEN_TOOLS3개 (tools/index.ts:315, 354) ⇒ 툴/확장 5→4 · 네 번째 스킬은team(optional tmux) ⇒ 4스킬 표현 보정 · README가 experimental/beta 명시 ⇒ 아키텍처·DX 5→4- Claude가 빠뜨린 점(Codex 보강): RPC가
--listen영속 UDS 서버로 진전 · 좁은 표면은 선언이 아니라 테스트로 강제 · memory/self-improvement는 기본 off(opt-in) ⇒ 자기개선 4→3- 가장 저평가된 핵심: “gjc의 본질은 스킬을 늘리는 게 아니라 상태 전이와 증거 제출 경로를 좁혀 모델의 자유도를 줄이는 것”이다. ultragoal은 완료를 말로 믿지 않고 architectReview/executorQa/iteration JSON과 fresh goal snapshot을 요구한다 (ultragoal-runtime.ts:1074, 1098).