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는 일을 시작하기 전과 끝낸 후에 증거를 요구하는 감리다.

  1. 먼저 충분히 묻는다 (deep-interview) — 집을 짓기 전 “방은 몇 개? 예산은? 언제까지?”를 끝까지 캐묻는다. gjc는 이걸 감으로 하지 않고 “목표·제약·기준·맥락” 점수를 매겨서, 모호함이 정해진 선 아래로 떨어지기 전까지는 일을 시작하지 못하게 막는다. 게다가 나중 답변이 오히려 모호함을 키울 수도 있어서, 한 번 통과했다고 끝이 아니다.

  2. 혼자 정하지 않고 합의한다 (ralplan) — 계획가·설계자·비평가 세 역할이 모여 안을 다듬고, 최종안은 따로 떼어내 사람의 승인을 기다린다.

  3. “다 했다”는 말을 믿지 않는다 (ultragoal) — 가장 중요한 부분이다. 작업이 끝나면 gjc는 화면용은 브라우저 자동화+스크린샷, 명령줄용은 로그, API는 블랙박스 테스트… 이렇게 종류별로 다른 증거를 강제로 제출시킨다. “내가 봤는데 잘 되더라”는 자기검증을 거부한다.

  4. 모든 흔적은 도장이 찍힌다 (영수증) — 작업 완료는 sha256 체크섬이 박힌 **영수증(receipt)**으로 증명한다. 위변조하면 어긋나서 통과 못 한다(fail-closed). 상태 폴더 .gjc/는 손으로 못 고치고 반드시 CLI를 거쳐야 한다.

지금은 베타다

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 서버 가동

10축 점수 (종합 평균 약 4.3)

컨텍스트엔지니어링·가드레일/안전·상태영속·철학 = 5 (근거 충분, 양측 합치) 아키텍처·툴/확장·오케스트레이션·검증루프·배포/DX = 4 (beta 단계·수치 보정 반영) 자기개선/반복 = 3 (메모리/반성 위주, 기본 OFF·opt-in)

이 노트의 독창적 아이디어 3가지

  1. 수학적 모호성 게이팅 — 가중 차원 점수가 임계값 이하로 떨어지기 전까지 실행 차단, 양방향·비단조 스코어링
  2. 영수증 제어면 — sha256 canonical-JSON으로 완료를 fail-closed 증명, state-machine의 nextAllowedActions가 “지금 가능한 동작/불가 사유”를 알려주는 강제 함수
  3. 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).

스스로 답해보기

  1. ultragoal이 “다 했다”는 모델의 말을 믿지 않기 위해 요구하는 증거는 어떤 종류들인가? (힌트: surface별 매트릭스)
  2. CliWriteReceiptWorkflowStateReceipt는 이름은 비슷한데 역할이 정반대다. 무엇이 어떻게 다른가?
  3. “툴 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 본문 에코 금지 vs WorkflowStateReceipt sha256 위변조 도장)과 .gjc/ 워크플로 상태, deep-interview의 수학적 모호성 단조 게이팅.

연결

_분석축_루브릭 · HOME · _비교매트릭스

핵심 파일

  • /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

Codex ↔ Claude 교차검증 (보존)

두 분석을 대조해 점수·사실을 보정했다. 불일치 지점이 곧 학습 포인트다.

  • 사실 오류(Codex가 잡음): “툴 71개” → 실제 공개 BUILTIN_TOOLS 약 35개 + HIDDEN_TOOLS 3개 (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).