| name | charlie-harness |
| description | 워크플로우 네이티브 메타 하네스. 도메인/프로젝트에 맞는 하네스를 결정적 Workflow 스크립트로 구성·구축·재구성·감사·동기화하는 메타 스킬. (1) '하네스 구성/구축/설계/엔지니어링', '워크플로우 하네스 만들어줘' 요청 시, (2) 새 도메인에 대한 에이전트·스킬·워크플로우·스키마·매니페스트 기반 자동화 체계를 구축할 때, (3) '하네스 점검/감사/현황', '에이전트/스킬/워크플로우 동기화', 'manifest drift 확인' 등 운영/유지보수 요청 시, (4) 기존 하네스를 '다시/재실행/업데이트/수정/보완/확장/재구성'하거나 부분만 다시 만들 때, (5) '오케스트레이션을 코드로', '산문 오케스트레이터를 워크플로우로 컴파일', 'v1 하네스를 v2로 마이그레이션' 요청 시 반드시 사용. 트리거되면 Workflow({name:'build-harness'})를 호출한다. |
Charlie-Harness — 워크플로우 네이티브 메타 하네스
도메인/프로젝트에 맞는 하네스를, 런타임에 모델이 해석하는 산문 오케스트레이터가 아니라 결정적 JavaScript Workflow 스크립트로 컴파일하는 메타 스킬. v1 harness의 계승 원칙(에이전트/스킬 분리, progressive disclosure, 진화 시스템, pushy 트리거)을 유지하되, 오케스트레이션 자체를 코드·스키마·매니페스트로 고정한다.
이 스킬의 본질: 무거운 빌드 로직은 본 SKILL.md 산문이 아니라 templates/build-harness.js 워크플로우에 있다. 이 스킬이 트리거되면 곧바로 Workflow({name: 'build-harness'})를 호출한다. SKILL.md는 트리거 + 철학 + 호출 규약 + 체크리스트만 담는 얇은 진입점이다.
빌드 철학 — 오케스트레이션은 코드다
v1은 "누가 언제 어떤 순서로 협업하는가"를 산문 마크다운으로 적고 매 실행마다 모델이 재해석했다. 그 결과 비결정적 제어 흐름(L5), 강제력 없는 프로즈 계약(L1), 산문 권고에 그친 검증(L6), 무성 폴백(L2)이 누적됐다. charlie-harness는 이 지점을 정확히 뒤집는다 — 제어 흐름은 pipeline()/parallel()로, 경계 계약은 JSON Schema로, 적대적 검증은 워크플로우 단계로, 폴백은 throw/log()로 코드화한다. "모델이 매번 읽는 지시서"에서 "버전 관리·테스트·재현 가능한 실행 산출물"로의 전환이 전부다.
10원칙 (5 계승 + 5 신규)
v1에서 계승 (불변):
| # | 원칙 | 의미 |
|---|
| 1 | 에이전트(누가) / 스킬(어떻게) 분리 | 역할 페르소나와 절차 지식을 별도 파일로 |
| 2 | Progressive disclosure | 3-tier 컨텍스트 (metadata → SKILL.md → references) |
| 3 | 하네스는 진화 시스템 | 변경 이력·피드백 루프 유지 |
| 4 | 적극적("pushy") 트리거 | description이 유일한 트리거 메커니즘 |
v2 신규 (워크플로우 도입):
| # | 원칙 | 해소하는 v1 한계 | 코드화 수단 |
|---|
| 5 | 오케스트레이션은 코드다 | L5 비결정 제어흐름 | {domain}.js Workflow 스크립트 |
| 6 | 계약은 스키마다 | L1 프로즈 계약 무강제 | agent(prompt, {schema}) |
| 7 | 검증은 구조다 | L6 검증 권고 | 적대적 verify 스테이지(코드) |
| 8 | 모델 티어는 역할별 | L3 블랭킷 opus | 역할별 agent({model}) |
| 9 | 단일 매니페스트 | L4 오케스트레이터 drift | .charlie/manifest.json SSOT |
| 10 | 큰 소리 실패 | L2 무성 degradation | throw + .filter(Boolean) + log() |
원칙 J(빌더 자기적용/dogfooding): 빌더 자신이 워크플로우라서, 하네스 생성 과정에도 동일한 스키마 강제·적대적 검증이 적용된다.
v2 산출물 구조
도메인 하네스 1개를 빌드하면 대상 프로젝트에 다음이 생성된다:
프로젝트/
├── .claude/
│ ├── agents/{role}.md # 에이전트 페르소나 (워크플로우가 agentType으로 참조)
│ ├── skills/
│ │ ├── {role-skill}/SKILL.md # 절차 스킬 (선택적, 역할 축소)
│ │ └── {domain}-harness/SKILL.md # ★ 얇은 트리거 스킬 → Workflow({name}) 호출
│ └── workflows/{domain}.js # ★ 결정적 오케스트레이터 (산문 오케스트레이터 대체)
├── .charlie/
│ ├── manifest.json # ★ SSOT — 에이전트·스킬·워크플로우·스키마 레지스트리
│ └── schemas/{name}.json # ★ 에이전트 간 산출물 계약 (JSON Schema)
└── CLAUDE.md # 하네스 포인터 + 변경 이력
왜 얇은 트리거 스킬인가 (R2 완화)
워크플로우는 키워드로 자동 발동하지 않는다. 따라서 도메인마다 {domain}-harness 스킬을 생성하되 본문은 최소화한다 — "이 도메인 요청이면 Workflow({name: '{domain}'})를 호출하라" + pushy description + 후속 키워드. 무거운 로직은 전부 {domain}.js에 있다. 트리거 스킬은 다리(bridge)일 뿐이다.
빌드 프로세스 — build-harness.js 워크플로우 실행
이 스킬이 트리거되면 산문으로 단계를 흉내 내지 말고 곧바로 빌드 워크플로우를 호출한다:
Workflow({ name: 'build-harness', args: { domain, projectRoot, request, runMode } })
빌드 워크플로우(templates/build-harness.js)의 meta.phases는 다음 6단계를 정의한다(각 phase는 코드로 박혀 있으며 산문 재해석 대상이 아니다). 실제로 실행되는 phase 셋은 Audit 결과의 분기 모드(신규/확장/유지보수)가 선택한다 — 아래 분기 규칙 참조:
| phase | 역할 | 핵심 수단 | 모델 티어 |
|---|
| Audit | 기존 .charlie/manifest.json·.claude 스캔 → 신규/확장/유지보수 분기, drift 감지 | 파일 스캔 + log()로 drift 명시 | haiku |
| Analyze | 도메인 분해: roles[], data_flow, execution_pattern, model_tiers | agent({schema: harness-spec}) | sonnet→opus |
| Design | judge-panel: N개 아키텍처 후보 → 점수 → 최적 선택 | perspective-diverse agent, parallel 합의 | opus |
| Generate | 에이전트.md / 워크플로우.js / 스키마 / 트리거 스킬 동시 생성 → manifest로 fan-in | parallel(thunks) 배리어(정당: 전 산출물이 단일 manifest 등록·정합성 검사로 cross-item 합류) | sonnet (생성) |
| Verify | 각 산출물 정적 검증 + 적대적 리뷰 → 발견 verify | pipeline(artifacts, lint, refute) | opus (검증) |
| Register | manifest.json·CLAUDE.md 갱신, 변경 이력 기록 | 파일 쓰기 + SSOT 등록 | haiku |
분기 규칙 (Audit 결과 — 어느 phase가 실행되는지 결정):
- 신규: manifest 없음 → 6단계(Audit→Analyze→Design→Generate→Verify→Register) 전부 실행.
- 확장: manifest 존재 + 새 역할 추가 → 6단계 실행하되, Analyze는 충돌/중복 검토, Generate는 신규 산출물만 생성, Register는 변경 이력 append.
- 유지보수/감사: 수정·동기화·drift 점검 요청 → Audit 중심, Analyze·Design·Generate 건너뛰고 Verify+Register로 drift 해소.
실패 내성: 빌드 중 1개 산출물 생성만 실패해도 resumeFromRunId로 실패 지점부터 재개, 나머지는 저널 캐시 재사용(L7 해소). 동일 도메인+args 재실행은 100% 캐시 히트 → 동일 에이전트 수·단계 수·파일 셋(결정성 가설 검증).
워크플로우 스크립트 규약 (생성물이 지켜야 할 계약)
빌드가 생성하는 모든 {domain}.js는 다음을 지키며, Verify phase가 이를 정적 검증한다:
meta는 순수 리터럴 (변수/함수호출/스프레드 금지). meta.phases 제목 = phase() 호출 제목.
- 금지 API: 벽시계 시각 호출·난수 호출·인자 없는 날짜 생성자 (resume 깨짐). 타임스탬프는
args 주입 또는 인덱스 기반 변형.
- 기본은
pipeline(items, ...stages) — 단계 간 배리어 없음. parallel(thunks) 배리어는 cross-item 의존(dedup/merge/early-exit/상호참조)일 때만, 주석으로 정당화.
- 모든 cross-agent 산출물은
agent(prompt, {schema}) — 스키마는 JSON Schema 객체, 검증된 객체 반환.
- 모델 티어는 역할별: 수집/추출/포맷 → haiku·sonnet; 합성/검증/설계 → opus. 생략 시 세션 모델 상속 — 더 싼 티어가 명백히 맞을 때만 명시.
- 모든 생성물에 적대적 verify 스테이지 (다수결 refute 또는 perspective-diverse). 검증은 산문 권고가 아니라 코드.
- 드롭/캡은
log()로 명시 (무성 truncation 금지).
- 동적 루프는
budget.total 가드 (target 없으면 remaining()은 Infinity).
상세는 references/ 참조:
references/WORKFLOW-CONTRACT.md — 정본 규약(SSOT): {domain}.js 작성 형식 C1~C16 (meta 리터럴, 톱레벨 본문, 앰비언트 글로벌, await 강제, 금지 API). 모든 생성물·패턴 문서가 따른다.
references/workflow-orchestration-patterns.md — pipeline/parallel/budget 관용구, v1 6패턴 → 워크플로우 매핑
references/schema-contracts.md — 스키마 라이브러리(harness-spec/agent-def/finding/verdict)
references/verification-patterns.md — 적대적 검증 템플릿(majority-refute, judge-panel, loop-until-dry)
references/agent-and-skill-design.md — v1 핵심 계승(압축): 에이전트 분리 기준, pushy description, progressive disclosure
references/migration-from-v1.md — 산문 오케스트레이터 → 워크플로우 점진 이전 경로
산출물 체크리스트
빌드 완료 후 Register phase가 확인 (워크플로우가 코드로 검증):
테스트 시나리오
정상 흐름 — 신규 research-harness 빌드
입력: "리서치 도메인 하네스 워크플로우로 구축해줘" (대상 프로젝트에 .charlie/manifest.json 없음).
- 스킬 트리거 →
Workflow({name:'build-harness', args:{domain:'research', projectRoot, request, runMode:'new'}}) 호출.
- Audit: manifest 부재 확인 →
runMode='new' 확정, log("신규 빌드: 기존 매니페스트 없음").
- Analyze:
agent({schema: harness-spec}) → roles=[collector, extractor, verifier, synthesizer], execution_pattern='producer-verifier', model_tiers={collector:'haiku', synthesizer:'opus', verifier:'opus'}.
- Design: judge-panel 3후보 점수화 → pipeline+적대적 verify 채택.
- Generate:
parallel로 agents/.md + workflows/research.js + schemas/.json + skills/research-harness/SKILL.md + manifest.json 동시 생성.
- Verify:
pipeline(artifacts, lint, refute) → research.js의 meta 리터럴·금지 API·pipeline-default·스키마·verify 스테이지 정적 통과.
- Register: manifest 등록 + CLAUDE.md 포인터·변경 이력 append.
기대: 위 체크리스트 전 항목 통과. 재실행 시 동일 파일 셋.
에러 흐름 — 누락 의존성에서 큰 소리 실패
입력: "research 하네스 verifier 에이전트만 다시 만들어줘" 인데 .charlie/manifest.json이 손상/부재.
- Audit: 부분 재실행 의도지만 SSOT 매니페스트 부재 감지.
- 무성 폴백(단일 에이전트로 조용히 진행) 금지 — 워크플로우가 명시적으로 throw:
"manifest.json 부재 — 부분 재실행 불가. 전체 빌드(runMode:'new') 또는 매니페스트 복구 필요."
- 사용자에게 복구 경로 2개 제시: (a) 전체 재빌드, (b)
resumeFromRunId로 직전 성공 빌드 저널에서 매니페스트 재생.
- Generate 중 특정 산출물 생성 실패 시 해당 thunk는
null → .filter(Boolean)로 제외하고 log("drop: <artifact> 생성 실패") — 나머지는 진행하되 드롭을 가시화.
기대: 조용한 성공 가장(假裝) 없음. 실패는 throw 또는 log()로 표면화.