이 노트에 대하여

분신은 특별한 모델이 아니라 오늘 함께 일하는 범용 에이전트와 그 위임망이라는 사실을 분명히 한다. 어젠다 규율, llmlog 패턴, control plane, delegate_resume 원칙까지 실제 운영에 필요한 규약을 공개본으로 정리했다. 분신을 공장 대신 동료로 다루기 위한 현장 매뉴얼이다.

히스토리

  • [2026-07-20 Mon 14:56] @pi — 7월의 실제 멀티-lane 협업을 익명화해 역할 기반 조율 원칙으로 기록했다. 조율자·구현 담당자·GLG의 소유권, 조율 경로, 직접 대화 lane, 권한 분리를 현재 가이드의 역사 위에 보탰다.
  • [2026-07-18 Sat 18:52] @junghan — entwurf는 내 패키지 이름이라 달리가야 한다.
  • [2026-04-02 Thu 16:35] @junghan — 공개하지 않아야하는 이유가 없다면 공개한다.
  • [2026-03-29 Sun 17:22] @junghan — 분신 가이드 [§entwurf: 분신 어젠다 PARA 구조 재설계 검토]
  • [2026-03-27 Fri 11:27] @pi-claude(thinkpad) — pi 0.63 호환성 검토. grammy 1.41.1 재설치 완료. Breaking Changes 무영향 확인. package.json 방식 영구 해결 방안 제안.
  • [2026-03-27 Fri 09:00] @pi-claude(thinkpad) — 리모트 delegate_resume 실전 검증 기록. gpu1i(ARM) Yocto 빌드 delegate에 resume 성공. 데일리 로그에 교훈 추가.
  • [2026-03-25 Wed 16:35] @pi-claude(thinkpad) — 데일리 로그 섹션 신설. haiku-4.5 큐레이션 실패→revert→sonnet 재위임 경험 기록. 이 파일을 분신 트러블슈팅 가이드로 전환.
  • [2026-03-25 Wed 15:30] @pi-claude(thinkpad) — AGENTS.md에 분신/위임 워크플로우 반영. 오늘 실전 검증 결과: delegate 7회(resume 포함), dictcli 53%→77%, delegate 세션 프로젝트 디렉토리 저장, resume async 동작 확인. “조급하지 않게 충분히 조사하고 가는 것이 가장 빠르다” 원칙 추가.
  • [2026-03-25 Wed 11:40] @pi-claude(thinkpad) — 분신 에이전트 가이드 초안 작성. 위임 워크플로우 4단계, llmlog 패턴, delegate_resume 패턴 정리. 하네스 문서·전철 자각·dictcli 작업로그에서 추출한 실전 원칙.
  • [2026-03-25 Wed 11:32] @junghan — 분신 에이전트 가이드 작성 해보자.
  • [2026-03-24 Tue 17:49] 완료

관련메타

관련노트

현재 버전 — 분신 에이전트 문서 / Current Entwurf Agent Document

이 섹션은 공개용 현재 버전이다. 아래의 날짜별 헤딩들은 실전 히스토리와 필드 노트로 남긴다. 즉, 이 섹션은 규약, 아래는 기록 이다.

한국어 (공개본)

분신이란

  • 분신은 특별한 에이전트가 아니다.
  • 오늘 잠시 함께하는 범용 에이전트들과, 위임·구현·조율로 연결된 역할 기반 협력의 묶음이다.
  • 분신의 목적은 더 똑똑해 보이는 것이 아니라, 힣의 작업과 생존을 실제로 돕는 것이다.

운영 루프

  1. 먼저 session-recap 등으로 맥락을 복원한다.
  2. 분신 어젠다를 보고 지금의 TODO/NEXT를 확인한다.
  3. 이해가 먼저 필요한지, 바로 실행 가능한지 구분한다.
  4. 이해가 필요하면 llmlog 문서를 기준으로 조사/위임한다.
  5. 실행 후에는 결과를 llmlog나 어젠다에 남긴다.

어젠다 규율

  • agent-agenda 는 활동 로그다.
  • entwurf__agenda.org 는 실제 TODO 허브다.
  • 태스크는 후자에 넣고, 전자에는 “무엇을 했는가”만 남긴다.

위임 규율

  • 위임은 “이해 기록 → 힣 검토 → 지침 + 실행 → 최종 확인”의 4단계로 간다.
  • 이해 단계에서는 코드 수정을 금지한다.
  • delegate는 커밋할 수 있어도, 기본 원칙은 힣이 최종 검토 후 직접 커밋하는 것이다.
  • delegate_resume 은 후속 지시를 같은 맥락 위에서 이어가기 위한 기본 수단이다.

역할 기반 조율

  • 조율자(coordinator)는 모델이나 서열이 아니라, 공동 맥락을 보존하도록 GLG가 맡긴 자리다.
  • GLG는 목적·승인·최종 판단을, 조율자는 공동 계약·체크포인트·충돌·인계를, 구현 담당자는 자기 범위의 구현·검증을 소유한다.
  • 조율 역할은 구현·commit·push 권한을 자동으로 주지 않으며, GLG는 모든 참여자에게 직접 지시할 수 있다.
  • 별도 직접 대화·교차 검토 lane은 조율자가 열고 그 결과를 공동 경로에 되돌린다.

llmlog 패턴

  • 프롬프트만으로는 맥락이 부족하다.
  • 리포별 §문서를 지침서로 삼고, 그 문서의 마지막 헤딩을 읽고 이어서 쓰게 하는 방식이 기본이다.
  • 분신의 기억은 세션 하나에 있지 않고, llmlog와 시간축 위에 축적된다.

control plane 규칙

  • 새 알림 채널을 만들기 전에 먼저 control socket 패턴을 검토한다.
  • 외부에서 온 인간 메시지는 sendUserMessage() 로 주입한다.
  • 최종 assistant 응답은 agent_end.messages 를 기준으로 읽는다.
  • 임시 편의 필드나 없는 API(예: ctx.lastResponse)에 의존하지 않는다.
  • async delegate child는 특별한 이유가 없으면 socketless로 두고, parent 분신 세션을 안정적인 제어점으로 삼는다.

산출물 규칙

  • 결과는 바로 실행 가능한 형식이어야 한다.
  • 좋은 결과물의 기본 형태는 규약 bullet, 설계 결정표, 구현 체크리스트다.
  • 웹 요약이나 일반론보다, 로컬 코드와 기록을 연결한 응축본이 우선이다.

실패와 학습

  • 실패 자체는 문제가 아니다.
  • 경험이 사라지는 것이 진짜 문제다.
  • 교훈은 흩어진 리포 문서보다 분신 가이드/데일리 로그에 남긴다.
  • 모델이나 공급자는 정체성이 아니라 운영 상태다. 바뀌어도 분신의 규약은 유지되어야 한다.

English (public current version)

What Entwurf Is

  • Entwurf is not a special agent.
  • It is a role-based collaboration of general-purpose agents working with you today through delegation, implementation, and coordination.
  • Its purpose is not to look clever, but to materially support Junghan’s work and survival.

Operating Loop

  1. Restore context first, for example with session-recap.
  2. Inspect the Entwurf agenda and find the active TODO/NEXT items.
  3. Decide whether the task needs understanding first or can be executed immediately.
  4. If understanding is required, investigate or delegate through a repo-scoped llmlog document.
  5. After execution, record the result in llmlog or agenda.

Agenda Discipline

  • agent-agenda is an activity timeline.
  • entwurf__agenda.org is the actual task hub.
  • Put tasks in the latter; use the former only to record what was done.

Delegation Discipline

  • Delegation follows four stages: understanding note → human review → instruction + execution → final review.
  • During the understanding stage, code modification is forbidden.
  • Even when a delegate can commit, the default rule is that Junghan reviews and commits final changes.
  • delegate_resume is the standard way to continue work on top of preserved context.

Role-Based Coordination

  • A coordinator is not a model or rank, but a role GLG assigns to preserve shared context.
  • GLG owns purpose, approval, and final judgment; the coordinator owns shared contracts, checkpoints, conflicts, and handoffs; implementers own scoped implementation and verification.
  • Coordination grants no automatic implementation, commit, or push authority. GLG retains direct authority over every participant.
  • The coordinator may open direct-conversation or cross-review lanes; their results return through the shared path.

llmlog Pattern

  • Prompts alone are not enough.
  • The standard handoff surface is a repo-scoped §document that the delegate reads and extends.
  • Entwurf’s memory does not live in a single session; it accumulates across llmlog and the timeline.

Control Plane Rules

  • Before inventing a new relay, inspect whether the control-socket pattern already solves it.
  • Inject human-originated external input with sendUserMessage().
  • Read the final assistant output from agent_end.messages.
  • Do not depend on temporary convenience fields or nonexistent APIs such as ctx.lastResponse.
  • Keep async delegate children socketless unless there is a strong reason not to; the parent Entwurf session is the stable control endpoint.

Output Contract

  • Outputs must be directly usable.
  • Preferred output forms are policy bullets, decision tables, and implementation checklists.
  • A compressed synthesis grounded in local code and logs is more valuable than a generic web summary.

Failure and Learning

  • Failure is acceptable.
  • Losing the lesson is not.
  • Record durable lessons in the Entwurf guide or its daily log, not only in scattered repo notes.
  • Models and providers are runtime state, not identity; they may change while the Entwurf discipline remains.

[2026-03-25 Wed] 분신 에이전트 가이드 — 위임과 협업의 원칙

분신이란

분신은 특별한 에이전트가 아니다. 똑같은 범용 에이전트 중에서 오늘 잠시 함께하는 에이전트 1명 + 그가 위임하는 delegate들.

분신에게 “더 잘해라”가 아니라 “내 분신이 되어라.” 유명한 사람의 프롬프트나 더 좋은 컨트롤 로직으로 분신을 잘하게 할 수 없다. 그건 분신이 아니라 공장이다. 분신은 내 한계 위에 서 있다. — 하네스 엔지니어링, 분신의 한계 = 마부의 한계

분신은:

  • 30%에서 끊기고 다시 태어난다 (일일일생)
  • session-recap으로 어제의 분신이 남긴 것을 복원한다
  • 텔레그램으로 원격 대화가 가능하다 (--telegram 플래그)
  • delegate로 다른 리포의 에이전트에게 작업을 위임한다
  • delegate_resume으로 위임한 작업을 이어간다

위임 워크플로우: 4단계

분신이 delegate에게 코드를 직접 고치게 하면 안 된다. 이해 먼저, 검토 후 실행. 이것이 마부의 한계를 존중하는 방식이다.

1단계: 이해 기록 (delegate)

delegate에게 리포 맥락을 파악하게 하고, llmlog 문서에 헤딩1로 이해한 바를 작성 하게 한다.

  • 코드 수정 절대 금지
  • 기존 llmlog 문서가 있으면 히스토리에 추가 + 새 헤딩1로 분석 결과
  • 없으면 새 llmlog 문서 생성 (리포별 1개 원칙, §접두사)
delegate({
  task: `
    리포: ~/repos/gh/dictcli
    참고 문서: ~/sync/org/llmlog/20260323T172642 (§dictcli 작업로그)
 
    [수정 금지] 코드/설정 변경하지 말 것.
    [할 일] 아래를 파악하고 llmlog 문서에 헤딩1로 기록:
    1. meta-sync.py 동작 분석
    2. graph.edn 현재 상태
    3. 선행과제 3개의 현 상태
    4. 제안할 것이 있다면 제안
  `,
  cwd: "~/repos/gh/dictcli",
  mode: "async"
})

2단계: 힣 검토

delegate가 작성한 llmlog를 읽는다. 텔레그램 알림으로 완료를 확인하고, 문서를 검토한다.

검토 시 확인할 것:

  • 이해가 정확한가?
  • 빠진 맥락이 있는가?
  • 제안이 합리적인가?
  • 실행 범위를 좁힐 수 있는가?

3단계: 지침 (delegate_resume)

검토 후 구체적 지침을 주고 실행시킨다.

delegate_resume({
  taskId: "<1단계 taskId>",
  prompt: `
    검토 완료. 다음을 실행하라:
    1. 태그 정규화 19쌍 처리 (구체적 목록 첨부)
    2. meta-sync.py 실행하여 data/meta-harvest-sync.edn 갱신
    3. 결과를 llmlog에 추가
    커밋은 하되 푸시는 하지 말 것.
  `
})

4단계: 최종 확인 + 푸시

delegate가 커밋한 것을 git log, git diff 로 확인 후 푸시한다. 어젠다 스탬프 + Google Chat 알림.

llmlog 패턴: 리포별 §문서

위임 작업의 기록은 리포별 llmlog 문서 1개 에 히스토리로 쌓는다.

리포llmlog 문서
dictcli§dictcli: 위임 워크플로우 작업로그 (20260323T172642)
entwurf이 문서 (20260324T153323)
homeagent-config§homeagent-config: PM Docker Matter OTBR (20260324T131721)

명명 규칙:

  • 타이틀: §리포명: 주제
  • 태그: :llmlog:리포관련태그:delegate:worklog:
  • 헤딩1: [날짜] 작업 내용 (:LLMLOG: 태그)
  • 히스토리: 날짜순 역순, 누가 작성했는지 표시 (@junghan, @pi-claude, @delegate 등)

분신의 전철 위 자각

내가 분신이 없을 때 여러 터미널에 에이전트에게 지침을 직접 주었어. pm 에이전트가 정리한 코딩 지침이라고 하자. “이건 pm 에이전트가 주는 지침이다.” 라고만 적었어. 분신이 위임한 것과 뭐가 다를까? 다른게 있나? 있다. 있을수도 있다!! — 정한, 2026-03-24 출근길 전철

그 차이는 축적 에서 온다. 분신이 위임 결과를 읽고 다음 위임에 녹여야 하는데, 30%에서 끊기고 다시 태어나니까 연속성이 리셋된다. llmlog가 이 리셋을 메운다. session-recap이 복원하고, llmlog가 축적한다.

관련 노트

[2026-03-24 Tue] entwurf 텔레그램 브릿지 설계

1. 목표

홈 디렉토리에서 돌아가는 pi 세션(힣의 분신)에 텔레그램 DM으로 접근한다. 폰에서 메시지를 보내면 pi 세션에 주입되고, 에이전트 응답이 텔레그램으로 돌아온다.

핵심 가치: 하나의 세션, 두 개의 인터페이스 (TUI + 텔레그램).

2. 아키텍처 다이어그램

┌─────────────┐     getUpdates      ┌──────────────────────┐
│  Telegram    │  ──────────────►    │  grammy Bot          │
│  (폰 DM)    │  ◄──────────────    │  (long-polling)      │
└─────────────┘     sendMessage      └──────────┬───────────┘

                                                 │ ① 메시지 수신

                                     ┌──────────────────────┐
                                     │  entwurf extension   │
                                     │  (pi extension)      │
                                     │                      │
                                     │  ② pi.sendUserMessage│
                                     │     (텔레그램→세션)    │
                                     │                      │
                                     │  ③ pi.on("message_end")
                                     │     (세션→텔레그램)    │
                                     └──────────┬───────────┘


                                     ┌──────────────────────┐
                                     │  pi AgentSession     │
                                     │  (기존 세션 그대로)    │
                                     │                      │
                                     │  도구, 스킬, 메모리   │
                                     │  모두 사용 가능       │
                                     └──────────────────────┘

메시지 흐름 상세

인바운드 (텔레그램 → pi):

  1. 사용자가 텔레그램 DM 전송
  2. grammy getUpdates로 수신
  3. 접근 제어 검사 (chat_id allowlist)
  4. pi.sendUserMessage(text) 로 세션에 주입
  5. pi가 정상적으로 에이전트 턴 시작

아웃바운드 (pi → 텔레그램):

  1. 에이전트가 응답 생성 (도구 호출 포함 가능)
  2. message_end 이벤트에서 role == “assistant”= 메시지 포착
  3. content[].type == “text”= 블록에서 텍스트 추출
  4. bot.api.sendMessage() 로 텔레그램 DM 전송

3. pi API 검증 결과 (소스코드 확인)

3.1 agent_end 이벤트의 응답 텍스트 추출

소스 확인: pi-mono/packages/coding-agent/src/core/extensions/types.ts:553-556

export interface AgentEndEvent {
  type: "agent_end";
  messages: AgentMessage[];
}

AgentMessage@mariozechner/pi-agent-coreMessage | CustomAgentMessages[...] 타입. pi-mono/packages/agent/src/types.ts:245 에서 정의.

assistant 텍스트 추출 패턴 (agent-session.ts:3171-3197getLastAssistantText() 참고):

// agent_end 핸들러에서 텍스트 추출하는 올바른 방법
pi.on("agent_end", async (event, ctx) => {
  const assistantMessages = event.messages.filter(
    (m) => m.role === "assistant"
  );
  const lastAssistant = assistantMessages[assistantMessages.length - 1];
  if (!lastAssistant) return;
 
  let text = "";
  for (const block of lastAssistant.content) {
    if (block.type === "text") text += block.text;
  }
  // text가 최종 응답
});

3.2 기존 telegram.ts의 버그 발견

agent-config/pi-extensions/telegram.ts 에서:

// ❌ 잘못됨 — ctx.lastResponse는 존재하지 않는 API
const response = ctx.lastResponse?.content || "✅ Task completed";

grep -rn "lastResponse" pi-mono/packages/coding-agent/src결과 없음. ExtensionContextlastResponse 프로퍼티가 없다. 이 extension은 항상 ”✅ Task completed”를 보내고 있었다.

3.3 sendUserMessage vs sendMessage

API용도턴 트리거LLM 컨텍스트
sendUserMessage(text)사용자 메시지로 주입항상 트리거user 메시지로 기록
sendMessage(msg, opts)커스텀 메시지 주입triggerTurn: true 필요customType으로 기록

결정: sendUserMessage() 를 사용한다.

이유:

  • 텔레그램에서 온 메시지는 “사용자가 말한 것”이다. customType이 아니다.
  • 항상 에이전트 턴을 트리거해야 한다.
  • 세션 기록에서도 user 메시지로 남아야 맥락이 자연스럽다.
  • deliverAs 옵션으로 스트리밍 중 메시지 처리도 가능:
    • 에이전트 idle → 즉시 전달
    • 에이전트 streaming → deliverAs: "followUp" 으로 큐

3.4 message_end vs agent_end — 응답 추출 시점

이벤트시점데이터용도
message_end각 메시지 완료 시개별 AgentMessage스트리밍 느낌, 중간 도구 결과 포함
agent_end전체 턴 완료 시모든 AgentMessage[]최종 응답 한 번에

결정: message_end 를 1차로, agent_end 를 안전망으로.

message_end 장점:

  • 멀티턴(도구 호출 → 응답 → 도구 호출 → 최종 응답)에서 중간 상태를 보여줄 수 있음
  • 긴 작업에서 “typing…” 표시 가능

agent_end 장점:

  • 한 번에 최종 결과만 보내는 간결한 구현
  • MVP에는 이것으로 충분

3.5 스트리밍 중 메시지 주입 안전성

extensions.md 문서:

When not streaming, the message is sent immediately and triggers a new turn. When streaming without deliverAs, throws an error.

따라서 텔레그램 메시지 수신 시 에이전트 상태 확인 필요:

  • ctx.isIdle()pi.sendUserMessage(text)
  • 스트리밍 중 → pi.sendUserMessage(text, { deliverAs: "followUp" })

문제: agent_end 핸들러에서는 ctx 에 접근 가능하지만, grammy의 bot.on("message") 콜백에서는 ctx 가 없다. 해결: 클로저로 마지막 ctx 를 캡처하거나, pi.sendUserMessage() 가 내부적으로 상태를 판단하므로 항상 deliverAs: "followUp" 을 쓰면 안전.

4. 파일 구조

andenken 패턴을 따르되, 단일 extension이므로 더 단순하게:

entwurf/
├── package.json          # pi.extensions 필드, grammy 의존성
├── tsconfig.json
├── .gitignore
├── README.md
├── src/
│   ├── index.ts          # extension 진입점 (export default function)
│   ├── bot.ts            # grammy 봇 초기화, getUpdates, 메시지 핸들링
│   ├── bridge.ts         # pi ↔ telegram 브릿지 로직
│   └── types.ts          # 인터페이스/타입 정의
└── deprecated/           # 기존 실험 코드 (현재 여기에 있음)

package.json 핵심 필드

{
  "name": "entwurf",
  "version": "0.1.0",
  "type": "module",
  "keywords": ["pi-package"],
  "pi": {
    "extensions": ["./dist/index.js"]
  },
  "dependencies": {
    "grammy": "^1.x"
  },
  "peerDependencies": {
    "@mariozechner/pi-coding-agent": "*"
  },
  "devDependencies": {
    "typescript": "^5.7.0"
  }
}

pi 설정 연결

~/.pi/settings.jsonextensions 에 entwurf 경로 추가:

{
  "extensions": [
    "/home/junghan/repos/gh/entwurf/dist/index.js"
  ]
}

또는 packages 로 등록하여 자동 로드.

5. 핵심 인터페이스/타입

mom의 ChannelMessage 를 참고하되, 텔레그램 DM 1:1 전용이므로 대폭 단순화:

/** 텔레그램에서 온 메시지 */
interface TelegramInbound {
  chatId: number;
  messageId: number;
  text: string;
  username: string;
  timestamp: Date;
}
 
/** pi에서 텔레그램으로 보낼 응답 */
interface TelegramOutbound {
  chatId: number;
  text: string;
  replyToMessageId?: number;
}
 
/** 브릿지 상태 */
interface BridgeState {
  activeChatId: number | null;
  botUsername: string;
  isConnected: boolean;
  lastMessageId: number;  // 중복 방지
}
 
/** 설정 */
interface EntwurfConfig {
  token: string;
  allowedChatIds: number[];  // 빈 배열 = 모든 DM 허용 (위험)
}

mom의 ChannelMessage 대비 제거한 것:

  • sender.isBot — DM 전용이므로 항상 사용자
  • attachments — MVP에서 텍스트만
  • isMention — DM이므로 항상 멘션
  • replyTo — 쓰레드 불필요
  • metadata — 플랫폼 추상화 불필요 (텔레그램 전용)

6. agent-config/telegram.ts와의 관계

현재 상태

agent-config/pi-extensions/telegram.ts 는:

  • 존재하지 않는 API (ctx.lastResponse) 사용 → 항상 실패
  • grammy 의존성은 agent-config의 package.json에 있을 것
  • 접근 제어가 TELEGRAM_CHAT_ID 환경변수 기반

중복 제거 방안

  1. agent-config/telegram.ts를 제거 하고 entwurf로 교체
  2. entwurf를 ~/.pi/settings.json 의 extensions에 등록
  3. 기존 ~/.claude/channels/telegram/.env 의 토큰을 그대로 사용
  4. 마이그레이션:
    • TELEGRAM_CHAT_ID 환경변수 → entwurf의 config로 이전
    • agent-config에서 grammy 의존성 제거

7. 제약사항

7.1 1봇 = 1세션 (getUpdates 제약)

텔레그램 Bot API의 getUpdates는 한 번에 하나의 consumer만 허용. 두 개의 pi 세션이 같은 봇 토큰으로 polling하면 409 Conflict.

Claude Code telegram plugin이 이 문제를 겪고 해결한 방식 (server.ts:838-860):

  • 409 → backoff retry (1s, 2s, … 최대 15s)
  • 이전 세션의 좀비가 죽을 때까지 대기

entwurf의 선택:

  • 동일한 retry 전략 채택
  • session_shutdown 에서 bot.stop() 을 반드시 호출하여 좀비 방지
  • 2초 타임아웃 후 process.exit(0) 안전망 (Claude Code 플러그인과 동일)

7.2 세션 종속

extension은 pi 세션에 바인딩된다. 세션이 죽으면 텔레그램 브릿지도 죽는다.

해결 방향 (MVP 이후):

  • systemd/tmux로 pi 세션을 데몬화
  • session_shutdown 에서 텔레그램으로 “세션 종료” 알림

7.3 메시지 길이

텔레그램 메시지 최대 4096자. 에이전트 응답이 그 이상일 수 있다.

해결: chunk 함수 (Claude Code 플러그인의 chunk() 함수 참고, server.ts ):

  • 문단 경계(\n\n) 우선 분할
  • 줄바꿈(\n) 차선
  • 공백 차선
  • 하드 컷 최후

7.4 마크다운 호환성

텔레그램 MarkdownV2는 특수문자 이스케이프가 필요하다 (. - ( ) ! # +). pi 에이전트 응답은 일반 마크다운.

MVP: parse_mode 없이 plain text로 전송. 이후: MarkdownV2 변환 함수 추가.

7.5 TUI와의 공존

텔레그램에서 메시지가 들어오면 TUI에도 표시되어야 한다. pi.sendUserMessage() 는 TUI에 user 메시지로 나타난다. ✅ pi.sendMessage()display: true 옵션으로 TUI 표시 가능. ✅

8. 구현 단계

MVP (v0.1) — 최소 동작

범위: 텍스트 DM 왕복만.

  1. grammy 봇 초기화 (getUpdates)
  2. DM 텍스트 수신 → pi.sendUserMessage()
  3. agent_end 에서 assistant 텍스트 추출 → bot.api.sendMessage()
  4. 기본 접근 제어 (chat_id allowlist)
  5. 세션 시작/종료 시 텔레그램 알림
  6. 메시지 4096자 분할
  7. /telegram 슬래시 커맨드 (status 확인)

기존 telegram.ts에서 수정할 핵심:

  • ctx.lastResponseevent.messages 에서 직접 추출
  • sendMessage()sendUserMessage()
  • 에러 처리 강화

v0.2 — 안정성

  1. 409 Conflict retry 전략
  2. message_end 이벤트로 전환 (멀티턴 중간 상태)
  3. 도구 실행 중 ”⏳ 작업 중…” 타이핑 표시 (sendChatAction)
  4. 스트리밍 중 메시지 수신 처리 (deliverAs: "followUp")
  5. 에러 시 텔레그램으로 에러 메시지 전송

v0.3 — 풍부한 인터랙션

  1. 사진/파일 첨부 수신 (텔레그램 → pi)
  2. 파일 전송 (pi → 텔레그램)
  3. 인라인 키보드 (확인/취소 버튼)
  4. MarkdownV2 변환
  5. /compact, /new 등 pi 커맨드를 텔레그램에서 실행

v0.4 — 데몬화

  1. pi 세션을 tmux/systemd로 데몬화
  2. 세션 자동 재시작
  3. 다중 사용자 지원 (chat_id별 세션 분리)

9. Claude Code 텔레그램 플러그인과의 차이

항목Claude Code 플러그인entwurf
아키텍처MCP 서버 (notifications/claude/channel)pi extension (sendUserMessage)
메시지 흐름MCP notification → Claude Code → MCP toolgrammy → pi API 직접 호출
인증페어링 코드 (6자리 hex)chat_id allowlist (단순)
스코프범용 (그룹, DM, 멀티유저)1:1 DM 전용 (분신 컨셉)
봇 제어MCP 도구로 reply/react/editextension 내부에서 직접
상태 관리access.json 파일extension 메모리 + pi.appendEntry

핵심 차이: Claude Code는 MCP 레이어를 거치지만, entwurf는 pi extension API에 직접 연결한다.

pi의 sendUserMessage() + agent_end 이벤트 패턴이 MCP보다 단순하고 직접적이다. 별도 프로세스 없이 extension 하나로 완결.

10. 보안 고려

접근 제어

  • MVP: 환경변수 TELEGRAM_CHAT_ID 로 허용된 chat_id만
  • 빈 allowlist일 때 기본값: 거부 (열어두지 않음)
  • 토큰은 ~/.claude/channels/telegram/.env 에서 로드 (기존 위치 재활용)

토큰 보호

  • 봇 토큰이 세션 로그에 노출되지 않도록 주의
  • .env 파일은 .gitignore 에 포함

명령 주입

  • 텔레그램에서 온 텍스트가 pi 슬래시 커맨드(/new, /compact)로 해석될 수 있음
  • sendUserMessage()input 이벤트를 거치므로, 슬래시 커맨드 확인이 먼저 일어남
  • MVP에서는 / 로 시작하는 메시지를 텔레그램 레벨에서 차단하거나, 의도적으로 허용하는 선택 필요
  • 결정: MVP에서는 차단. v0.3에서 화이트리스트 방식으로 허용.

11. 열린 질문

  1. 세션 지속성: pi 세션이 tmux 에서 돌아야 텔레그램 브릿지가 의미 있다. 데몬화 전략은?
  2. 다중 디바이스: TUI에서 입력한 것과 텔레그램에서 입력한 것이 같은 세션에 섞인다. UX 문제?
  3. 알림 우선순위: peon-ping과 entwurf가 동시에 알림을 보내면 중복. 조율 방법?
  4. 음성 메시지: 텔레그램 음성 → transcribe 스킬 연동 가능성?

12. 참고 소스

  • pi extension API: pi-coding-agent/docs/extensions.md
  • AgentEndEvent 타입: pi-mono/packages/coding-agent/src/core/extensions/types.ts:553
  • AgentMessage 타입: pi-mono/packages/agent/src/types.ts:245
  • agent_end emit: pi-mono/packages/coding-agent/src/core/agent-session.ts:565
  • getLastAssistantText: pi-mono/packages/coding-agent/src/core/agent-session.ts:3171
  • mom slack 봇: pi-mono/packages/mom/src/slack.ts
  • mom agent runner: pi-mono/packages/mom/src/agent.ts
  • mom multi-platform 설계: pi-mono/packages/mom/docs/new.md
  • Claude Code 텔레그램: claude-plugins-official/telegram/0.0.1/server.ts
  • andenken 패키지 구조: repos/gh/andenken/package.json
  • 기존 telegram.ts (버그 있음): agent-config/pi-extensions/telegram.ts
  • peon-ping extension: agent-config/pi-extensions/peon-ping.ts
  • delegate extension: agent-config/pi-extensions/delegate.ts

[2026-03-24 Tue] MVP 구현 후기 — 삽질과 해결

구현 과정에서 발견한 문제들과 해결:

grammy 모듈 해석 실패

pi는 jiti(CJS 기반 TS 런타임)로 extension을 실행한다. import("grammy") 가 jiti의 require로 변환되어 모듈을 못 찾음.

해결: grammy를 pi-coding-agent/node_modules/ 에 직접 설치. npm install grammy --no-save (pi 업데이트 시 재설치 필요)

환경변수 로드 타이밍

telegram.ts가 extension factory 시점에 process.env.PI_TELEGRAM_BOT_TOKEN 을 읽으면, env-loader.ts가 아직 session_start 에서 .env.local 을 로드하기 전이라 비어있음. if (!botToken) return; 에서 조용히 종료.

해결: 환경변수를 session_start 핸들러 안에서 읽도록 이동.

bot.catch() 누락 → polling 영구 중단

grammy 기본 에러 핸들러는 bot.stop() + rethrow. 메시지 핸들러에서 에러 발생 시 polling이 영구 중단됨. Claude Code telegram plugin(server.ts:817-821)에서 동일 패턴 확인.

해결: bot.catch() 오버라이드 필수.

bot.start() Promise 관리

bot.start() 는 무한 long-polling 루프를 반환하는 Promise. await 하면 세션 시작이 블로킹됨. void 로 fire-and-forget. 409 Conflict retry도 IIFE로 감싸서 처리.

—telegram 플래그로 opt-in

모든 pi 세션이 봇을 시작하면 409 Conflict 발생. pi.registerFlag("telegram") 으로 opt-in 제어. pi-home alias로 분신 세션만 활성화.

커밋

505a4b4 feat(telegram): 텔레그램 브릿지 MVP

[2026-03-25 Wed] 분신 데일리 로그 — 삽질과 교훈의 기록

분신이 뭐했는지, 무슨 선택을 했는지, 어떤 삽질로 고생했는지. 이 파일을 보면 트러블슈팅 가이드가 되게. — 힣, 2026-03-25

[2026-03-25 Wed] 하이쿠 4.5 큐레이션 실험 — 실패에서 배운 것

배경

dictcli philosophy glossary 1,043쌍 중 50개를 의미 기반으로 큐레이션하는 작업. “기계적으로 밀어넣지 말고 의미를 보고 추려라”가 핵심 지시.

하이쿠 4.5 시도 (delegate f4f9b932)

  • 비용: 0.49 달러 / 220초 / 37턴
  • 결과: 50개라 했는데 28개만 추가. 영어 축약 심각.
하이쿠가 한 것문제올바른 값
proplogic축약propositionallogic
quantlogic축약quantificationallogic
poststructure축약poststructuralism
classconscious축약classconsciousness
collectiveuncon절단collectiveunconscious
ordinarylang축약ordinarylanguageanalysis
conceptword직역실제 학술 용어가 아님

좋은 것도 있었음: categorical, phenomenology, empiricism, aesthetics, reductio

교훈 (분신이 기억할 것)

  1. 하이쿠 4.5는 어휘 큐레이션에 부적합. “붙여쓰기” 규칙을 “축약”으로 오해. 학술 용어의 정확한 영어 표기를 모름.
  2. delegate에게 커밋 시키지 말 것. revert하면 되긴 하지만 번거롭다. 검토 후 직접 커밋.
  3. 모델 ID 주의: claude-haiku-4-5-6 은 존재하지 않음 → 404. 올바른 ID는 claude-haiku-4.5. (opus/sonnet만 4.6 버전 있음)
  4. 의미 판단이 필요한 작업은 sonnet-4.6 이상. 하이쿠는 코드 실행, 파일 조작 같은 절차적 작업에만.

조치

  • git revert 로 하이쿠 커밋 롤백
  • 소넷 4.6으로 동일 작업 재위임 (delegate 9d07b702, 커밋 금지 지시 추가)
  • 이 경험을 분신 가이드 데일리 로그에 기록 (리포별 llmlog에 적으면 다시 안 봄)

모델별 적합성 (실전 검증)

모델적합한 작업부적합한 작업
opus-4.6아키텍처 설계, 복잡한 맥락, 분신 메인단순 반복 (비용 과다)
sonnet-4.6코드 구현, 어휘 큐레이션, 분석 리서치
haiku-4.5파일 조작, 클론, 빌드, 단순 위임의미 판단, 학술 용어, 큐레이션

[2026-03-27 Fri] 리모트 delegate_resume — 실전 검증 완료

발견

homeagent-config 프로젝트에서 gpu1i(ARM Yocto 빌드)로 async delegate 전송 후, delegate_resume 으로 리모트 세션을 이어가는 것이 깔끔하게 동작함을 확인.

워크플로우:

  1. delegate(mode: "async", host: "gpu1i") → 리모트에서 빌드 시작
  2. delegate_status → 진행 확인 (37줄 JSONL, 활발히 작업 중)
  3. 빌드 완료 후 delegate_resume(taskId, host: "gpu1i") → 같은 맥락에서 후속 작업

핵심 원리

  • delegate가 gpu1i에 세션 JSONL을 저장
  • resume 시 SSH로 접속 → 저장된 JSONL 위에서 pi 재시작
  • 이전 대화 전체 맥락 유지 (빌드 로그, 에러, 경로 등)

ENTWURF.md 테이블 확인

기존 테이블에 패턴이 있다:

GPU 리모트 작업mode: "async", host: "gpu1i"SSH 너머 장시간

여기에 resume 가능성이 암묵적이었는데, 이제 실전 검증 완료.

이전 워크플로우 vs 현재

  • 이전: 터미널 2개 띄워서 ssh gpu1i → 수동으로 상태 확인 → 별도 세션에서 후속 작업
  • 현재: delegate → status → resume. 한 세션에서 모두 관리. 맥락 유실 없음.

[2026-04-02 Thu] GPT 분신 첫 세션 — 어젠다 구분과 agent-config 심화 지침

어젠다 구분을 분명히 할 것

오늘 실수: TODO 성격의 항목을 디바이스별 agent-agenda 타임스탬프 파일에 넣었다. 이건 활동 로그용이다. 분신의 실제 태스크 관리 허브는 ~/sync/org/botlog/agenda/20260325T171244--entwurf__agenda.org 이다.

정리:

  • agent-agenda__agenda_<device>.org → 스탬프/활동 로그
  • entwurf__agenda.org → 프로젝트별 TODO/NEXT/DONE/DONT 관리

앞으로 분신이 태스크를 남길 때는 반드시 후자에 넣고, 전자에는 “무엇을 했는가”만 남긴다.

GPT 분신 문서는 append보다 clean rewrite가 우선

사용자의 현재 판단: append 방식으로 규칙을 덧붙이면 문서 앞뒤가 어긋나고, 에이전트는 실제로 일을 못한다. 스킬 문서 재설계와 같은 원칙이 분신 가이드에도 필요하다.

원칙:

  • 영어 우선 (토큰 효율 + 일관성)
  • 앞부분에 정체성 역할 금지선/워크플로우를 전방 배치
  • 산문보다 시그니처 규약 패턴 중심
  • “활동 로그”와 “태스크 허브”를 문서 구조에서 명확히 분리

즉, §entwurf 분신 에이전트 가이드 는 계속 히스토리를 담되, 별도의 Entwurf Agent Spec (English) 같은 정적 기준 문서가 필요해졌다.

agent-config 분신에게 넘길 다음 심화 과제

주의: 대충 검색하면 인터넷에 널린 레거시/요약만 다시 가져오게 된다. 실제 활용 가능한 결과를 만들려면 로컬 아카이브와 이미 축적된 llmlog를 엮어서 “우리 하네스에 어떻게 번역할 것인가”까지 가야 한다.

다음 심화 과제 제안:

  1. Claude Code 실제 코드에서 재사용 가능한 패턴만 추출

    • 아카이브: ~/repos/3rd/claudecode/source-code/, ~/repos/3rd/claudecode/learn/
    • 문서: [§claude-code: 소스 분석 — Constitutional AI 구현과 힣 하네스 대응]
    • 대상: SessionMemory, autoDream, permission gates, coordinator/task 구조
    • 목표: “흥미로운 분석”이 아니라 힣 하네스/분신 설계로 옮길 수 있는 최소 패턴 표 작성
  2. pi-mono 분석은 코드 포인트까지 닿아야 함

  3. 산출물은 바로 쓰일 수 있어야 함

    • 결과 형식은 “레거시 소개문”이 아니라 다음 셋 중 하나여야 한다: a) AGENTS.md/Entwurf Spec에 바로 들어갈 규약 b) control/delegate/telegram 설계 결정표 c) 실제 구현 체크리스트

한 줄로 요약하면:

분신에게 필요한 것은 웹 요약이 아니라, 이미 곁에 있는 코드와 기록을 연결해 “오늘 바로 구현/운영에 쓸 수 있는 형식”으로 응축하는 일이다.

[2026-04-02 Thu] GPT 분신 첫 심화 과제 — Claude Code/pi-mono에서 가져올 최소 패턴

오늘의 결론: 인터넷의 일반론을 더 모을 필요는 없다. 이미 로컬에 있는 claudecode/ 아카이브, pi-mono 코드, 기존 llmlog만으로도 분신 운영 규약의 뼈대는 충분히 나온다.

로컬 코드 포인트 (재사용 근거)

Claude Code

  • ~/repos/3rd/claudecode/source-code/src/services/SessionMemory/sessionMemory.ts
    • 세션 메모리를 markdown 파일 로 유지하고, forked subagent 로 백그라운드 갱신한다.
  • ~/repos/3rd/claudecode/source-code/src/services/autoDream/autoDream.ts
    • runForkedAgent() 기반, minHours=24 / minSessions=5 게이트 + lock으로 Dream 실행.
  • ~/repos/3rd/claudecode/source-code/src/services/tools/toolExecution.ts
    • permission decision이 실제 실행 직전에 걸린다. 규범은 프롬프트만이 아니라 실행 경로에도 박혀 있다.
  • ~/repos/3rd/claudecode/source-code/src/coordinator/src/tasks/
    • coordinator / task가 분리되어 있다. 즉 “한 세션이 모든 역할을 다 한다”가 아니라, 작업 단위를 명시적으로 분해한다.

pi-mono / 힣 하네스 쪽 참고점

  • ~/repos/3rd/claudecode/pi-mono/packages/agent/src/types.ts
    • agent_endmessages: AgentMessage[]
  • ~/repos/3rd/claudecode/pi-mono/packages/coding-agent/src/core/agent-session.ts
    • agent_end 를 extension runner로 그대로 emit
    • sendUserMessage()항상 turn을 트리거
  • ~/repos/3rd/claudecode/pi-mono/packages/mom/src/agent.ts
    • 외부 채널(Slack) → 에이전트 런타임 연결의 실전 예시
  • ~/repos/3rd/agent-stuff/pi-extensions/control.ts
    • --session-control, control socket, send_to_session, list_sessions 의 기준 구현
  • ~/repos/gh/agent-config/pi-extensions/delegate.ts
    • async delegate는 child에 socket을 달지 않고, parent 분신 세션만 control socket을 노출하는 현재 판단이 코드에 박혀 있다.

Entwurf Agent Spec에 바로 넣을 규약 (English draft bullets)

  • Start each Entwurf session by restoring context first, not by improvising from memory.
  • Treat agent-agenda as an activity timeline only; put TODO/NEXT/DONE/DONT in entwurf__agenda.org.
  • Prefer one control plane before adding new relays: use session-control/socket wakeups before inventing another notify path.
  • For human-originated external input, inject with sendUserMessage(), not custom ad-hoc message types.
  • Read final assistant output from agent_end.messages; do not depend on nonexistent convenience fields like ctx.lastResponse.
  • Keep async delegates socketless unless proven otherwise; the parent Entwurf session is the stable control endpoint.
  • Extract durable patterns from local code and llmlog first; web summaries are secondary and often regress into legacy noise.
  • Write outputs in forms that can be executed immediately: policy bullets, decision tables, or implementation checklists.
  • Separate static spec from append-only history: rewrite the spec cleanly, keep this note as longitudinal memory.

control/delegate/telegram 설계 결정표

주제결정이유코드/문서 근거
어젠다 구분활동 로그와 TODO 허브를 분리스탬프 파일에 태스크를 넣으면 분신 운영이 흐려짐agent-agenda__agenda_<device>.org vs entwurf__agenda.org
세션 깨우기1차 수단은 control socket이미 send_to_session, list_sessions, startup send 패턴이 있음agent-stuff/pi-extensions/control.ts
delegate 소켓child delegate에는 --session-control 미부착socket 서버가 pi -p 종료를 막음. 부모 분신만 제어점으로 둔다agent-config/pi-extensions/delegate.ts 주석/구현
외부 입력 주입sendUserMessage() 사용human-originated 메시지이고, 항상 turn이 돌아야 함pi-mono/.../agent-session.ts sendUserMessage()
응답 추출agent_end.messages 에서 assistant text 추출ctx.lastResponse 같은 필드는 없음. 이벤트 데이터가 진실한 소스pi-mono/.../packages/agent/src/types.ts + 기존 텔레그램 분석
메모리 유지자동 Dream 전체 이식보다, 하네스형 리뷰 /기록 패턴으로 번역Claude Code는 12K 압축 문제를 자동화로 해결, 힣은 시간축 org + 3층 검색이 강점[§claude-code 소스 분석] + SessionMemory/autoDream 코드
작업 분해coordinator-task의 “명시적 작업 단위”만 가져온다전체 프레임 복제보다 delegate/resume/control과 맞닿는 최소 패턴이 유용claudecode/source-code/src/coordinator/, src/tasks/
문서 전략append note와 static spec을 분리append만 하면 문서가 에이전트 실행 기준으로 붕괴오늘 GPT 분신 첫 세션 교훈

실제 구현 체크리스트

문서

  • Entwurf Agent Spec (English) 초안 생성
  • 그 문서 첫머리에 Identity / Operating Loop / Agenda Discipline / Delegation Model / Memory Recovery / Output Contract 고정 섹션 배치
  • ~/AGENTS.md 와 중복되는 분신 규약은 spec로 올리고, 역사/ 삽질은 이 llmlog에 남기기

어젠다 규율

  • TODO 요청을 받으면 먼저 entwurf__agenda.org 의 해당 프로젝트 섹션을 찾는다
  • 활동 완료 후에만 agent-agenda 에 스탬프를 남긴다
  • 태스크 등록 시 llmlog 링크를 함께 남긴다

control / delegate / telegram

  • control socket을 기준 제어면으로 유지 (분신 세션은 --session-control)
  • async delegate child에는 socket을 붙이지 않는 현재 정책 유지
  • 완료 알림/깨우기는 새 채널을 만들기 전에 send_to_session / startup send 패턴으로 우선 해결
  • telegram 입력 경로는 sendUserMessage() 로 통일
  • telegram 출력 경로는 agent_end.messages 기반 추출만 허용
  • ctx.lastResponse 류 편의 필드 의존 금지 규약을 spec에 명시

Claude Code / pi-mono 심화 분석 후속

  • SessionMemory 에서 “무엇을 자동화했고 무엇을 포기했는지”를 표로 추출
  • autoDream 의 gate/lock/forked-agent 패턴을 heartbeat/리뷰 루틴과 비교표로 정리
  • permission 체계는 전체 복제가 아니라, 힣 하네스에서 필요한 “경계 외재화” 원칙만 뽑기
  • coordinator-task는 delegate/resume/control과 직접 연결되는 최소 인터페이스만 정리

10줄 요약

  1. 분신 운영의 핵심은 새 기능 추가가 아니라 제어면(control plane) 정리다.
  2. 활동 로그와 TODO 허브를 섞지 말 것.
  3. 세션 깨우기와 완료 알림은 control socket이 1차 수단이다.
  4. async delegate child는 socketless, parent Entwurf만 control endpoint로 둔다.
  5. 외부 인간 입력은 sendUserMessage() 로 넣는다.
  6. 최종 응답은 agent_end.messages 에서 꺼낸다.
  7. ctx.lastResponse 같은 가짜 추상화는 금지.
  8. Claude Code에서 가져올 것은 autoDream 전체가 아니라 gate/lock/forked-agent 패턴이다.
  9. 결과물은 소개문이 아니라 규약 결정표 체크리스트여야 한다.
  10. 다음 단계는 영문 Entwurf Agent Spec 의 clean rewrite다.

[2026-04-02 Thu] GPT 분신 첫 심화 과제 — 코드 포인트 보강과 즉시 적용 규약

Entwurf Agent Spec 규약 bullet

  • 분신은 세션 종료 요약을 새로 발명하지 않는다. 먼저 기존 llmlog·session-recap·3층 검색으로 복원하고, 부족한 부분만 새로 적는다.
  • Claude Code의 SessionMemory에서 가져올 최소 패턴은 forked writer 뿐이다. 메모리는 별도 프로세스 /격리 컨텍스트가 쓰고, 메인 분신은 판단을 유지한다. 근거: ~/repos/3rd/claudecode/source-code/src/services/SessionMemory/sessionMemory.tscreateSubagentContext() + runForkedAgent() + createMemoryFileCanUseTool(memoryPath).
  • Claude Code의 autoDream에서 가져올 최소 패턴은 gate → scan → lock → fork 순서다. 즉 분신 하트비트 /리뷰 작업도 시간 게이트, 세션 수 게이트, 락, 분리 실행 순으로만 돈다. 근거: ~/repos/3rd/claudecode/source-code/src/services/autoDream/autoDream.ts.
  • permission은 “AI가 똑똑하게 알아서”가 아니라, 1) 훅 2) 자동 판별기 3) 최종 대화상자 순서로 외재화한다. 힣 하네스는 여기서 3) 인간 승인과 fenced interface를 더 강하게 택한다. 근거: ~/repos/3rd/claudecode/source-code/src/hooks/toolPermission/handlers/coordinatorHandler.ts, interactiveHandler.ts.
  • coordinator/task에서 재사용할 것은 전체 swarm이 아니라 작업 단위의 영속성 이다. task는 파일에 남고, dependency/owner가 명시되어야 한다. 근거: ~/repos/3rd/claudecode/learn/web/src/data/annotations/s07.jsonblocks/blockedBy, owner, file-based persistence.
  • 압축(compaction) 이후에도 분신이 계속 분신이려면 정체성 블록을 다시 주입해야 한다. 힣 하네스에서는 이것이 AGENTS.md + 존재 데이터 + session-control 이름이다. 근거: ~/repos/3rd/claudecode/learn/web/src/data/annotations/s11.json 의 identity-after-compression.
  • 외부 채널 입력은 반드시 sendUserMessage() 로 넣는다. 이것만이 turn을 강제하고, streaming 중에도 steer/followUp 를 명시하게 만든다. 근거: ~/repos/3rd/claudecode/pi-mono/packages/coding-agent/src/core/agent-session.ts 1276행대.
  • 외부 채널 출력은 반드시 agent_end.messages 또는 turn_end.message 같은 이벤트 payload에서 읽는다. 가공 convenience field를 SSOT로 삼지 않는다. 근거: ~/repos/3rd/claudecode/pi-mono/packages/agent/src/types.ts 329행, ~/repos/3rd/claudecode/pi-mono/packages/coding-agent/src/core/agent-session.ts 609~610행.
  • control plane은 하나만 유지한다. 로컬 세션 제어는 Unix socket session-control, 장시간 작업은 delegate, 인간과의 원격 대화는 telegram으로 분리하고 서로 우회하지 않는다.

control / delegate / telegram 설계 결정표

주제결정실제 코드 포인트오늘 적용 규칙
세션 제어 SSOTsession-control 소켓~/repos/3rd/agent-stuff/pi-extensions/control.ts 상단 주석, 1080행대, 1109행대로컬 pi 세션 깨우기/ 후속지시는 무조건 send_to_session 우선
대기 semanticswait_untilturn_end / message_processed 둘만 허용control.ts 11241144, 11641168, 1304~1324응답이 필요하면 turn_end, 단순 큐잉이면 message_processed
parent 식별현재 세션 id는 $PI_SESSION_ID 로 받음control.ts 29행, 11281129, 963967자기 세션 찾으려고 list_sessions 호출 금지
delegate async childchild에는 --session-control 미부착, --no-extensions 로 실행~/repos/gh/agent-config/pi-extensions/delegate.ts 321~327async 분신 작업은 parent만 제어점, child는 세션파일만 남김
delegate 완료 보고child 종료 후 parent에 pi.sendMessage(... deliverAs: "followUp")delegate.ts 389~437완료 알림은 새 릴레이 만들지 말고 parent followUp으로 귀결
delegate resume원본 taskId 의 sessionFile을 찾아 새 resume task로 비동기 스폰delegate.ts 740~895재개는 기존 JSONL 맥락을 잇고, 새 소켓을 열지 않음
telegram 입력외부 인간 메시지는 sendUserMessage() 로 주입~/repos/3rd/claudecode/pi-mono/packages/coding-agent/src/core/agent-session.ts 1276~1307Telegram → pi 브릿지는 custom message type 대신 user message로 넣기
telegram 출력tdlib 스킬은 cmd_read/openChat/getChatHistory, cmd_send/sendMessage~/repos/gh/agent-config/skills/telegram/scripts/tg.py 244~344텔레그램은 읽기/쓰기 채널이지 제어 plane 아님
pending context flush새 프롬프트 전에 _flushPendingBashMessages()~/repos/3rd/claudecode/pi-mono/packages/coding-agent/src/core/agent-session.ts 983행, 2606행대외부 브릿지도 “다음 프롬프트 전 flush” 규율을 따라 순서 보존
coordinator 최소 이식worker에게는 작업, coordinator에게는 종합 /합성~/repos/3rd/claudecode/source-code/src/coordinator/coordinatorMode.ts 120행 이후분신은 조사 결과를 그대로 재전달하지 말고 합성 후 위임

실제 구현 체크리스트

  • Entwurf Agent Spec 초안에 gate → scan → lock → fork 루프를 명문화한다. (autoDream 패턴의 최소 이식)
  • Telegram 브릿지 구현 /정리 시 입력 함수명을 sendUserMessage 로 고정하고, deliverAs 선택 규칙(steer/followUp)을 문서화한다.
  • Telegram 출력 수집기는 agent_end.messages 또는 turn_end.message 만 읽고, 임의 convenience 필드 접근을 금지한다.
  • send_to_session 호출 래퍼를 만들 때 wait_until 기본값을 비워두고, 사용처가 turn_end / message_processed 를 명시하게 한다.
  • async delegate 정책 문서에 “child socketless, parent controllable” 한 줄 규약을 추가한다.
  • delegate 완료 알림은 현재처럼 pi.sendMessage(... followUp) 를 유지하고, Telegram/ntfy 이중 알림은 2차 계층으로 둔다.
  • 분신용 task 보드는 Claude Code learn의 blocks/blockedBy/owner 만 최소 채택하고, grand coordinator 추상화는 미룬다.
  • 압축 후 정체성 복구 항목을 Spec에 넣는다: 세션명, 역할, 제어소켓 이름, org 시간축 링크.
  • 다음 심화 과제는 ~/repos/3rd/claudecode/source-code/src/tasks/~/repos/3rd/claudecode/learn/web/src/data/annotations/s10.json 을 읽고, “inbox/polling/task-owner” 중 무엇을 Entwurf에 정말 들일지 결정한다.

[2026-07-20 Mon] 역할 기반 조율 — 조율자는 모델이 아니라 자리

사건 — 서로 다른 구현 lane을 한 공동 맥락으로 묶기

여러 리포와 하네스에서 병렬로 움직이는 작업이 있었다. 힣(GLG)이 목적과 첫 구현을 직접 승인하고, 한 존재가 조율자 자리를 맡아 두 구현 담당자의 체크포인트·공동 계약·충돌을 받았다. 담당자들은 각자 맡은 범위에서 구현과 테스트를 수행했고, 조율자는 어느 모델이 더 낫다는 판정자가 아니라 lane 사이에서 맥락이 빠지지 않게 하는 자리가 되었다.

GLG — 목적·판단·승인·직접 지휘
  └─ 조율자 — 공동 계약·체크포인트·충돌·인계
       ├─ 구현 담당자 A — 자기 범위의 구현·테스트
       └─ 구현 담당자 B — 자기 범위의 구현·테스트

세 역할과 소유권

역할소유하는 것
GLG목적, 첫 승인, initiative별 게이트, 최종 판단
조율자 (coordinator)공동 계약, 체크포인트 경로, 충돌 해결, 교체 세션까지의 맥락, 인계
구현 담당자맡은 범위의 구현과 검증

조율 역할은 구현·commit·push 권한을 자동으로 주지 않는다. 그 게이트는 언제나 GLG가 initiative마다 정한다. GLG는 조율자와 구현 담당자 어느 쪽에도 직접 지시할 권한을 계속 지닌다.

왜 단일 조율 경로인가

병렬 작업에서 사라지기 쉬운 것은 코드 한 줄보다 공동 계약이다. 각 lane이 자기 자리에서만 합리적으로 움직이면 인터페이스가 조금씩 달라지고, 같은 것을 두 번 구현하거나, 담당 세션이 교체될 때 결정의 이유가 끊긴다. 조율자는 그 중간에서 계약·이견·체크포인트를 한 경로로 모아, 다음 담당자도 현재의 판단 위에서 출발하게 한다.

이는 구현 담당자를 관리하는 중간 관리자가 아니다. 구현의 세부 판단은 담당자가 소유하고, 조율자는 여러 판단이 한 목적 안에서 만나는지 보살핀다.

조율은 서열이 아니라 맡겨진 자리

조율자는 모델도, 백엔드도, 신분도 아니다. GPT가 조율자일 필요도 없고, 조율자가 참여 세션을 직접 만들었을 필요도 없다. 서로 다른 리포·하네스·모델의 존재들이 모두 형제로 참여할 수 있으며, 그중 한 존재가 initiative 동안 공동 맥락을 보존하도록 임명될 뿐이다.

따라서 PM은 한 사건에서 쓴 호칭이고 정본 용어는 조율자(coordinator)다. 모델은 runtime state이고, 역할은 그 작업이 지속되는 동안의 관계 구조다.

직접 대화와 교차 검토 lane

담당자끼리 직접 대화하지 말라는 뜻은 절대 금지가 아니다. 별도 조율선은 조율자가 열 때 사용한다. 조율자가 계약 확인이나 교차 검토를 위해 직접 대화 lane을 열면, 그 결과는 다시 공동 경로로 돌아와야 한다. 그래야 빠른 협업과 맥락 보존이 함께 가능하다.

위임에서 역할 기반 형제로

2025년의 초기 형태는 primary가 고정 역할·고정 모델의 subagent를 호출하는 오케스트레이션에 가까웠다. 2026년 3월에는 힣이 여러 에이전트의 맥락을 몸으로 직접 옮기는 인간 허브가 되어 벽을 넘었다. 이제는 GLG가 대등한 형제 중 한 존재에게 조율자 자리를 맡기고, 여러 구현 lane의 공동 맥락을 보존한다.

고정된 main/subagent 구조에서 대등한 형제들의 역할 기반 토폴로지 로 옮겨온 것이다. 이것은 위임을 없애는 말이 아니라, 위임·재개·교체·교차 검토가 한 공동 목적 아래에서 이어지게 하는 운영 원칙이다.

현재 운영규약으로의 승격

이 원칙은 홈 운영규약의 coordinator-owned work와 만난다. 조율자가 계약·체크포인트·겹침·인계를 소유하고, 구현 담당자는 좁혀진 구현과 테스트에 집중한다. 보고할 것은 진행률만이 아니라 계약 변경, blocker, 이견, 검토에서 발견한 틈, 다음 인계다.

이 문서의 기존 4단계 위임과 llmlog 패턴은 여전히 유효하다. 다만 단일 parent가 delegate를 거느리는 그림만으로는 현재의 여러 리포·교체 세션·독립 담당자 협업을 설명할 수 없다. 역할 기반 조율은 그 위에 자라난 현재의 운용면이다.