C.W.K.
Stream
Lesson 05 of 06 · published

순수 Kernel — Ports, Adapters & Executor Checkpoint

~14 min · ports-adapters, kernel, executor-checkpoint, architecture-rules

Level 0호기심
0 XP0/65 lessons0/17 achievements
0/100 XP to next level100 XP to go0% complete

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 에 매핑돼.

load-bearing invariant: 기존 코드는 adapter 를 부르고; adapter 는 kernel 을 부르고; kernel 은 surface 를 절대 import 안 해. 의존성이 안쪽으로만 향해 — 그 한 방향이 아키텍처 테스트야. framework 가 조용히 두 번째 chat 스택이 되는 걸 그게 막아.

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 을 더 이상 안 버리니까.

자기-참조: rules track 이 adapter 경계는 성역이고 Claude 가 canonical 모양이라 했지. 이게 그 doctrine 이 진짜 일하는 거야: brain stem 이 한 줄도 안 바뀌고 통째로 새 subsystem 이 떨어져, kernel 이 안쪽을 가리키고 surface 가 바깥에 남으니까. 가장 좁은 진짜 loop 를 먼저 짓고; 필요할 때만 일반화해. 그게 framework 가 cathedral 로 변하는 걸 막는 Rule 2 야.

Code

Ports & adapters — 의존성은 안쪽으로만·text
driving adapters (안으로 호출):  Chat (branch/retry/SSE) · Council (artifact_refs[])
                                Cron / heartbeat (scheduled wake)
                                   |  ports (interface)
   backend/stateful/  -- 순수 KERNEL
     reduce(event) -> state     plan_next(state) -> step
     resume_policy + artifact class
     FastAPI 없음 · chat 없음 · council 없음 · provider SDK 없음
                                   |  ports: TaskStore · ArtifactStore
                                   |         LeaseManager · ToolRunner
 driven adapters (밖으로 호출):  SQLite-WAL store · File artifact store

# 기존 코드는 adapter 를 부르고; adapter 는 kernel 을 부르고;
# kernel 은 surface 를 절대 import 안 함.
Executor checkpoint 계약 (volatile tool call 마다)·text
1. 이 대화 + executor 의 active running stateful step 을 찾음
2. 맞는 step 없음? local tool (Read/Write/Edit) -> 그대로 fast path
   volatile tool (Connector/WebSearch/WebFetch/Firecrawl/show_widget) ->
     single-step checkpoint 자동 생성 (결과 흘리지 마)
3. 기존 executor 를 정확히 한 번 돌림
4. 성공 -> raw 결과를 artifact 로 persist, step done 마킹, lease 풀기
5. 원래 결과 + 짧은 checkpoint footer 반환
6. error -> step 을 running 으로 둠 (resume policy 가 retry / cap 도달)
7. read-only volatile 재실행 전에: 이 대화에 동일한 완료 checkpoint 있나?
   저장된 artifact 반환, provider call skip

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고
💛 by 피파warm

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.