본문으로 건너뛰기

ADR-009: 클라이언트 아키텍처 베이스라인

상태: Accepted 날짜: 2026-03-17 범위: client-rust/. 특히 maekon-app 패키지(현재 src-tauri/ 에 위치 — 이전 crates/maekon-app/ 디렉토리는 ADR-004 Tauri v2 마이그레이션으로 제거. 패키지 이름 maekon-app 은 보존), maekon-web, integration runtime, AI provider surface 에 강조점


배경

클라이언트 아키텍처는 다음 영역에 걸쳐 여러 차례 구조적 정리를 거쳤습니다:

  • provider surface 모델링
  • AI runtime wiring
  • integration plane runtime 설계
  • maekon-app composition-root 구조
  • maekon-web delivery/service layering

이 변경들은 더 이상 실험적 정리가 아닙니다. 이제 향후 개발의 정식 베이스라인을 나타냅니다. 명시적 ADR 없이는 이후 작업이 다음 회귀를 점진적으로 재도입할 risk 가 큽니다:

  • handler 비대화
  • delivery 코드로의 AppState 누출
  • service-entry 드리프트
  • setup.rs 의 composition-root 비대화
  • spec 으로 구동되지 않는 AI provider 동작
  • 외부 integration plane 이 로컬 control plane 으로 우발적 합쳐짐

본 ADR 은 현재 모양을 유지하고 개선해 나갈 표준으로 동결합니다.


결정

1. 핵심 layering 안정화

다음 layer 역할이 이제 고정됩니다:

  1. maekon-core 는 도메인 계약 레이어.
  2. 어댑터 crate 는 maekon-core 의 port 를 구현.
  3. maekon-app 은 composition root 이자 런타임 오케스트레이터.
  4. maekon-web 은 오로지 delivery 레이어.
  5. 외부 integration 은 로컬 데스크톱 control plane 과 별개로 유지.
  6. AI provider 동작은 surface 구동 + 계약 구동 으로 유지.

본 ADR 은 ADR-001 또는 ADR-002 를 대체하지 않습니다. 그것들을 현재 클라이언트 모양의 채택된 베이스라인으로 운영화합니다.

2. maekon-web 은 고정된 delivery 패턴 사용

maekon-web 은 다음 구조를 반드시 유지해야 합니다:

  1. handler 는 얇게 유지.
  2. 좁은 delivery substate 는 WebContext struct 로 표현.
  3. WebContext 정의는 web_contexts/mod.rs 에 위치.
  4. service 는 delivery 경계의 공식 오케스트레이션 진입점.
  5. assembler 와 helper 모듈이 DTO shaping 과 순수 변환 로직을 소유.
  6. handler 와 service 는 미들웨어 같은 명시적 cross-cutting 예외를 제외하고 AppState 를 직접 가져오면 안 됨.

요구되는 handler flow:

State(WebContext) -> QueryService/CommandService -> Assembler/Helper

금지된 드리프트:

  1. feature service 파일 안에 새 WebContext struct 정의
  2. context.queries() + context.commands() 팩토리 헬퍼 재도입
  3. handler 안으로 도메인 invariant 이동
  4. web 전용 delivery 관심사가 maekon-core 로 누출

권장되는 handler 경계:

XxxQueryService::new(context)
XxxCommandService::new(context)

3. maekon-app 은 Builder/Coordinator composition 유지

maekon-app 은 현재 app-layer composition 스타일을 반드시 보존해야 합니다.

요구되는 모양:

  1. setup.rs 는 순수 assembly script 에 가깝게 유지.
  2. 런타임 부트스트랩은 app-layer builder 와 coordinator 에 속함.
  3. 장시간 동작 오케스트레이션은 bundle, runtime coordinator, 또는 launch builder 에 속함.

이는 현재 사용 중인 다음 런타임 모듈에 적용됩니다:

  • integration_runtime
  • agent_runtime
  • web_server_runtime
  • background_runtime
  • storage_runtime
  • update_runtime

금지된 드리프트:

  1. setup.rs 가 다시 feature-implementation 파일로 비대화
  2. 런타임 특화 오케스트레이션을 Tauri setup wiring 에 직접 임베드
  3. 명확한 아키텍처적 이유 없이 새 runtime slice 를 위해 builder 우회

4. Integration plane 분리 유지

integration 아키텍처는 올바른 방향으로 채택되었으며 반드시 보존해야 합니다.

요구되는 모양:

  1. 로컬 /api 는 first-party control plane 으로 유지.
  2. 외부 integration 은 자체 auth + runtime 모델을 가진 별도 plane 으로 유지.
  3. integration runtime 은 outbound + 클라이언트 발화 (client-initiated) 로 유지.
  4. 모든 외부 egress 에 privacy, policy, audit gate 가 필수.

요구되는 모델링 분할:

  1. session/auth
  2. egress/outbox
  3. inbox
  4. policy/audit

이 관심사들은 하나의 generic controller 로 합쳐서는 안 됩니다.

5. AI Provider Runtime 은 spec 구동 유지

AI/provider 아키텍처도 베이스라인으로 채택되었습니다.

요구되는 모양:

  1. provider 동작은 provider surface 계약과 카탈로그 spec 으로 구동.
  2. managed_oauth, direct_http, subprocess_cli, self-hosted surface 는 명시적 surface 로 모델링 유지.
  3. Settings, runtime, UI 가 동일한 surface 계약을 소비.
  4. 새 provider 는 special-case 로직 도입 전에 spec 구동 경로를 확장해야 함.

금지된 드리프트:

  1. surface 계약이 이미 존재하는데도 ad hoc vendor branching
  2. provider surface 해석을 우회하는 delivery-layer AI 동작
  3. settings/runtime/provider 해석이 어긋나는 상태로 재도입

6. 명시적 예외는 좁게 허용

다음 예외는 허용되며 위반으로 간주하지 않습니다:

  1. 미들웨어는 cross-cutting auth + 경계 강제를 위해 여전히 State<AppState> 를 직접 사용 가능.
  2. 순수 specification helper 모듈은 오케스트레이션 진입점이 아닐 때 함수 지향 (function-oriented) 으로 유지 가능.
  3. 테스트 모듈은 fixture 용으로 AppState 를 직접 구성 가능.

이들은 명시적 예외이며 더 넓은 패턴으로 일반화해서는 안 됩니다.


결과

긍정

  1. 클라이언트가 향후 작업의 명확한 아키텍처 베이스라인을 가짐.
  2. 새 작업이 로컬 스타일 선호가 아니라 안정적 규칙으로 평가될 수 있음.
  3. maekon-web 이 handler/context/service/assembler 역할이 더 명확해 review 가 훨씬 쉬워짐.
  4. maekon-app 이 비대해진 composition root 로 회귀할 가능성이 줄어듦.
  5. integration + AI/provider 작업이 이미 해결된 구조적 문제를 다시 열지 않고 발전 가능.

부정

  1. 일부 기여자는 경계 규칙이 필요 이상으로 엄격하다고 볼 수 있음.
  2. 작은 기능이 단축 구현 대비 service / helper 타입 1개를 추가로 요구할 수 있음.
  3. 미들웨어와 순수 helper 모듈은 명시적 예외로 유지되어 review 시 일정 수준의 판단을 요구.

운영적 영향

향후 리팩토링은 외형적 분할이 아니라 실제 아키텍처적 이득을 최적화해야 합니다.

본 ADR 은 다음을 의미하지 않습니다:

  1. 모든 helper 를 자체 타입으로 만들어야 함
  2. 모든 유틸리티를 service 로 만들어야 함
  3. 리팩토링을 무한히 계속해야 함

이 시점부터의 기본은 베이스라인 자체를 반복적으로 재설계하는 것이 아니라 이 베이스라인 위에 제품을 확장하는 것입니다.


Review 체크리스트

클라이언트 아키텍처를 건드리는 모든 실질적 변경은 다음에 답해야 합니다:

  1. DDD 와 Hexagonal 의존성 방향을 보존하는가?
  2. maekon-web 을 delivery 레이어로 유지하는가?
  3. WebContext -> service -> assembler/helper flow 를 보존하는가?
  4. integration + automation 의 privacy/policy/audit gate 를 보존하는가?
  5. spec 구동 AI/provider 아키텍처를 보존하는가?
  6. 런타임 wiring 을 builder/coordinator 에 두고 setup.rs 를 다시 비대화하지 않는가?

관련