Index
한 줄 소개: 펀드 운용 lifecycle (소싱 → 실사 → IC → 포트폴리오 → 엑싯 → LP IR) 의 투자판단 backend. frame (회계) · hive (HR) 와 같은 vertical layer 이되, “사실의 보존소” 를 넘어 판단(가정·calibration·comp·base_rate)을 typed fact 로 적재하고 그 판단이 지배하는 relational compute 를 deterministic 하게 재실행한다. Rust + axum + sqlx (D-cortex-7 precedent).
상태: LIVE. MCP
https://axe.axelabs.ai/index/mcp· schema discovery/index/schemas· 공개 집계 현황 https://axe.axelabs.ai/index . 23 deal · 380 artifact · 15 typed-fact schema · 35 MCP 도구 (live 집계 = 현황 페이지). 브라우저 SSO firm-read 상세 뷰 LIVE (D-index-48) — axe.axelabs.ai/index 로그인 → Entra → 딜별 IRR·calibration 상세.
3-layer 모델
index 는 한 덩어리가 아니라 세 layer 가 쌓인 구조다:
| Layer | 무엇 | 예 |
|---|---|---|
| L1 · relational compute substrate | deal 의 숫자가 사는 관계형 SoT. financial_model 6-table + fund_investment N:M + DSL formula + topo evaluator. cell 재계산 deterministic | compute_outputs · query_irr · compute_full_model |
| L2 · artifact-first judgment layer | relational 값을 지배하는 판단 을 typed artifact 로 적재. 가정·calibration·comp·base_rate + citation(근거) + append-only event(감사) | get_judgment_provenance · list_calibrations · confirm_artifact |
| L3 · skills + schema contract | 투자 도메인 skill (owner:index) 의 SoT + frozen_enums_hash 로 고정된 typed-fact 계약 | list_skills · /index/schemas |
아키텍처 한 줄 (현황 페이지 의 “아키텍처” 섹션과 동일): index owns TRUTH (사실 레이어) · Blueprint owns ROAD (운영·UI, index 사실 소비) · surface owns RUN (claude.ai connector / Claude Code — 인증 후 MCP 호출).
artifact-first judgment layer (D-index-45)
index 의 본질적 차별성. relational compute 만 있으면 “IRR 이 23.4%” 는 알지만 “왜 그 값인가” 는 휘발한다. judgment layer 가 그 판단을 일급 fact 로 보존한다.
- 5 judgment kind:
index.assumption(한 relational field 를 지배하는 입력) ·index.calibration(SURFACE→CALIBRATED scrub) ·index.comp(비교 밴드) ·index.base_rate(확률 기준율) ·index.deal_judgment(thesis-level 처분 판단 — 왜 passed/lost/died + durable lesson, D-index-49 dead-deal harvest; claim 과 달리 author·불변·supersede). field 모양 = schema-catalog § judgment. - 링크는 일급 citation 이지 컬럼이 아님: citation kind
index_field(ref{deal,field}) 가 relational field 로,artifact_ref(ref{artifact_id,relation}, relation ∈calibrated_from/scrubbed_from/anchored_to/contradicts/supersedes) 가 fact↔fact 로 연결. - lifecycle propose→confirm, RLS owner_only, append-only
artifact_event. - seed = SoT (D-index-46): judgment 는
seed.yaml의judgment:block +seeds/_corpus.yaml에서seed-ingest --emit-judgment로 파생. hardcoded backfill 폐기. - scrub 의 정직: surface(표면) 값을 research-calibrated 값으로 조정할 때 조용히 하나 고르지 않고 calibration artifact 로 충돌을 드러낸다 (D-index-24/26).
현재 380 artifact / 23 deal (assumption 218 · calibration 58 · comp 35 · base_rate 7 · deal_judgment 23 + extracted_metric/figure — live). deal_judgment = 16 passed · 6 invested · 1 lost (D-index-49 — 죽은 딜의 “왜 패스했나” judgment corpus).
MCP 도구 카탈로그 (35)
Archive (L-Archive · D-index-50 · D-index-51) — 죽은 딜 teardown: OneDrive/Blueprint raw 파일을 index 가 흡수 (파일 bytes 를 Postgres bytea content-addressed 저장 → 단일 DB 백업·OneDrive 독립). MCP tools:
register_evidence_blob(512MiB 상한) ·list_deal_evidence·get_evidence_blob·schedule_postmortem·list_postmortems·update_postmortem. CLI/audit surface 는 아래 표 —ingest-evidence(archive) ↔export-evidence(restore 역연산) +teardown_event(recovery map) +axe index teardownorchestrator (D-index-51).
Archive — teardown CLI / audit (L-Archive)
| CLI / audit | 기능 |
|---|---|
index ingest-evidence --deal <c> --kind <k> <files…> | 파일 → evidence_blob (archive, content-addressed sha256 dedup, 512MiB 상한) |
index export-evidence --deal <c> --out <dir> | evidence_blob → 파일 복원 (restore = 역연산; 디스크 재-hash sha256 round-trip 검증, 마지막 줄 JSON mismatches==[] 게이트) |
teardown_event (table) | teardown 감사 행 + sha_manifest recovery map [{path,sha256,kind,size}], RLS owner_only |
axe index teardown / restore / list-archive | cross-service orchestrator — 폴더해소(Blueprint Workspace.drivePath)·OneDrive+workspace 삭제·teardown_event 감사 (D-index-51) |
served tool 은 src/mcp.rs 의 tool_schemas() 가 SoT (현황 페이지의 “MCP 도구 카탈로그” 와 동일). 인증된 /index/mcp 에서만 호출 가능. 그룹별:
deal / IRR query (L1)
| Tool | 기능 |
|---|---|
list_deals | deal 요약 list (stage/sector 필터) |
get_deal | deal full snapshot (target_company + fund_investments + scenarios + leaf/driver count) |
query_irr | deal IRR + per-position 독립 IRR. IRR(E[CF]) canonical |
fund_performance | 투자조합(1호/2호/3호) 펀드별 수익성 — 횡단 pool → fund IRR(E[CF]) + E[MoM] |
compute_outputs | exit_matrix aggregation per scenario (Σ leaf.prob × proceeds) + dead_leaf |
get_exit_matrix | leaf-level breakdown (scenario × timing × path × prob × proceeds) |
cross_deal_benchmark | driver 별 cross-deal 비교 |
validate_financial_model | 6 sanity check (DAG cycle · scenario coverage · leaf prob · invariants) |
compute_full_model | DSL evaluator 가 derived formula 를 period 순차 evaluate (cell-equiv) |
compute_3fs | IS/BS/CF typed line items 재구성 (IS focus) |
artifact / judgment (L2)
| Tool | 기능 |
|---|---|
query_artifacts | owner artifact list (para_anchor/kind/metric_kind/status 필터, 파생 status) |
get_artifact | 단일 artifact full view (payload + citation + event 이력 + 파생 status) |
confirm_artifact | proposed fact confirm (append-only event, edit_payload 시 payload UPDATE) |
reject_artifact | proposed fact reject (row 유지, status→rejected) |
reconcile_artifacts | cross-source 충돌 surface (metric별 group, relative_gap > 10% flag) |
get_judgment_provenance | 한 relational field 를 지배하는 assumption/calibration + 해소된 evidence |
list_calibrations | deal 의 모든 calibration (scrub_kind + surface→calibrated + 링크) |
query_dispositions | dead-deal harvest — verdict/sector/tag 횡단 deal_judgment (“왜 passed/lost 했나” + durable lesson, D-index-49) |
get_deal_judgment | 단일 deal 의 처분 JUDGMENT (verdict + thesis + rationale + lesson + backing comp + supersede 체인) |
verify_citations | evidence-durability audit (durable vs fragile 집계) |
ingest / propose (L2 적재)
| Tool | 기능 |
|---|---|
propose_artifacts_from_ingest | dataroom ingest sidecar → artifact store 에 proposed fact 적재 (+_provenance stamp + drift gate) |
propose_deal_closure | atomic batch — target_company + deal + fund_investment[] + financial_model 을 1 transaction INSERT |
import_xlsx | LP 가 수정한 xlsx Assumptions sheet → DB driver_value diff/apply |
draft_seed_from_artifacts | deal artifact → seed.yaml SCAFFOLD auto-draft (정문 자동화, calibration 자동생성 안 함) |
export (LP deliverable)
| Tool | 기능 |
|---|---|
export_lp_html | self-contained HTML dashboard (IRR + IS + Exit Matrix + Assumptions) |
export_lp_model | 4-sheet xlsx (Assumptions · IS · Exit Matrix · IRR Summary), deterministic |
export_lp_bundle | xlsx + index.html + README.md 를 단일 zip |
skill (L3)
| Tool | 기능 |
|---|---|
list_skills | index 산하 skill 카탈로그 (frontmatter + sub-dir) |
get_skill_resource | skill resource fetch (content + sha256) |
evidence-durability
citation 은 source 파일이 이동·개명·삭제돼도 살아남아야 한다. evidence-durability v1 에서 모든 citation 은 sha256 content-anchor (cited 파일 bytes 의 hash) 를 PRIMARY 앵커로 carry + 추가 앵커 (drive_item_id · workspace_id+rel_path · marker readiness).
- DURABLE := ref 에 non-null
sha256ORdrive_item_idOR (workspace_idANDrel_path). 아니면 FRAGILE (path-only). verify_citations도구가 owner citation 을 durable/fragile 로 집계 (per-deal 분해 + fragile kind 목록).- 현황 페이지 가 durable% 를 공개 (현재 sha256 backfill 진행 전 — citation durability 0%, anchor 적재 path 가동).
상세 citation kind = schema-catalog § citation.
기술 스택
frame/hive 패턴 미러하되 Rust + axum + sqlx (D-cortex-7 precedent, D-index-2):
| 항목 | 값 |
|---|---|
| 언어 | Rust |
| 프레임워크 | axum + tower-http |
| DB | PostgreSQL 16 + sqlx (compile-time SQL check) |
| Migration | sqlx migrate (timestamped SQL) |
| MCP transport | axum + Streamable HTTP (cortex 패턴) |
| 인증 | jsonwebtoken + reqwest JWKS — 다중 issuer peek: Microsoft Entra ID (RS256, claude.ai/Claude Code) + Blueprint 플랫폼 토큰 (RS256/JWKS, axe CLI·브라우저 SSO, D-axe-idp-1) + 선택 HS256 self-token. email = RLS actor |
| RLS | index_app NOSUPERUSER role + per-request SET LOCAL index.actor GUC (owner_only) |
| Formula DSL | 10-operator parser + topological evaluator |
| Container | distroless 단일 binary |
이유: (a) artifact 의 discriminated union 과 Rust algebraic type 자연, (b) sqlx compile-time SQL check 가 schema/RLS query 안전성 보강, (c) long-running 단일 process panic-free.
포트 (범위: 40xx)
| 포트 | 컨테이너 | 용도 |
|---|---|---|
| 4000 | index-postgres | PostgreSQL 16 |
| 4010 | index-mcp-blue | MCP HTTP (active) |
| 4011 | index-mcp-green | MCP HTTP (passive) |
| 4012 | axe-index-proxy | Caddy blue/green selector |
39xx (matrix) 다음 40xx 자연 할당. cloudflared ingress ^/index(/.*)?$ → host.docker.internal:4012. (32xx 는 Cortex.)
URL 컨벤션
axe.axelabs.ai/index ← 공개 집계 현황 (HTML) · 세션 있으면 firm-read 상세 (D-index-48)
axe.axelabs.ai/index/login ← 브라우저 SSO 시작 (Blueprint OIDC Auth-Code + PKCE S256)
axe.axelabs.ai/index/callback ← OAuth redirect (code→token→세션 쿠키)
axe.axelabs.ai/index/logout ← 세션 쿠키 제거
axe.axelabs.ai/index/mcp ← MCP endpoint (인증 필요, per-deal 상세)
axe.axelabs.ai/index/schemas ← schema discovery (인증)
axe.axelabs.ai/index/healthz ← readiness
axe.axelabs.ai/index/.well-known/oauth-protected-resource
GET /index는 두 얼굴 (D-index-48): 세션 없으면 공개 집계 (deal.stage count · artifact.kind count · schema 이름·버전 · 도구 list 만 — 개별 deal·회사·재무값 불포함, RLS per-owner private, D-index-2); 유효 Blueprint-SSO 세션이면 firm-read 상세 (deal별 entry 시점·예상 exit(entry+E[holding])·상태(Project/Resource/Archive lifecycle, D-index-50) + IRR(E[CF])·E[MoM]·P(loss) + 펀드 1·2·3호 성과 + calibration — MCPquery_irr/fund_performance와 byte-identical). 무세션 leak-tripwire 는 회귀 테스트로 강제. 쿠키 서명은INDEX_JWT_SECRET재사용(httpOnly+Secure+SameSite=Lax). 브라우저 SSO 는 ✅ LIVE (2026-06-04 — Blueprintaxe-index-webweb policy 배포 + envINDEX_WEB_LOGIN_READY=true):axe.axelabs.ai/index로그인 버튼 → Blueprint OIDC(Auth-Code+PKCE) → Entra → 상세. per-deal 상세는 그 외엔 인증된/index/mcp로.
owner:index skills (D-index-47)
투자 도메인 skill (ic · ingest · pmc + due-diligence · vc-deal-sourcing · investor-relations · portfolio-management · legal-compliance) 은 owner: index 로 vertical-gated. index customer (axe) 만 투자 skill 수신, 비-index customer 는 universal 9개만. 분배 = universal-base mirror + --attest drift sentinel + Blueprint boot/webhook 양 경로 gate. 상세 (P0–P3 LIVE) = skill-ownership.
OAuth-RP 흐름
frame/hive 와 동일. customers.yaml sso.apps.index_mcp 에서 client_id / application_id_uri 읽어 Microsoft Entra ID id_token RS256 검증.
surface → POST /index/mcp (no auth)
index → 401 + WWW-Authenticate: Bearer resource_metadata="..."
client → GET /index/.well-known/oauth-protected-resource
index → { resource, authorization_servers: [Microsoft] }
client → Microsoft OAuth (PKCE) → access_token (aud = Application ID URI)
client → POST /index/mcp Authorization: Bearer <token>
index → JWKS RS256 verify + aud + iss + email → owner 매핑 → MCP sessionBlueprint platform token 도 trust (D-axe-idp-1 Phase 2). 상세: /architecture/auth.
Production 배포 (axe ship index)
D-index-10 Phase 0 acceptance 8/8 PASS → production LIVE. axe ship index (docs-check → push → blue/green deploy). Entra ID app 47fe856f-75e8-457b-a10e-fce1559939f5, vault 5 secret manifest, cloudflared /index ingress (CF API self-service). 검증:
docker compose up -d # 4 컨테이너 healthy
curl http://localhost:4010/healthz # blue 직접
curl http://localhost:4012/healthz # proxy 경유
curl -X POST http://localhost:4012/index/mcp # 401 + WWW-Authenticate
docker exec index-mcp-blue /usr/local/bin/index dump-schemas | jq '.metadata' # frozen_enums_hashCLI 회귀 (auth 미경유 직접 dispatch):
docker exec index-mcp-blue /usr/local/bin/index mcp-call query_irr --args '{"deal_code":"Iippo"}'
docker exec index-mcp-blue /usr/local/bin/index mcp-call compute_outputs --args '{"deal_code":"Iippo"}'운영 노트
- Blue/green deploy (4010/4011 동시 실행, network alias swap via axe-index-proxy)
- Append-only: 모든 typed fact 에
artifact_eventaudit + financial_modellocked_at후 immutable - RLS owner_only: per-request
SET LOCAL index.actorGUC, FORCE RLS — 다른 owner 의 artifact 미열람 - provenance + drift gate (D-index-47 P1): propose event 에
_provenancestamp +SCHEMA_CONTRACT_DRIFTgate - 백업: restic Tier A — index-postgres
pg_dumpall매일 03:00 (D-index-51:evidence_blob= 죽은 딜 SOLE 사본, 백업이 유일 보호) + D-config-14 - 환경변수 = env_file 단일 출처 (D-ops-18),
axe secret pull index가 vault →.env.local
관련 문서
- /services/index/financial-model — L1 relational: 6-table SoT + DSL + topo evaluator + xlsx round-trip + 3 deal worked example
- /services/index/schema-catalog — 14 active typed-fact schema (10 base + 4 judgment) + frozen_enums_hash + citation kinds
- /services/index/skill-ownership — owner:index skill 의 P0–P3 구현 (D-index-47)
- /services/index/skill-evolution — 5 skill → service 진화 (design-era, 일부 superseded)
- /services/index/skill-integration — skill 통합 아키텍처 (design-era, 일부 superseded)
- 현황 페이지 — live 집계 (deal/artifact/schema/도구)
- /ops/decisions D-index-45/46/47 — judgment layer · seed=SoT · provenance+skill ownership
- /services/cortex — Rust + axum + sqlx 미러 reference