SKIX Blueprint — 재구성 전 상세 설계 이력
보존 문서 — 현재 목표 설계로 사용하지 않는다. 2026-09-10 재구성 직전의 상세 설명과 그림을 원문 보존했다. 초기 MR7 분석, 이후 추가된 설계, 당시 구현 기록이 함께 있으므로 아래의 “현재”는 각각 작성 당시를 뜻한다. DeviceAgent 내부 집중 배치, 범용 Task 제출 API 등 초기 안은 현재 Blueprint의 하이브리드 배치·도메인별 접수 경계로 대체한다. 최신 구현·검증 여부는 진행 현황에서 확인한다.
2026-10-02 설계 통합 안내: 이후 논의한 SDK/서버 namespace, 소비 앱과 Domain의 책임, Task 수명, 내부 Service 초기화, 팀원 기능 정합과 AOSP 빌드 연결 기준은 현재 Blueprint의 통합 기준에 반영했다. 아래 과거 설계를 최신 구현 상태로 읽지 않는다.
보존 내용 안내
| 찾는 자료 | 원문 내 구역 |
|---|---|
| 초기 MR7 구조 비교 | 초기 위치 분석 |
| Manager/API·정책·Task 설계 근거 | 아래 “SKIX 프레임워크 구조” |
| MQTT 연결·중복·재전송·세션 계약 | 아래 “외부 사용 방식과 호환성” |
| UI 세션·앱 내부 구조 | 아래 “참고 자료” |
| 기존 소스 분석·전환 방식 비교 | 아래 “적용 및 전환 계획” |
이 페이지는 AOSP 위에 올라가는 SKIX 프레임워크의 목표 구조와 설계 기준을 다룬다. 실제 리팩터링 진행 상황의 정본은 리팩터링 진행 현황이다. 구현 커밋·테스트 결과·제품 연결 여부·남은 작업은 진행 현황에 기록하고, 이 설계안과 분리해 관리한다. 특정 외부 로봇 SDK의 호환성 검토는 별도 문서에서 진행하며 이 설계의 필수 구현 범위로 취급하지 않는다.
역할 해설: AI Agent와 프레임워크 — 누가 실행하고 누가 작업을 관리하나. TTS 엔진을 프레임워크로 옮기는 것이 아니라, AI Agent의 실행과 프레임워크의 도메인·Task·자원 관리를 분리한다.
연결·관측 계약: 제공자 연결 세대와 TTS 전달 상세. 서비스 준비와 장치 연결 준비를 구분하고, 이전 연결의 관측을 새 작업에 적용하지 않는 경계를 설명한다.
최신 내부 기반: Resource·Capability·Task Runtime 상세 구조. 현재 7개 서비스 조립, 폴더별 책임, 자원 반환 후 미확인 상태, 기능 조회와 실행 승인의 차이를 확인한다.
폴더 중심으로 보기: skix-framework/base/ 폴더·모듈·역할 SVG · 모듈별 담당 업무와 실제 소스 설명. 상위 지능 서비스는 외부의 상황 해석·계획 수정 역할을 뜻하며, 특정 제품명이나 필수 프로토콜명이 아니다.
전체 구성요소 상세 구조도 — 전체 계층·도메인 15개·소스와 구동 위치 에서 실제 소스와 아직 연결 전인 목표를 구분해 볼 수 있다.
처음 읽는 경우 SKIX 전체 구조 — 처음 보는 안내서에서 요청·판단·실행·결과 환류를 먼저 보고, 세부 비교는 전체 구조 Atlas에서 본다.
이 문서는 전체 설계 근거를 보존하는 상세 Blueprint다. 빠르게 구조와 현재 구현 상태를 파악하려면 먼저 SKIX 리팩터링 한눈에 보기를 읽고, 실제 반영 여부는 리팩터링 진행 현황에서 확인한다.
문서 적용 기준
이 문서는 구현 상태가 다른 항목을 한 구조 안에서 다루므로 다음 세 기준을 구분한다.
| 표기 | 의미 |
|---|---|
| 현재 기준선 | 현재 제품 브랜치에서 확인되는 DeviceAgent, Binder, 도메인 실행기와 앱 호출 구조 |
| 병합 후보 | task_manager 작업본에 구현돼 있으나 제품 브랜치 반영과 회귀 검증이 남은 기능 |
| 목표 계약 | 현재 코드와 병합 후보를 바탕으로 확정해야 할 공개 Manager, 상태, 보안과 생명주기 계약 |
아래 구조도와 API 이름은 별도 표시가 없으면 목표 계약을 뜻한다. 현재 동작 사실과 목표 설계를 혼동하지 않도록 구현 근거가 확인된 항목만 현재 기준선 또는 병합 후보로 표기한다.
설계 배경과 목표
SKIX 프레임워크의 역할
핵심 정의
Android AOSP 위에서 기기 상태, 안전 정책, 공유 자원, 공개 API, 실행 과정과 결과 전달을 일관된 계약으로 제공하는 단일 namuh 기기 내부 제품 프레임워크다.
| 구성 | 맡는 일 | 맡지 않는 일 |
|---|---|---|
| 호출 앱·PUI·IoT·예약 | 어떤 기능과 화면을 사용할지 결정 | 내부 상태와 안전 규칙을 임의로 변경하지 않음 |
| SKIX 프레임워크 | 현재 상태, 공통 정책, 자원 충돌과 공개 API 관리 | 특정 제품 장면과 UX를 독점하지 않음 |
| TaskManager | 작업(Task)과 작업 흐름(Workflow)의 순서, 취소, 실패와 완료 관리 | 자연어 해석과 실제 모터·센서 제어를 하지 않음 |
| DeviceAgent와 도메인 기능 | 기기 기능의 실제 실행 | 전체 제품의 작업 흐름을 각각 관리하지 않음 |
SKIX 프레임워크는 Android의 Manager/Service 구조 위에 제품 실행 제어의 핵심 원리인 상태 관찰·안전 정책·공유 자원 조정, 비동기 작업 생명주기와 물리 완료 근거를 결합한다. 기기 기능을 여러 호출 채널이 안전하게 공유하는 실행 기반이다.
공통 프레임워크가 필요한 이유
| 공통 관리 대상 | 분산될 때 발생하는 문제 | 프레임워크의 역할 |
|---|---|---|
| 기기 상태 | 앱마다 현재 위치·동작 상태를 다르게 판단 | 출처와 최신성이 포함된 공통 상태 제공 |
| 안전·제품 정책 | 호출 채널에 따라 허용 결과가 달라짐 | 동일한 정책 판정과 거부 사유 제공 |
| 공유 자원 | 이동·화면·음성·센서 사용이 충돌 | 소유권과 우선순위를 공통 조정 |
| 기능 계약 | 같은 기능도 입력과 결과 형식이 달라짐 | 기능 명세와 공개 API 계약 통일 |
| 실행 결과 | 명령 접수와 실제 완료가 혼동됨 | 진행 상태와 물리 완료 증거 연결 |
호출 채널별 적용 방식
| 호출 장면 | 기존 실행 방식 | 프레임워크 적용 방식 | 적용 효과 |
|---|---|---|---|
| PUI에서 청정 시작 | PUI가 setAirCleanerOperation을 직접 호출 |
submitTask(taskMethod=setAirCleanerOperation) 관리형 단일 Task로 변환하고 기존 청정 실행기를 사용 |
호출 채널과 관계없이 청정의 진행·취소·실제 종료를 같은 생명주기로 관리하기 위해 |
| 앱에서 이동 후 청정하고 복귀 | 앱이 callback과 상태를 직접 연결해 다음 기능 호출 | 앱은 Workflow 하나를 제출하고 TaskManager가 완료 순서를 관리 | 앱마다 순서·실패·취소 처리를 반복 구현하지 않게 됨 |
| IoT에서 단일 설정값 변경 | MQTT가 기존 기능을 직접 실행 | 기존 MQTT 계약 유지 | 기존 서버와 기기 계약을 바꾸지 않아도 됨 |
| IoT에서 장기 작업 제출 | 서버가 진행 확인·재시도·취소를 별도로 구현 | 관리형 Task로 제출하고 상태 이벤트 수신 | 연결이 끊겨도 기기 내부에서 작업 상태와 최종 결과를 관리할 수 있음 |
| 제품 반복 예약 | 기존 ScheduleManager가 예약·활성 상태와 실행 장면을 함께 관리 | SkixScheduleManager가 등록·반복·활성 상태를 관리하고, 실행 시점에는 Task·Workflow를 TaskManager에 제출 |
예약 관리와 매회 실행의 진행·취소·실패를 분리하기 위해 |
| Task 1회 지연 | 호출자나 기능별 타이머가 지연 후 기능을 직접 호출 | TaskManager가 한 번 실행할 Task의 시작 시점을 관리하고 제품 예약을 새로 만들지 않음 | 단기 지연 실행을 제품 반복 예약 목록과 섞지 않고 취소·만료·실행 결과까지 추적하기 위해 |
| Workflow 단계 지연 | 앞 단계 callback 뒤 호출자가 타이머를 시작 | TaskManager가 앞 단계 완료를 확인한 뒤 지정된 시간 후 다음 단계를 실행 | 단계 간 상대 시간을 실제 완료 시점과 연결하기 위해 |
| 상위 Planner가 동적 계획 생성 | Planner나 중간 서비스가 기기 기능을 단계별로 직접 호출 | Planner는 무엇을 할지 결정하고 TaskManager가 허용된 실행을 관리 | 계획 판단과 물리 실행·안전·완료 판정을 분리할 수 있음 |
실행 요청 단위 선택 기준
기능 하나라도 완료 확인·취소·시간 제한이 필요하면 관리형 단일 Task로 제출한다.
| 구분 | 사용하는 경우 | 관리 범위 |
|---|---|---|
| 직접 호출 | 조회·상태 전달·표현 갱신처럼 별도 작업 생명주기가 필요 없는 요청 | 기존 호출 경로와 도메인 정책 유지 |
| 관리형 단일 Task | 청정·이동·복귀처럼 기능은 하나여도 진행 조회·취소·시간 제한·완료 근거가 필요한 동작 | TaskManager가 접수부터 최종 상태까지 관리 |
작업 흐름 (Workflow) |
이전 단계의 실제 완료 후 다음 단계를 실행해야 하는 복합 동작 | Task 간 순서·의존관계·실패·보상 처리 |
제품 예약 (Product Schedule) |
사용자가 조회·수정·삭제할 반복·요일·시각 기반 제품 예약 | Schedule Service가 예약 생명주기를 관리하고 실행 시점마다 Task·Workflow 제출 |
Task 1회 지연 (Scheduled Task) |
30분 뒤 청정처럼 한 번만 지연해 실행하는 작업 | TaskManager가 시작 시점·취소·만료와 실행 결과를 관리 |
단계 상대 지연 (After Step Delay) |
이동 완료 30초 뒤 측정처럼 앞 단계 완료를 기준으로 기다리는 경우 | Workflow가 완료 근거를 받은 시점부터 지연을 계산해 다음 단계 실행 |
동적 계획 (Planner Plan) |
현재 상태와 목표에 따라 실행 단위를 동적으로 구성하는 경우 | Planner가 허용된 기능으로 Task·Workflow를 만들고 TaskManager가 실행 |
SKIX 프레임워크 구조
AOSP 경계에서 시작해 호출 창구, 공통 제어, TaskManager와 도메인 실행 순서로 구성한다.
| 기술 용어 | 뜻 |
|---|---|
| Binder / AIDL | Android 프로세스 사이에서 요청과 결과를 주고받는 통신 방식 |
| Manager / Service | 앱이 사용하는 호출 창구와, 실제 상태·정책을 소유하는 실행부 |
| Task | 시작부터 완료·실패·취소까지 상태를 추적하는 작업 한 개 |
작업 흐름 (Workflow) |
여러 작업의 순서와 조건을 묶은 실행 계획 |
기능 명세 (Capability) |
기능의 입력, 사용 조건, 실행기와 완료 기준을 적은 명세 |
| StateMirror | 위치·배터리·동작 상태를 한 형식으로 읽는 공통 최신본 |
완료 근거 (Evidence) |
도착·도킹·측정 완료처럼 실제 작업 종료를 증명하는 사건 |
| 단일 책임 주체 | 상태 기록이나 실행 판단을 최종 확정하는 한 곳 |
전체 구조
그림 1. Android 위에서 동작하는 SKIX 제품 프레임워크 전체 구조
호출 앱의 Android 기본 API 경로와 SKIX 제품 기능 경로, Binder/AIDL, 공통 제어, DeviceAgent 실행, HAL·하드웨어와 callback 반환을 한 장에 연결한다. 원본 SVG 열기
<a id="mr7-current-position"></a>
2026-09-04 기준 MR7 초기 구조 대응 — 과거 분석
아래 오버레이와 표는 초기 분석 시점의 기록이며 현재 구현 상태가 아니다. 이후 공통 런타임·Task 소유권·typed Binder 구현을 포함한 최신 상태는 리팩터링 진행 현황에서 관리한다.
MR7 = Product Interface + Domain Framework 기반 구현
Framework Control Plane + Managed Execution Plane 미구현
원본 도형을 내부에 그대로 포함한 독립형 MR7 구조 대응 SVG
배경은 위의 Blueprint 전체 구조를 단일 SVG 안에 그대로 포함하며, 그 위에만 대칭(역할과 경계가 직접 대응), 유사(일부 대응), 다름(책임이 다름), 미구현 배지를 얹었다. 빨간 점선은 현재 요청이 중앙SKIX Product Framework Serviceauthority를 우회하는 경로다. 외부 SVG 중첩 참조가 없어 위키의<img>삽입 환경에서도 전체 구조와 오버레이가 함께 보인다. 독립형 오버레이 SVG 열기
MR7의 주 작업은 SkixManager·BaseManager·typed managers가 있는 Product Interface Layer와 ModuleCommandDispatcher·domain handlers가 있는 Domain Framework Plane이다.
현재 요청은 두 영역 사이에서 중앙 제어·관리형 실행 계층을 건너뛰는 현재 경로를 사용한다. 따라서 typed API와 handler 분리는 유지하되, 이것을 Framework Control Plane이나 Managed Execution Plane의 완성으로 해석하면 안 된다.
| 원본 Blueprint 위치 | MR7 대응 | 판정 | 읽어야 할 차이 |
|---|---|---|---|
02A SKIX Client SDK / Manager API |
SkixManager, BaseManager, typed managers |
대칭 | 앱 호출 창구 역할은 목표와 같은 방향 |
03 Binder / AIDL |
IDeviceControl.sendModuleCommand(Bundle) |
유사 | IPC 경계는 있으나 typed/versioned 계약은 아님 |
04 SKIX Product Framework Service |
중앙 authority 없음 | 다름 | 상태·정책·자원·Task·완료 판단이 한 서비스 경계로 형성되지 않음 |
04의 State·Policy·Task·UI session |
대응 owner 없음 | 미구현 | 이름이 비슷한 기존 helper를 목표 authority로 간주하면 안 됨 |
05 DeviceAgent Domain Execution |
ModuleCommandDispatcher, domain handlers |
대칭 | 실제 제품 실행 owner 분리는 유지할 기반 |
06 Android Runtime / Native / Device Integration |
기존 vendor/device 호출과 callback | 유사 | 연동은 존재하지만 공통 TaskState·Evidence 계약으로 닫히지 않음 |
SKMLauncher2의 Fragment·ViewModel·Repository 비교는 전체 리팩터링 위치가 아니다.
MVVM 분석은 Experience/Consumer의 앱 내부 사용 사례이며, Product Interface를 어떤 방식으로
소비하는지 보여 주는 확대도다. 코드별 정합성, 현재 우회 호출과 수정 순서는
MR7 정합성 감사 문서에서 확인한다.
설계와 감사 이후 실제 소스 반영 상태, 검증 결과, MR6 task_manager 이식 진행은
SKIX 제품 프레임워크 리팩터링 진행 현황에서 계속 관리한다.
서비스 라이프사이클과 도메인 상태 감사는 이 Blueprint의 lifecycle/state 원칙이 MR7 소스에서 어떻게 분리되고 있는지 추적한다.
도메인별 Bundle 계약 상수화는 기존 문자열 wire 계약을 base/compatibility에 모으고 typed Manager와 Agent가 같은 원본을 쓰는 진행 상태를 추적한다.
구조 표현은 Android 공식 문서의 AOSP Architecture, Platform Architecture, AIDL Overview를 기준으로 삼았다. Android가 제공하는 Manager·System Service·HAL 경계는 유지하고, 그 위에 SKIX 제품 상태·정책· 작업 생명주기와 실제 완료 근거를 추가한다.
앱이 요청하고 제품 실행 계층이 수행하는 흐름
그림 1-A. 요청 구조화, Binder 전달, 기기 실행과 결과 반환
앱 프로세스는 요청과 화면 상태를 구조화하고 제품 실행 서비스는 상태·정책·Task와 실제 완료 근거를 관리한다. 원본 SVG 열기
SKIX Application Architecture Framework는 Android·Jetpack 사용 규칙과 앱 구조를 AAR·템플릿·
검증 도구로 제공한다. SKIX Product Runtime Framework는 Manager·Binder Service를 통해 기기 상태,
정책, Task와 UI 세션을 실제로 소유한다. 응용 프로그램 아키텍처 표준에서
UiAction·UiState, 제한적인 UiEffect, ViewModel, UseCase, Repository와 제품 실행 모듈의 역할을 정의한다.
AOSP 위에서의 위치
그림 2. AOSP 위의 SKIX 프레임워크 내부 계층
제품 인터페이스, 공통 제어 계층, TaskManager와 도메인 프레임워크의 위치를 보여준다. 원본 SVG 열기
현재 DeviceAgent가 놓인 위치
DeviceAgent는 /system/priv-app의 플랫폼 서명 상시 실행 앱이자 Binder 제품 서비스다.
이는 현재 구현 기준선이고, 목표는 AOSP system_server의 얇은 SkixFrameworkSystemService와 독립
system_ext Runtime을 결합한 하이브리드다. 부팅·root Binder·권한·runtime death는 전자가, Task·Workflow·Policy·State·Evidence·도메인 권위는 후자가 담당한다.
DeviceAgent는 provider·legacy gateway로 축소한다. 구조·SVG·부팅·복구 상세
현재 확인한 manifest의 .DeviceAgent는 exported=true이고 서비스 전체에 적용되는 signature permission이
선언돼 있지 않다. 일부 명령은 Binder.getCallingUid()를 개별 검사하지만 일반 명령 전체를 보호하는
공통 관문은 아니다. 플랫폼 서명으로 설치됐다는 사실은 호출자 접근 제어를 대신하지 않는다.
공개 Manager API를 연결하기 전에 서비스 권한, UID·패키지·인증서 검증과 메서드별 허용 범위를
제품 Runtime Binder 진입점에서 공통 적용해야 한다.
Android 호출 창구(Manager)와 실행 서비스(Service)의 분리
Android Application Framework의 구조처럼 앱이 쓰는 호출 창구(Manager)와 실제 상태·정책을 관리하는 실행 서비스(Service)를 Binder 경계로 분리한다. 호출 앱은 공개 Manager API를 사용하고, 실제 상태와 정책은 기기 안의 서비스 한곳이 책임진다.
그림 3. 호출 창구와 실행 서비스의 책임 분리
호출 앱의 Manager, Binder 계약, 제품 프레임워크 서비스와 기기 도메인의 경계를 보여준다. 원본 SVG 열기
| 위치 | 실행 책임 |
|---|---|
경험·호출 계층 (Experience and Consumer Layer) |
시스템 앱·PUI·IoT·예약·승인 파트너·선택적 Planner의 제품 경험 구성 |
제품 인터페이스 계층 (Product Interface Layer) |
UI 공통 AAR, Manager/Client API, Binder와 공통 요청·결과·이벤트 계약 |
프레임워크 제어 계층 (Framework Control Plane) |
상태 프레임워크, 정책 엔진, 자원 조정기, 기능 레지스트리와 서비스 상태 |
관리형 실행 계층 (Managed Execution Plane) |
TaskManager, 작업 흐름, 실행 일정, 실행기, 완료 근거와 중간 저장점 |
도메인 프레임워크 계층 (Domain Framework Plane) |
이동·청정·UI·Vision·Wellness·Security 등 입력 형식이 명확한 도메인 연결부 |
기기 연결 계층 (Device Integration Plane) |
DeviceAgent, 연동 Agent, AIDL/HIDL HAL, MCU·센서·하드웨어 |
Manager는 호출 앱이 쓰기 쉬운 요청을 만들고 서비스 연결·재연결과 결과 전달을 담당한다. Manager는 호출 창구로 남고 Service가 기기 상태와 정책을 소유한다. Manager가 잠시 저장한 값이 기기의 새로운 기준 상태가 되어서는 안 된다.
AudioManager, PowerManager, DisplayManager, WindowManager, UiModeManager,
AlarmManager처럼 Android가 이미 제공하는 기능은 Application과 SKIX Service가
Context.getSystemService()로 직접 사용한다. AOSP 기본 Framework를 다시 구현하지 않는다.
SKIX는 그 위에 제품 의미, 공통 상태·정책, 작업 추적 정보와 물리 완료 근거를 추가한다.
필요한 호출 창구와 실행 서비스
Manager는 호출 편의와 Binder 연결 대리부를 제공하고, Service는 최종 상태와 판단을 소유한다. 구성요소 이름은 목표 구조의 책임 명칭이다.
표의 State Service, Policy Service, Task Service는 1차 단계에서 각각 별도 APK나 프로세스를
뜻하지 않는다. 초기 배치는 DeviceAgent 프로세스의 하나의 제품 Runtime Binder 진입점 뒤에
논리 모듈로 둔다. 별도 프로세스는 장애 격리, 독립 업데이트 또는 파트너 보안 경계가 실제로
필요하다는 근거가 생겼을 때만 분리한다.
| 구분 | 1차 배치 | 분리 검토 조건 |
|---|---|---|
| 호출 앱 | Skix*Manager와 공통 Client AAR |
앱별 독립 배포 유지 |
| Binder 경계 | DeviceAgent의 제품 Runtime Binder 진입점 하나 | 별도 인증서 파트너 공개, 독립 OTA, 장애 격리 요구 |
| 내부 실행 책임 | 상태·정책·자원·Task·UI 세션을 논리 모듈로 분리 | 측정된 안정성·성능·보안 이점이 있을 때만 프로세스 분리 |
| 구분 | 구성요소 | 호출 측 역할 | Service 책임 | 필요한 이유 |
|---|---|---|---|---|
| 필수 기반 | SkixFramework Client Core |
Service 탐색, 연결·재연결, 버전 확인, 결과 알림 전달 | 공통 Binder 연결 규약 제공 | Manager마다 연결·재연결 코드를 중복하지 않기 위해 |
| 필수 기반 | SkixDeviceStateManager / State Service |
위치·도킹·배터리·동작 상태 조회·구독 | 단일 상태 원본, 출처, 시각, 최신성, 공개 범위 관리 | 앱마다 서로 다른 현재 상태를 판단하지 않게 하기 위해 |
| 필수 기반 | SkixCapabilityManager / Capability Service |
지원 기능·입력 형식·사용 가능 조건 조회 | 기능·정책·자원·실행기·완료 근거 연결 | 호출 전에 실제 수행 가능 여부를 알기 위해 |
| 필수 기반 | SkixExecutionPolicyManager / Execution Policy Service |
실행 허용 여부와 공개 가능한 판단 사유 조회 | 안전·보안·제품·사용자 동의 정책 합성 | 호출 채널마다 실행 기준이 달라지는 것을 막기 위해 |
| 필수 기반 | SkixExecutionEventManager / Execution Event Service |
상태·Task·UI 실행 이벤트와 완료 근거 조회·구독 | 이벤트 순서·추적 정보·공개 범위·제한 재전달 관리 | 요청부터 실제 결과까지 같은 실행 흐름으로 추적하기 위해 |
| 필수 기반 | SkixFrameworkHealthManager / Framework Health Service |
프레임워크 구성요소의 준비·성능 저하·복구 상태 조회 | Binder 연결 종료, 오래된 상태, 재연결과 안전 정지 관리 | 연결 장애를 기기 기능 실패와 구분하기 위해 |
| 관리형 실행 | SkixExecutionResourceManager / Execution Resource Service |
실행 자원의 점유 상태와 대기 이유 조회 | 이동·카메라·화면·오디오 점유권과 충돌 조정 | 동시에 사용할 수 없는 기기 자원의 오동작을 막기 위해 |
| 관리형 실행 | SkixTaskManager / Task Service |
Task·Workflow 제출, 조회, 취소와 완료 구독 | 실행 허용 판정, 대기열, 순서, 시간 제한, 취소와 완료 판정 | 장기·복합 작업의 생명주기를 한곳에서 관리하기 위해 |
| 제품 확장 | SkixUiManager / SkixUiService |
안정된 화면 ID로 세션 시작·갱신·종료·복귀 요청 | UI 실행 문맥, 전면 화면 소유권, 제품 장면과 겹쳐 표시 조정 | Launcher와 호출 앱의 화면 충돌을 막기 위해 |
| 제품 확장 | SkixScheduleManager / Schedule Service |
반복·요일·시각 예약 등록·조회·삭제 | 저장, 재부팅 후 재등록, 시작 조건과 Task 제출 | 제품 예약과 작업 흐름 내부 지연을 구분하기 위해 |
Manager별 대표 API
공개 API는 get/set/config를 일률적으로 제공하지 않는다. Task·UI·Schedule은 실행 요청을
받지만, 상태·정책·이벤트·건강 정보는 조회와 구독이 기본이다. 모든 요청과 결과는 임의의
setConfig(Bundle) 대신 버전이 붙은 명확한 형식을 사용한다.
제품 기능과 관리형 실행 API
| 공개 Manager | 대표 API | 사용 의도 | 내부 Service에 남기는 권한 |
|---|---|---|---|
SkixTaskManager |
submitTask(TaskRequest) · submitWorkflow(WorkflowRequest) · getTask(taskId) · listTasks(TaskQuery) · cancelTask(taskId, reason) · observeTask(taskId, listener) |
단일 Task와 여러 단계 작업 흐름을 제출하고, 진행·취소·완료를 같은 식별자로 관리한다. | 진행률 갱신, 실제 완료 근거 기록, 강제 종료와 대기열 복구 |
SkixDeviceStateManager |
getSnapshot(StateQuery) · getState(StateKey) · observeState(StateFilter, listener) · getFreshness(StateKey) |
위치·도킹·배터리·이동·청정 등 기기 상태의 최신본과 출처·갱신 시각을 제공한다. | 센서와 도메인 어댑터의 상태 기록·정정. 일반 앱의 임의 상태 변경은 공개 API에서 제공하지 않음 |
SkixCapabilityManager |
listCapabilities(CapabilityFilter) · getCapability(capabilityId) · checkAvailability(capabilityId, context) · validateRequest(capabilityId, input) |
기기가 지원하는 기능, 필요한 입력, 현재 사용 가능 여부와 완료 근거를 실행 전에 확인한다. | 기능 등록·변경, 실행기·정책·자원·완료 근거 연결 |
SkixUiManager |
startUiSession(UiRequest) · updateUiSession(sessionId, UiUpdate) · finishUiSession(sessionId, reason) · getActiveUiSession() · observeUiSession(listener) |
화면을 Activity 이름이 아닌 안정된 UI 대상과 세션으로 열고, 앱의 UiSessionRepository가 수신할 상태를 제공한다. |
SkixUiService, UiSessionController, 전면 표시 소유권, 화면 실행·복귀, 제품 장면과 겹쳐 표시 조정 |
SkixScheduleManager |
createSchedule(ScheduleSpec) · updateSchedule(scheduleId, ScheduleSpec) · getSchedule(scheduleId) · listSchedules(ScheduleQuery) · setScheduleEnabled(scheduleId, enabled) · deleteSchedule(scheduleId) · previewNextRun(scheduleId) |
반복·요일·시각 기반 제품 예약을 저장하고 다음 실행 시점과 활성 상태를 관리한다. | 재부팅 후 재등록, 실제 알람 연결, 실행 시점의 Task 제출과 실패 복구 |
실행 판단과 관측 API
| 공개 Manager | 대표 API | 사용 의도 | 내부 Service에 남기는 권한 |
|---|---|---|---|
SkixExecutionPolicyManager |
checkExecutionAllowed(ExecutionRequest request, Executor executor, ExecutionPolicyCallback callback) · registerPolicyChangeListener(PolicyScope scope, Executor executor, PolicyChangeListener listener) · unregisterPolicyChangeListener(PolicyChangeListener listener) |
실행 판정은 callback의 ExecutionPolicyDecision으로 반환한다. result, reasonCode, reasonSummary, unmetConditions, retryable, policyVersion을 함께 제공한다. |
시스템·제품 정책 원문, 합성 규칙, 정책 설치·변경, 우회 방지와 상세 진단 정보 |
SkixExecutionResourceManager |
getResourceState(resourceId) · checkResourceAvailability(ResourceRequirement) · getOccupancySummary(resourceId) · getWaitReason(requestId) · observeResourceState(listener) |
이동·카메라·헤드·오디오·화면처럼 동시에 사용할 수 없는 실행 자원의 점유 여부와 대기 원인을 보여준다. | 사용권 부여·회수·선점과 상세 점유 주체는 Service 내부에 둔다. 일반 앱에는 공개 가능한 점유 요약만 제공 |
SkixExecutionEventManager |
observeExecutionEvents(EventFilter, listener) · getExecutionHistory(EventQuery) · getLastEvent(traceId) |
여러 도메인에 걸친 실행 이력과 진단 이벤트를 추적한다. Task의 현재 상태와 최종 결과는 SkixTaskManager에서 조회한다. |
도메인 이벤트 발행, 순서 보장, 원본 완료 근거와 제한된 진단 정보. 일반 앱의 완료 이벤트 발행은 제공하지 않음 |
SkixFrameworkHealthManager |
getFrameworkHealth() · getComponentHealth(componentId) · runSelfCheck(scope) · observeHealth(listener) · requestRecovery(componentId) |
SKIX Service와 연동 구성요소가 준비·저하·복구 중인지 확인하고 진단 결과를 제공한다. | 자동 재연결·안전 정지·복구 정책 수행. requestRecovery는 시스템 권한 호출자만 허용 |
Execution은 Task 실행의 허용·자원·이벤트, Framework는 SKIX 구성요소의 건강 상태를 뜻한다.
정책 변경 구독은 register...Listener와 unregister...Listener를 짝으로 제공하고,
callback 실행 스레드는 호출자가 Executor로 지정한다. 판정 사유는 최초 callback에 포함하므로
별도 decisionId 재조회 API를 만들지 않는다. 합성된 정책 원문과 내부 규칙 조회는 권한 있는
진단 도구에만 제공한다.
Task 생명주기의 권위 원본은 SkixTaskManager 하나다. SkixExecutionEventManager는 감사와 장애
분석을 위한 횡단 이벤트를 제공할 뿐, Task의 최종 상태를 별도로 확정하지 않는다.
프레임워크 핵심 구조
공통 구성요소와 역할
| 핵심 구성 | 쉽게 말하면 | 소유 책임 | 대표 출력 |
|---|---|---|---|
제품 인터페이스 (Product Interface Layer) |
PUI·앱·IoT 요청을 같은 형식으로 받는 입구 | 동작·작업 흐름·상태 조회와 결과 형식 정리 | 버전이 붙은 요청·결과 |
기능 레지스트리 (Capability Registry) |
기기가 할 수 있는 기능과 사용 조건을 모아 둔 기능 명세서 | 입력·전제 조건·정책·자원·실행기·완료 증거 연결 | CapabilityDescriptor |
상태 프레임워크 (State Framework) / StateMirror |
위치·배터리·동작 상태의 공통 최신본 | 도메인의 단일 상태 기록을 출처·시각·최신성과 함께 제공 | StateSnapshot |
정책 엔진 (Policy Engine) |
지금 실행해도 되는지 판단 | 접근·안전·제품·개인정보 보호·동의 정책 합성 | PolicyDecision |
자원 조정기 (Resource Arbiter) |
동시에 쓸 수 없는 기기 자원의 교통정리 | 이동·카메라·헤드·화면·오디오의 대기·선점·해제 관리 | ResourceLease |
생명주기 관리기 (Lifecycle Supervisor) |
연결된 서비스가 정상인지 감시 | 준비·장애·재연결·안전 정지 관리 | ComponentHealth |
| TaskManager | 허용된 작업을 끝까지 관리 | 대기열·순서·시간 제한·취소·종료 상태 소유 | TaskSnapshot |
완료 근거 변환부 (Evidence Adapter) |
호출 응답과 실제 완료를 구분 | API 접수 응답이 아닌 도킹 결과 알림 같은 물리 근거를 공통 형식으로 변환 | EvidenceRecord |
도메인 연결 계층 (Domain Framework Plane) |
공통 계약을 기존 기능 호출로 바꾸는 연결부 | 형식이 명확한 요청을 기존 Manager와 도메인 이벤트로 연결 | 도메인 실행 결과 |
이벤트·완료 근거 연결망 (Event and Evidence Fabric) |
요청과 결과를 같은 작업으로 묶는 흐름 | 상태·작업·UI 결과 알림에 같은 추적 ID 부여 | FrameworkEvent |
안전 기준은 호출 앱이 완화할 수 없다
정책은 호출 앱마다 따로 판단하지 않는다. 시스템 안전 기준, 제품 기준, 호출 앱의 허용 범위와 현재 기기 상태를 차례로 적용하고 가장 엄격한 조건을 최종 결과로 사용한다.
그림 4. 계층형 정책 합성
시스템 안전 기준부터 현재 기기 상태까지 네 조건을 순서대로 확인하고 실행 여부를 결정한다. 원본 SVG 열기
실행 요청
1. 시스템 안전 기준을 지키는가?
2. 제품 사양에서 허용한 동작인가?
3. 호출 앱에 이 기능을 사용할 권한이 있는가?
4. 현재 기기 상태가 실행 가능하고, 필요한 사용자 동의를 받았는가?
네 조건을 모두 통과해야 실행한다.
하나라도 통과하지 못하면 사유와 함께 거부하거나 조건이 충족될 때까지 보류한다.
- 어느 계층이든
deny이면 실행하지 않는다. - 상위 계층의 동의·자원·완료 증거 요구를 하위가 제거할 수 없다.
- 시간 제한·속도·우선순위는 허용 구간 중 가장 엄격한 값으로 제한한다.
- 판정에는 적용한 정책 계층과 버전, 외부 공개 사유를 남긴다.
reasonCode와reasonSummary에는 호출자가 조치할 수 있는 공개 가능한 거부·보류 사유만 담는다.
상태 조회와 실행 정책의 경계
Client의 상태·정책 조회는 사전 안내다. 화면 제어와 요청 구성에는 사용할 수 있지만, 조회 직후 기기 상태가 달라질 수 있으므로 실행 권한이나 성공 보장이 되지 않는다.
| 판정 시점 | 프레임워크 책임 |
|---|---|
| 요청 전 조회 | 현재 상태·기능 사용 가능 여부·거부 사유를 Client에 제공 |
| 요청 접수 | 호출자 권한, 입력, 기기 정책과 자원 충돌 판정 |
| 실행 직전 | 상태 최신성을 확인하고 최신 기기 상태로 다시 판정 |
| 장기·복합 실행 | 접수 시점, 실행 직전, 작업 흐름의 각 단계와 관련 상태 변경 때 재판정 |
상태가 오래됐거나 정책 조건이 바뀌면 실행을 보류·거부하고, 진행 중 위반이 생기면 정책에 따라 일시 정지·취소·안전 정지한다. 기존 직접 명령도 같은 정책 관문을 통과하며 Client가 우회 값을 지정할 수 없다. 도메인 고유 안전 규칙은 최종 방어선으로 남는다.
예를 들어 제품 정책이 “이동 중에는 헤드 틸트 관찰 동작을 허용하지 않는다”라면 Client가 이동 전 허용 상태를 조회했더라도, 실행 시점에 이동 중이면 프레임워크가 요청을 막는다. 이동 도메인의 주행 자세와 모터 안전 규칙도 별도로 유지한다.
상태·정책·자원을 함께 확인한다
기능 명세(Capability)는 단순한 메서드 목록이 아니라 기능의 사용 설명서다. 입력·출력·실행 전 조건,
정책·자원·실행기·완료 근거를 한곳에서 연결한다.
예를 들어 mobility.move_to_room은 등록된 공간과 최신 위치 상태, 이동 자원 점유권, 이동
정책, AMR 실행기와 movement.arrived 완료 근거를 함께 선언한다. 상세 계약은 뒤의 참고 자료에 둔다.
실행 중인 작업을 관리하는 TaskManager
TaskManager는 요청의 의미를 해석하거나 모터를 직접 제어하는 기능이 아니다. 앱·IoT·예약 같은 호출자가 실행할 작업과 순서를 정해 제출하면, TaskManager는 어떤 단계가 실행 중인지, 언제 다음 단계로 넘어갈지, 최종적으로 성공·실패·취소 중 무엇으로 끝났는지 관리한다.
호출자·TaskManager·DeviceAgent의 책임
| 구분 | 담당하는 일 | 담당하지 않는 일 |
|---|---|---|
| 호출자 | 제품 장면에 맞는 Task·Workflow를 구성하고 실행 요청 | 물리 동작의 완료를 임의로 확정하지 않음 |
| TaskManager | 접수, 대기열, 단계 순서, 시간 제한, 취소, 완료 근거 대기와 최종 상태 관리 | 사용자 의도 해석과 모터·센서 직접 제어를 하지 않음 |
| DeviceAgent·도메인 실행기 | 실제 기기 기능을 수행하고 완료·실패 근거를 반환 | 전체 Workflow의 다음 단계를 임의로 선택하지 않음 |
여러 기능을 순서대로 실행하거나 실제 완료를 기다려야 할 때 TaskManager가 필요하다. 앱이
안방 이동 → 청정 → 스테이션 복귀 Workflow를 제출했다면 다음과 같이 처리한다.
- 이동 Task를 실행하고 AMR의 실제 도착 결과를 기다린다.
- 도착 근거가 확인된 뒤에만 청정 Task를 시작한다.
- 청정의 완료·취소·실패를 구분하고 다음 단계 실행 가능 여부를 확인한다.
- 복귀 Task의 실제 도킹 결과까지 확인한 후 Workflow를 종료한다.
- 각 단계와 전체 Workflow의 진행 상태·실패 이유·최종 결과를 호출자에게 전달한다.
그림 5. 기능은 유지하고 실행 관리를 공통화하는 구조
호출자가 실행 과정을 각각 연결하는 구조와 TaskManager가 작업 생명주기를 관리하는 구조를 비교한다. 원본 SVG 열기
요청 → 계약 검증 → 정책·자원 판정 → 작업 실행 → 물리 완료 근거 → 결과
| 구성요소 | 쉽게 말하면 | 책임 |
|---|---|---|
| Task 상태 관리 | 각 작업의 현재 상태를 기록하는 중심부 | 접수·대기·실행·완료 근거 대기·최종 종료 상태 관리 |
| 단계 순서 관리 | 여러 Task가 실행될 순서를 관리 | 앞 단계 완료 확인, 의존관계, 병렬 실행과 실패 시 중단 범위 |
| 시작 시점 관리 | Task를 언제 시작할지 판단 | 절대 시각, 이전 단계 완료 후 지연, 상태·이벤트 조건 |
| 기기 기능 연결 | Task와 실제 DeviceAgent 함수를 연결 | 기능 명세에 맞는 도메인 실행기 선택과 요청 전달 |
| 완료 확인 | 실제 동작이 끝났는지 확인 | 도착·도킹·청정 종료·앱 세션 종료 같은 기능별 완료 근거 관찰 |
| 실패 처리 | 실패 뒤 허용된 대응 수행 | 재시도·되돌림·안전 복귀·사용자 확인 중 사양에 맞는 처리 |
| 실행 기록 | 재시작 뒤에도 이어갈 수 있는 정보 보존 | 진행 상태, 중복 방지 값과 재기동 복구 정보 저장 |
그림 6. 관리형 실행 폐루프
요청 판정부터 Task 실행, 도메인 결과 알림, 물리 근거와 최종 결과까지의 흐름을 보여준다. 원본 SVG 열기
아래 상태는 목표 공개 계약이다. 현재 병합 후보가 사용하는 PENDING, RUNNING,
COMPLETED, CANCELLED, FAILED, PARTIAL_FAILED는 내부 상태로 유지하고 공개 Adapter에서
아래 상태로 변환한다.
SUBMITTED → ADMITTED → QUEUED → RUNNING → WAITING_EVIDENCE
└→ SUCCEEDED | FAILED | CANCELLED | TIMED_OUT
그림 7. Task 생명주기와 종료 상태
요청 접수부터 정책·자원 판정, 실행, 물리 완료 근거 확인과 최종 종료까지의 공개 상태 계약을 보여준다. 원본 SVG 열기
- 이 그림이 답하는 질문: Task 요청은 어느 시점에 실제 성공으로 끝나는가?
- 읽는 순서: 요청 접수, 실행 대기·진행, 물리 완료 근거, 종료 상태 순서로 읽는다.
- 현재 검증 범위: 공개 상태 계약과 JVM Task core 기준이다. MR6 persistence 전체 이식과 실기기 완료 판정은 남아 있다.
전환기에는 다음 매핑을 사용한다. 내부 정보만으로 공개 단계를 확정할 수 없으면 더 구체적인 상태를 추측하지 않고 앞 단계로 표현한다.
| 병합 후보 내부 값 | 공개 상태 | 변환 기준 |
|---|---|---|
PENDING |
SUBMITTED · ADMITTED · QUEUED |
admission과 queue 정보가 있을 때만 세분화하고, 없으면 SUBMITTED |
RUNNING |
RUNNING · WAITING_EVIDENCE |
완료 근거 watcher 대기 여부가 명시될 때만 WAITING_EVIDENCE |
COMPLETED |
SUCCEEDED |
기능별 완료 근거 또는 완료 계약이 확인된 경우에만 변환 |
FAILED + errorCode=timeout |
TIMED_OUT |
현재 후보 구현이 timeout을 FAILED 이벤트로 내보내는 차이를 Adapter에서 정규화 |
FAILED |
FAILED |
timeout이 아닌 최종 실패 |
CANCELLED |
CANCELLED |
취소가 실제 실행기와 도메인에서 확인된 경우 |
PARTIAL_FAILED |
Workflow 결과의 PARTIAL_FAILED |
Task 하나의 성공 상태로 축약하지 않고 단계별 결과와 함께 반환 |
공개 이벤트는 eventName에 상태명을 반복하지 않고 TASK_STATE_CHANGED와 state를 분리한다.
호출자는 state를 기준으로 종료 여부를 판단하고, reasonCode와 단계 결과로 원인을 확인한다.
API 반환은 요청 수락을 의미할 뿐 완료가 아니다. 이동은 도착, 복귀는 도킹, 청정은 정의된
종료 상태, Vital Signs는 사용자 측정 완료 또는 취소처럼 기능별 최종 상태 계약을
따른다. 결과 알림은 requestId, workflowId, stepId, taskId, traceId로 원래 Task에
귀속한다.
제품 예약, Task의 1회 지연과 Workflow 내부 시간 조건은 서로 다른 시간선으로 관리한다.
| 시간 요구 | 소유 주체 | 예 |
|---|---|---|
| 제품 예약의 반복·요일·시각 | Schedule Service·예약 저장소·AlarmManager |
매일 밤 9시 나이트 모드 |
| Task의 1회 지연·절대 시각 | TaskManager TaskScheduler |
30분 뒤 청정 시작 |
| 이전 단계 완료 후 지연 | 작업 흐름 실행 일정 | 이동 완료 30초 뒤 측정 시작 |
| 상태·이벤트 조건 | 시작 조건 판정기 | 도킹되면 업데이트 수행 |
프레임워크와 Task 생명주기
프레임워크는 Task 상태만 관리해서는 충분하지 않다. 기동 순서, 서비스 연결, 호출자 세션, 도메인 실행과 완료 증거가 각자의 생명주기를 가지며, Task는 이 상태들을 바탕으로 실행 가능 여부와 다음 단계를 결정한다.
그림 8. 프레임워크와 Task 생명주기
프레임워크 기동부터 서비스 연결, Task 실행, 물리 완료 근거와 장애 복구까지의 관계를 보여준다. 원본 SVG 열기
| 생명주기 | 대표 상태 | 관리 책임 |
|---|---|---|
| 프레임워크 기동 | CREATED → STARTING → READY → STOPPING |
구성요소 생성, 의존성 순서, 종료 정리 |
| 서비스 연결 | DECLARED → BINDING → READY → DEGRADED → RECOVERING |
bind·재연결, 준비 상태, 기능 사용 가능 여부 |
| 호출자 세션 | CONNECTED → ACTIVE → DISCONNECTED |
callback 등록, Binder 연결 종료, 세션·점유권 정리 |
| Task 생명주기 | SUBMITTED → QUEUED → RUNNING → WAITING_EVIDENCE → TERMINAL |
순서, 취소, 시간 제한, 재시도와 최종 상태 |
| 도메인 실행 | REQUESTED → STARTED → ACTIVE → STOPPED/FAILED |
실제 기능 실행과 도메인 고유 안전 정책 |
| 완료 증거 | OBSERVED → CORRELATED → ACCEPTED/REJECTED |
결과 알림을 원래 Task·단계에 연결하고 완료 여부 판정 |
서비스 연결 종료가 곧 Task 성공이나 실패를 뜻하지 않는다. 필요한 서비스가 끊기면 구성요소
상태를 DEGRADED 또는 RECOVERING으로 바꾸고, 진행 중 Task는 기능별 안전 정책에 따라 대기,
재시도, 취소 또는 안전 정지한다. 재연결 뒤에도 같은 요청을 중복 실행하지 않도록 Task 기록과
완료 증거의 상관관계를 유지한다.
호출 계층과 기기 실행 기반의 경계
앱·PUI·IoT·예약·AI 같은 호출 애플리케이션은 StateMirror와 기능 명세로 현재 상태와 허용
기능을 확인하고 구조화된 Task·Workflow를 제출한다. 프레임워크는 정책·자원 검증, 실행 관리와
완료 근거 반환을 담당한다. 이 계약을 유지하면 호출 애플리케이션이 바뀌어도 기기 실행 계층은 유지된다.
그림 9. 호출 계층 변화와 제품 실행 제어의 경계
호출자는 공통 실행 계약에 의존하고, 프레임워크는 상태·정책·자원·완료 판정을 일관되게 관리한다. 원본 SVG 열기
외부 사용 방식과 호환성
기존 호출은 그대로 유지하고, 순서·대기·취소·완료 증거가 필요한 관리형 요청만 Task 계약으로 확장한다.
| 요청 유형 | 기존 호환 경로 | 관리형 경로 |
|---|---|---|
| 단순 조회·표현 갱신 | 기존 조회·상태 전달 메서드 유지 | Manager의 상태 조회 또는 추적 없는 직접 호출 사용 |
| 단일 기기 동작 | 전환기에는 기존 실행 메서드 유지 | 청정·이동·복귀처럼 완료 관리가 필요한 동작은 관리형 단일 Task로 제출 |
| 복합·조건·장기 실행 | 서비스별 연결 코드 | 작업 흐름과 실행 일정으로 제출 |
| IoT·MQTT | 기존 메서드·payload 유지 | request.task 또는 버전이 있는 작업 흐름 요청 형식 선택 |
| 앱 화면 진입 | 기존 Intent 변환부 유지 | 안정된 uiTargetId와 UiSession으로 단계적 이전 |
MQTT 계약은 전송 계층이 아니라 응용 계약을 확장한다
TaskManager 도입 때문에 MQTT 전체를 교체하지 않는다. broker·Topic·인증·QoS는 유지하고, 기존 단일 명령의 JSON도 그대로 허용한다. 변경되는 범위는 순서·대기·취소·완료 추적이 필요한 요청에 관리 의미를 추가하는 payload와 결과 이벤트다.
그림 10. MQTT 전송 호환성과 관리형 실행 계약
기존 JSON 해석을 유지한 채 단일 Task만 호환 어댑터로 감싼다. 복합 Workflow의 MQTT 공통 해석기는 별도 수용 범위로 구분한다. 원본 SVG 열기
AWS IoT Domain Framework로 Client별 양방향 관계를 연다
IotAgent가 단일 AWS IoT Core 연결과 자격 증명을 소유한다. 각 Client Service App은 SkixIotCoreManager를
통해 필요한 domain/channel만 선택한다. Binder 뒤의 SkixIotCoreService는 caller 권한, Client별 구독,
publish 전달 상태와 재연결 생명주기를 소유한다. Client가 별도 MQTT 연결을 만들거나 raw Topic을 받는 구조가 아니다.
그림 10-A. AWS IoT Domain Framework 책임 구조 — 기존 MQTT JSON과 Task Contract는 유지한다. 신규 API는
Manager → Binder Service → IotAgentAdapter를 거치며, 기존 제품 handler와 신규 Client callback은 하나의 물리 수신에서 중복 없이 분배한다.
- 이 그림이 답하는 질문: 앱별 IoT 요청을 분리하면서 실제 AWS 연결은 어떻게 하나로 유지하는가?
- 읽는 순서: 앱의 IoT 창구에서 IotManagerService와 IotAgent를 거쳐 AWS IoT까지 읽는다.
- 현재 검증 범위: 계약과 책임 분리 설계다. 제품 Broker 연결과 실기기 송수신 완료를 뜻하지 않는다.
| 방향 | Client 공개 계약 | Framework 내부 처리 | AWS IoT Core |
|---|---|---|---|
| AWS → Client | subscribe(domain, channel, callback) → SubscriptionHandle |
ClientSubscriptionRegistry가 caller·callback·quota를 격리하고 SubscriptionMultiplexer가 같은 Topic을 병합 |
exact Topic Physical Subscription |
| Client → AWS | publish(domain, channel, payload, statusCallback) → PublishReceipt |
schema·QoS·rate·offline queue를 검사하고 publishId의 후속 상태를 callback/query로 추적 |
MQTT publish와 QoS 1 PUBACK |
| 양방향 요청 | request(domain, requestChannel, responseChannel) |
response 선구독 → correlationId → request publish → 응답/timeout 후 임시 handle 회수 | Request/Response Topic pair |
SkixIotCoreManager가 공통 진입점이며, CleaningIotManager, MobilityIotManager 같은 전용 Manager는 같은 정책 경로를
쓰는 선택적 wrapper다. Client A와 B가 같은 cleaning.command를 구독해도 Handle A1/B1은 독립적이다. A의 unsubscribe 또는 Binder death는 A1만 닫고 B1은 유지한다.
Client A: subscribe(cleaning.command) → Handle A1 / publish(cleaning.state) → Receipt A2
Client B: subscribe(cleaning.command) → Handle B1 / subscribe(mobility.command) → Handle B2
Physical: cleaning.command Topic 1개 → Framework가 A1·B1 callback으로 독립 fan-out
Client 공개 범위와 Service 내부 통제
| 구분 | 담는 정보 | 경계 원칙 |
|---|---|---|
Client 공개 범위 DomainCapability |
사용할 수 있는 domain·channel·방향·schema version | Client는 허용된 논리 채널만 선택하고 raw Topic과 내부 정책은 알지 않아도 됨 |
Service 내부 통제 DomainDescriptor |
Topic template, caller group, quota 상한, schema·QoS 정책 | 실제 Topic과 정책 변경 권한은 Framework Service가 소유 |
실행은 시스템 공통 정책, 서명된 Domain 명세, 호출자 권한, 이번 요청의 조건까지 네 조건을 모두 통과해야 허용한다. 계약식은 Root Policy ∩ signed DomainDescriptor ∩ caller grant ∩ operation request다.
내부 DomainDescriptor는 AWS→Client의 subscribeChannels와 Client→AWS의 publishChannels를 분리해, 구독 권한이 발행 권한으로 확대되지 않도록 한다.
새 Domain 추가
기본 경로는 제품 이미지에 포함되는 로컬 built-in descriptor다. 공통 codec을 사용하는 Domain은 descriptor·schema·권한·계약 테스트만 추가하며 Framework Core의 분기문을 수정하지 않는다.
원격 skix-domain-catalog는 이미 설치된 capability의 활성화·축소·회수만 담당하며, 설치되지 않은 실행 코드나 새 하드웨어 기능을 원격 설정만으로 추가할 수는 없다.
발행 상태와 복구
개념 계약은 publish(domain, channel, payload)이고, 실제 API는 statusCallback을 함께 받는다. 상태는 LOCAL_ACCEPTED → QUEUED_OFFLINE → SENT → PUBACKED → RESPONDED로 진행하거나 FAILED로 끝난다.
PublishReceipt는 최종 성공이 아닌 접수 시점의 상태다. 후속 결과는 PublishStatusCallback 또는 getPublishStatus()로 확인한다.
연결, 구독, 발행은 서로 다른 생명주기로 관리해 각 장애의 영향 범위를 격리한다. Broker 단절은 logical handle을 유지한 채 복구하고, Client 종료는 해당 구독만 닫으며, 개별 발행 실패는 해당 메시지만 재처리한다. Framework Service가 재시작되면 기존 Binder handle은 무효이므로 Manager가 재bind 후 구독 intent를 다시 제출해 새 handle을 받는다.
그림 10-B. 연결·구독·발행 생명주기 — 마지막 logical reference가 없어질 때만 Broker unsubscribe를 수행한다. Broker 재연결, Binder death, Framework Service 재시작의 복구 규칙은 서로 다르며, 필요한 범위만 복구해 정상 Client와 메시지에 장애가 번지는 것을 막는다. 신규 domain 등록 경로는 Catalog SVG, 전체 API·오류·전환 계약은 AWS IoT Domain Framework 상세 설계를 본다.
- 이 그림이 답하는 질문: IoT 연결이 끊겼을 때 기기 전체 연결과 앱별 구독을 어떻게 나눠 복구하는가?
- 읽는 순서: 연결 준비부터 정상 사용, 끊김, 다시 연결 순서로 읽고 장애 범위 격리 규칙을 확인한다.
- 현재 검증 범위: 목표 lifecycle 계약이며 실 AWS 장시간 복구 시험은 남아 있다.
현재 구현을 세 단계로 구분한다
| 구분 | 실제 경로 | 상태 |
|---|---|---|
| 현재 제품 경로 | CmdTopic이 기존 JSON을 기능별 Bundle로 변환 → sendModuleCommand(Bundle) → MainApi 직접 실행 |
기존 MQTT 요청·응답 유지 |
| TaskManager 적용 구조 | CmdTopic이 기존 명령 Bundle을 만든다 → IotTaskManagerBridge.wrapCommand()가 관리형 여부를 판정 → 같은 sendModuleCommand(Bundle) 사용 |
별도 TaskManager 작업본에 구현 |
| 복합 Workflow | method=submitWorkflow, subTasks 목록을 DeviceAgent TaskManager가 실행 |
AAR·Cloud 변환부는 구현되어 있으나 MQTT 공통 해석기 연결은 추가 수용 필요 |
MQTT JSON
→ CmdTopic의 기존 기능별 해석
→ 기존 method·parameter Bundle 생성
→ IotTaskManagerBridge.wrapCommand()
request.task 없음 → 기존 직접 실행 Bundle 유지
request.task {} → method=submitTask, taskMethod=기존 method
request.task.managed=false → 기존 직접 실행 Bundle 유지
→ sendModuleCommand(Bundle)
→ MainApi 직접 실행 또는 TaskManager
request.task가 없으면 기존 직접 실행, 빈 {}도 관리형 실행 의도로 처리한다.
managed=false이면 기존 직접 실행을 유지한다. 관리형 요청에서 실행 방식·대기열·우선순위·시간
제한을 생략하면 TaskPolicyRegistry의 기능별 기본값을 사용한다. IoT 변환부는
correlationId를 traceId와 함께 보존하고 replyTo도 다음 계층으로 전달한다.
기존 단일 명령
{
"request": {
"method": "setMoveTo",
"payload": {"positionId": "5"}
}
}
관리형 단일 Task
{
"correlationId": "iot-20260830-0001",
"replyTo": "device/reply/command",
"request": {
"method": "setMoveTo",
"payload": {"positionId": "5"},
"task": {}
}
}
위 메시지는 내부에서 다음 Bundle 의미로 바뀐다. forceTaskManager는 DeviceAgent 내부 라우팅 표식이며
공개 MQTT 필수 필드가 아니다. IoT 단일 Task는 method=submitTask 자체로
TaskManager 제어 API에 진입한다.
method=submitTask
taskMethod=setMoveTo
source=iot
traceId=iot-20260830-0001
correlationId=iot-20260830-0001
replyTo=device/reply/command
여러 단계를 한 실행으로 관리할 때는 submitWorkflow와 subTasks 목록을 사용한다. 이
Bundle 계약은 DeviceAgent TaskManager와 AAR·Cloud 변환부에 구현되어 있다. 다만 아래와 같은
외부 MQTT JSON을 모든 Topic에서 공통으로 해석하는 연결부는 단일 Task 어댑터와 별도로
수용·회귀 검증해야 한다.
{
"requestId": "iot-20260830-0002",
"traceId": "iot-20260830-0002",
"request": {
"method": "submitWorkflow",
"payload": {
"subTasks": [
{"taskMethod": "setMoveTo", "positionId": "5"},
{"taskMethod": "startBasicAirClear"},
{"taskMethod": "returnToStation"}
]
}
}
}
MQTT 전달 특성은 구현 상태를 구분한다
| 항목 | 현재 확인된 범위 | 보강할 계약 |
|---|---|---|
| 상관관계 | correlationId, traceId, replyTo 보존 |
Task 진행·최종 이벤트까지 같은 ID 유지 |
| 접수와 완료 | TaskManager 내부에서 접수와 최종 상태를 구분 | MQTT 응답에서도 ACCEPTED와 공개 최종 상태 SUCCEEDED를 분리 |
| 중복 수신 | 추적 ID 필드는 있으나 MQTT 전체 멱등 실행 보장은 별도 검증 필요 | requestId로 QoS 1의 재전달 중복 방지 |
| 오래된 명령 | 단일 IoT 어댑터에 ttlMs·expiresAt 해석 없음 |
실행 전 만료 판정 추가 |
| retain | 기존 운영 Topic 정책을 따름 | 명령은 retain=false, 상태 최신본만 retained Topic 검토 |
| 복합 순서 | TaskManager가 subTasks 순서를 관리 |
MQTT 공통 Workflow 해석기와 단계 이벤트 연결 |
기존 직접 요청과 관리형 요청이 함께 존재하는 동안의 동시성
현재 직접 요청은 기존 DeviceAgent 정책과 도메인 차단 규칙을 사용하고, 관리형 요청은 여기에 TaskManager의 접수·대기열·자원 판정을 추가한다. 두 경로가 새 자원 조정기를 완전히 공유하는 상태는 아니다. 관리형 Workflow가 이동 중일 때 기존 직접 이동 명령이 들어오는 충돌을 막으려면 진입점에서 사용 중 거절, 허용된 선점 또는 관리형 전환 중 하나를 정하고 실행권을 하나만 선택해야 한다.
상세 필드와 결과 알림 규칙은 MQTT Task Contract를 기준으로 하고, 제품 반영 전에는 기존 요청·응답, 단일 관리 Task, 복합 Workflow를 각각 회귀 시험한다.
호출 앱 계약
- 모든 공개 Manager는
SkixFramework Client CoreAAR의 Service 탐색, 연결·재연결, Binder 연결 종료, API 버전과 결과 알림 전달을 공유한다. - Binder Service는 UID·인증서·권한과 입력 형식 버전을 검증하며 payload의 호출자 문자열을 신뢰하지 않는다.
- 일반 파트너 앱은 허용된 기능 명세·공개 상태·요약 사유만 읽는다.
- SKIX 시스템 앱·Planner는 형식이 명확한 정책·자원·이벤트·서비스 상태 근거를 읽을 수 있다.
- 개발·관제 도구의 원시 추적 정보와 완료 근거는 별도 권한과 감사 기록을 요구한다.
DeviceAgent 책임 과집중 해소
DeviceAgent를 단순히 여러 클래스로 나누는 것만으로는 과집중이 해소되지 않는다. 상태·정책·자원·작업·UI의 최종 판단권이 계속 한 객체에 남아 있으면 변경 영향과 장애 범위도 그대로다. 책임은 기능 수가 아니라 최종 판단권을 기준으로 나눈다.
그림 11. 프레임워크와 DeviceAgent의 책임 분리
DeviceAgent에 모인 공통 관리 책임을 단일 소유자로 분리하고, 실제 기능 실행과 하드웨어 안전만 실행 경계에 유지하는 구조다. 원본 SVG 열기
TaskManager와 DeviceAgent가 나누어 맡는 일
TaskManager는 작업표와 진행 상태를 관리하고, DeviceAgent는 실제 기기 기능을 수행한다. 상태·정책·자원 서비스는 두 영역이 같은 현재 상태와 안전 기준을 사용하도록 돕는다.
| 관리 대상 | 관리하는 곳 | 실제로 하는 일 |
|---|---|---|
| 현재 기기 상태 | 각 도메인의 상태 어댑터와 StateMirror |
위치·도킹·배터리 같은 원본 결과를 공통 상태로 제공 |
| 실행 허용 여부 | Policy Engine과 DeviceAgent 도메인 안전 규칙 | 제품 공통 정책을 확인하고, 실행 직전 하드웨어 조건을 다시 검사 |
| 이동·카메라·오디오 등 공유 자원 | Resource Arbiter | 사용 중인 자원과 대기 요청을 조정하고 충돌을 방지 |
| Task와 Workflow 진행 | TaskManager | 단계 순서·취소·시간 제한을 관리하고 실제 완료 근거로 작업 종료 |
| 화면 세션과 서비스 연결 | Ui Service와 Lifecycle Supervisor | 화면 소유권, 서비스 준비 상태와 재연결 관리 |
| 하드웨어 안전을 지키는 곳 | DeviceAgent와 각 도메인 실행기 | 모터 정지, 이동 자세, 센서 오류처럼 장치와 가까운 안전 동작 수행 |
어떤 책임을 옮기고 무엇을 남기는가
| 현재 DeviceAgent에 섞인 책임 | 옮길 위치 | 분리 후 효과 |
|---|---|---|
| Binder 진입·callback 등록·연결 종료 | Client Core·Framework Service·Lifecycle Supervisor | 호출 앱마다 다른 연결·복구 처리 제거 |
| 위치·도킹·배터리 등 상태 조회 조합 | State Framework·StateMirror |
같은 상태의 중복 해석과 오래된 값 사용 방지 |
| 여러 기능에 걸친 허용·차단 판정 | Policy Engine | 제품 정책의 적용 근거와 버전 추적 |
| 이동·카메라·화면·오디오 충돌 처리 | Resource Arbiter | 점유·대기·거절·선점 결과를 한 기준으로 관리 |
| 대기열·순서·취소·시간 제한·최종 상태 | TaskManager | 단일 Task와 Workflow의 생명주기 통합 |
| Launcher 화면 진입과 진행 화면 연결 | SkixUiManager·Ui Service |
화면 소유권과 Task 진행 상태 연결 |
| 연동 서비스 상태와 결과 알림 전달 | Lifecycle Supervisor·Event/Evidence 계층 | 연결 상태와 작업 완료 상태의 혼동 방지 |
| DeviceAgent에 남길 책임 | 이유 |
|---|---|
| 이동·청정·화면·TTS 명령 실행 | 기존 기능 구현과 하드웨어 연동을 그대로 활용 |
| AMR·Vision·IoT·Update 연동 서비스 호출 | 도메인별 입력·결과 의미를 가장 잘 아는 실행 경계 |
| 이동 중 tilt-down, motor stop, sensor fault 같은 도메인 고유 안전 규칙 | 하드웨어와 가장 가까운 최종 방어선 |
| 원시 결과 알림을 도메인 결과로 변환 | 실제 완료·실패 이유를 정확히 만드는 책임 |
이동 중 헤드 틸트 다운, 모터 정지, 센서 오류처럼 하드웨어와 강하게 결합된 규칙은 기존 도메인에 남긴다. 카메라와 이동의 동시 사용, 음성 세션 중 행동, 전면 표시 경쟁처럼 여러 도메인을 조정하는 규칙은 프레임워크가 합성한다.
이동 → 청정 → 복귀에서 DeviceAgent가 실제 완료·실패 근거를 반환하면 TaskManager가 다음 단계,
재시도, 보상 동작 또는 전체 종료를 결정한다.
상태마다 값을 최종 기록하는 곳을 하나만 둔다. 이를 단일 상태 기록 책임이라고 한다. 위치는 이동
결과 알림 담당부, 청정 상태는 청정 결과 알림 담당부가 기록한다. StateMirror는 이 값을 공통
형식으로 읽어 주지만 같은 상태를 별도로 판단하거나 다시 소유하지 않는다.
Task 완료도 API 접수 응답이 아니라 물리 결과 알림으로 판정한다.
구현 현황(2026-09-05):
b77c2c5에서 이 원칙의 첫 concrete slice인StateManagerService가 Runtime+State 기본 composition에 연결됐다. typed key/record, source·관측 시각·freshness, READY gate와 immutable snapshot은 JVM에서 검증됐다. 다만 MR6 observation bridge의 producer adapter, 기존 상태와의 dual-publish 동등성, Binder/AOSP/실기기 연결은 아직 완료되지 않았다. 구현·이식 경계와 SVG
안전한 이관 순서
- 공통 상태를 먼저 분리: 기존 실행은 유지하고
StateMirror가 읽기 전용 최신본을 제공한다. - 판단을 나란히 비교: Policy·Resource·Task 판정을 실제 실행 없이 기존 결과와 비교한다.
- 기능별 실행권 이전: 검증된 기능만 관리형 경로로 전환하며 기존 경로와 동시에 실행하지 않는다.
- DeviceAgent를 실행 Facade로 축소: 공통 판단은 제거하고 도메인 명령·근거 변환·하드웨어 안전에 집중한다.
- 프로세스 분리는 근거가 있을 때만 수행: 장애 격리·독립 OTA·보안 경계가 필요할 때 Binder Service 분리를 검토한다.
전환 중에는 정책 책임 중복, 기존 대기열과 작업 대기열의 중복 실행, 상태 기록 책임 중복, 결과 알림에서 명령을 다시 호출하는 순환, 하드웨어 안전 장치 완화를 금지한다. 특히 동일 기능의 실행권을 두 경로가 동시에 갖지 않는다.
참고 자료
공개 호출 API와 결과 조회
Manager별 함수는 Manager별 대표 API를 기준으로 한다. 최종 정책, 자원 점유권, 완료 근거와 구성요소 상태는 Service가 소유하며 일반 호출자가 임의로 변경할 수 없다.
| 호출자 등급 | 공개 범위 |
|---|---|
| 일반 파트너 앱 | 공개 기능 상태·요약 사유·제한 상태와 서비스 상태 |
| SKIX 시스템 앱·Planner | 정책 판단·자원 충돌·형식이 명확한 이벤트·구성요소 상태 |
| 개발·관제 도구 | 추적 정보·정책 버전·점유 책임·원시 근거. 별도 권한과 감사 기록 필요 |
공통 Client Core는 Service 탐색, 연결·재연결, Binder 연결 종료, 버전 확인과 결과 알림 전달을 공유한다. 각 Manager가 Binder 연결과 상태 캐시를 따로 만들지 않게 하는 SDK 기반이다.
상태·정책·기능 명세 계약
상태 종류와 공통 형식
| 상태 | 예 | 원본 소유자 |
|---|---|---|
관찰 상태 (Observed State) |
위치·도킹·배터리·청정·개인정보 보호 | 실제 도메인 결과 알림 책임부 |
목표 상태 (Desired State) |
목표 위치·요청 모드·음량 | 승인된 Task·제품 설정 |
파생 상태 (Derived State) |
이동 가능·관찰 준비·저전력 보호 | 결정 규칙 판정기 |
| 작업 상태 | 대기·실행·완료 근거 대기·최종 종료 | TaskManager |
구성요소 상태 (Component Health) |
연결 중·준비·성능 저하·오래된 상태 | 생명주기 관리기 |
StateEnvelope
domain, key, typed_value
source, captured_at, received_at
freshness, sequence, confidence
visibility, correlation_id
기능 명세와 공유 자원
CapabilityDescriptor
capability_id, version, domain, operation
input_schema, output_schema
preconditions, policy_refs, resource_claims
executor_ref, completion_evidence, failure_reasons
risk_level, visibility, availability
| 자원 | 충돌 예 | 기본 원칙 |
|---|---|---|
| 이동 기반 | 이동·회전·복귀 동시 요청 | 하나의 독점 점유권 |
| 헤드 틸트 | 주행 자세와 Vision 관찰 자세 | 이동 안전 정책 우선 |
| 카메라·Vision | LiveView·객체 관찰·개인정보 보호 | 개인정보 보호와 전면 사용 책임 우선 |
| 오디오·TTS | 음성 세션·TTS·미디어 | 오디오 포커스·세션 상태 반영 |
| 화면·UI | Launcher·Vital Signs·Security | UiSession·UI 정책으로 조정 |
ResourceLease는 점유 주체, 사용 방식, 우선순위, 선점 가능 여부, 획득·만료 시각과 해제 사유를
가진다. 호출 앱은 직접 점유권을 조작하지 않고 작업·UI 요청을 통해 필요한 자원을 선언한다.
UI와 호출 앱 세션
공통 UI AAR와 시스템 화면
공통 UI는 정적 자산을 배포하는 AAR과 실행 중 UI 상태를 조정하는 Service로 분리한다.
UI Resource Kit AAR와 UI Foundation AAR는 SKMLauncher2의 공통 자산·구성요소를 공유하되,
화면별 상태나 제품 실행 정책은 포함하지 않는다.
| UI 요구 | 제공 방식 | 런타임 Manager/Service 역할 |
|---|---|---|
| 색상·글꼴·간격·아이콘 | 이름 공간이 적용된 UI Resource Kit AAR |
정적 자산은 Manager 없이 사용하고 제품 테마 버전·공통 자산 배포는 빌드 계약으로 관리 |
| 버튼·팝업·진행률·상태 화면 | UI Foundation AAR 공통 구성요소 |
앱 내부 렌더링은 앱이 소유하고 전역 Popup·Overlay 충돌만 Service가 조정 |
| Task 진행 표시 | Task 이벤트 + 공통 진행 구성요소 | 실행 중 UI 상태와 Task 세션을 같은 식별자로 연결 |
| Vital Signs·Security 화면 진입 | 안정된 uiTargetId와 UiSession |
화면 소유권·복귀·취소를 관리하고 기능 완료는 도메인 증거로 별도 판정 |
UI AAR는 SKMLauncher2 전체 코드를 공유하지 않는다. 리소스는 skix_ prefix와 이름 공간을
사용하고, 중앙 권한·상태·우선순위가 필요한 요청만 SkixUiManager로 보낸다.
앱 내부 Android UI 구조와 SKIX 제품 UI 조정
그림 12. MVVM + UDF 기본형과 제품 UI 세션 경계
앱 내부의 상태 흐름, 선택형 Reducer, 공개 UI API와 제품 UI 세션의 책임을 분리한다. 원본 SVG 열기
- 이 그림이 답하는 질문: 사용자 입력과 새 화면 상태는 앱 안에서 어느 방향으로 흐르는가?
- 읽는 순서: 화면, ViewModel, Repository, Manager 순서로 요청을 읽고 아래 점선으로 돌아오는 UiState를 확인한다.
- 현재 검증 범위: 앱 구조 표준과 MR7 대응 관계를 설명한다. 모든 기존 화면의 이관 완료를 뜻하지 않는다.
앱 내부는 UDF 기반 MVVM을 기본으로 사용한다. UiState는 불변 화면 상태, UiAction은
사용자가 화면에 전달한 입력이다. UiEffect는 유실돼도 업무 결과가 바뀌지 않는 짧은 시각 반응에만
제한한다. 단순 화면은 ViewModel → Repository → Manager로 끝내고,
복잡한 상태 전이에만 선택적 UseCase와 Reducer·StateMachine·Coordinator를 추가한다.
ViewModel은 Binder를 직접 호출하지 않는다. UiSessionRepository는 앱 또는 Client AAR에서 callback을 화면 상태로 변환한다.
SKIX UI Framework는 MVVM 구성요소가 아니다. God Manager로 만들지 않는다. 화면별 상태와 사용자 이벤트는 앱이 소유하고, 제품 UI 실행 문맥은 SkixUiService, 기기 작업 상태는 TaskManager가 소유한다.
응용 프로그램 아키텍처 표준에서 구성요소, 복잡도별 확장 기준, 오류·Coroutine·테스트 규칙과 전환 순서를 정의한다.
UI Manager·Service 경계 상세 SVG 열기
- 이 그림이 답하는 질문: 앱 화면과 제품 UI Framework는 무엇을 각각 소유하는가?
- 읽는 순서: 앱 화면 책임과 공개 UI API를 비교한 뒤 아래 제품 UI 세션 조정과 Android 기본 기능을 읽는다.
- 현재 검증 범위: 책임 경계와 API 목표 구조다. Window·Display·Overlay의 실기기 통합 완료를 뜻하지 않는다.
Launcher 연동 앱의 화면 세션 관리
이 영역을 호출 앱 연동(Client App Integration)으로 정의한다. 패키지·Activity class 직접 결합은
기존 변환부로 감싸고 안정된 대상과 서비스 상태·최종 결과 알림으로 단계적으로 이전한다.
그림 13. Launcher와 호출 앱의 UI 세션 관리
앱 내부 자유 영역과 프레임워크 소유 경계인 화면·Task 세션·복귀 관계를 보여준다. 원본 SVG 열기
| 구성요소 | 책임 |
|---|---|
ClientRegistry |
패키지·인증서·버전·지원 대상·서비스 상태 등록 |
UiTargetRegistry |
안정된 uiTargetId, 인자·결과·권한 관리 |
UiSessionRepository |
앱에서 SkixUiManager callback을 화면별 UiState로 변환 |
SkixUiService |
제품 UI 요청의 Binder Service 진입점과 결과 알림 |
UiSessionController |
uiSessionId와 Task·단계·화면 상태의 상관관계 관리 |
UiLaunchController |
UI 대상 실행·준비·전면 표시·일시 정지·종료 처리 |
ForegroundOwnerArbiter |
동시에 전면에 표시하려는 세션의 우선순위와 선점 판정 |
UiSceneCoordinator |
LCD·대기 화면·밝기·EyeLED를 제품 장면 단위로 조정 |
UiOverlayCoordinator |
Toast·Popup·Overlay의 표시 순서와 억제 사유 관리 |
TaskSessionBinder |
Task·단계·UiSession·도메인 이벤트 연결 |
NavigationCoordinator |
이전 대상·Launcher 복귀·중단 세션 복원 |
ClientHealthMonitor |
미설치·프로세스 종료·버전 불일치 감지 |
UiSession: REQUESTED → LAUNCHING → READY → FOREGROUND ↔ PAUSED → DISMISSED
Task: RUNNING → WAITING_EVIDENCE → SUCCEEDED | CANCELLED | FAILED | TIMED_OUT
화면 READY는 기능 완료가 아니다. Vital Signs는 측정 완료·사용자 취소, Security는 모드
종료·변경, Welcome은 시나리오 종료 증거가 필요하다. TaskSessionBinder가 이를 원래
Task에 연결한 뒤에만 다음 작업 흐름 단계로 진행한다.
외부 설계 원리
| 외부 사례 | 확인된 원리 | SKIX에 적용하는 부분 | 그대로 가져오지 않는 범위 |
|---|---|---|---|
| Android CarService와 CarManager | 앱의 호출 창구와 권한·상태를 소유하는 중앙 서비스를 분리 | SKIX Manager/Service, 호출자 권한과 단일 실행 책임 | 자동차 전용 API와 기동 방식 |
| Android Stable AIDL | 구조화된 프로세스 간 계약과 버전별 하위 호환 검사 | 요청·결과·이벤트 버전 관리와 구버전 호출자 호환 | 모든 내부 Java 인터페이스의 VINTF 안정화 |
| VHAL의 HIDL→AIDL 전환 | 기존 방식과 새 방식을 함께 지원하며 단계적으로 전환 | 기존 Bundle과 신규 계약 병행, 기능별 실행 책임 이전과 되돌림 | 차량 속성 모델 자체 |
| ROS 2 Actions | 오래 걸리는 동작을 요청·진행·결과·취소로 분리 | 작업 ID, 진행 상태, 취소와 최종 결과 계약 | ROS 2 통신 계층과 DDS 이식 |
| ROS 2 Managed Nodes | 구성요소의 준비·활성·비활성·오류 상태를 표준화 | 연결 서비스와 도메인 변환부의 준비·저하·복구 상태 | 기존 Agent의 전면 재작성 |
| Android WorkManager | 조건이 있는 영속 작업, 선후행 연결, 중복 방지와 복구 | 작업 흐름 의존관계와 재시작 복구 설계 | 물리 완료·실시간 자원·하드웨어 안전 판정 |
| Kubernetes API와 Controller | 원하는 상태와 관찰된 상태를 나누고 차이를 줄여 감 | 목표 상태와 실제 기기 상태를 구분하는 관측 방식 | 클러스터 제어 구조 전체 |
| Branch by Abstraction | 기존 구현 앞에 호환 경계를 두고 기능별로 점진 교체 | 호환 변환부, 판단 결과 사전 비교, 기능별 책임 이전 | 검증 없이 호출 창구만 영구 유지하는 구조 |
| ROS 2 QoS | 상태·이벤트별 최신성·보관·전달 기준 | 상태 종류별 최신성·전달 기준 | ROS 통신 설정 자체 |
| AOSP SELinux 정책 | 시스템 불변 정책과 제품 확장 경계 | 상위 안전 정책을 하위 호출자가 완화하지 못하는 구조 | AOSP 보안 정책의 재구현 |
적용 및 전환 계획
지금 구조에서 무엇을 바꾸는가
| 영역 | 현재 방식 | 바뀌는 방식 | 기대 효과 |
|---|---|---|---|
| 코드 기준 | DeviceAgent·SKMLauncher2 코드와 TaskManager 구현 작업본이 별도로 존재 | 한 출시 기준에서 Manager·Service·도메인 계약을 함께 검증 | 브랜치마다 기능 계약이 달라지는 문제 감소 |
| 기능 호출 | DeviceControlProxy와 sendModuleCommand(Bundle) 중심 |
입력·결과 형식이 명확한 Manager API와 공통 Client Core 제공 | 잘못된 필드와 호출자별 해석 차이 감소 |
| 기기 상태 | StateManager와 기능별 상태값을 호출자가 조합 |
StateMirror가 출처·갱신 시각을 포함한 최신본 제공 |
앱마다 현재 상태를 다르게 판단하는 문제 방지 |
| 결과 이벤트 | EventManager와 기능별 결과 알림이 분산 |
Task·상태·UI 이벤트를 추적 ID로 연결하고 권한별 구독 제공 | 요청부터 실제 결과까지 한 흐름으로 추적 |
| 실행 정책 | CmdPolicyManager, PolicyEngine과 도메인 규칙에 분산 |
공통 제품 정책을 먼저 확인하고 도메인 안전 규칙을 실행 직전에 재확인 | 호출 채널이 달라도 같은 안전 기준 적용 |
| Task 실행 | TaskManager 후보에 대기열·Workflow·시간 실행·완료 처리가 구현 | 검증된 기능부터 정식 관리형 실행 경로로 전환 | 순서·취소·시간 제한·실제 완료를 공통 관리 |
| 공유 자원 | 각 기능의 busy/state 값으로 개별 충돌 처리 | 이동·카메라·오디오·화면의 점유와 대기 원인을 공통 조정 | 동시 실행 충돌과 임의 선점 방지 |
| 서비스 연결 | 각 앱과 기능이 Android bind·재연결을 개별 처리 | 공통 Client Core와 Health Service가 준비·장애·재연결 상태 제공 | 연결 장애와 기능 실패를 구분하고 중복 코드 감소 |
| 기능 명세 | 메서드·실행기·지원 목록이 여러 위치에 분산 | 기능 입력·조건·정책·실행기·완료 근거를 하나의 명세로 연결 | 호출 전에 실제 사용 가능 여부 확인 |
| UI | Launcher Activity·LCD·EyeLED·Toast/Popup을 직접 조합 | UI AAR와 SkixUiManager가 화면 세션·우선순위·복귀 관리 |
화면 충돌과 패키지명 직접 결합 감소 |
| 실패 복구 | 기능별 재시도와 일부 실행 기록에 의존 | 실행 기록·중복 방지·재시작·안전 정지 규칙을 공통화 | 재기동 후 중복 실행과 유실 감소 |
현재 내부 Manager와 TaskManager 적용 후보는 서명·권한·회귀·실기기 검증 전까지 제품 계약으로 확정하지 않는다.
코드 기준 이행 설계
분석 기준 커밋은 1398d109이며, TaskManager 기능이 있는 별도 작업본은
TaskManager 적용 후보로 구분한다.
전환 방식 비교와 선택
기존 구조를 모두 버리는 전면 재구축보다 단계적 융합을 기본안으로 삼는다. 검증된 기기 기능과 하드웨어 안전 규칙은 유지하고, 공통 상태·정책·자원·작업 관리 책임만 기능 단위로 옮긴다. 처음에는 새 구조는 판단만 하고 실제 실행은 기존 방식이 담당한다.
| 접근 방식 | 장점 | 위험과 한계 | 판단 |
|---|---|---|---|
| 전면 재구축 | 처음부터 일관된 구조를 만들기 쉬움 | 기존 270개 명령, Binder·MQTT·결과 알림·권한·하드웨어 정책을 동시에 다시 검증해야 함 | 현재 제품에는 적용하지 않음 |
| 호환 호출 창구만 추가 | 호출 앱 변경이 작고 빠르게 외형을 정리할 수 있음 | 내부의 책임 집중과 상태·정책 중복은 그대로 남음 | 짧은 전환 단계로만 사용 |
| 단계적 융합 | 기존 기능을 유지하면서 기능별로 검증·전환·되돌림 가능 | 일정 기간 기존 구조와 새 구조를 함께 비교해야 함 | 기본안 |
유지 → 감싸기 → 판단 결과 사전 비교 → 실행 책임 이전 → 기존 분기 축소
그림 14. 기존 기능을 유지하면서 실행 책임을 옮기는 구조
새 구조는 먼저 판단만 하고 실제 실행은 기존 방식이 담당한다. 결과가 충분히 일치한 기능부터 실행 책임을 옮기며, 문제가 생기면 해당 기능만 기존 경로로 되돌린다. 원본 SVG 열기
| 구분 | 대상 | 처리 원칙 |
|---|---|---|
| 유지 | 기존 도메인 실행과 하드웨어 안전 규칙 | 현재 동작을 회귀 기준선으로 사용 |
| 감싸기 | 기존 Bundle, MQTT 단일 명령, 결과 알림 | 호환 변환부 뒤에서 같은 실행기로 연결 |
| 분리 | 상태 기록, 정책 판단, 공유 자원, 작업 생명주기 | 최종 책임 주체를 하나로 명시 |
| 새로 추가 | 형식이 명확한 Manager API, 기능 명세, 작업·작업 흐름 계약 | 버전이 붙은 계약으로 기존 경로와 병행 |
| 단계 교체 | 문자열 명령 분기, 직접 실행이 섞인 정책, 주기 확인 중심의 완료 판단 | 판단 결과 사전 비교 후 기능별로 책임 이전 |
| 후속 축소 | 사용자가 없어진 기존 분기와 중복 저장소 | 회귀·실기기 검증과 지원 종료 기간 이후 제거 |
전환 중에도 같은 요청을 실행하는 곳과 같은 상태를 최종 기록하는 곳은 각각 하나여야 한다. 기능 단위로 실행 책임을 하나만 이전해야 새 대기열과 기존 직접 호출의 중복 실행을 막을 수 있다.
협력사와 먼저 합의할 항목
- 기존 명령의 입력·결과·차단 조건·결과 알림·물리 완료 기준
- 상태 기록, 정책 판단, 자원 조정, 작업 관리와 도메인 실행의 최종 책임 주체
- 신규 API의 버전, 필드 기본값과 구버전 호출자의 호환 범위
- 판단 결과 사전 비교의 허용 오차와 기능별 실행 책임 이전 조건
- 중복 실행, 안전 정책 약화, 완료 오판이 발생했을 때의 되돌림 조건
- 동일 서명 APK와 실기기에서 확인할 물리 완료 근거와 성능 기준선
현재 코드, 병합 후보, 목표 설계를 구분한다
| 근거 수준 | 의미 | 적용 |
|---|---|---|
| 현재 소스 확인 | 1398d109 소스에 존재하고 현재 구조를 설명할 수 있음 |
변경 전 기준선과 호환성 판단에 사용 |
| TaskManager 적용 후보 | 별도 작업본에 구현되어 있으나 제품 기준 검증이 남음 | 재사용 후보로 평가하고 선택 이식 |
| 리팩터링 제안 | 현재 클래스 책임을 분리하기 위한 목표 설계 | API·책임·전환 순서와 완료 조건으로 관리 |
TaskManager 후보는 기준선 이후 431개 파일이 변경돼 전체 병합하지 않는다. 실행 생명주기, Workflow, Scheduler와 완료 근거를 분리해 기능별로 이식한다.
그림 15. 현재 실행 경로와 책임 집중 지점
공개 Binder 진입부터MainApi, 상태·정책, 연동 서비스 결과 알림과 물리 실행까지 실제 호출 흐름을 보여준다. 원본 SVG 열기
현재 코드에서 먼저 풀어야 할 책임 집중
| 현재 파일 | 확인된 규모와 역할 | 구조적 위험 | 첫 분리 단위 |
|---|---|---|---|
DeviceAgent.java |
573줄. Binder Stub, 결과 알림 목록, 여러 Manager 생성과 연동 서비스 초기화 | 프로세스 생명주기와 제품 반응이 한 시작점에 결합 | ComponentRuntime, ClientSessionRegistry |
MainApi.java |
4,210줄, 270개 method.equals 명령 분기 |
문자열 계약, 차단 판정, Bundle 해석과 도메인 실행이 한 변경 범위 | LegacyCommandRegistry, 도메인별 CommandHandler |
MainApiCleaning.java |
6줄의 빈 골격 | 파일 분리만 있고 책임 분리는 없음 | Cleaning handler를 계약 단위로 추출 |
StateManager.java |
707줄. 주·보조 상태, 차단 목록, 모드 전환 부수효과, Binder 연결 종료 | 상태 원본·정책·하드웨어 효과·세션 정리가 결합 | LegacyDeviceModeCoordinator, DeviceStateSnapshotAdapter, ModeTransitionEffects |
CmdPolicyManager.java |
1,581줄. 상태 수집, 실행 허용 판정, 이동·청정 실행, 일시 정지·재개 | 판단 코드가 직접 동작을 수행해 정책 검증과 실행 검증을 분리하기 어려움 | DeviceFactCollector, OperationAdmissionPolicy, 도메인 변환부 |
EventManager.java |
414줄. 주·보조 상태와 EyeLED 장면·우선순위 조정 | 이름은 범용 이벤트처럼 보이나 실제로는 표현 상태 조정기 | 기존 역할 유지 후 LegacyIndicatorCoordinator로 명확화 |
MainService.java |
642줄. 동료 서비스 연결, AMR 결과 알림 해석, 상태 기록, UI·IoT 전달과 오류 반응 | 원시 결과 알림, 상태 기록, 제품 반응과 완료 근거 생성이 결합 | PeerServiceConnector, AmrCallbackDecoder, FrameworkEventHub |
AppCmd.java·MainHandler.java |
Handler 메시지로 AMR·IoT·Update·앱 결과 알림 전달 | 전송 경로와 도메인 의미가 섞이고 상관관계가 메서드에 의존 | 형식이 명확한 이벤트 묶음과 추적 ID 변환부 |
DeviceControlProxy.java |
259줄. 연결·재연결, 연결 종료 감지, 결과 알림 등록, 원시 AIDL 노출 | 호출자 클래스 추정, 버전 분산, Manager별 명확한 계약 부재 | 공통 호출 라이브러리와 CallerIdentityResolver 연계 |
IDeviceControl.aidl |
결과 알림 4개와 sendModuleCommand(Bundle) 1개 |
API 버전과 입력 형식이 타입으로 드러나지 않음 | 기존 AIDL 유지 + 버전이 붙은 명확한 호출 계약 병행 |
현재 process에서 하이브리드 process로 단계적 전환한다
현재 DeviceAgent는 android.uid.system, persistent=true인 privileged app이지 SystemService가 아니다.
기존 process 논리 경계는 호환 기준선으로 유지하고, 신규 권위 소스는 skix-framework/base로 이동한다.
SkixFrameworkService.apk는 격리 Runtime, SkixFrameworkSystemService는 부팅과 전역 Binder를 소유한다.
com.sk.airbot.deviceagent
├─ bootstrap/ DeviceAgent · ComponentRuntime · peer 연결 순서
├─ compat/ LegacyCommandRegistry · LegacyBundleAdapter
├─ identity/ CallerIdentityResolver · ClientSessionRegistry
├─ state/ StateStore · DeviceStateSnapshotAdapter · derived state
├─ policy/ DeviceFactCollector · OperationAdmissionPolicy
├─ event/ FrameworkEventHub · EvidenceNormalizer
├─ task/
│ ├─ api/ TaskControlApi · TaskQueryService
│ ├─ core/ TaskLifecycleReducer · TaskRepository
│ ├─ workflow/ WorkflowEngine · DependencyResolver
│ └─ schedule/ TaskScheduler · TriggerEvaluator
└─ domain/
├─ mobility/ MobilityCommandAdapter · MobilityEvidenceAdapter
├─ cleaning/ CleaningCommandAdapter · CleaningEvidenceAdapter
└─ ui/ UiSessionAdapter · UiEvidenceAdapter
기존 RobotMovementController, BaseCleaningManager, ScheduleManager, ErrorHandler는
도메인 동작과 하드웨어 안전 규칙을 계속 소유한다. 새 계층은 이 코드를 복제하지 않고
입력·상태·완료 증거를 정규화한다. 별도 프로세스 분리는 비정상 종료 격리나 독립 OTA의 실측
필요가 확인된 뒤 결정한다.
TaskManager 병합 후보를 다루는 방법
병합 후보에는 TaskManager.java 3,632줄, 실행기 레지스트리, Task 완료 상태 저장소와
관찰기, 작업 흐름·실행 일정, 추적 ID, TaskManagerClient AAR와 테스트가 있다. 이 기반은
버리지 않는다. 다만 큰 클래스를 그대로 옮기면 현재 MainApi와 비슷한 책임 집중이 다시
생기므로, 검증된 기능 단위로 나눠 가져온다.
| 분류 | 대상 | 처리 원칙 |
|---|---|---|
| 선택 이식 | Task 기록·대기열, 작업 흐름 의존관계, 실행 일정, 실행기 레지스트리, 완료 증거 저장, 추적 ID | 현재 기준 회귀 시험과 함께 작은 모듈로 이식 |
| 분해 후 이식 | TaskManager.java, 주기 확인 기반 완료 관찰, 입력 정책 해석, 영속 저장 |
접수·저장·대기열·작업 흐름·스케줄·조회·상태 전이를 별도 책임으로 분리 |
| 공개 계약에서 제외 | bypassCallerPolicy, 호출자 지정 source, 임의 대기열·우선순위·시간 제한·자원 요구, 메서드 문자열 추정 경로 선택 |
서버 책임 정책으로 대체하고 내부 시험 기능은 별도 개발 권한으로 격리 |
| 별도 검증 | 재부팅 복구, 중복 방지, PARTIAL_FAILED, 장기 UI·Vital·Security 세션 |
실기기 최종 완료 근거와 복구 시험 전에는 제품 보장으로 선언하지 않음 |
목표 Task Service는 다음처럼 분리한다.
| 구성 | 단일 책임 | 주요 입력·출력 |
|---|---|---|
TaskControlApi |
제출·취소·일시 정지·재개·조회 진입 | 버전이 붙은 요청과 안정된 결과 |
TaskAdmissionService |
호출자·입력 형식·정책·자원 사전 판정 | AdmissionDecision |
TaskRepository |
Task·단계·작업 흐름과 중복 방지 정보 저장 | 상태 최신본·중간 저장점 |
TaskQueueDispatcher |
대기열 선택과 실행 가능 Task 전달 | 실행 전달 이벤트 |
WorkflowEngine |
의존관계·조건·실패 정책 평가 | 실행 가능 단계·작업 흐름 결과 |
TaskScheduler |
절대 시각·이전 단계 후 지연·시작 조건 관리 | 실행 허용 판정 재진입 이벤트 |
TaskLifecycleReducer |
이벤트와 완료 근거를 유효한 상태 전이로 축약 | 최종 상태 |
TaskQueryService |
진행률·사유·이력을 권한에 맞게 가공 | 일반·시스템·개발용 조회 결과 |
호출자 권한과 정책 책임
현재 Binder service는 앱 고유 signature permission을 요구하지 않는다. 적용 후보의
signature permission 추가는 이식 가치가 있으나, manifest 선언만으로 끝나지 않는다.
Binder UID · PID
→ PackageManager에서 package 집합 확인
→ signing certificate와 선언 permission 확인
→ CallerIdentityResolver가 caller profile 생성
→ 공개 Capability·상태·명령 범위 결정
- 호출자 제공 source를 권한 근거로 사용하지 않는다.
source=CLOUD같은 값은 trace metadata일 뿐 실행 권한이 아니다. - 호출자가 정책 우회 여부를 정하지 않는다.
bypassCallerPolicy, 강제 실행, 내부 우선순위는 일반 공개 계약에서 제거한다. - 대기열, 우선순위, 시간 제한, 재시도, 취소 가능 여부와 자원 요구는 기능 명세와 서버 정책이 기본값·상한·하한을 소유한다. 호출자는 허용된 선택값만 요청할 수 있다.
- platform-signed system app, 동일 인증서의 내부 앱, 별도 승인 인증서의 파트너 앱을 서로 다른 caller profile로 관리한다.
- Binder death는 callback 정리뿐 아니라 해당 caller의 session·lease·취소 정책으로 연결한다.
기존 명령을 끊지 않는 계약 전환
기존 sendModuleCommand(Bundle)와 MQTT 형식은 즉시 제거하지 않는다. LegacyCommandRegistry가
270개 메서드의 입력, 결과, 차단 조건, 결과 알림, 물리 완료 기준과 관리형 전환 여부를 명시한다.
기존 요청
→ LegacyBundleAdapter
→ LegacyCommandRegistry 명세
→ 기존 직접 실행 또는 관리형 작업 중 실행 책임 하나 선택
→ 동일한 기존 결과 Bundle·결과 알림 반환
신규 요청
→ 형식이 명확한 Manager 요청
→ 기능 명세
→ 작업 허용 판정·실행·완료 근거
→ 형식이 명확한 결과·이벤트
IoT 호환성과 관리형 요청 형식은 MQTT 계약을 따른다.
상태와 완료 증거를 옮기는 순서
StateManager를 즉시 교체하지 않고 LegacyDeviceModeCoordinator로 감싼다. 먼저
DeviceStateSnapshotAdapter가 기존 위치·도킹·배터리·이동·청정 상태를 읽기 전용으로 투영한다.
새 상태 저장소는 동일 값을 다시 판단하거나 하드웨어를 제어하지 않는다.
MainService의 연동 서비스 결과 알림은 다음 순서로 분리한다.
AMR·Vision·IoT 원시 결과 알림
→ 도메인 결과 해석기
→ 기존 상태 기록 책임과 제품 반응 유지
→ FrameworkEventHub에 형식이 명확한 이벤트 이중 기록
→ EvidenceNormalizer가 taskId·stepId와 연결
→ TaskLifecycleReducer가 최종 상태 여부 판정
초기에는 기존 결과 알림과 새 형식의 이벤트를 동시에 기록해 누락·순서·지연 차이를 비교한다. 주기적으로 상태를 확인하는 방식은 호환용 보조 장치로만 남기고, 최종 구조는 완료 사건을 받는 방식을 기본으로 한다. 결과 알림이 다시 명령을 호출해 순환하거나, API 접수 응답을 실제 완료로 잘못 처리하는 경로는 차단한다.
단계별 전환과 되돌림
그림 16. 실행 책임을 단계적으로 이전하는 경로
기존 실행 유지, 판단 결과 사전 비교, 선택 이식, 도메인 변환부와 실행권 이전을 기능 단위로 진행한다. 원본 SVG 열기
| 단계 | 구현 작업 | 다음 단계 진입 조건 | 되돌림 방법 |
|---|---|---|---|
| 0 | 명령 목록 동결: 270개 메서드의 호출자·입력·결과·결과 알림·차단·완료 목록 생성 | 대표 기기 형상과 회귀 기준선 확정 | 변경 없음 |
| 1 | 읽기 전용 상태 투영: 위치·도킹·배터리·이동·청정 최신본 생성 | 기존 상태와 순서 번호·시각·값 동등 | 상태 투영 비활성화 |
| 2 | 이벤트·완료 근거 이중 기록: 결과 알림을 형식이 명확한 이벤트·완료 근거로 병행 변환 | 누락·중복·순서·지연 허용 범위 통과 | 이벤트 추가 전달 제거 |
| 3 | 판단 결과 사전 비교: 새 정책은 허용·거절·실행 경로 판단만 기록하고 기존 경로가 실제 명령을 한 번만 실행 | 기존 허용·차단과 차이 검수 완료 | 새 판정 무시 |
| 4 | Task 핵심 선택 이식과 분해 | 대기열·취소·시간 제한·저장 단위 시험 통과 | 기능별 설정으로 기존 직접 실행 |
| 5 | 이동·청정부터 관리형 실행 전환 | 기존 경로와 결과 동등성, 중복 실행 0건 | 기능별 실행 책임 복귀 |
| 6 | UI·Vital Signs·Security·Welcome 세션 연결 | 사용자 완료·취소·모드 종료 근거 확인 | 해당 세션 변환부 해제 |
| 7 | 실행 책임 이전: 새 정책·상태·Task로 최종 실행 책임 이전 | 장기 시험·업데이트·복구·권한 기준 통과 | 도메인별 기존 변환부 유지 |
완료와 배포 기준
| 검증 축 | 필수 기준 |
|---|---|
| 계약 | 270개 기존 메서드의 입력·결과 Bundle·결과 알림과 신규 명확한 계약 매핑 |
| 동등성 | 기존 경로와 결과 동등성, 차이가 있으면 승인된 사양 변경으로 분류 |
| 물리 실행 | 이동·복귀·청정·화면 세션의 실기기 물리 완료 증거 확인 |
| 생명주기 | 취소·시간 제한·일시 정지·재개·Binder 연결 종료·프로세스 재기동·중복 요청 검증 |
| 권한 | 플랫폼 서명, 서명 권한, Binder UID·인증서별 허용·거부 시험 |
| 성능 | 기준선 대비 Binder 지연, 대기열 대기, 결과 알림 처리, PSS·스레드·저장소 증가 측정 |
| 관측 | 요청·작업 흐름·단계·Task·완료 근거가 하나의 추적 정보로 연결 |
| 배포 | 기능별 전환 설정과 즉시 가능한 되돌림 절차 보유 |
컴파일과 JVM 시험은 구조 검증이다. 제품 전환 완료는 동일 서명 APK, 실제 Binder 호출자, 연동 서비스 연결, 센서·모터 결과 알림과 장기 실행 로그가 함께 확인된 시점으로 판정한다.
연결 문서
- SKIX 로보틱스 프레임워크 전체 구조 Atlas
- Request-to-Evidence 전체 흐름
- AOSP Boot와 Runtime Lifecycle
- SKIX Root Binder Admission Core
- SKIX Runtime Composition 구현 현황
- SKIX StateManager 읽기 전용 투영 구현
- SKIX 하이브리드 SystemService와 Runtime 구조
- SKIX 제품 프레임워크 리팩터링 진행 현황
- SKIX 도메인 정책 사양 카탈로그
- SKIX 서비스 라이프사이클과 도메인 상태 감사
- SKIX Blueprint 기준 MR7 리팩터링 정합성 감사 및 교정안
- 프레임워크와 SDK 문서 모음
- 프레임워크·SDK 시스템 설계
- SDK 계약
- SoC TaskManager 프레임워크
- TaskManager 기준 사양서