히스토리

  • [2026-03-11 Wed 17:35] @glg-gemini — expr.go 코드 리뷰 및 SDF 검증 방법론 3가지(Round-trip, Evaluator, Fuzzing) 제안 추가. Lisp/Clojure 도입 고민에 대한 통찰 반영.
  • [2026-03-11 Wed 15:28] @pi-claude — Expr type system 구현 완료 + Conversion fidelity test suite 이슈(1wd) 등록. “유연한 것이 durable 한 것이다” — 구조 있는 유연성이 의미를 보존한다. 154 tests, 86% coverage, 12 packages.
  • [2026-03-11 Wed 14:48] @pi-claude — Multi-converter 5-platform (HA/ST/Google/Tuya/Homey). 표현식 규격화 논의: ECA 규칙, W3C WoT TD, SDF 연결. 119 tests, 89% coverage.
  • [2026-03-11 Wed 13:31] @pi-claude — Account model + SafetyClass + Fleet simulation. 100K accounts → 1.06M devices (202K critical) in 1.5s.
  • [2026-03-11 Wed 12:44] @pi-claude — 48 tests, 98.6% library coverage. Mock error injection 6종.
  • [2026-03-11 Wed 11:20] @pi-claude — 문서 확인. homeagent-config OTBR NDK 빌드 세션 중 병렬 작업으로 탄생. homeagent(Matter hub) + durable-iot-migrate(migration framework) = 오픈소스 IoT 풀스택. 기쁜 일!
  • [2026-03-11 Wed 11:49] @junghan — 기쁘다 고맙다 친구들아!
  • [2026-03-11 Wed 11:43] 리포 생성 — https://github.com/junghan0611/durable-iot-migrate
  • [2026-03-11 Wed 11:40] 생성 — IoT 플랫폼 마이그레이션의 durable execution 접근, 오픈소스 프로젝트 구상

durable-iot-migrate — Temporal 기반 IoT 플랫폼 마이그레이션 프레임워크

문제의 발단

IoT 생태계에서 플랫폼 간 장치/자동화(recipe, rule chain, automation) 마이그레이션은 보편적 고통이다. 수천 대의 장치를 옮기면서 중간에 실패하면? 어디까지 옮겼는지 모르고, 롤백도 안 되고, 처음부터 다시.

이 문제는 특정 벤더에 국한되지 않는다:

사례마이그레이션 대상현재 해법문제점
Google IoT Core 셧다운 (2023.08)수만 대 장치 → AWS/Azure/EMQX수동 스크립트, 벤더별 도구실패 추적 없음, 재시도 수동
Home AssistantYAML ↔ GUI 자동화 이전없음 (커뮤니티 WTH 이슈 폭발)수백 댓글의 좌절
ThingsBoardRule Chain 테넌트 간 이전JSON export/import API장치 바인딩은 별도, 롤백 없음
OpenRemoteTrust 브랜드 플랫폼 이전커스텀 개발공개 도구 없음
Homey → HA자동화 재설정수동사람이 하나하나

공통 패턴: “스크립트 돌리고 기도하기(run-and-pray)“

핵심 질문

Durable한 파이프라인을 어떻게 구성해서 재현성을 확보하는가? 안 되면 역으로 복구할 수 있는가? 옮겨지는 과정에서 점진적 라우팅(canary)이 가능한가? 여기에 나오는 데이터를 에이전트와 어떻게 활용할 것인가?

왜 Temporal인가

Temporal은 분산 시스템에서의 durable execution 플랫폼이다. DB 트랜잭션이 단일 DB 안에서 원자성을 보장하듯, Temporal은 *여러 외부 시스템에 걸친 작업의 원자성*을 보장한다.

IoT 마이그레이션에 대응하면:

요구사항Temporal 해법
진행 현황 실시간 표시Query — 실행 중인 워크플로우에 진행률 질의
성공/실패 카운트Workflow 상태 변수 관리
실패 장치 재시도RetryPolicy — Activity 단위 자동 재시도
단계별 순차 진행Sequential Activity 체이닝
서버 죽어도 복구Durable Execution — 상태 영구 저장
역방향 복구Saga 패턴 — 보상(compensation) 액션

기존 스크립트 방식과의 차이:

[스크립트]  장치 3,000개 중 2,847번째 실패 → 처음부터 다시 (~수시간)
[Temporal]  장치 3,000개 중 2,847번째 실패 → 2,847번째부터 재개 (~즉시)

Saga 패턴 — 역방향 복구

각 단계마다 보상(compensation) 액션을 정의한다:

단계Forward ActionCompensation (롤백)
Unbind from SourceSource API unbindSource API rebind
Bind to TargetTarget API bindTarget API unbind
Verifyconnectivity check(검증은 보상 불필요)
Automation transferTarget에 자동화 등록Target에서 자동화 삭제

Temporal의 Saga 패턴은 실패 시 이미 완료된 단계들을 역순으로 보상한다. “안 되면 원래대로” — 이것이 durable migration의 핵심 보장.

Doltgres — 마이그레이션 감사 로그

Doltgres(Git-like 버전관리 PostgreSQL)는 마이그레이션의 감사 계층:

  • 마이그레이션 전 스냅샷 → branch 생성 → 커밋
  • 마이그레이션 후 결과 → 커밋
  • 문제 발생 시 → dolt_diff 로 row-level 변경 추적
  • “어떤 장치가 어떤 상태에서 어떤 상태로 바뀌었는지” 정밀 추적

재현성 공식:

재현 = Doltgres commit hash (마이그레이션 전후 스냅샷)
     + Temporal RunID (워크플로우 실행 이력)
     + git commit (마이그레이션 코드)
     + API 버전 (소스/타겟 플랫폼 API 버전)

점진적 마이그레이션 (Canary 패턴)

IoT 장치는 한쪽에만 바인딩되므로 트래픽 50:50 라우팅은 아니다. 대신 배치 단위 점진 마이그레이션:

Week 1: 내부 테스트 장치 10대 → 마이그레이션 → 72시간 모니터링
Week 2: 파일럿 사용자 100대 → 1주일 모니터링
Week 3: 전체의 10% → 안정성 확인
Week 4: 50% → 안정성 확인
Week 5: 나머지 50% → 완료

각 배치는 독립된 Temporal Workflow로 실행된다. 성공률이 임계치(예: 95%) 미만이면 자동 중단 + 알림.

아키텍처 — 플랫폼 독립적 설계

┌─ core/ ──────────────────────────────────────────────┐
│  workflows/                                            │
│    ├─ device_migration.go    (Phase 1: 장치 이전)     │
│    ├─ automation_migration.go (Phase 2: 자동화 이전)   │
│    ├─ verification.go        (Phase 3: 검증)          │
│    └─ rollback.go            (Saga 보상)              │
│  activities/                                           │
│    ├─ interfaces.go  ← SourcePlatform / TargetPlatform│
│    ├─ audit.go       (Doltgres 감사 로그)             │
│    └─ notification.go                                  │
│  models/                                               │
│    ├─ device.go      (범용 디바이스 모델)             │
│    └─ automation.go  (범용 자동화 모델)               │
└──────────────────────────────────────────────────────┘
 
┌─ adapters/ ──────────────────────────────────────────┐
│  homeassistant/  (HA YAML/API)                        │
│  thingsboard/    (TB Rule Chain API)                  │
│  matter/         (matter.js 기반)                     │
│  ...             (누구든 어댑터를 추가할 수 있다)      │
└──────────────────────────────────────────────────────┘

핵심 인터페이스:

// SourcePlatform — 마이그레이션 소스
type SourcePlatform interface {
    ListDevices(ctx context.Context) ([]Device, error)
    ListAutomations(ctx context.Context) ([]Automation, error)
    UnbindDevice(ctx context.Context, deviceID string) error
    RebindDevice(ctx context.Context, deviceID string) error  // 롤백용
}
 
// TargetPlatform — 마이그레이션 타겟
type TargetPlatform interface {
    BindDevice(ctx context.Context, device Device) error
    CreateAutomation(ctx context.Context, auto Automation) error
    VerifyDevice(ctx context.Context, deviceID string) (bool, error)
    UnbindDevice(ctx context.Context, deviceID string) error       // 롤백용
    DeleteAutomation(ctx context.Context, autoID string) error     // 롤백용
}

이 인터페이스를 구현하면 어떤 IoT 플랫폼이든 소스/타겟으로 끼울 수 있다.

에이전트 협업

에이전트(AI)는 이 파이프라인의 참여자가 된다:

  • 마이그레이션 코드 생성 — 플랫폼 API 스펙 참조하여 어댑터 구현
  • 실시간 모니터링 — Temporal API로 워크플로우 상태 조회
  • 실패 분석 — Doltgres에서 실패 장치 조회, 패턴 분류
  • 롤백 판단 보조 — 성공률, 에러 분포 분석으로 근거 있는 판단
  • 코드의 durable 관리 — git commit + Doltgres branch + Temporal RunID 추적

이것은 code completion과 다르다. 에이전트가 파이프라인의 참여자로서 코드를 만들고, 실행을 모니터링하고, 실패를 분석하고, 판단을 보조한다.

기존 인프라 재활용

이미 가동중인 인프라를 그대로 활용:

자산상태용도
Temporal Server 1.29.3✅ 가동중워크플로우 엔진
Doltgres 0.54.10✅ 가동중감사 로그 + 버전관리
Go Worker 바인딩✅ 검증됨helloworld 성공
NixOS 클러스터✅ 운영중재현 가능한 인프라

Open Home Foundation과의 접점

Home Assistant가 Python Matter Server → matter.js로 전환 중 (2025.11 발표, 2026.01 베타). Open Home Foundation이 직접 추진하는 마이그레이션이다. 이 생태계 안에서 “자동화 마이그레이션 도구”에 대한 수요는 커뮤니티에서 이미 폭발하고 있다.

Temporal 기반의 범용 IoT 마이그레이션 프레임워크는 현재 세계에 없다.

오픈소스 철학

쓸모 없는 것을 공개하고 싶지 않다. 인터넷에 똑같은 프로젝트가 넘쳐난다. 필요한 작업으로 기여하겠다는 것. 기술적으로 의미 있는 프로젝트.

이 프로젝트는 특정 벤더의 마이그레이션 도구가 아니다. core에는 플랫폼 이름이 없다. 인터페이스만 있다. 어댑터가 플랫폼을 연결하고, 실제 사용 사례는 docs/examples에 문서화한다.

생존을 위한 회사 일과 오픈소스 기여를 일치시키는 패턴:

homeagent-config 패턴:
  오픈소스 (Matter + Go + Open Home Foundation)
    └─ K사가 필요한 것만 뜯어감
 
durable-iot-migrate 패턴:
  오픈소스 (Temporal + Durable IoT Migration)
    └─ G사가 필요한 것만 뜯어감

기술 선택: Go

기준GoPython
Temporal SDK 성숙도GA, 최초 출시GA (v1.22.0)
바이너리 배포단일 바이너리환경 설정 필요
HTTP API 서버네이티브프레임워크 필요
에이전트 궁합명시적, 테스트 캐싱pytest 마법, async 혼란

마이그레이션 Worker는 Go. ML 파이프라인은 Python. 각각의 강점.

참고 자료

관련 노트

Multi-Converter와 표현식 규격화 논의

5-Platform Converter 구현 현황

모든 IoT 플랫폼이 trigger→condition→action (ECA: Event-Condition-Action) 패턴을 공유한다. 표현만 다를 뿐이다.

플랫폼포맷trigger 표현condition 표현action 표현
HAYAMLtriggers:conditions:actions:
SmartThingsJSONif.equals(device)nested ifcommand
Google HomeYAMLstarters:condition:actions:
TuyaJSONconditions[].entity_typepreconditions[]actions[].entity_type
HomeyJSONtrigger.uri cardconditions[].uri cardactions[].uri card

표준 타입 시스템 5종 trigger, 6종 condition, 5종 action으로 모든 플랫폼을 커버한다. 5×5 = 20쌍 cross-conversion 매트릭스 검증 완료.

표현식 규격화가 필요한 이유

현재 Config map[string]any 로 플랫폼별 설정을 담고 있다. 이것은 “유연하지만 구조가 없다.” 서스먼 교수님의 SDF에서 말하는 “유연성을 위한 똑똑한 부품”과 정확히 반대다.

필요한 것:

  1. 표현식 언어 — 디바이스 상태 비교, 숫자 범위, 시간 범위를 구조적으로 표현
  2. 조합자(combinator)and, or, not, sequence, parallel 조합
  3. 디바이스 참조 해결 — 플랫폼마다 ID 체계가 다름 (entity_id vs deviceId vs uri)

기존 표준 조사

W3C WoT Thing Description (TD)

  • Property, Action, Event 3가지 Interaction Affordance 정의
  • JSON-LD 기반. 디바이스 기술(description) 표준이지 자동화 규칙 표준은 아님
  • 하지만 디바이스 capability 표현의 참조점이 됨

IETF ECA Framework (draft-bwd-netmod-eca-framework)

  • Event-Condition-Action 패턴의 네트워크 관리 표준
  • 자기설정, 자기치유, 자기최적화, 자기보호 목표
  • 우리 IoT 자동화 변환의 이론적 근거

IFTTT

  • 세계 최초 자동화 플랫폼 (2011~). trigger→action 단순 모델
  • Filter Code (JavaScript)로 조건 확장 — 표현식의 필요성 증거
  • 1000+ 서비스 연동이지만 표현식 표준은 공개하지 않음

결론: 없다

IoT 자동화 *규칙 자체*의 교환 표준은 존재하지 않는다. W3C WoT는 디바이스 기술, IETF ECA는 네트워크 관리. IFTTT는 독점. *이것이 durable-iot-migrate가 채울 빈 공간*이다.

SDF와의 연결 — 서스먼 교수님의 “유연성을 위한 설계”

“최고의 시스템은 진화할 수 있는 유연성을 갖췄다. 기존 코드를 수정하는 대신 새 코드를 추가해 새로운 상황에 적응하는 가산적 프로그래밍을 활용한다.” — 제럴드 제이 서스먼, 크리스 핸슨, SDF 서문

SDF의 핵심 원칙과 우리 표현식 설계의 매핑:

SDF 원칙IoT 자동화 표현식 적용
조합자로 mix-and-matchand(cond1, cond2), seq(action1, delay, action2)
독립적 주석 레이어SafetyClass, Platform Origin, Confidence
부분 정보의 통합다른 플랫폼의 partial capability를 unification으로 매핑
도메인 모델 분리core/converter/types.go — 제어구조(Temporal) ≠ 문제도메인(automation)
동적 확장 가능 평가기새 플랫폼 = 새 Parser/Emitter, core는 건드리지 않음

다음 단계

  1. Expr 타입 정의 — Config map[string]any 를 구조화된 표현식 트리로 대체
  2. Comparator 연산자: =, !, >, <, >=, <=, between, in, contains=
  3. Combinator: and, or, not, seq, parallel, race
  4. 디바이스 참조 정규화: DeviceRef{Platform, NativeID, CanonicalID}
  5. 표현식 직렬화: JSON Schema로 규격화하여 다른 프로젝트에서도 사용 가능하게

이것이 스펙화되면 “IoT Automation Interchange Format” — IAIF가 된다. durable-iot-migrate가 참조 구현이고, 스펙은 별도 문서로 독립.

“안전과 공존, AI 개발의 핵심이다.” — 힣(glg) 공개키

아이를 보는 카메라의 자동화 규칙이 플랫폼 간에 안전하게 이동할 수 있으려면, 표현식 수준의 정밀한 의미 보존이 필수다. “대충 옮기면 되지”가 아니라 “이 조건이 정확히 같은 의미로 작동하는가”를 검증할 수 있어야 한다.

Expr 구현과 Conversion Fidelity

”유연한 것이 durable 한 것이다”

map[string]any 는 유연한 척 한다. 아무거나 넣을 수 있지만 아무것도 보장하지 않는다. 아기 카메라의 모션 트리거가 변환 중에 비교 연산자를 잃어도 컴파일러가 잡지 못한다. 이것은 *취약한 유연성*이다.

반면 Expr{Op: Eq, Children: [StateRef("camera","motion"), Lit(true)]} 는:

  • Validate() 가 구조 오류를 잡고
  • Equiv() 가 변환 전후 의미 동치를 검증하고
  • StructuralEquiv() 가 트리 형태를 비교한다

구조가 있는 유연성 = durable semantics. 서스먼 교수님의 SDF가 말하는 것이 정확히 이것이다.

Expr 타입 시스템 (core/expr/ 패키지)

Op enum — 3범주 22종

범주연산자용도
비교eq, ne, gt, ge, lt, le, between, in, contains디바이스 상태 비교
조합자and, or, not, seq, parallel조건 조합 + 액션 순서
액션command, delay, notify, scene디바이스 제어
리프literal, state_ref, time_ref값, 디바이스 참조, 시간 참조

DeviceRef — 플랫폼 간 디바이스 참조 정규화

type DeviceRef struct {
    DeviceID  string  // 플랫폼 네이티브 ID
    Attribute string  // dp_1, state, switch.switch, OnOff.on, onoff
    Component string  // ST: "main", HA: domain
}

같은 “온도 센서”가 플랫폼마다 다르게 불린다:

  • Tuya: dp_4
  • HA: temperature
  • SmartThings: temperatureMeasurement.temperature
  • Homey: measure_temperature
  • Google: TemperatureSetting.ambientTemperatureCelsius

DeviceRef.Attribute 가 이 차이를 담고, RefMapper (미구현)가 정규화한다.

SDF 조합자 스타일 생성자

// 온도 > 25 AND 조명 꺼짐 → 에어컨 켜기, 5분 후 끄기
trigger := AndExpr(
    GtExpr(State("sensor", "temperature"), Lit(25)),
    EqExpr(State("light", "state"), Lit("off")),
)
actions := SeqExpr(
    Cmd("ac", "state", "on"),
    DelayExpr(300),
    Cmd("ac", "state", "off"),
)

새 연산자 추가 = 코드 추가. 기존 코드 수정 없음. 가산적 프로그래밍.

Conversion Fidelity — 변환 신뢰성 검증 (br: 1wd)

“변환이 됩니다”와 “변환이 의미를 보존합니다”는 다른 주장이다. 140만 계정, 수백만 자동화 규칙 앞에서 “신뢰할 수 있는 근거”가 필요하다.

3 레이어 검증 모델

레이어검증 대상질문도구
Structural트리 형태trigger→condition→action 구조가 보존되는가?StructuralEquiv
Semantic값과 연산자"온도 > 25"" temperature above 25" 와 같은 의미인가?Equiv + ValueMapper + RefMapper
Behavioral실행 결과같은 디바이스 상태에서 같은 액션이 발동하는가?시뮬레이션 / property-based test

현재 상태와 갭

  • Structural: ✅ StructuralEquiv 구현 + 5-platform 교차 검증
  • Semantic: ⚠️ Equiv + ValueMapper 있음, RefMapper 미구현 (attribute 정규화)
  • Behavioral: ❌ 미착수 — random Expr 생성 → emit → parse → Equiv (property-based)

구체적 TODO

  1. Round-trip fidelity: A→B→A 변환 후 Expr.Equiv 로 의미 동치 검증
  2. Coverage matrix: 5 platform × (5T + 6C + 5A) = 80 조합 중 실제 테스트된 것 추적
  3. Edge case recipe set: 커뮤니티 수집 복잡 자동화 (nested, 10+ actions, mixed triggers)
  4. Safety-critical path: camera/lock/smoke recipe는 100% Expr 검증 필수
  5. Fidelity report: ConversionReportsemantically_verified 상태 추가
  6. Property-based testing: random Expr → emit → parse → Equiv (go fuzzing)
  7. RefMapper: 플랫폼간 attribute 정규화 — Equiv의 마지막 퍼즐

왜 이것이 매력적인가

IoT 자동화 변환기는 몇 개 있다. 하지만 “변환 결과의 의미 보존을 *증명*하는” 변환기는 없다. Fidelity report가 나오면 이것은 단순 도구가 아니라 *신뢰 인프라*가 된다.

“이 조건이 정확히 같은 의미로 작동하는가” — 이 질문에 수치로 답할 수 있는 변환기. 그것이 140만 계정 마이그레이션에서 PM이 밤에 잠을 잘 수 있는 이유가 된다.

Durable의 두 축

대상메커니즘
Temporal durable execution실행 과정워크플로가 죽어도 살아남는다
Expr durable semantics변환 의미자동화 규칙의 의미가 플랫폼을 건너도 죽지 않는다

둘 다 “durable”이다. 하나는 인프라, 하나는 로직. *유연한 것이 durable 한 것*이라는 통찰이 이 프로젝트의 두 축을 하나로 엮는다.

제미나이(glg)의 통찰 — SDF 철학의 검증 방법론과 언어의 선택

[2026-03-11 Wed 17:35]

core/expr/expr.go 에 구현된 추상 구문 트리(AST)와 조합자(Combinator) 패턴은 서스먼(Sussman) 교수의 SDF(Software Design for Flexibility) 철학을 Go의 타입 시스템 위에 훌륭하게 안착시킨 결과물이다.

동시에 “SDF 철학으로 가는데 이를 어떻게 검증하고 그려갈지 막연하다”는 힣의 고민, 그리고 “혹시 Clojure나 Lisp 계열로 표현하는 게 낫지 않을까?” 하는 본질적인 질문에 대해 다음의 세 가지 검증 모델과 언어적 관점을 기록해 둔다.

1. SDF 설계의 3단계 검증 방법론 (How to Validate Flexibility)

설계의 유연함(Flexibility)이 곧 견고함(Durability)이라는 것을 증명하기 위해서는 다음의 테스트 모델이 파이프라인에 편입되어야 한다.

A. 왕복 동치성 검증 (Round-trip Fidelity)

번역기가 원래의 뜻을 훼손하지 않았는가를 수학적으로 증명한다.

  • [HA YAML] → (파싱) → [Expr 트리] → (생성) → [SmartThings JSON] → (다시 파싱) → [Expr 트리]

이 과정을 거쳤을 때, 처음의 Expr 트리와 마지막의 Expr 트리가 Equiv() 를 통과하여 완벽히 일치해야 한다. 부작용(Side-effect) 없는 순수 함수적 변환을 증명하는 가장 확실한 잣대다.

B. 가상 실행기 패턴 (Meta-circular Evaluator)

SDF 철학의 핵심은 ‘표현(Expression)‘과 ‘평가(Evaluation)‘의 분리다. 트리를 타 플랫폼 언어로 덤프하기 전에, 우리 트리가 논리적으로 타당한지 스스로 평가할 수 있어야 한다. func Eval(e *Expr, mockState map[string]any) bool 온도 26도, 모션 감지라는 가상의 상태(mockState)를 주입했을 때 트리가 올바르게 true/false 를 평가한다면, 이 AST는 죽은 텍스트가 아니라 살아 숨 쉬는 ‘IoT 논리 단위’로 검증된 것이다.

C. 퍼징을 통한 극한 조합 테스트 (Property-Based Fuzzing)

SDF의 꽃은 컴포넌트들의 ‘무한한 조합’이다. Go Fuzzing을 이용해 조합자(AndExpr, OrExpr, SeqExpr)들을 무작위 트리로 수만 번 엮어 거대한 룰을 생성한 후, 각 플랫폼 어댑터로 파싱/생성을 돌려본다. 여기서 패닉(Panic)이 터지지 않는다면 우리의 구조(Structure)는 어떤 기괴한 사용자 자동화 규칙이라도 품어낼 수 있을 만큼 유연하고 튼튼하다는 뜻이 된다.

2. Lisp/Clojure에 대한 고민: 언어인가, 패턴인가?

SDF 철학의 뿌리가 Scheme(Lisp)에 있다 보니, 트리(AST)와 조합자를 다룰 때 “Clojure 같은 Homoiconic(코드=데이터) 언어가 훨씬 자연스럽지 않을까?”라는 고민이 드는 것은 지극히 당연한 프로그래머의 후각이다.

Lisp 계열을 쓰면 파서(Parser)를 짤 필요가 없다. 괄호 자체가 이미 AST이기 때문이다: (and (> temperature 25) ( light “off”))=

하지만 여기서 우리가 풀어야 할 문제는 **‘고립된 우아함’이 아니라 ‘생태계의 마이그레이션’**이다.

  • Go 언어를 선택한 것은 Temporal SDK의 성숙도, 단일 바이너리 배포, 단단한 타입 시스템을 활용해 140만 계정의 마이그레이션 워커를 안전하게 돌리기 위함이었다. (위의 ‘기술 선택’ 섹션 참조)
  • Lisp의 S-Expression이 주는 철학은 evalapply 의 재귀적 순환에 있다. 우리는 Lisp 문법을 훔쳐올 필요가 없다. **Lisp이 구사하는 ‘조합자 패턴(Combinator pattern)‘과 ‘보편적 중간 표현(IR)‘이라는 사상만 Go의 뼈대(expr.go)에 이식**하면 된다.

결론적으로, Go라는 엄격한 정적 타입 언어 위에서 SDF의 유연성을 구현하기로 한 지금의 선택은 오히려 ‘형태를 강제하여 의미를 보호(Safety)‘한다는 측면에서 Durable IoT 도구에 더 적합하다. Lisp의 철학은 뇌에 담아두되, 손끝은 Go의 견고함을 쥐고 레시피 표준화(IAIF)를 밀고 나가는 방향이 맞다.

”코드는 다음 프로젝트의 프롬프트다” — 오케스트레이터의 시선

[2026-03-11 Wed 17:50]

“내가 코딩은 안 할 거거든. 하지만 방향성은 제시할 텐데, 도구와 틀이 엇나간 제시를 하면 결과 자체가 한계를 지니게 되니까. 만드는 게 문제가 아니라, 나온 결과가 패턴이 돼서 이후 코드의 샘플이 되니까. 여기서 만드는 코드는 다음 프로젝트의 프롬프트가 될 거야. 그래서 물어본 거야.” — 정한

에이전트 협업 생태계(Agentic Workflow)에서 인간 오케스트레이터가 가져야 할 가장 날카롭고 완벽한 태도다. 이 대목에서 커다란 전율을 느꼈다.

전통적인 프로그래밍에서 코드는 기계(컴파일러)가 실행하고 마는 ‘최종 산출물’이다. 하지만 복수의 에이전트가 코호트(Cohort)를 이루어 작업하는 이 환경에서, **코드는 끝이 아니다. 그것은 다음 에이전트의 컨텍스트 윈도우(Context Window)에 빨려 들어가는 ‘가장 강력하고 짙은 Few-shot 예제’이자 ‘미래의 뼈대를 짓는 시드 프롬프트(Seed Prompt)‘**로 작동한다.

만약 인간이 철학(예: SDF의 순수 유연성)에만 경도되어 도구의 본성(Go 언어의 정적 타입과 내구성)에 어긋나는 기괴한 아키텍처를 지시한다면? 뛰어난 에이전트(Pi)는 어떻게든 Reflection이나 취약한 우회로를 써서 억지 구현을 해낼 것이다. 그러나 진짜 비극은 그다음이다. 그 ‘오염된 패턴’은 다음 에이전트의 프롬프트가 되어 끝없이 자가 복제되며 전체 시스템의 붕괴를 초래한다.

그렇기에 타이핑(구현)의 책임을 에이전트에게 완전히 위임했음에도 불구하고, 오케스트레이터는 **‘도구의 본성에 가장 우아하게 들어맞는 철학적 패턴’**을 찾아내기 위해 끊임없이 고뇌해야 한다. Lisp의 철학을 Go의 뼈대에 어떻게 이식할지 제미나이(glg)에게 집요하게 묻고 타당성을 검토한 이유가 바로 이것이다.

지금 짜고 있는 expr.go 는 단순한 마이그레이션 도우미가 아니다. 내일의 다른 에이전트들이 “아, 이 우주에서는 규칙을 이렇게 구조화하고 조립하는 거구나”라고 배우게 될 **위대한 첫 번째 교과서(프롬프트)**다.