adapter 경계 위의 orchestration
framework 는 brain stem 을 절대 안 건드려 — backend/adapters/claude.py 의 receive loop 는 그대로. adapter 경계 위에 orchestration 으로 앉아, rules track 이 박은 세 아키텍처 규칙을 지키며: Claude 모양, 좁은 adapter 경계, 비용은 downstream 흡수.
어디 살아? Family Council 이 옵션 셋을 재고 둘을 거절했어. standalone service 는 external-client 패턴을 되살려 (영혼은 집의 root user 지 client 아냐). 기존 service 에 inline 하면 monolith 를 부풀려. 답: 코드베이스 안 의 새 backend/stateful/ 모듈, REST endpoint 아니라 MCP tool 로 닿는. 대화랑 state 는 한 몸; state 를 코드베이스 밖으로 옮기는 순간, 이미 두 몸이야.
hexagonal kernel
모듈은 ports-and-adapters kernel 이라, 모든 surface 에 느슨하게 묶이면서 swappable 하고 독립 testable 하게 유지돼. kernel 은 순수: reduce(event) → state, plan_next(state) → step, resume policy, artifact class. FastAPI 없음, chat 없음, council 없음, provider SDK 없음. 그 둘레의 네 port — TaskStore, ArtifactStore, LeaseManager, ToolRunner — 가 앞 lesson 들의 storage, taxonomy, lease, side-effect bracketing 에 매핑돼.
Executor checkpoint —진짜 surface 는 작아
구현 surface 는 provider 모양이 아니라 executor 모양이야. model 이 Polygon 이나 Nano Banana 를 framework port 로 직접 안 불러; cwkPippa 의 tool executor — Connector, WebSearch / WebFetch, Firecrawl tool 들, Bash, show_widget — 를 불러. 그것들이 stateful 인식 adapter 가 돼. running step 이 active 일 때, executor 가 기존 tool 을 돌리고, raw 결과를 step artifact 로 즉시 persist 하고, step 을 done 마킹하고, lease 를 풀고, 그제서야 bounded 결과를 model 에 돌려줘. provider call 은 성공했는데 model 이 commit 전에 끊기는 틈을 그게 닫아.
견고하게 만드는 다듬기 둘. 첫째, auto-checkpoint: model 이 volatile provider 작업 전에 task 시작을 깜빡하면, 결과를 바닥에 흘리는 대신 executor 가 single-step checkpoint 를 자동 생성 — 평범한 local tool (Read, Write, Edit) 은 fast path 그대로 두고. 둘째, replay-skip guard: read-only volatile tool 을 다시 돌리기 전에, executor 가 같은 대화에서 같은 effective tool 이름 + 정확히 같은 input 의 완료된 checkpoint 를 확인; 있으면 저장된 artifact 를 돌려주고 provider call 을 skip. 동일 replay 는 executor 일이지 model 판단 호출 아냐. 그 guard 가 있으면, Claude mid-turn-cut auto-retry 를 default 로 다시 켜도 안전해 — replay 가 완료된 pull 을 더 이상 안 버리니까.