Pipeline Architecture Spec — C4I Framework

Status: draft Created: 2026-04-18 결정자: 회장 근거: 다이아몬드 토론 2회 (A07 구조적 복구 + 파이프라인 아키텍처)

1. 개요

1.1 현재 문제

현재 파이프라인(server/src/index.ts)은 모놀리스 핸들러 구조다:

  • 메시지 수신 → CEO 분석 → C레벨 지시 → 워커 실행 → 결과 수집이 하나의 거대한 함수 안에 뒤섞여 있음
  • 계층 간 통신이 프롬프트 텍스트 파싱([DELEGATE] 태그 정규식)에 의존 → 깨질 수 있는 경로 존재
  • 리더 계층이 dead code (정의만 있고 호출 0회)
  • 명령은 아래로만 흐르고, 보고↑ 채널 부재
  • 에러 시 구조적 복구 없이 catch-log-continue

1.2 왜 C4I인가

BigBossOS는 계급 조직이다 (회장→CEO→C레벨→리더→워커). 군사 지휘통제체계(C4I: Command, Control, Communications, Intelligence)가 이 구조에 가장 자연스럽게 매핑된다.

C4I를 뼈대로 잡고, 다른 체계에서 이점만 차용한다:

차용 출처가져오는 것적용 위치
컴파일러IR(중간 표현) 타입계층 간 데이터 규격 — 타입 불일치 시 컴파일 에러
OS 커널syscall = 구조화 출력계층 간 통신 — 프롬프트 해석 제거, 구조적 강제
Unix 철학독립 모듈공정별 분리 — 하나 고장나도 다른 공정 무관
원자력발전소SIL 등급 + SCRAM안전 체계 — 위험도별 검증 단계 자동 결정
도요타 TPS안돈 시그널이상 감지 시 일시정지 + 상위 판단 요청
항공관제핸드오프 프로토콜 + 스트립계층 간 인계 3단계 + 작업 추적
잠수함 운용침묵 항해 + 구획화 + 당직제한 자원 하 독립 운용, 자원 격리, 에너지 관리

1.3 설계 원칙

  1. 프롬프트 믿지 말고 구조화 — 행동은 코드 플로우(choke point)로 강제. 프롬프트 의도 서술 금지.
  2. 증상치료 금지, 근본해결만 — 현실적 타협 무관용. 초기/중기/장기 분할 금지.
  3. WHAT vs WHO 분리 — C레벨은 WHAT(도메인 과업)만 출력. WHO(인원 배치)는 시스템이 결정.
  4. 순차 실행 + ViewHolder — 메모리/CPU 제약(셀프호스팅). C레벨 듀얼트랙만 예외.
  5. 무료 전용 — 유료 서비스 회장 승인 필수.

2. Command (지휘)

2.1 지휘 체계

회장 (Chairman) ──── 인간. 최종 권한. 시스템 외부.
  └─ CEO ─────────── AI. 조직 수준 의사결정, C레벨 인사권.
       └─ C-Level ── AI. 도메인 정책 수립 (CTO/COO/CFO/CMO/CPO/CISO).
            └─ Leader ── AI. 구현 계획 수립 (backend_lead, frontend_lead, ...).
                 └─ Worker ── AI. 코드 실행. 유일한 코드 작성 계층.

하향 단방향 명령 원칙: 상위→직속 하위만 명령 가능. 계층 건너뛰기 금지.

CEO    → C-Level만
C-Level → Leader만
Leader  → Worker만
Worker  → 명령 불가 (보고만 가능)

2.2 OPORD (작전명령서) 구조

NATO 작전명령서 5단계를 IR 타입의 필수 필드로 강제한다. 계층별로 필수 필드가 다르다:

필드설명CEO→C레벨C레벨→리더리더→워커
situation현재 프로젝트/도메인 상태필수선택-
mission이번 사이클에서 달성할 것필수필수필수
execution구체적 과업 분해필수필수필수
sustainment토큰/메모리/시간 제약필수필수선택
commandSignal보고 경로, 에스컬레이션 조건필수선택-

필수 필드 누락 시 타입 에러 → 컴파일 불가. 런타임에 도달하지 않는다.


3. Control (통제)

3.1 계층별 권한 범위

각 계층은 할 수 있는 것절대 하면 안 되는 것(ROE)이 정의된다.

계층권한금지 (ROE)
CEOC레벨 인사(고용/해고), 조직 구조 변경, 전체 진행 판단코드 작성, 직접 워커 지시, 도메인 세부 결정
C-Level도메인 정책 수립, 리더 배치 지시, 콘실리에리 활용 토론/작업타 도메인 침범, 직접 워커 지시, 인사권
Leader섹션 내 워커 배치, 구현 계획 수립, 워커 결과 검증타 섹션 워커 지시, 정책 수립, 코드 직접 작성
Worker코드 작성/수정, 빌드/테스트 실행상위 계층 명령, 타 워커 지시, 정책 결정

3.2 ROE (교전규칙) — 도메인 권한

C레벨별 관할 도메인. sections.tscLevel 필드로 코드에 이미 정의되어 있으며, 이를 STRICT 강제한다:

// ROE enforcement — C-Level can only command sections under their domain
interface ROE {
  clevelId: CLevel;
  allowedSections: string[];    // sections.ts에서 자동 도출
  forbiddenActions: string[];   // tier-routing에서 구조적 차단
}

// Example: CTO의 ROE
// allowedSections: ['cto', 'architecture', 'backend', 'frontend', 'qa']
// forbiddenActions: ['budget_decision', 'marketing_campaign', 'hiring_non_tech']
//
// getSectionsForCLevel('cto')로 자동 도출 — 하드코딩 아님

위반 시: STRICT 모드에서 명령 자체가 차단. WARN 모드 폐지.

3.3 SIL (Safety Integrity Level)

모든 에이전트 도구 호출에 위험 등급이 내장된다. 등급에 따라 검증 단계 수가 자동 결정:

SIL위험도검증예시
SIL-1조회무검증Read, Glob, Grep
SIL-2분석로그 기록WebSearch, WebFetch
SIL-3변경단일 검증 (리더 or 자동)Write, Edit
SIL-4파괴/배포이중 검증 (리더 + C레벨)Bash(rm/deploy), DB 삭제
// SIL is derived from the tool itself, not assigned per-task
enum SIL { QUERY = 1, ANALYSIS = 2, MUTATION = 3, DESTRUCTIVE = 4 }

const TOOL_SIL: Record<string, SIL> = {
  Read: SIL.QUERY,
  Glob: SIL.QUERY,
  Grep: SIL.ANALYSIS,
  WebSearch: SIL.ANALYSIS,
  Write: SIL.MUTATION,
  Edit: SIL.MUTATION,
  Bash: SIL.DESTRUCTIVE,    // default — specific commands can be downgraded
};

// SIL-4 verification: leader.verify() + clevel.verify() both must return true
// SIL-3 verification: leader.verify() only
// SIL-2: log only
// SIL-1: no verification

4. Communications (통신)

4.1 구조화된 출력 = Syscall

계층 간 통신은 스키마 검증된 구조화 출력으로만 이루어진다. 텍스트 파싱(정규식) 금지.

현행 (제거 대상):

C-Level이 텍스트로 "[DELEGATE] backend_dev_1: API 만들어" 출력
→ 정규식으로 파싱 → agentId 추출 → 실패 가능

목표 (구조적 강제):

C-Level → Agent Adapter → 구조화 출력(IR 스키마 준수)
→ 파이프라인이 IR 스키마 검증 → 불일치 시 거부 → 깨질 수 있는 경로 없음

4.2 Agent Adapter — 모델/CLI 교체 대비

파이프라인은 IR 타입만 안다. 어떤 모델로, 어떤 CLI로 IR을 생성하는지는 어댑터 책임.

// Agent Adapter Interface — 모든 모델/CLI가 구현해야 하는 계약
interface AgentAdapter {
  // 에이전트를 호출하고 IR 스키마에 맞는 구조화 출력을 반환
  invoke<T>(params: AgentInvokeParams<T>): Promise<T>;
}

interface AgentInvokeParams<T> {
  agentId: string;
  role: string;
  systemPrompt: string;
  message: string;
  outputSchema: JSONSchema;          // IR 타입의 JSON 스키마
  cwd: string;
  tier: AgentTier;
}

// ── 어댑터 구현체 ──

// Claude CLI (현재 사용 중)
class ClaudeCLIAdapter implements AgentAdapter {
  // claude -p --json-schema '...' --model sonnet ...
  // 또는 claude -p → 텍스트 출력 → 서버 측 스키마 검증
}

// Ollama (Gemma/DeepSeek/Qwen 로컬 모델)
class OllamaAdapter implements AgentAdapter {
  // ollama run --format json ...
  // 서버 측 스키마 검증
}

// Soldato (Pizza 로컬 모델, 침묵 항해 시 사용)
class SoldatoAdapter implements AgentAdapter {
  // soldato run --schema '...' ...
}

// OpenAI Codex
class CodexAdapter implements AgentAdapter {
  // codex --json-schema '...' ...
}

// 미래 추가 어댑터
// class QwenAdapter implements AgentAdapter { ... }
// class DeepSeekAdapter implements AgentAdapter { ... }

핵심 원칙:

  • 파이프라인 코드에 claude, ollama, codex 등의 이름이 직접 등장하지 않는다
  • 파이프라인은 adapter.invoke(params) 만 호출
  • 어댑터 교체 = 환경변수 1개 변경 (AGENT_ADAPTER=claude-cli | ollama | codex | soldato)
  • 스키마 검증은 파이프라인 측에서 수행 (어댑터 내부 검증에 의존하지 않음)
// 파이프라인의 Phase 모듈이 어댑터를 사용하는 방식
async function phaseCLevel(directive: CEODirective, adapter: AgentAdapter): Promise<CLevelOrder[]> {
  const raw = await adapter.invoke<CLevelOrderOutput>({
    agentId: `clevel-${directive.targetCLevel}`,
    role: directive.targetCLevel,
    systemPrompt: buildCLevelPrompt(directive),
    message: JSON.stringify(directive),
    outputSchema: CLEVEL_ORDER_SCHEMA,    // IR 스키마
    cwd: projectDir,
    tier: 'clevel',
  });

  // 파이프라인 측 스키마 재검증 (어댑터를 신뢰하지 않음)
  validateIR(raw, CLEVEL_ORDER_SCHEMA);   // 실패 시 안돈 발동

  return raw.orders;
}

4.3 계층별 출력 스키마

각 계층은 자기 계층의 스키마로만 출력 가능. 타 계층 스키마 출력 불가.

// ── CEO 출력 스키마 ──
// CEO LLM 호출 시 outputSchema로 전달. 이 스키마에 맞는 JSON만 유효 출력.
const CEO_OUTPUT_SCHEMA = {
  type: "object",
  required: ["action"],
  properties: {
    action: { type: "string", enum: ["issue_directive", "hire_clevel", "fire_clevel"] },
    directives: {
      type: "array",
      items: {
        type: "object",
        required: ["targetCLevel", "situation", "mission", "execution", "sustainment", "commandSignal"],
        // ... CEODirective 전체 스키마
      },
    },
    hireProposal: {
      type: "object",
      properties: {
        role: { type: "string" },
        justification: { type: "string" },
      },
    },
  },
};

// ── C-Level 출력 스키마 ──
const CLEVEL_OUTPUT_SCHEMA = {
  type: "object",
  required: ["orders"],
  properties: {
    orders: {
      type: "array",
      items: {
        type: "object",
        required: ["section", "mission", "tasks"],
        // ... CLevelOrder 전체 스키마
      },
    },
    debateRequest: {
      type: "object",
      properties: {
        topic: { type: "string" },
        urgency: { type: "string", enum: ["immediate", "normal", "background"] },
      },
    },
  },
};

// ── Leader 출력 스키마 ──
const LEADER_OUTPUT_SCHEMA = {
  type: "object",
  required: ["assignments"],
  properties: {
    assignments: {
      type: "array",
      items: {
        type: "object",
        required: ["workerRole", "mission", "targetFiles", "expectedOutput"],
        // ... LeaderAssignment 전체 스키마
      },
    },
  },
};

// ── Worker 출력 스키마 ──
// Worker는 코드 실행 도구(Read/Write/Edit/Bash/Glob/Grep)로 작업 후
// 결과를 구조화 출력으로 보고
const WORKER_OUTPUT_SCHEMA = {
  type: "object",
  required: ["status", "summary", "filesModified"],
  properties: {
    status: { type: "string", enum: ["success", "failure", "partial"] },
    summary: { type: "string" },
    filesModified: { type: "array", items: { type: "string" } },
    errors: { type: "array", items: { type: "string" } },
  },
};

4.3 핸드오프 프로토콜

항공관제 인계 3단계. 계층 간 작업 전달 시 수신 측이 거부할 수 있다.

1. 상위: handoff_request(IR 데이터) → 하위에게 전달
2. 하위: handoff_accept 또는 handoff_reject(사유)
3. 상위: handoff_confirm → 관할 이전 완료
interface HandoffRequest {
  fromAgent: string;
  toAgent: string;
  ir: CEODirective | CLevelOrder | LeaderAssignment;
  sil: SIL;
  taskStripId: string;
}

interface HandoffResponse {
  action: 'accept' | 'reject';
  reason?: string;         // reject 시 필수
}

// Reject 상한: 2회. 초과 시 자동 에스컬레이션.
// reject 사유: 'out_of_section' | 'resource_exceeded' | 'capability_mismatch'
const MAX_REJECTS_PER_TASK = 2;

거부 시 흐름:

  1. 1차 거부 → 상위 계층이 재배치 (다른 리더/워커)
  2. 2차 거부 → 자동 에스컬레이션 (상위 계층의 상위로)
  3. CEO까지 올라가면 → 회장 에스컬레이션 큐

5. Intelligence (정보)

5.1 보고↑ 채널

현행: 명령↓만 존재. 결과는 agentResults 배열로 수집되지만, 구조화된 보고 채널 없음.

목표: 각 계층이 정형화된 보고서를 상위에 제출. 기존 lifecycle-emitter.ts의 U01~U09 마커와 통합.

Worker  → Leader:  WorkerResult   (U01)
Leader  → C-Level: LeaderReport   (U02)
C-Level → CEO:     CLevelReport   (U03)
CEO     → Chairman: CEOReport     (U04)

보고서는 구조화 출력(IR 스키마) 으로 제출. 텍스트 파싱 아님.

5.2 콘실리에리 정보 수집

콘실리에리는 Intelligence 축의 핵심 자산이다:

  • 하향: 에이전트 생성 시 getConsigliereContext(task, role)로 관련 지식 주입
  • 상향: 토론 결과, 의사결정 로그를 콘실리에리 DB에 자동 색인
  • 수평: C레벨 간 교차 도메인 참조 시 콘실리에리가 관련 문서 제공

C레벨 듀얼트랙에서 콘실리에리의 역할:

C-Level ──┬── [Track A] 토론 (콘실리에리 → 도메인 지식 검색 → 토론 근거 제공)
           └── [Track B] 작업 (콘실리에리 → 섹션 컨텍스트 주입 → 리더에게 지시)

5.3 Task Strip (작업 추적표)

항공관제 비행 진행 스트립. 각 task에 메타데이터를 부착하여 파이프라인 어디서든 현재 위치 추적.

interface TaskStrip {
  taskId: string;
  originMessage: string;           // chairman의 원본 요청 ID
  currentHolder: string;           // 현재 담당 에이전트 ID
  tier: AgentTier;                 // 현재 계층
  phase: 'intake' | 'command' | 'handoff' | 'execution' | 'report' | 'review' | 'complete' | 'escalated';
  sil: SIL;
  handoffCount: number;
  rejectCount: number;
  elapsedMs: number;
  tokensBudget: number;
  tokensConsumed: number;
  andonHistory: AndonSignal[];     // 이 task에서 발생한 안돈 이력
  createdAt: string;               // ISO timestamp
}

// Supabase task_strips 테이블 또는 messages 테이블 확장으로 저장
// 실시간 조회: SELECT * FROM task_strips WHERE phase NOT IN ('complete','escalated')

6. IR 타입 정의

컴파일러의 중간 표현(IR) 개념 차용. 각 계층 경계에 타입이 지정된 데이터 구조가 흐른다. 타입 불일치 = 컴파일 에러.

6.1 하향 명령 IR (Command Channel)

// ── Chairman → CEO ──
interface ChairmanDirective {
  rawMessage: string;
  projectId: string;
  channelId: string;
  timestamp: string;
}

// ── CEO → C-Level ──
// OPORD 5단계 전부 필수
interface CEODirective {
  directiveId: string;                // UUID
  targetCLevel: CLevel;
  situation: string;                  // 현재 프로젝트 상태 분석
  mission: string;                    // 이번 사이클 달성 목표
  execution: {
    tasks: TaskSpec[];                // 과업 분해
    priority: 'critical' | 'high' | 'normal' | 'low';
  };
  sustainment: {
    tokenBudget: number;              // 이 directive에 할당된 토큰
    timeoutMs: number;                // 최대 허용 시간
    memoryLimitMb?: number;           // 구획 메모리 상한
  };
  commandSignal: {
    reportTo: 'ceo';                  // 항상 CEO에게 보고
    escalationCondition: string;      // 어떤 조건에서 에스컬레이션
    roe: string[];                    // 이 directive에 적용되는 ROE
  };
}

interface TaskSpec {
  taskId: string;
  description: string;
  section: string;                    // WHAT: 어떤 섹션의 일인가
  sil: SIL;                          // 위험 등급
  // WHO는 여기 없음 — 시스템이 section→leader→worker 매핑
}

// ── C-Level → Leader ──
// mission + execution + sustainment 필수
interface CLevelOrder {
  orderId: string;
  fromCLevel: CLevel;
  section: string;
  mission: string;
  execution: {
    tasks: LeaderTaskSpec[];
    constraints: string[];            // 도메인 정책 제약
  };
  sustainment: {
    tokenBudget: number;
    timeoutMs: number;
  };
}

interface LeaderTaskSpec {
  taskId: string;
  description: string;
  requiredCapability: string;         // 'api_dev' | 'ios_dev' | ... — WHAT, not WHO
  sil: SIL;
}

// ── Leader → Worker ──
// mission + execution 필수
interface LeaderAssignment {
  assignmentId: string;
  fromLeader: string;
  mission: string;
  execution: {
    targetFiles: string[];            // 작업 대상 파일
    expectedOutput: string;           // 기대 결과물 설명
    allowedTools: string[];           // harness 퍼미션 매트릭스에서 도출
    sil: SIL;
  };
}

6.2 상향 보고 IR (Report Channel)

// ── Worker → Leader ──
interface WorkerResult {
  assignmentId: string;               // LeaderAssignment.assignmentId 참조
  status: 'success' | 'failure' | 'partial';
  output: string;                     // 작업 결과 요약
  filesModified: string[];
  errors: string[];
  toolsUsed: string[];
  tokensConsumed: number;
  elapsedMs: number;
}

// ── Leader → C-Level ──
interface LeaderReport {
  orderId: string;                    // CLevelOrder.orderId 참조
  section: string;
  summary: string;
  completedTasks: string[];           // taskId 목록
  failedTasks: {
    taskId: string;
    reason: string;
    recommendation: 'retry' | 'reassign' | 'escalate';
  }[];
  workerPerformance: {
    agentId: string;
    tokensUsed: number;
    quality: 'good' | 'acceptable' | 'poor';
  }[];
  tokensConsumed: number;
}

// ── C-Level → CEO ──
interface CLevelReport {
  directiveId: string;                // CEODirective.directiveId 참조
  domain: CLevel;
  progress: number;                   // 0-100
  decisionsApplied: string[];
  blockers: string[];
  debateResults?: string;             // consigliere 토론 결과 요약
  sectionReports: LeaderReport[];     // 산하 섹션 보고서 집합
  recommendations: string[];
  tokensConsumed: number;
}

// ── CEO → Chairman ──
interface CEOReport {
  projectId: string;
  overallProgress: number;
  cycle: number;                      // 몇 번째 워크플로 사이클
  directivesIssued: number;
  decisionsApplied: string[];
  escalations: string[];              // chairman 판단 필요 사항
  clevelReports: CLevelReport[];
  nextActions: string[];
  totalTokens: number;
  totalElapsedMs: number;
}

7. 구조화 출력 스키마

4.3절의 계층별 출력 스키마와 6절의 IR 타입이 실제 JSON Schema로 정의된 것. 어댑터가 이 스키마를 모델/CLI에 전달하여 구조화 출력을 강제한다. 스키마 검증은 파이프라인 측에서 수행 — 어댑터 내부 검증에 의존하지 않는다.

7.1 스키마 검증 흐름

Phase 모듈 → adapter.invoke(params, outputSchema)
                  ↓
          [어댑터가 모델/CLI 호출]
                  ↓
          [모델이 JSON 출력]
                  ↓
          adapter → raw JSON 반환
                  ↓
          Phase 모듈 → validateIR(raw, schema)  ← 파이프라인 측 검증
                  ↓
          유효 → IR 객체로 사용
          무효 → 안돈 발동 → retry 또는 에스컬레이션

7.2 검증 함수

import Ajv from 'ajv';
const ajv = new Ajv({ allErrors: true });

// 파이프라인 측 IR 검증 — 어댑터를 신뢰하지 않음
function validateIR<T>(raw: unknown, schema: object): T {
  const validate = ajv.compile(schema);
  if (!validate(raw)) {
    throw new IRValidationError(validate.errors);
  }
  return raw as T;
}

// 검증 실패 시: 안돈 발동 → retry 1회 → 재실패 시 에스컬레이션
// 이 패턴은 A07 구조적 복구와 동일

7.3 핸드오프 스키마

핸드오프 응답도 구조화 출력으로 수신. 수신 측 에이전트가 accept/reject를 IR로 반환.

const HANDOFF_RESPONSE_SCHEMA = {
  type: "object",
  required: ["action"],
  properties: {
    action: { type: "string", enum: ["accept", "reject"] },
    reason: { type: "string" },    // reject 시 필수
  },
};

8. 모듈 분리 — 구획 격리

8.1 Phase 모듈 (Unix 독립 모듈)

현재 모놀리스를 7개 독립 Phase 모듈로 분해한다. 각 모듈은:

  • 입력: 하나의 IR 타입
  • 출력: 하나의 IR 타입
  • 부작용: 정의된 구조화 출력만
  • 에러: 안돈 시그널 또는 SCRAM
server/src/pipeline/
├── orchestrator.ts          # 배관공 — Phase 간 라우팅만. 비즈니스 로직 0
├── phase-intake.ts          # Chairman 메시지 수신 → ChairmanDirective
├── phase-ceo.ts             # CEO 분석 → CEODirective[]
├── phase-clevel.ts          # C-Level 처리 → CLevelOrder[]
├── phase-leader.ts          # Leader 계획 → LeaderAssignment[]
├── phase-worker.ts          # Worker 실행 → WorkerResult[]
├── phase-review.ts          # 검증/평가 → ReviewResult
├── phase-report.ts          # 보고 집계 → CEOReport
├── ir-types.ts              # 모든 IR 타입 정의
├── output-schemas.ts        # 계층별 구조화 출력 JSON 스키마
├── adapter.ts               # AgentAdapter 인터페이스 + 어댑터 팩토리
├── adapters/
│   ├── claude-cli.ts        # Claude CLI 어댑터
│   ├── ollama.ts            # Ollama 어댑터 (Gemma/DeepSeek/Qwen)
│   └── soldato.ts           # Soldato 로컬 모델 어댑터
├── safety.ts                # 안돈 + SCRAM + SIL
├── handoff.ts               # 핸드오프 프로토콜
└── task-strip.ts            # Task Strip 관리

8.2 배관공 (Pipeline Orchestrator)

역할: Phase 출력을 다음 Phase 입력으로 연결. 비즈니스 로직 0.

// orchestrator.ts — pseudo code
async function runPipeline(chairman: ChairmanDirective): Promise<CEOReport> {

  // Phase 1: Intake
  const intake = await phaseIntake(chairman);

  // Phase 2: CEO Analysis
  const directives = await phaseCEO(intake);

  // Phase 3~5: C-Level → Leader → Worker (순차, ViewHolder)
  const clevelResults: CLevelReport[] = [];
  for (const directive of directives) {
    const orders = await phaseCLevel(directive);
    for (const order of orders) {
      const assignments = await phaseLeader(order);
      for (const assignment of assignments) {
        const result = await phaseWorker(assignment);    // ViewHolder 슬롯 사용
        // 보고↑: Worker → Leader
      }
      // 보고↑: Leader → C-Level
    }
    // 보고↑: C-Level → CEO
  }

  // Phase 6: Review
  const review = await phaseReview(clevelResults);

  // Phase 7: Report
  return phaseReport(review);
}

8.3 구획 격리 (Compartmentalization)

잠수함 구획화. 한 슬롯이 폭주해도 다른 공정에 영향 없음.

interface CompartmentLimits {
  maxTokens: number;          // 이 구획에 할당된 토큰 상한
  maxTimeMs: number;          // 시간 상한
  maxMemoryMb: number;        // 메모리 상한 (프로세스 모니터링)
}

// ViewHolder 슬롯별 구획 상한
const DEFAULT_COMPARTMENT: CompartmentLimits = {
  maxTokens: 50000,
  maxTimeMs: 300000,          // 5분
  maxMemoryMb: 256,
};

// 구획 위반 시:
// 1. 토큰 150% 초과 → 안돈 (일시정지)
// 2. 토큰 300% 초과 → SCRAM (강제 종료)
// 3. 시간 초과 → 안돈
// 4. 메모리 초과 → SCRAM (해당 슬롯만 kill, 나머지 무영향)

9. 실행 모델

9.1 순차 실행 + ViewHolder

원칙: 셀프호스팅 환경에서 메모리/CPU 보호. ViewHolder 풀로 CLI 슬롯을 재활용.

ViewHolder Pool (기본 3슬롯)
┌──────────┐  ┌──────────┐  ┌──────────┐
│ slot-0   │  │ slot-1   │  │ slot-2   │
│ idle     │  │ idle     │  │ idle     │
└──────────┘  └──────────┘  └──────────┘

작업 A 도착 → slot-0 bind(A) → 실행 → 완료 → slot-0 release → idle
작업 B 도착 → slot-0 bind(B) → 실행 (재활용)
3개 초과 시 → Queue 대기 → 슬롯 반환 시 자동 할당
  • 한 슬롯에서 한 에이전트만 실행
  • 에이전트 = CLI가 아니라 주입된 컨텍스트(bind 파라미터)
  • 풀 사이즈: VIEWHOLDER_POOL_SIZE 환경변수 (기본 3)

9.2 C레벨 듀얼트랙 (유일한 병렬)

C레벨만 토론작업을 콘실리에리를 통해 병렬 수행.

C-Level Agent
  ├── [Track A: 토론] ── 콘실리에리 ── 다이아몬드 토론 (24/7 상시)
  └── [Track B: 작업] ── 콘실리에리 ── 섹션 지시 (요청 도착 시)

두 트랙은 동시 실행. 나머지 모든 것은 순차.

실행 방식: Track A와 Track B는 별도 ViewHolder 슬롯을 점유하지 않는다. 콘실리에리가 자체 프로세스로 운영되며, C레벨은 콘실리에리에게 요청만 전달하고 결과를 수신.

9.3 다이아몬드 토론 실행

다이아몬드 토론은 순차. DAG 노드를 ViewHolder에 하나씩 bind하여 실행.

Root Node → bind(slot-0) → 실행 → 완료
  ├── Child A → bind(slot-0) → 실행 → 완료 (슬롯 재활용)
  ├── Child B → bind(slot-0) → 실행 → 완료
  └── Child C → bind(slot-0) → 실행 → 완료
Director Node → bind(slot-0) → 수렴 → 완료

10. 안전 체계

10.1 안돈 시그널 (Andon)

도요타 생산라인의 안돈 줄. 수치화된 임계값 초과 시 자동 발동.

interface AndonSignal {
  source: string;            // 발생 에이전트 ID
  taskStripId: string;       // 관련 Task Strip
  trigger: AndonTrigger;
  severity: 'pause' | 'scram';
  threshold: number;         // 기준값
  actual: number;            // 실제값
  timestamp: string;
}

type AndonTrigger =
  | 'token_overrun'          // 토큰 예산 초과
  | 'consecutive_errors'     // 연속 에러
  | 'consecutive_timeouts'   // 연속 타임아웃
  | 'sil_violation'          // SIL 등급 위반
  | 'memory_overrun'         // 메모리 초과
  | 'handoff_reject_limit';  // 핸드오프 거부 상한

const ANDON_THRESHOLDS = {
  token_overrun_ratio: 1.5,        // 예산의 150% → 안돈
  consecutive_errors: 3,           // 3회 연속 에러 → 안돈
  consecutive_timeouts: 2,         // 2회 연속 타임아웃 → 안돈
  handoff_reject_limit: 2,         // 2회 거부 → 안돈 + 에스컬레이션
};

안돈 발동 시 흐름:

  1. 현재 작업 일시정지 (kill 아님)
  2. 상위 계층에 AndonSignal 전달
  3. 상위 계층이 판단:
  • continue — 임계값 상향 후 재개
  • reassign — 다른 에이전트에게 재배정
  • escalate — 더 상위로 올림
  • abort — 이 task 중단, 보고서에 기록

10.2 SCRAM (긴급정지)

원자력 SCRAM. 안돈보다 심각한 상황에서 파이프라인 전체 즉시 중단.

const SCRAM_THRESHOLDS = {
  token_overrun_ratio: 3.0,        // 예산의 300% → SCRAM
  sil4_unauthorized: true,          // SIL-4 이중 검증 없이 실행 시도 → SCRAM
  memory_critical_mb: 512,          // 시스템 전체 메모리 임계점 → SCRAM
};

SCRAM 발동 시 흐름:

  1. 모든 ViewHolder 슬롯 즉시 종료
  2. 진행 중인 모든 Task Strip → phase: 'escalated' 상태
  3. 현재 상태를 Supabase에 스냅샷 저장 (복구용)
  4. pending_restructure = true 설정 (A07 패턴)
  5. 회장에게 SCRAM 발생 보고 (유일한 회장 알림 케이스 — 구조적 복구 불가 상황)

10.3 A07 구조적 복구 통합

기존 A07 패턴(retry → safe state → DB flag → choke point)이 안전 체계의 기본 프레임:

에러 발생
  → retry 1회 (2초 대기)
  → 재실패 시 safe state (변경 없이 안전하게 반환)
  → pending_restructure DB flag 설정
  → 다음 사이클 choke point에서 자동 구조조정

안돈/SCRAM은 이 패턴의 상위 확장:

  • 안돈 = 특정 task의 A07 (일시정지 + 상위 판단)
  • SCRAM = 전체 파이프라인의 A07 (전체 정지 + 스냅샷 + 복구 대기)

11. 침묵 항해 모드 (Silent Running)

11.1 개요

잠수함의 침묵 항해. 외부 API 불가 시 로컬만으로 핵심 기능 유지.

트리거 조건:

  • API 쿼터 소진 (Anthropic rate limit)
  • 네트워크 장애
  • 회장 수동 전환 (SILENT_RUNNING=1)

11.2 폴백 경로

정상 모드:
  CEO/C-Level/Leader → 기본 어댑터 (ClaudeCLI/Ollama 등 설정에 따름)
  Worker → 기본 어댑터
  Consigliere → 기본 어댑터 + SQLite

침묵 항해 모드:
  CEO/C-Level/Leader → SoldatoAdapter (로컬 Gemma 4, soldato.md 참조)
  Worker → SoldatoAdapter
  Consigliere → SQLite BM25 캐시만 (임베딩 검색 불가)

전환 = 어댑터 교체. 파이프라인 코드 변경 0.

11.3 성능 저하 명시

침묵 항해 모드에서 축소되는 기능:

기능정상침묵 항해
C레벨 도메인 분석Opus/Sonnet 품질Soldato 94% (Pro) ~ 72% (Lite)
콘실리에리 검색BM25 + VectorBM25만
토론 품질전문가급저하 (모델 성능 의존)
SIL-4 검증이중 검증이중 검증 유지 (모델 무관)
핸드오프 프로토콜정상정상 (구조적 — 모델 무관)

핵심: 구조적 안전 장치(SIL, 핸드오프, 안돈, 타입 검증)는 모델과 무관하게 항상 동작. 침묵 항해에서 저하되는 것은 LLM 판단 품질뿐.

11.4 자동 전환

interface SilentRunningState {
  active: boolean;
  trigger: 'api_quota' | 'network_failure' | 'manual';
  activatedAt: string;
  degradedCapabilities: string[];
  fallbackModel: string;            // 'soldato-pro' | 'soldato-main' | 'soldato-lite'
}

// API 호출 실패 3회 연속 → 자동 전환
// 네트워크 복구 감지 → 자동 복귀 (60초 간격 health check)
const SILENT_RUNNING_TRIGGER_THRESHOLD = 3;
const HEALTH_CHECK_INTERVAL_MS = 60000;

12. 당직 사이클 (Watch Cycle)

12.1 개요

잠수함 3교대 당직 체계. 토큰 예산을 시간대별로 배분하여 24시간 지속 가능한 운용 보장.

12.2 당직 구간

interface WatchPeriod {
  name: string;
  hours: [number, number];          // [start, end) in 24h
  tokenAllocationRatio: number;     // 일 예산 중 이 구간 배분 비율
  debateThrottlePerHour: number;    // 시간당 토론 제한
  maxActiveSlots: number;           // ViewHolder 최대 슬롯
}

const WATCH_SCHEDULE: WatchPeriod[] = [
  {
    name: 'peak',
    hours: [9, 18],                  // 09:00-18:00 (회장 활동 시간)
    tokenAllocationRatio: 0.6,       // 일 예산의 60%
    debateThrottlePerHour: 4,
    maxActiveSlots: 3,
  },
  {
    name: 'off-peak',
    hours: [18, 1],                  // 18:00-01:00 (저녁)
    tokenAllocationRatio: 0.3,       // 일 예산의 30%
    debateThrottlePerHour: 2,
    maxActiveSlots: 2,
  },
  {
    name: 'maintenance',
    hours: [1, 9],                   // 01:00-09:00 (새벽)
    tokenAllocationRatio: 0.1,       // 일 예산의 10%
    debateThrottlePerHour: 1,
    maxActiveSlots: 1,
  },
];

12.3 예산 관리

interface DailyBudget {
  totalTokens: number;               // 일 총 예산 (환경변수 DAILY_TOKEN_BUDGET)
  consumed: number;
  remaining: number;
  currentPeriod: WatchPeriod;
  periodBudget: number;              // 현재 구간에 배분된 예산
  periodConsumed: number;
}

// 구간 예산 초과 시:
// - 안돈 발동 (pause) → C-Level 토론 빈도 자동 축소
// - 일 예산 초과 시: SCRAM → 다음날 09:00까지 maintenance 모드
// - 침묵 항해 전환이 가능하면 전환 (Soldato 사용 시 토큰 무관)

12.4 C레벨 듀얼트랙과 당직

peak (09-18):
  Track A 토론: 시간당 4회 토론 허용
  Track B 작업: 풀 속도
  
off-peak (18-01):
  Track A 토론: 시간당 2회 (심층 토론 위주)
  Track B 작업: 긴급 건만

maintenance (01-09):
  Track A 토론: 시간당 1회 (유지보수 토론)
  Track B 작업: 정지 (예약 작업만)

13. 에스컬레이션

13.1 기존 Level 1~4 통합

현행 에스컬레이션 체계(workflow.md)를 C4I 보고 채널과 통합:

Level 1: Worker 실패 → Leader 개입 (재지시 + 재시도)
         └─ WorkerResult(status:'failure') → Leader가 재배정

Level 2: Leader 실패 → C-Level 결정 (다른 섹션 또는 다른 접근)
         └─ LeaderReport(failedTasks) → C-Level이 재지시

Level 3: C-Level 실패 → Council 토론 (다중 C-Level 협의)
         └─ CLevelReport(blockers) → CEO가 Council 소집

Level 4: Council 실패 → CEO/Chairman 판단
         └─ CEO가 해결 불가 → CEOReport(escalations) → Chairman 큐

13.2 핸드오프 거부 에스컬레이션

핸드오프 거부는 안돈과 연동:

1차 거부 → 같은 계층 내 재배치
2차 거부 → 안돈 발동 → 상위 계층 판단
  → 상위가 'reassign' → 다른 섹션으로
  → 상위가 'escalate' → 더 상위로
  → CEO까지 도달 → Chairman 에스컬레이션 큐

13.3 자동 에스컬레이션 매핑

// 에스컬레이션은 보고 채널(구조화 출력 IR)을 통해 구조적으로 흐른다
// 각 level은 lifecycle-emitter 마커와 매핑:
//   Level 1: W04 (worker retry) → LH05 (leader intervention)
//   Level 2: U02 (leader→clevel report) with status:'failure'
//   Level 3: CD01~CD38 (council debate)
//   Level 4: U04 (ceo→chairman report) with escalations

14. 현행→목표 대조표

#현행 (As-Is)목표 (To-Be)
1index.ts 모놀리스 핸들러7개 독립 Phase 모듈 + 배관공
2[DELEGATE] 텍스트 파싱 (정규식)구조화 출력 (JSON 스키마 검증) + Agent Adapter
3WARN 모드 (tier 위반 통과)STRICT + SIL 등급 (위반 = 차단)
4명령↓만 존재명령↓ + 보고↑ 이중 채널
5하향 일방 전달 (거부 불가)핸드오프 3단계 (요청→수락/거부→확인)
6작업 위치 추적 불가Task Strip으로 전 구간 추적
7하드코딩된 타임아웃안돈(일시정지) + SCRAM(긴급정지)
8A07만 safe state전 계층 구획 격리 + 자원 상한
9리더 계층 dead code구조적 경유점으로 활성화 (Phase-Leader)
10외부 API 단일 경로침묵 항해 모드 (로컬 Soldato 폴백)
11토큰 총량 제한만당직 사이클 (시간대별 예산 배분)
12C레벨 도메인 침범 미감지ROE 강제 (sections.ts 기반 자동 도출)
13IR 타입 없음 (자유형 텍스트)OPORD 기반 IR 타입 (TypeScript 타입 안전성)
14dispatcher.ts, leader-escalation.ts dead code핸드오프/에스컬레이션으로 흡수 또는 삭제

부록 A: Lifecycle Emitter 매핑

기존 lifecycle-emitter 체크포인트를 C4I 4대 축에 매핑:

C4I 축체크포인트설명
CommandI01~I03Intake — 명령 수신
A01~A09CEO Analysis — 명령 해석/분해
S01~S04Spec Issue — 하위 명령서 발행
D01~D04Delegate — 명령 전달
ControlCH01~CH08C-Level Hire — 자산 배치
LH01~LH06Leader Hire — 하위 자산 배치
BD01~BD06Build — 검증
CommunicationsW01~W17Worker Exec — 작전 수행
R01~R17Review — 결과 평가
IntelligenceCD01~CD38C-Level Debate — 정보 분석/토론
U01~U09Report Up — 정보 상향 보고

부록 B: 구현 순서

Phase 1: ir-types.ts + output-schemas.ts (타입/스키마 정의)
Phase 2: adapter.ts + adapters/ (AgentAdapter 인터페이스 + Claude CLI/Ollama/Soldato 어댑터)
Phase 3: safety.ts + handoff.ts + task-strip.ts (안전/통신/추적)
Phase 4: phase-*.ts 7개 모듈 (독립 공정)
Phase 5: orchestrator.ts (배관공)
Phase 6: 기존 index.ts 모놀리스 → orchestrator 호출로 교체
Phase 7: 침묵 항해 + 당직 사이클 (확장 — 어댑터 교체로 자동 적용)
Phase 8: dead code 삭제 (dispatcher.ts, leader-escalation.ts 등)

부록 C: 환경변수

# Pipeline
TIER_ROUTING_STRICT=1                  # STRICT 모드 (default: 1, WARN 폐지)
VIEWHOLDER_POOL_SIZE=3                 # ViewHolder 슬롯 수
DAILY_TOKEN_BUDGET=1000000             # 일 토큰 예산

# Agent Adapter
AGENT_ADAPTER=claude-cli               # claude-cli | ollama | soldato | codex
AGENT_ADAPTER_MODEL=sonnet             # 어댑터 내 기본 모델
CLEVEL_ADAPTER=claude-cli              # C레벨 전용 어댑터 (별도 지정 가능)
CLEVEL_ADAPTER_MODEL=sonnet            # C레벨 모델

# Silent Running
SILENT_RUNNING=0                       # 수동 전환 (0=off, 1=on)
SOLDATO_MODEL=soldato-pro              # 침묵 항해 시 사용 모델
HEALTH_CHECK_INTERVAL_MS=60000         # API 상태 확인 간격

# Safety
SCRAM_TOKEN_RATIO=3.0                  # SCRAM 토큰 임계 비율
SCRAM_MEMORY_MB=512                    # SCRAM 메모리 임계값
ANDON_TOKEN_RATIO=1.5                  # 안돈 토큰 임계 비율
ANDON_CONSECUTIVE_ERRORS=3             # 안돈 연속 에러 임계
ANDON_CONSECUTIVE_TIMEOUTS=2           # 안돈 연속 타임아웃 임계

# Watch Cycle
WATCH_PEAK_HOURS=9-18                  # 피크 시간대
WATCH_OFFPEAK_HOURS=18-1               # 오프피크 시간대
WATCH_PEAK_RATIO=0.6                   # 피크 예산 비율
WATCH_OFFPEAK_RATIO=0.3                # 오프피크 예산 비율