Files
multi-agent-mux/docs/contracts/issue-5/herdr-runtime.md
T

9.5 KiB

📑 Herdr Runtime Contract and Backend Capability Matrix

  • Document Version: Rev.3 (Post Cross-Review Corrections)
  • Issue: Gitea Issue #5
  • Target Herdr Version: herdr 0.8.2
  • Scope: Native Herdr API Contract, External Collector Specification, and Backend Matrix

1. Herdr 0.8.2 네이티브 API 계약 (Native API Contract)

1-1. 핵심 CLI 명령어 및 반환 페이로드

herdr는 AI 코딩 에이전트 전용 터미널 멀티플렉서로서, 소켓 API를 통해 터미널 스크린 감시 상태를 제공합니다:

  1. herdr agent list: 현재 활성화된 모든 에이전트 목록 및 상태 반환 (JSON stdout, exit 0).
  2. herdr agent get <target>: 특정 에이전트의 단일 시점 스냅샷 반환 (agent_status, interactive_ready, pane_id, revision, state_change_seq 등).
  3. herdr agent wait <target> [OPTIONS]: 에이전트가 지정된 상태에 도달할 때까지 블로킹 대기.
  4. herdr agent explain [OPTIONS] [target]: 내부 정규식 매칭 규칙(matched_rule, evaluated_rules) 평가 세부정보 반환.

1-2. 네이티브 상태 집합 (agent_status)

  • 지원 Enum: idle, working, blocked, done, unknown (총 5종).
  • interactive_ready (boolean):
    • 터미널이 키 입력을 수신할 준비가 되었는지를 나타내는 플래그.
    • 실측 불변식: 에이전트가 코딩 작업 중(agent_status: "working")일 때도 interactive_ready: true임이 입증됨. 따라서 interactive_ready 단독으로는 작업 완료의 충분조건이 될 수 없으며, 오직 agent_status in {"idle", "done"} 상태와 결합되어야 합니다.

1-3. herdr agent wait 호출 규격 및 채널 분리 실측

실제 herdr 0.8.2 실행(wait-contract.json 및 evidence/timeout_stderr.json)을 통해 검증된 입출력 채널 및 종료 코드 계약은 다음과 같습니다:

호출 조건 명령 예시 종료 코드 출력 채널 반환 JSON 페이로드 구조
상태 도달 (성공) herdr agent wait creator-agy-01 --until working --timeout 1000 exit 0 stdout {"id":"cli:agent:wait","result":{"agent":{...},"type":"agent_info"}}
타임아웃 (Timeout) herdr agent wait creator-agy-01 --until done --timeout 50 exit 1 stderr {"error":{"code":"timeout","message":"timed out waiting for agent status"},"id":"cli:agent:wait"}
대상 부재 (Unknown) herdr agent wait non-existent --until idle --timeout 50 exit 1 stderr {"error":{"code":"agent_not_found","message":"agent target non-existent not found"},"id":"cli:agent:wait"}
기본 대기 옵션 생략 herdr agent wait <target> N/A N/A --until 생략 시 기본 매칭 대상은 idle, done, blocked임. --timeout 생략 시 무기한 대기함

🚨 Critical Empirical Finding (수정 반영): herdr agent wait에서 성공(상태 일치) 시에는 정상 JSON이 stdout으로 출력되지만, **타임아웃(timeout) 및 대상 부재(agent_not_found) 등 모든 에러 응답은 stderr로 에러 JSON이 출력되며 종료 코드는 exit 1**입니다 (stdout은 비어있음). 따라서 Watcher 엔진은 exit 1 시 반드시 stderr 스트림에서 JSON 에러 페이로드를 파싱해야 합니다.


2. 외부 시퀀스 수집기 계약 (External Sequence Collector)

2-1. 단일 wait 호출의 본질적 한계

  • herdr agent wait는 타겟이 특정 상태에 도달한 시점에 단 1개의 최종 스냅샷 JSON만 반환하는 동기적 장벽(Barrier)입니다.
  • 호출 도중 거쳐간 중간 전이 과정(Transition Stream)을 반환하지 않습니다.
  • 따라서 working ➔ idle과 같은 상태 전이를 입증하려면, 외부 오케스트레이터/수집기가 사전 스냅샷(before)과 사후 스냅샷(after)을 독립적으로 획득하여 타임스탬프와 함께 연결해야 합니다.

2-2. 수집기(Collector) 권장 규격

  • 폴링 주기: 1~2초 수준의 유계(Bounded) 폴링 (agent get). 고정밀 10ms 스핀 폴링은 불필요하며 CPU 낭비를 초래합니다.
  • Envelope 메타데이터: 단조 시계 오프셋(monotonic_start, monotonic_end), collector_clock_id, capture_id, source_command를 필수로 보존하여 시점 간 왜곡을 방지합니다.

3. 이벤트, 파일시스템 및 디스패치 연계 경계

Herdr 네이티브 페이로드와 Multi-Agent-Mux 오케스트레이션 메타데이터 사이에는 엄격한 책임 격리가 유지되어야 합니다:

┌─────────────────────────────────────────────────────────────┐
│                 Herdr Native API Boundary                   │
│   • agent_status (idle/working/blocked/done/unknown)        │
│   • interactive_ready (true/false)                          │
│   • pane_id, state_change_seq, terminal_title               │
└──────────────────────────────┬──────────────────────────────┘
                               │ 관측 증거 제공 (채널 2)
                               ▼
┌─────────────────────────────────────────────────────────────┐
│             Multi-Agent-Mux Watcher Boundary                │
│   • 4-Fold Attribution:                                     │
│     (job_id, attempt_id, session_uuid,                      │
│      pane_process_generation)                               │
│   • File Evidence (report mtime debounce >=15s, hash)       │
│   • Backplane Events (seq, HMAC signature, started/progress)│
└─────────────────────────────────────────────────────────────┘
  • 불변식: Herdr 원본 응답 페이로드에는 job_id, attempt_id, report phase, expected_decision 등의 MAM 내부 필드를 절대 주입하지 않습니다.

4. 6개 백엔드 기능 및 실측 증거 행렬 (Capability Matrix)

본 프로젝트가 지원하는 6개 에이전트 백엔드(claude, agy, hermes, grok, opencode, codex)의 현 환경 실측 상태 및 Gap 현황입니다 (모든 슬롯은 tests/fixtures/issue_5/herdr/manifest.json과 100% 일치):

백엔드 설치 바이너리 경로 활성 세션명 실측 캡처 슬롯 미관측 슬롯 (Gaps) 및 사유 Provenance
claude ~/.local/bin/claude planner-reviewer-claude-01 idle (claude/idle.json) working, blocked, done, unknown (캡처 시점에 idle 상태였음) observed
agy ~/.local/bin/agy creator-agy-01 working (agy/working.json), wait_timeout (agy/wait_timeout.json) idle, blocked, done, unknown (작업 수행 중이며 권한 건너뛰기 적용) observed
grok ~/.grok/bin/grok reviewer-creator-grok-01 idle (grok/idle.json) working, blocked, done, unknown (리뷰 대기 중 유휴 상태 캡처) observed
codex ~/.local/bin/codex planner-reviewer-codex-01 done (codex/done.json) idle, working, blocked, unknown (이전 플래너 작업 완료 직후 캡처) observed
hermes ~/.local/bin/hermes N/A (미가동) 없음 idle, working, blocked, done, unknown (Herdr 서버에 활성 세션 부재) unobserved
opencode ~/.opencode/bin/opencode N/A (미가동) 없음 idle, working, blocked, done, unknown (Herdr 서버에 활성 세션 부재) unobserved

📌 정직한 증거 보고 원칙 (D3, D6):

  1. 오직 실제로 실행하여 캡처한 슬롯만 observed로 인정하며, 모의 실행이나 가상 시뮬레이션을 네이티브 캡처로 둔갑시키지 않습니다.
  2. hermes와 opencode의 미가동 슬롯 및 기존 4개 백엔드의 미관측 상태는 모두 정직하게 unobserved gap으로 기록합니다.
  3. Grok 세션 등은 캡처 시점에 idle이었으나 리뷰 실행 시 working으로 전이되므로, 정적 캡처가 에이전트의 영구 불변 능력을 뜻하지 않음을 명시합니다.

5. 복합 시나리오 기대 정책 (Composite Expected Policy)

Watcher가 다중 채널 증거를 결합하여 내리는 최종 완료 판정 정책:

  1. initial_idle: 디스패치 기록은 있으나 해당 시도의 실행 앵커가 없으면 ➔ hold (완료 거부).
  2. tool_running: Herdr는 working이나 하네스에서 도구 실행 중이면 ➔ hold (대기).
  3. report_pause_15s: 파일이 15초간 멈추었으나 확정 매니페스트가 없으면 ➔ hold (대기).
  4. finalized_candidate: 4중 귀속 일치 + Fresh idle/done + 원자적 매니페스트/해시 일치 ➔ candidate_approved (CAS 커밋 허용).
  5. blocked_permission: Herdr가 blocked이면 ➔ hold_blocked (완료 금지).
  6. transport_disconnected: 소켓 통신 실패 시 ➔ hold_reconnect (스냅샷 재동기화).
  7. restarted_generation: PID/세션 식별자가 변경된 과거 시도의 신호 ➔ reject_stale (전이 거부).