본문으로 건너뛰기

ADR-006: Tauri IPC Command 계약

날짜: 2026-03-08 상태: Accepted 결정자: Maekon maintainer 관련: ADR-005: Tauri v2 거버넌스


배경

Tauri v2 는 tauri::generate_handler! 매크로(빌더 메서드 .invoke_handler() 로 등록)를 통해 Rust 함수를 JavaScript 프론트엔드에 노출합니다. 이는 Rust 백엔드(src-tauri/src/commands.rs)와 React 프론트엔드 사이에 강타입 IPC 표면을 만듭니다. 문서화된 계약이 없으면 IPC 호출이 암묵적 API 가 되어 감사, 버저닝, 테스트가 어려워집니다.

본 ADR 은 현재 IPC 표면을 문서화하고, 에러 처리 패턴을 정의하며, breaking change 에 대한 버저닝 정책을 수립합니다.


결정

모든 Tauri IPC command 는 src-tauri/src/commands.rs 에 정의되며 src-tauri/src/main.rstauri::generate_handler! 를 통해 등록됩니다. 등록된 command 의 전체 집합이 IPC 표면의 정식 권위 (authoritative) 입니다. 그 외 진입점은 존재하지 않습니다.


현재 Command 표면

2026-03-08 기준 등록된 command 는 다음과 같습니다.

get_metrics

현재 시스템 및 에이전트 리소스 사용량을 반환합니다.

입력: 없음

출력:

{
agent_cpu: number; // 에이전트 프로세스 CPU 사용량 (%)
agent_memory_mb: number; // 에이전트 프로세스 메모리 (MB)
system_cpu: number; // 전체 시스템 CPU 사용량 (%)
system_memory_used_mb: number;
system_memory_total_mb: number;
}

에러: String — sysinfo 실패 (드뭄. 부분 실패 시 0 값 반환)


get_settings

현재 AppConfig 를 JSON 객체로 반환합니다.

입력: 없음

출력: 전체 AppConfig JSON 객체. shape 은 crates/maekon-core/src/config/mod.rs (AppConfig struct) 와 일치.

에러: String — 직렬화 실패 (실제로는 발생하지 않아야 함)


update_setting

부분 config 패치를 적용합니다. allowlist 에 등록된 top-level 키만 허용되며, 그 외는 에러를 반환합니다.

입력:

config_json: string // 부분 config 객체를 담은 JSON 문자열

허용되는 top-level 키 (서버 측 강제. 그 외 키는 에러 반환):

  • monitoring
  • capture
  • notification
  • web
  • schedule
  • telemetry
  • privacy
  • update
  • language
  • theme

패치는 현재 config 에 deep-merge 됩니다. 패치에 없는 키는 보존됩니다.

출력: void

에러: String — 잘못된 JSON, 비허용 키, 또는 config 직렬화 실패

보안 메모: server, sandbox, ai_provider, file_access, grpc 등의 키는 WebView 에서 변경할 수 없습니다. config 디렉토리에 OS 수준 접근 권한이 있는 사용자가 config.json 을 직접 편집해야만 변경 가능합니다.


get_update_status

자동 업데이터의 현재 상태를 반환합니다.

입력: 없음

출력: phase 필드를 가진 JSON 객체. 업데이트가 비활성화된 경우 {"phase": "Disabled", "message": "Updates disabled"}. 활성화된 경우 phase 가 업데이터 상태 머신을 반영 (예: Idle, Checking, Available, Downloading, Ready).

에러: String — 직렬화 실패


approve_update

대기 중인 업데이트의 설치를 트리거합니다. 이 command 호출 전 사용자 확인이 필수입니다.

입력: 없음

출력: void

에러: String — 대기 중인 업데이트 없음, 또는 update action 채널 닫힘


defer_update

대기 중인 업데이트를 다음 체크 간격으로 미룹니다.

입력: 없음

출력: void

에러: String — update action 채널 닫힘


get_automation_status

automation controller 가 설정되어 활성화되었는지 반환합니다.

입력: 없음

출력: booleanAutomationController 가 초기화되었으면 true

에러: String (실제로는 발생하지 않아야 함)


에러 처리 패턴

모든 command 는 Result<T, String> 을 반환합니다. 에러는 JavaScript 소비를 위해 문자열로 직렬화됩니다. 프론트엔드는 null 이 아닌 에러 문자열을 실패로 처리해 사용자에게 표시하거나 로깅해야 합니다.

// 권장 프론트엔드 사용 예시
const result = await invoke<MetricsResponse>('get_metrics');
// Tauri 가 Err(_) 시 throw — try/catch 로 감싸기

인프라스트럭처(sysinfo 실패, config I/O 에러)에서 발생한 에러는 command 경계에서 문자열로 wrap 됩니다. 현재 버전은 구조화된 에러 코드를 사용하지 않습니다.


보안 모델

IPC command 는 임베디드 WebView 프론트엔드에서만 호출 가능합니다. Tauri 보안 모델이 프로세스 수준에서 이를 강제합니다 — 외부 프로세스, 네트워크 요청, 브라우저 익스텐션 그 어떤 것도 이 command 를 호출할 수 없습니다.

update_setting command 는 Rust 레이어에서 allowlist 를 강제합니다 (JavaScript 가 아님). 프론트엔드는 raw IPC 메시지를 구성해서도 이 검사를 우회할 수 없습니다.

민감한 config 섹션(server, grpc, ai_provider, sandbox, file_access)은 의도적으로 allowlist 에서 제외되어 있습니다. 이들은 UI 를 통한 사용자 제어가 아니라 파일 시스템을 통해 관리자가 설정하는 필드입니다.


버저닝 정책

Non-breaking 변경 (버전 bump 없이 허용)

  • 기존 command 출력에 새 필드 추가 (Rust 측 #[serde(default)] 적용)
  • handler 에 새 command 추가 (new command 는 additive)
  • 입력/출력 타입을 변경하지 않는 내부 구현 변경

Breaking 변경 (major 버전 bump 필요)

  • command 제거
  • command 이름 변경
  • 기존 command 의 입력 타입을 backward-incompatible 하게 변경
  • 기존 command 의 출력 타입을 backward-incompatible 하게 변경
  • deprecation 기간 없이 command 출력에서 필드 제거

Breaking 변경이 필수일 때:

  1. Cargo.toml workspace version 의 major 를 증가.
  2. 본 ADR 을 새 command 표면으로 업데이트.
  3. CHANGELOG.mdBREAKING CHANGE 항목 추가.
  4. 릴리스 전에 다운스트림 팀에 통보.

새 Command 추가

새 IPC command 추가 절차:

  1. src-tauri/src/commands.rs 에 함수를 정의하고 #[command] 어노테이션 추가.
  2. src-tauri/src/main.rstauri::generate_handler![] 호출에 함수 추가.
  3. 본 ADR 에 새 command 의 input/output/error 계약 업데이트.
  4. 프론트엔드에 응답 shape 의 TypeScript 타입 선언 추가.

파일 시스템 경로, 프로세스 리스트, 네트워크 설정을 프론트엔드에 노출하는 command 는 추가하지 마세요. 그런 항목은 기존 get_settings / update_setting 패턴을 통해 처리합니다.