init: company-haness 설계
This commit is contained in:
@@ -0,0 +1,527 @@
|
||||
# P1 — Company / Venture Bootstrap (설계)
|
||||
|
||||
- 날짜: 2026-07-12
|
||||
- 상태: 설계 확정 대기 → (승인 후) 구현 계획(writing-plans)
|
||||
- 범위: 리뷰 반영 로드맵의 **P1**. 리뷰 핵심결함 #1(회사를 정의하기 전에 회사 문맥을 요구하는 순환의존) 해소.
|
||||
- 관련: 리뷰 로드맵의 P0(실행 무결성, 대부분 완료·재검증)·P2(디자인 방향)·P3(프롬프트/스킬 분리)·P4(벤치마크)는 **별도 사이클**. 본 스펙은 P1만 다룬다.
|
||||
|
||||
---
|
||||
|
||||
## 1. 문제 (순환의존)
|
||||
|
||||
현재 cascade는 `intake → discovery → decide → design → spec → build → …`이며, `/ground`·`/decide`·`/design`은 이미 회사 방향·제품 제약(`company-context.yaml`)을 전제한다. 그런데 `company-context.yaml`은 `status: demo`(빈 템플릿)이고 `projects: []`다. 즉:
|
||||
|
||||
```
|
||||
아이디어를 고르려면 회사의 전략·제약이 필요함
|
||||
↑
|
||||
회사 전략을 정하려면 아이디어를 먼저 골라야 함
|
||||
```
|
||||
|
||||
지금은 이 공백을 매 intake 문장과 임시 가정으로 메우므로 아이디어 검토 결과가 일관되지 않는다.
|
||||
|
||||
**해소 원리:** `founder-context`(회사 정의 이전에도 사람이 채울 수 있는 유일한 입력)를 **입력**으로 하는 별도 `venture-bootstrap` plan을 두고, 그 plan의 **terminal 산출물**로 `company-context.yaml (status: provisional)`을 **생산**한다. 이후 제품 cascade는 그 산출물을 **입력으로 소비**만 한다. bootstrap 내부에서는 company-context를 요구하지 않으므로 순환이 끊긴다.
|
||||
|
||||
## 2. 목표 / 비목표
|
||||
|
||||
**목표**
|
||||
- 회사 lifecycle(1회성 수립)과 제품 lifecycle(반복)을 **별도 plan**으로 분리한다.
|
||||
- `founder-context.yaml`(사람 입력) → 기회탐색 → 벤처검증 → 벤처결정 → company-context commit의 강제된 stage 그래프를 만든다.
|
||||
- `company-context.yaml`을 **항목별 provenance**를 갖는 facts / strategic-decisions / hypotheses 구조로 재편하고, 공식 SoT 상태 어휘를 `template|provisional|operating`(3-상태)로 교체한다(작성 중은 공식 status가 아니라 candidate-status/workflow stage로 표현 — §7.3).
|
||||
- 회사 문맥 인용 상한을 **항목 단위**로 정밀화하되(전체 보고서 강등 금지), 신뢰경계(worker는 전이 불가)와 원자적 commit을 지킨다.
|
||||
- 제품 cascade가 bootstrap 결과를 정확히 참조할 **진입 계약**을 정의한다(단, product-definition stage 자체는 P1에서 만들지 않는다).
|
||||
|
||||
**비목표(YAGNI / 이후 사이클)**
|
||||
- `product-definition` stage 신설 — 제품 lifecycle 소관. seam(진입 계약)만 정의.
|
||||
- 보고서별 **완전 citation-provenance 추적**(모든 보고서에서 인용 출처를 파싱해 항목별 ceiling) — 최소 형태(회사 문맥을 evidence로 포함한 보고서에만, hypothesis 인용은 Med 상한)만 구현.
|
||||
- 자연어 **의미 기반** hypothesis-as-fact 오분류 판정 — Hard Fail이 아니라 Warning.
|
||||
- DES-VISUAL/DES-DIRECTOR·디자인 단계(P2), skill 분리(P3), 벤치마크(P4).
|
||||
|
||||
---
|
||||
|
||||
## 3. 아키텍처 개요 — 두 lifecycle과 seam
|
||||
|
||||
```
|
||||
Company lifecycle (1회성, plan=venture-bootstrap)
|
||||
founder-context.yaml (사람)
|
||||
→ opportunity-discovery
|
||||
→ venture-validation
|
||||
→ venture-decision (+ HUMAN acceptance receipt)
|
||||
→ company-context-commit (candidate → atomic replace)
|
||||
→ bootstrap-complete ⇒ 공식 company-context.yaml (status: provisional)
|
||||
|
||||
│ seam = company-context-ready 진입 계약
|
||||
▼
|
||||
|
||||
Product lifecycle (반복, plan=cascade)
|
||||
selected venture → (product-definition) → design → spec → build → …
|
||||
↑ company-context.yaml + venture-decision-id + company-decision-ids 를 입력으로 참조
|
||||
```
|
||||
|
||||
핵심: 공식 `company-context.yaml`(SoT)은 bootstrap **도중에는 바뀌지 않는다**. candidate 파일에 작성·검증한 뒤, 마지막에 **한 번, 원자적으로** 교체한다(§9.3).
|
||||
|
||||
---
|
||||
|
||||
## 4. 신규/변경 아티팩트 인벤토리
|
||||
|
||||
| 파일 | 위치 | 성격 | 변경 |
|
||||
|---|---|---|---|
|
||||
| `founder-context.yaml` | `org-os/01-company/` | 사람 입력 | 신규 |
|
||||
| `venture-option-spec.yaml` | `org-os/06-agent-work/` | 데이터 스키마 계약 | 신규 |
|
||||
| `venture-validation-map.yaml` | `org-os/06-agent-work/` | 역할·게이트 매핑 계약 | 신규 |
|
||||
| `company-context.yaml` | `org-os/01-company/` | 회사 SoT | **재구조화** |
|
||||
| `state-transition-rules.yaml` | `org-os/00-role-registry/` | 전이 SSOT | venture-bootstrap 전이·조건 추가 |
|
||||
| `execution-plans.yaml` | `org-os/06-agent-work/` | plan 프리셋 | `venture-bootstrap` plan 추가 |
|
||||
| `ceo-intake.md` | `.claude/commands/` | 커맨드 | `--plan` 선택·founder-context 유도 |
|
||||
| `venture-validate.md` | `.claude/commands/` | 커맨드 | 신규 |
|
||||
| `company-bootstrap.md` | `.claude/commands/` | 커맨드 | 신규 |
|
||||
| `state_engine.py` | `.claude/hooks/` | 전이 강제기 | 신규 predicate 6종 |
|
||||
| `validate_report.py` | `.claude/hooks/` | 보고 검증 | status 어휘 + 항목 ceiling |
|
||||
| `lint_company_context.py` | `.claude/hooks/` | 파일 린터 | 신규(Hard Fail + Warning) |
|
||||
| `commit_company_context.py` | `.claude/hooks/` | trusted commit CLI | 신규(atomic replace) |
|
||||
| `acceptance_log.py` / `acceptance-event.schema.json` | `.claude/hooks/`·`schemas/` | 수락 원장 | 선택 `report-sha256` 바인딩 추가 |
|
||||
| `guard_tools.py` | `.claude/hooks/` | 권한 경계 | 공식 company-context.yaml 직접쓰기 보호 |
|
||||
| `doctor.py` | `.claude/hooks/` | preflight | 신규 아티팩트·plan 배선 점검 |
|
||||
| 테스트 | `.claude/tests/` | 단위테스트 | `test_venture_bootstrap.py`(신규) 외 |
|
||||
|
||||
---
|
||||
|
||||
## 5. `founder-context.yaml` (사람 입력)
|
||||
|
||||
회사 정의 이전에도 사람이 채울 수 있는 유일 입력. **여러 venture validation에서 재사용**되며, 누락되면 founder-fit 판단 전체가 무효 → 독립 stage(`founder-setup`)의 게이팅 아티팩트.
|
||||
|
||||
```yaml
|
||||
schema-version: 1
|
||||
status: template # template | filled
|
||||
founder:
|
||||
strengths: [backend, database, infrastructure]
|
||||
available-time: "" # 예: "solo, 주 50h"
|
||||
available-capital: ""
|
||||
desired-business-size: "" # 예: "$1-5M ARR, solo-operable"
|
||||
preferred-market: ""
|
||||
distribution-capability: "" # self-serve? community? outbound?
|
||||
sales-tolerance: "" # low|med|high
|
||||
operation-tolerance: ""
|
||||
risk-tolerance: ""
|
||||
hard-constraints:
|
||||
- solo-operable
|
||||
- self-serve-distribution
|
||||
- no-enterprise-sales-dependency
|
||||
strategic-preferences:
|
||||
- recurring-revenue
|
||||
- technical-moat
|
||||
- global-developer-market
|
||||
```
|
||||
|
||||
- 위치: `org-os/01-company/founder-context.yaml`(회사 SoT 옆).
|
||||
- `status: filled`이어야 `founder-setup → opportunity-discovery` 통과.
|
||||
- 비밀/키는 두지 않는다(company-context와 동일 정책).
|
||||
|
||||
---
|
||||
|
||||
## 6. 벤처 계약 — 두 파일로 분리 (리뷰 #8)
|
||||
|
||||
스키마(산출물 구조)와 역할 매핑(협업 방식)은 변경 이유가 달라 분리한다.
|
||||
|
||||
### 6.1 `venture-option-spec.yaml` (데이터 스키마)
|
||||
|
||||
```yaml
|
||||
venture-option-spec:
|
||||
version: 1
|
||||
opportunity-cluster: # opportunity-discovery 산출(제품명 이전, 문제 클러스터)
|
||||
required: [id, problem-domain, target-user, triggering-event,
|
||||
current-alternative, why-now, founder-fit]
|
||||
venture-option: # venture-validation 산출(옵션별)
|
||||
required: [id, customer, painful-job, current-alternative, wedge,
|
||||
monetization, expected-price, reachable-customers,
|
||||
rough-revenue-ceiling, acquisition-channel, build-cost,
|
||||
operation-cost, founder-fit, defensibility, kill-criteria,
|
||||
unresolved-assumptions]
|
||||
notes:
|
||||
- "unknown 은 허용값이다(모른다고 적을 수 있어야 한다) — 단 unresolved-assumptions 에 명시."
|
||||
- "kill-criteria 는 필수(없으면 venture-validation→venture-decision 차단)."
|
||||
validation-result: # 게이트별 판정 스냅샷
|
||||
required: [option-id, gate, verdict, evidence, dissent]
|
||||
verdict-enum: [pass, fail, unknown]
|
||||
```
|
||||
|
||||
### 6.2 `venture-validation-map.yaml` (역할·게이트 매핑) — 리뷰 역할 보강 반영
|
||||
|
||||
9-게이트를 **CFO 1인이 대신할 수 없으므로**(가격/WTP/유통/획득/기술해자/운영) 역할을 보강한다. 각 게이트는 primary(작성) + contrarian/auditor(반증) + synthesis-owner를 가진다. 렌즈 다양성·이해상충 방지(작성자≠감사자).
|
||||
|
||||
| Gate | Primary | Contrarian/Auditor |
|
||||
|---|---|---|
|
||||
| 문제 강도·빈도 | UX-RESEARCHER | PROD-PM |
|
||||
| 경쟁·대체재 | GTM-CI | STR-ANALYST |
|
||||
| 지불 의사(WTP) | GTM-PRICING | CFO |
|
||||
| 매출모델·단위경제 | CFO · GTM-REVOPS | GTM-PRICING |
|
||||
| 기술 가능성·해자 | (CTO) ARCH-TECH | CFO |
|
||||
| 운영 가능성 | (COO) CONSULT-OPS | ARCH-TECH |
|
||||
| 유통 가능성 | GTM-GROWTHPM · GTM-SALES | CFO |
|
||||
| 창업자 적합성 | EXEC-CEO | ARCH-TECH |
|
||||
| 실패·중단 기준 | CFO | EXEC-CEO |
|
||||
|
||||
```yaml
|
||||
venture-validation-map:
|
||||
version: 1
|
||||
synthesis-owner: EXEC-CEO # 종합(수렴)은 CEO, 최종 선택은 사람
|
||||
gates:
|
||||
- { gate: problem-intensity, primary: [UX-RESEARCHER], auditor: [PROD-PM] }
|
||||
- { gate: competition-alternatives, primary: [GTM-CI], auditor: [STR-ANALYST] }
|
||||
- { gate: willingness-to-pay, primary: [GTM-PRICING], auditor: [CFO] }
|
||||
- { gate: revenue-unit-economics, primary: [CFO, GTM-REVOPS], auditor: [GTM-PRICING] }
|
||||
- { gate: tech-feasibility-moat, primary: [ARCH-TECH], auditor: [CFO] }
|
||||
- { gate: operability, primary: [CONSULT-OPS], auditor: [ARCH-TECH] }
|
||||
- { gate: distribution, primary: [GTM-GROWTHPM, GTM-SALES], auditor: [CFO] }
|
||||
- { gate: founder-fit, primary: [EXEC-CEO], auditor: [ARCH-TECH] }
|
||||
- { gate: kill-criteria, primary: [CFO], auditor: [EXEC-CEO] }
|
||||
opportunity-discovery-roles: # 기회탐색(발산) 참여 역할
|
||||
diverge: [EXEC-CEO, FAM-CPO, STR-ANALYST, PROD-PM, UX-RESEARCHER, GTM-PMM]
|
||||
contrarian: [CFO] # 왜 실패하는가 — 초기 아이디어의 경제구조 반증
|
||||
```
|
||||
|
||||
> **CFO의 위치(리뷰 강조):** CFO는 "마지막에 돈이 되는지 확인"이 아니라 **초기 아이디어의 경제구조를 반증**하는 역할로 opportunity-discovery부터 contrarian으로 참여한다.
|
||||
|
||||
> 파일을 늘리기 싫으면 한 파일 두 섹션으로 둘 수 있으나, 본 스펙은 변경축 분리를 위해 2파일을 채택한다.
|
||||
|
||||
---
|
||||
|
||||
## 7. `company-context.yaml` 재구조화 — 항목별 provenance (리뷰 #1)
|
||||
|
||||
### 7.1 왜 블록 단위 evidence-cap을 제거하는가
|
||||
|
||||
`fact/decision/hypothesis`는 **정보의 종류**이고 `E1~E5`는 **증거의 강도**다. 둘은 독립이다. 창업자 자가입력 사실은 fact지만 E1~E2일 수 있고, 코드 실행으로 확인한 스택은 fact이며 E4~E5일 수 있다. 전략 결정은 "E3 증거"가 아니라 **HUMAN 권한**으로 유효해진다. 따라서 블록 cap을 제거하고 **항목별 provenance**를 둔다.
|
||||
|
||||
### 7.2 구조
|
||||
|
||||
```yaml
|
||||
schema-version: 2
|
||||
status: provisional # 공식 SoT는 3-상태만: template | provisional | operating (bootstrap 아님)
|
||||
company:
|
||||
facts:
|
||||
- id: FACT-001
|
||||
statement: "창업자는 백엔드·인프라 개발 역량을 보유한다."
|
||||
category: founder-capability
|
||||
provenance:
|
||||
- { source-uri: org-os/01-company/founder-context.yaml, grade: E2 }
|
||||
verified-at: "2026-07-12"
|
||||
status: active # active | retired
|
||||
strategic-decisions:
|
||||
- id: DEC-001
|
||||
statement: "초기 고객은 소규모 백엔드·DB 운영팀으로 한정한다."
|
||||
decision-type: target-market
|
||||
accepted-by: HUMAN-001
|
||||
accepted-at: "2026-07-12"
|
||||
source-decision-id: VD-001 # venture-decision report 계보
|
||||
supporting-evidence:
|
||||
- { source-uri: completion-records/<wf>/exec-packet-*.report.yaml, grade: E2 }
|
||||
status: active
|
||||
hypotheses:
|
||||
- id: HYP-001
|
||||
statement: "대상 고객은 월 $79 이상 지불 의사가 있다."
|
||||
hypothesis-type: willingness-to-pay
|
||||
confidence: Med
|
||||
validation-status: untested # untested | validated | refuted
|
||||
evidence:
|
||||
- { source-uri: completion-records/<wf>/pricing-*.report.yaml, grade: E2 }
|
||||
promotion-criteria: ["유료 사전판매 5+"]
|
||||
falsification-criteria: ["2주 랜딩 유료전환 < 1%"]
|
||||
validation-state:
|
||||
stage: pre-traction
|
||||
validated: []
|
||||
open: [HYP-001]
|
||||
refuted: []
|
||||
projects: [] # 기존 유지(제품 lifecycle 소관)
|
||||
```
|
||||
|
||||
- 단일 `decision-provenance` 객체 **제거** — 결정은 여러 개 누적되므로 **각 decision이 자기 provenance**(accepted-by/accepted-at/source-decision-id/supporting-evidence)를 갖는다.
|
||||
- `schema-version: 1 → 2`. 기존 `company:` 블록(자유서술)은 마이그레이션 시 facts/decisions로 이전하거나 보존(§12).
|
||||
|
||||
### 7.3 상태 어휘 — 공식 SoT는 3-상태만
|
||||
|
||||
**공식 `company-context.yaml`의 `status`는 다음 3개만 가진다.** `bootstrap`은 공식 SoT 상태가 **아니다**(중간·모호 상태 방지 — 리뷰 2차 반영).
|
||||
|
||||
```
|
||||
공식 SoT status:
|
||||
template : 초기(빈) — 회사 미정의
|
||||
provisional : bootstrap 산출. 결정은 유효, 시장 가설은 검증 상태에 종속
|
||||
operating : 실검증·실운영 데이터로 승격(operating 승격 acceptance event 필요)
|
||||
|
||||
공식 SoT 상태 전이(§9.3):
|
||||
template ──(atomic commit)──▶ provisional ──(human-approved promotion)──▶ operating
|
||||
```
|
||||
|
||||
"작성 중인 bootstrap"은 **공식 status로 표현하지 않는다**. 두 가지로만 표현한다:
|
||||
- **candidate 파일**의 별도 필드 `candidate-status: bootstrap`(공식 `status` 필드와 분리 — §9.3), 그리고
|
||||
- **workflow stage** `company-context-commit`(진행 중).
|
||||
|
||||
이로써 "공식 status=bootstrap인데 candidate인가? commit 중인가? cascade가 읽어도 되나?" 같은 애매한 상태가 원천 차단된다. 제품 cascade는 공식 status가 `provisional|operating`일 때만 읽는다(§11).
|
||||
|
||||
`demo/populated`(구 어휘)는 **읽기 호환 + deprecation warning + 일회성 migration**으로 처리(영구 별칭 아님, §12: demo→template, populated→operating).
|
||||
|
||||
---
|
||||
|
||||
## 8. 상태머신 — `venture-bootstrap` plan (리뷰 #4, #5)
|
||||
|
||||
### 8.1 stage 그래프 (terminal 이전에 commit·lint 전이 존재)
|
||||
|
||||
`company-bootstrap`에 "진입하는 순간 terminal 도달" 문제를 피하기 위해 commit과 완료를 분리한다.
|
||||
|
||||
```yaml
|
||||
# execution-plans.yaml
|
||||
plans:
|
||||
venture-bootstrap:
|
||||
description: >
|
||||
회사 수립(1회성). founder-context 를 입력으로 기회탐색→벤처검증→벤처결정→
|
||||
company-context commit 을 거쳐 company-context.yaml(provisional) 을 산출한다.
|
||||
제품 cascade 의 선행이며 별도 lifecycle 이다.
|
||||
stages: [intake, founder-setup, opportunity-discovery, venture-validation,
|
||||
venture-decision, company-context-commit, bootstrap-complete]
|
||||
terminal-stage: bootstrap-complete
|
||||
default-tier: standard
|
||||
outputs: "org-os/01-company/company-context.yaml (status: provisional)"
|
||||
```
|
||||
|
||||
### 8.2 전이·조건 (state-transition-rules.yaml `workflow-stage-transitions`에 추가)
|
||||
|
||||
전이 **집행 주체는 OPS-ORCH(trusted) 단독**. C-Level·전문역할은 intake·결정·추천 **보고서만** 생산하고 상태 원장을 직접 전이하지 않는다(리뷰 #5·2차 반영, 기존 신뢰경계와 정합). `-role-agent` placeholder와 `EXEC-CEO`를 allowed-by에서 **전부 제거**해 worker/C-Level-authored 전이 경로를 원천 차단한다 — venture-bootstrap의 **모든** 전이는 `allowed-by: [OPS-ORCH]`로 통일한다.
|
||||
|
||||
| 전이 | allowed-by | required-conditions(신규 predicate) |
|
||||
|---|---|---|
|
||||
| intake → founder-setup | `[OPS-ORCH]` | `decision-brief-present` |
|
||||
| founder-setup → opportunity-discovery | `[OPS-ORCH]` | `founder-context-present` |
|
||||
| opportunity-discovery → venture-validation | `[OPS-ORCH]` | `opportunity-clusters-present`(≥2) |
|
||||
| venture-validation → venture-decision | `[OPS-ORCH]` | `venture-options-validated` |
|
||||
| venture-decision → company-context-commit | `[OPS-ORCH]` | `venture-decision-accepted` + `human-acceptance-receipt-present` |
|
||||
| company-context-commit → bootstrap-complete | `[OPS-ORCH]` | `company-context-provisional-committed` + `company-context-lint-passed` + `company-context-artifact-recorded` |
|
||||
|
||||
> `EXEC-CEO`는 intake 보고서(decision-brief)·venture-decision 종합을 **생산**할 수 있지만, 그 산출물을 근거로 stage를 전이하는 것은 OPS-ORCH다. (기존 cascade 일부 전이는 `[OPS-ORCH, discovery-role-agent]`처럼 placeholder를 병기하지만 — 실제 집행자는 항상 OPS-ORCH이고 엔진이 `EXEC-CEO` actor를 거부함 — venture-bootstrap은 그 잠재 경로마저 없애기 위해 OPS-ORCH 단독으로 못박는다.)
|
||||
|
||||
이 분리 덕에 "결정은 승인됐지만 company-context 쓰기·검증은 실패" 상태를 정확히 표현·재개할 수 있다.
|
||||
|
||||
### 8.3 신규 condition-catalog (state_engine.py가 원장 사실로 평가)
|
||||
|
||||
```yaml
|
||||
condition-catalog:
|
||||
founder-context-present: "org-os/01-company/founder-context.yaml status=filled"
|
||||
opportunity-clusters-present: "opportunity-cluster 산출 ≥ 2 (ledger.artifacts/보고서)"
|
||||
venture-options-validated: "각 venture-option 이 venture-option-spec required 필드 충족 + kill-criteria 존재 + 9-gate 결과 present"
|
||||
venture-decision-accepted: "venture-decision 보고서 존재 + validate_report 통과 + acceptance_log accepted 이벤트(=report-id·workflow-id 바인딩)"
|
||||
human-acceptance-receipt-present: "HUMAN-001 acceptance 이벤트가 그 venture-decision report-id/hash/workflow-id 에 바인딩(§9.4)"
|
||||
company-context-provisional-committed: "공식 company-context.yaml status=provisional 로 원자적 교체 완료(commit_company_context receipt)"
|
||||
company-context-lint-passed: "lint_company_context Hard Fail 0 (candidate 및 최종)"
|
||||
company-context-artifact-recorded: "commit receipt 가 evidence-ledger/통합원장에 기록됨"
|
||||
```
|
||||
|
||||
### 8.4 human-gate는 boolean이 아니라 바인딩된 receipt (리뷰 #5)
|
||||
|
||||
`human_gate_approved: true` 단일 boolean 금지. `venture-decision-accepted`+`human-acceptance-receipt-present`는 다음을 모두 요구:
|
||||
1. venture-decision report 존재, 2. `validate_report` 통과, 3. `HUMAN-001` acceptance 이벤트 존재, 4. 이벤트가 **동일 report-id + report-sha256 + workflow-id**에 바인딩. (report-sha256 바인딩은 acceptance-event에 추가하는 신규 필드 — §9.4.)
|
||||
|
||||
---
|
||||
|
||||
## 9. 강제기 (hook / validator)
|
||||
|
||||
### 9.1 `validate_report` — 항목 단위 상한 (리뷰 #2, 자기수정 포함)
|
||||
|
||||
**정정:** 기존 코드는 이미 **항목 단위**로 동작한다. [validate_report.py:474-480](.claude/hooks/validate_report.py#L474-L480)의 `_is_unpopulated_company_ref(source-uri)`는 **개별 evidence 항목의 source-uri가 회사 네임스페이스를 가리키고 status != populated일 때 그 항목만** E2로 상한한다(외부·코드·테스트 증거는 원래 등급 유지). 전체 보고서 강등이 아니다. 따라서 리뷰 #2의 우려(전역 강등)는 **기존 구현엔 없으며**, 변경은 아래 두 가지로 한정한다:
|
||||
|
||||
1. **상태 어휘 확장:** `_company_context_populated()` → 공식 status가 `operating`일 때만 상한 해제. `template/provisional`(및 구 `demo`)은 회사 네임스페이스 인용을 계속 E2/Med 상한. 구 `populated`는 `operating`으로 읽기 호환. (공식 SoT에 `bootstrap`은 존재하지 않으므로 처리 대상 아님 — §7.3.)
|
||||
2. **hypothesis 항목 ceiling(신규 최소구현):** 회사 문맥 인용의 `source-uri`가 특정 항목(`company-context.yaml#HYP-001` 형태 anchor)을 가리키면:
|
||||
- `hypotheses` 항목 → 회사별 결론 **confidence ≤ Med**, grade ≤ E2 (검증 상태 무관하게 가설 기반).
|
||||
- `facts`/`strategic-decisions` 항목(provenance 有) → 항목 provenance grade까지 허용(단 status=operating 또는 결정은 결정으로서 유효).
|
||||
- anchor 미지정(파일 전체 인용) → 기존 네임스페이스 상한(coarse).
|
||||
3. **불변:** 외부 E3/E4/E5(코드 실행·테스트·외부 조사)는 회사 status와 **독립**으로 원등급 유지.
|
||||
|
||||
### 9.2 `lint_company_context.py` — 구조는 Hard Fail, 의미는 Warning (리뷰 #3)
|
||||
|
||||
자연어 의미로 "이건 가설인데 fact로 위장"을 정적 판정하는 것은 오탐·누락이 크다 → **Warning**. 구조·참조·권한·상태 정합만 **Hard Fail**.
|
||||
|
||||
**Hard Fail**
|
||||
- 항목 ID 누락 / 중복 ID
|
||||
- 공식 파일의 `status`가 `template|provisional|operating`(3-상태) 밖 — 특히 공식 파일에 `status: bootstrap`이면 Hard Fail(§7.3)
|
||||
- 항목 `status`가 허용값 밖
|
||||
- candidate 파일이 아닌데 `candidate-status` 필드가 존재(또는 공식 파일에 `candidate-status: bootstrap`이 남아있음)
|
||||
- `fact`의 provenance 누락
|
||||
- `decision`의 `accepted-by`/`accepted-at`/`source-decision-id` 누락
|
||||
- `hypothesis`의 `validation-status`/`confidence`/`falsification-criteria` 누락
|
||||
- hypothesis ID를 fact reference 자리에 사용
|
||||
- 존재하지 않는 evidence 경로(source-uri)
|
||||
- `provisional`인데 human 승인 decision이 하나도 없음
|
||||
- `operating`인데 operating 승격 acceptance event 부재
|
||||
|
||||
**Warning**
|
||||
- fact 문장이 추정 표현("~일 것", "예상") 포함
|
||||
- hypothesis와 fact 내용이 의미상 중복 의심
|
||||
- 시장 규모·WTP가 fact에 들어간 것으로 의심
|
||||
- 장기 미검증 hypothesis(오래된 verified/updated 없음)
|
||||
- provenance는 있으나 근거 내용이 주장과 약하게 연결
|
||||
|
||||
- candidate 파일(§9.3)과 최종 파일 **둘 다** 검증 가능해야 한다.
|
||||
- `run_all.py`·`doctor.py`에 배선. 구 `demo/populated`는 읽기 호환하되 **deprecation warning** 발생.
|
||||
|
||||
### 9.3 `commit_company_context.py` — candidate → 원자적 교체 (리뷰 #6)
|
||||
|
||||
bootstrap 도중 공식 SoT를 수정하면 중간 상태를 제품 cascade가 소비할 위험이 있다. 따라서:
|
||||
|
||||
```
|
||||
공식 company-context.yaml (status: template) ← bootstrap 동안 불변, 공식 status에 bootstrap 없음
|
||||
│
|
||||
candidate 생성:
|
||||
<workspace>/completion-records/<workflow-id>/company-context.candidate.yaml
|
||||
· status: provisional # 최종 목표 상태(공식 3-상태 중 하나)
|
||||
· candidate-status: bootstrap # candidate임을 표시하는 별도 필드(공식 파일엔 없음)
|
||||
↓ schema validation
|
||||
↓ lint_company_context (Hard Fail 0; candidate-status:bootstrap 허용은 candidate에 한함)
|
||||
↓ venture-decision + human acceptance receipt 검증(바인딩)
|
||||
↓ trusted commit: candidate-status 필드 제거 → 임시파일 write → os.replace() 원자 교체
|
||||
공식 company-context.yaml (status: provisional) ← candidate-status 없음
|
||||
```
|
||||
|
||||
- `commit_company_context.py`는 **trusted CLI**(OPS-ORCH가 실행). 위 게이트를 모두 통과할 때만 `candidate-status`를 벗겨 `os.replace()`로 교체. 실패 시 기존 파일 **무변경**.
|
||||
- 공식 SoT는 `template → provisional → operating` 3-상태만 실질 사용(§7.3). "작성 중"은 공식 status가 아니라 **candidate 파일의 `candidate-status: bootstrap`** 및 **workflow stage `company-context-commit`**으로만 표현한다.
|
||||
- commit은 `evidence-ledger`/통합원장에 receipt를 남긴다(`company-context-artifact-recorded`).
|
||||
|
||||
### 9.4 `acceptance_log` / `acceptance-event.schema.json` — 해시 바인딩 추가 (리뷰 #5, tests #3/#4)
|
||||
|
||||
현재 이벤트는 report-id + workflow-id + 실존(`_resolve_report_path`, ghost-acceptance 차단)만 바인딩하고 **content hash는 없다**. venture-decision human-gate의 위조·재사용을 막기 위해 **선택적 `report-sha256`** 필드를 추가(스키마 `additionalProperties: true`라 additive):
|
||||
|
||||
- `acceptance_log.py append ... --report-sha256 <hash>` 지원.
|
||||
- `human-acceptance-receipt-present` predicate는 acceptance 이벤트의 `report-sha256`가 **현재 venture-decision 파일의 해시와 일치**하고 `workflow-id`가 같을 때만 통과. 불일치(결정 변경/타 workflow 재사용) → 거부.
|
||||
|
||||
### 9.5 `guard_tools.py` — 공식 SoT 직접쓰기 보호
|
||||
|
||||
공식 `org-os/01-company/company-context.yaml`은 fan-out worker/일반 Edit·Write로 **직접 수정 금지**. `commit_company_context.py`(trusted) 경로로만 교체. `founder-context.yaml`은 사람 입력이므로 별도(사람이 편집; worker 쓰기는 금지).
|
||||
|
||||
---
|
||||
|
||||
## 10. 커맨드 (리뷰 #7, #9)
|
||||
|
||||
기존 fan-out(divergent)·converge 인프라 위 **얇은 드라이버**. `/decide` **명령**을 호출하지 않고 공통 **converge contract**(collaboration-modes.yaml)를 재사용한다.
|
||||
|
||||
### 10.1 `/ceo-intake` (보강)
|
||||
- `--plan venture-bootstrap` 명시로만 회사 부트스트랩 선택(자동 선택 금지 — 기존 제품 cascade와 충돌 방지).
|
||||
- founder-context가 `template`이면 사람에게 채우도록 유도(또는 `/venture-validate` 진입 시 상태 확인해 founder-setup으로 유도).
|
||||
|
||||
### 10.2 `/venture-validate` (신규)
|
||||
- **opportunity-discovery(발산):** `venture-validation-map.opportunity-discovery-roles`로 fan-out → opportunity-cluster ≥2(중복·완전성 검사). 제품명 이전, 문제 클러스터부터.
|
||||
- **venture-validation:** option별 9-gate fan-out(primary/auditor, dissent 보존). `unknown` 허용, `kill-criteria` 필수. 산출 = validation-result + venture-option 보고서.
|
||||
- 진입 시 `state_engine guard`, 종료 시 OPS-ORCH가 `transition`(worker 아님).
|
||||
|
||||
### 10.3 `/company-bootstrap` (신규)
|
||||
- **venture-decision(수렴):** 공통 converge contract로 C-Level 독립 평가(CPO·CFO·CTO·COO·CPTO) → CEO synthesis(dissent 보존) → **ExecutiveDecisionPacket** 산출.
|
||||
- **HUMAN acceptance:** 사람이 하나를 선택 → `acceptance_log append`(report-id + report-sha256 + workflow-id 바인딩).
|
||||
- **company-context-commit:** candidate 생성 → schema/lint/acceptance 검증 → `commit_company_context.py`로 원자적 교체(§9.3).
|
||||
- 모든 stage 전이는 OPS-ORCH가 집행.
|
||||
|
||||
### 10.4 공통 converge contract의 위치
|
||||
재사용 단위는 slash command가 아니라 다음 중 하나로 둔다(구현 계획에서 택1):
|
||||
- `collaboration-modes.yaml`의 `converge` 계약(이미 존재: synthesis + report-header) + `context_package`(mode=divergent 평가 → converge 종합) 조합을 커맨드 문서가 **참조**.
|
||||
- 필요 시 얇은 orchestrator helper/command fragment로 절차를 공유(중복 서술 금지).
|
||||
|
||||
---
|
||||
|
||||
## 11. 제품 cascade 진입 계약 (seam, 리뷰 #9)
|
||||
|
||||
product-definition stage는 P1에서 만들지 않되, **후속 cascade가 bootstrap 결과를 정확히 참조**할 계약만 정의한다.
|
||||
|
||||
```yaml
|
||||
# 제품 cascade 진입 조건(신규 predicate: company-context-ready)
|
||||
company-context-ready:
|
||||
all:
|
||||
- "company-context.status in [provisional, operating]"
|
||||
- "selected-venture-decision-id exists (company.strategic-decisions[].source-decision-id 또는 별도 pointer)"
|
||||
- "selected venture accepted by HUMAN (acceptance event 바인딩)"
|
||||
- "no unresolved bootstrap blocker"
|
||||
```
|
||||
|
||||
제품 intake(decision-brief)에는 다음 참조를 포함한다:
|
||||
|
||||
```yaml
|
||||
company-context-ref: org-os/01-company/company-context.yaml
|
||||
venture-decision-id: VD-001
|
||||
company-decision-ids: [DEC-001, DEC-002]
|
||||
```
|
||||
|
||||
- `template` 상태(또는 company-context-commit 미완)에서 제품 cascade 진입은 **advisory 체크**로 가드된다 — 오케스트레이터가 진입 시 `python3 .claude/hooks/state_engine.py check-company-context-ready --workflow <wf>`(exit 2 = NOT READY)를 실행·확인하되, **기존 cascade 전이의 하드 선행조건으로는 넣지 않는다**(부트스트랩되지 않은 회사에서 도는 데모/샌드박스 cascade 회귀 방지 — 구현상 의도적 advisory, Task 12). `provisional/operating`은 READY. **후속 과제**: 이 advisory 체크를 `/ground`·`/decide` 커맨드 프롬프트의 진입 스텝으로 명시 배선(하드 게이트 승격은 데모 cascade 회귀와 상충하므로 신중)."
|
||||
- 이 계약은 state_engine의 cascade 진입 guard에 predicate로 추가(제품 stage 자체는 불변).
|
||||
|
||||
---
|
||||
|
||||
## 12. 마이그레이션 (`demo/populated` → 신 어휘)
|
||||
|
||||
영구 별칭이 아니라 **읽기 호환 + deprecation warning + 일회성 migration**:
|
||||
1. **읽기 호환:** validate_report·lint은 `demo`를 `template`으로, `populated`를 `operating`으로 **해석**하되 **deprecation warning** 출력.
|
||||
2. **일회성 migration:** `lint_company_context.py --migrate`(또는 별도 스니펫)로 현재 `company-context.yaml`을 schema-version 2 구조로 1회 변환(자유서술 `company:` → facts/decisions 이전, 나머지는 hypotheses/보존). 변환 후 status를 명시 어휘로 교체.
|
||||
3. 변환 뒤에는 구 어휘 사용 시 Hard Fail로 승격(후속 사이클).
|
||||
|
||||
---
|
||||
|
||||
## 13. 데이터 흐름 (확정)
|
||||
|
||||
```
|
||||
/ceo-intake --plan venture-bootstrap
|
||||
→ intake (decision-brief-present)
|
||||
→ founder-setup (founder-context.yaml status=filled)
|
||||
/venture-validate
|
||||
→ opportunity-discovery (독립 fan-out, cluster ≥2, 중복·완전성)
|
||||
→ venture-validation (option별 9-gate, unknown 허용, kill-criteria 필수, dissent 보존)
|
||||
/company-bootstrap
|
||||
→ venture-decision (C-Level 독립평가 → CEO synthesis → HUMAN acceptance receipt[hash 바인딩])
|
||||
→ company-context-commit (candidate → schema → lint → atomic os.replace)
|
||||
→ bootstrap-complete (company-context.status=provisional, artifact receipt 기록)
|
||||
│ seam: company-context-ready
|
||||
▼
|
||||
[product cascade] /ground /decide /design … (company-context + venture/decision ids 를 입력으로)
|
||||
```
|
||||
|
||||
전이는 전부 OPS-ORCH가 집행. 각 stage 산출물은 불변 보고서. 공식 SoT는 마지막 1회 원자 교체.
|
||||
|
||||
---
|
||||
|
||||
## 14. 테스트 (TDD, RED→GREEN, run_all 유지)
|
||||
|
||||
기존 제안(신규 predicate 게이팅, lint, status 어휘 캡)에 더해 **반드시 포함**:
|
||||
|
||||
1. worker agent가 state transition을 요청하면 거부(allowed-by=OPS-ORCH만).
|
||||
2. human boolean만 있고 acceptance receipt 없으면 거부.
|
||||
3. 다른 workflow의 decision report를 재사용하면 거부(workflow-id 불일치).
|
||||
4. decision hash ≠ acceptance hash면 거부(report-sha256 바인딩).
|
||||
5. candidate lint 실패 시 공식 company-context **무변경**.
|
||||
6. commit 중 실패해도 기존 파일 유지(atomic).
|
||||
7. `template` 상태(또는 company-context-commit 미완)에서 제품 cascade 진입 거부.
|
||||
8. `provisional` 상태에서 제품 cascade 진입 허용.
|
||||
9. 외부 E4 증거가 provisional 때문에 E2로 강등되지 **않음**.
|
||||
10. hypothesis를 참조한 회사별 주장은 Med ceiling 적용.
|
||||
11. `demo/populated` 읽기 호환은 되지만 deprecation warning 발생.
|
||||
12. 재실행 시 이미 완료된 fan-out을 중복 실행하지 않음(idempotent stage).
|
||||
13. 동일 candidate commit 재실행 idempotent.
|
||||
14. decision 변경 시 이전 candidate commit 거부.
|
||||
|
||||
추가 커버리지: lint Hard Fail 항목별(ID 누락/중복/provenance 누락/hypothesis 필드 누락/hypothesis-id-as-fact/nonexistent evidence path), founder-context 미충족 게이팅, opportunity-cluster <2 차단, kill-criteria 누락 차단.
|
||||
|
||||
---
|
||||
|
||||
## 15. 열린 사항 / 리스크
|
||||
|
||||
- **converge contract 재사용 형태**(collaboration-modes 참조 vs helper vs fragment)는 구현 계획에서 확정. 어느 쪽이든 `/decide` 명령 직접 호출 금지 원칙은 불변.
|
||||
- **hypothesis 항목 ceiling**의 anchor 규약(`company-context.yaml#HYP-001`) — 인용 표기 컨벤션을 context-package/보고 스키마 문서에 명시해야 실효.
|
||||
- **역할 보강**(GTM-PRICING·GTM-GROWTHPM·ARCH-TECH·CONSULT-OPS 등)이 venture-validation-map에서 실제 agent-card로 존재하는지 gen_agents 대조(doctor 체크 후보).
|
||||
- **company-context는 repo-level SoT**(회사 사실 + projects[]). bootstrap은 회사 수립이므로 repo SoT를 교체하는 것이 맞다. candidate는 workspace completion-records에 두고 최종만 repo로 원자 교체.
|
||||
|
||||
---
|
||||
|
||||
## 16. 확정 체크리스트(리뷰 9개 반영)
|
||||
|
||||
1. ✅ 블록 단위 evidence-cap 제거, 항목별 provenance(§7)
|
||||
2. ✅ company status가 보고서 전체 evidence를 강등하지 않도록 항목 단위로 한정(§9.1, 기존 구현이 이미 항목 단위임을 확인·확장)
|
||||
3. ✅ semantic hypothesis-as-fact는 Warning, 구조·참조·권한만 Hard Fail(§9.2)
|
||||
4. ✅ `company-context-commit → bootstrap-complete` 전이 추가(§8.1–8.2)
|
||||
5. ✅ 상태 전이는 worker 아니라 OPS-ORCH/trusted hook만 + acceptance receipt hash 바인딩(§8.2–8.4, §9.4)
|
||||
6. ✅ candidate 작성 후 공식 SoT 원자적 commit(§9.3)
|
||||
7. ✅ `/decide` 명령이 아니라 공통 converge contract 재사용(§10)
|
||||
8. ✅ GTM-PRICING·GTM-GROWTHPM·ARCH-TECH·CONSULT-OPS 등 역할 보강(§6.2)
|
||||
9. ✅ product cascade 진입 계약만 P1에서 정의(product-definition stage 미신설)(§11)
|
||||
|
||||
**2차 반영(구현 직전):**
|
||||
10. ✅ 상태 전이 권한 완전 통일 — venture-bootstrap 모든 전이 `allowed-by: [OPS-ORCH]` 단독(intake 행의 `EXEC-CEO` 제거). C-Level은 보고서 생산만(§8.2).
|
||||
11. ✅ 공식 `company-context.yaml` status는 3-상태(`template|provisional|operating`)만 — `bootstrap` 제거. "작성 중"은 candidate 파일의 `candidate-status: bootstrap` + workflow stage `company-context-commit`로만 표현(§7.3, §9.2–9.3).
|
||||
Reference in New Issue
Block a user