← Docs hub

자원·기능·작업 기반 — 어떤 서비스가 무엇을 책임지는가

이 기반 위의 후속 계약은 제공자 연결·TTS 전달 상세에서 본다. 서비스 세대 외에 연결 식별을 추가하며 Resource의 소유권·물리 재확인 책임은 바꾸지 않는다.

전체 구조에서 이번에 구현한 부분

skix-framework/base/services/core 안의 Resource·Capability를 상태가 있는 내부 서비스로 만들고, 기존 Task를 기본 Runtime에 연결했다. 기본 생성 대상은 7개다. 장치 실행기나 Android 부팅 호스트까지 완성했다는 의미는 아니다.

자원·기능·작업의 폴더별 소유권, Runtime 생명주기와 자원 상태 전이

SVG 확대 · Mermaid 원본

전체 배치는 전체 모듈·폴더 지도를 유지한다. 위 그림은 그중 공유 자원과 기능 조회, 작업 접수 기반을 확대한다.

1. 폴더부터 읽기

아래 경로는 base/services/core/java/com/sk/airbot/frameworkservice/server/ 기준이다.

폴더 / 대표 클래스 맡는 일 맡지 않는 일
runtime/SkixFrameworkCompositionRoot 실제 서비스 생성, 같은 감독자에 등록 장치 기능을 임의로 AVAILABLE로 표시
control/lifecycle/ 시작·중지 순서, 준비·장애 상태 모터나 재생기의 물리 상태 판정
control/resource/ResourceManagerService 공유 자원의 독점 소유권과 복구 필요 상태 작업 상태 변경, 제품 명령 해석
control/capability/CapabilityManagerService 기능 명세 등록과 현재 가용성 조회 자원 확보, Policy 승인, 자동 실행
execution/task/TaskManagerService 작업 접수·대기·진행·취소·종료 상태 등록만으로 실제 장치 실행 시작
execution/task/admission/LegacyDomainResourceAdmissionPolicy MR6 제품별 충돌 규칙의 형식화된 이관 공통 Resource에 명령별 분기를 혼합

공개 SDK는 이번 내부 계약 때문에 무리하게 확장하지 않는다. control/이 execution/task/의 구현 타입에 의존하지 않도록 자원 소유 식별을 분리한다. 내부 토큰은 외부 Binder 호출자 인증을 대신하지 않는다.

2. 실제 Runtime와 서비스 생명주기

생성·시작 대상은 Runtime → State → Evidence → Policy → Resource → Capability → Task다. 각 서비스는 같은 ServiceLifecycleSupervisor를 사용하고 종료는 역순이다. State·Policy 등 의존 서비스가 준비되지 않으면 새 자원 확보와 작업 접수를 차단한다. 복구 후에도 예전 세대의 토큰·준비 상태를 새 서비스에 재사용하지 않는다.

여기서 READY는 해당 내부 서비스가 요청을 처리할 준비가 됐음을 뜻한다. 카메라가 사용 가능하다거나 모든 기능의 제공자가 연결됐다는 뜻이 아니다. 기본 Capability 목록은 비어 있으며 자원은 UNVERIFIED에서 시작한다.

3. 공유 자원의 상태와 소유권

상태 뜻 새 확보
UNVERIFIED 장치 상태 미확인. 시작 직후 또는 반환 직후 거부
FREE 현재 세대와 버전의 신뢰된 관측으로 사용 가능 확인 확보 시 다시 검사
HELD 특정 소유자·요청의 토큰으로 독점 확보 다른 소유자는 거부
RECOVERY_REQUIRED 소유자 장애 등으로 정리·복구 확인이 필요 거부

관리하는 자원은 movement_base, camera, foreground_display, external_app_session, security_session, tts_playback이며 ResourceId로 고정한다. 요청한 여러 자원은 전부 확보하거나 하나도 확보하지 않는다. 같은 소유자·요청 ID·자원 집합의 재요청만 같은 토큰으로 멱등 처리한다.

소유자는 도메인 이름 문자열이나 호출자가 적어 넣은 세대 번호만으로 인정하지 않는다. ResourceManagerService.createOwner(...)가 같은 생명주기 감독자의 실제 READY 상태와 서비스 세대, Resource의 현재 세대를 묶어 발급한다. 도메인이 재시작하면 새 소유 식별을 받아야 한다. 소유 서비스가 실패하거나 세대가 바뀐 기존 점유는 다음 자원 연산에서 복구 필요로 차단한다. 이는 장애를 감지하는 별도 장치 감시기가 있다는 뜻은 아니다.

정확한 소유 토큰을 반환해도 HELD → UNVERIFIED다. 반환은 물리 정지 증거가 아니다. 다시 FREE로 만들려면 반환 이후의 새 관측이 필요하다. 과거 FREE 관측이나 이전 Runtime의 토큰으로 새 소유권을 바꿀 수 없다. 자동 만료·강제 선점·자동 재실행은 이번 구현에 없다.

예를 들어 카메라 사용 작업을 취소했다고 해서 다음 영상 작업을 즉시 시작하면 안 된다. 취소 요청, 작업 상태 전이, 자원 반환, 실제 카메라 정리 확인을 각각 추적해야 한다.

코드에서 읽는 순서

내부 호출 입력과 역할 이 호출만으로 보장하지 않는 것
createOwner(...) 실제 서비스 ID와 논리 소유자 ID를 현재 세대에 연결 Binder 호출자의 권한 인증
captureReconciliationToken() → reconcile(...) 관측 시작 시점의 세대·변경 버전을 확인하고 장치 상태를 반영 전달된 관측 내용 자체가 참이라는 증명
acquire(...) 소유자·요청 ID·필요 자원 집합을 다시 검사하여 일괄 확보 Policy 승인이나 실제 장치 시작
release(...) 정확한 소유 토큰을 반환하고 미확인 상태로 이동 카메라·모터의 물리 정지
snapshot(...) / snapshots() 불변 상태를 읽고 오래된 소유 세대를 차단 미래 시점의 자원 확보 성공

관측 토큰은 현재 Resource 전체의 변경 버전을 사용한다. 다른 자원이 바뀌어도 과거 관측을 거부할 수 있는 보수적인 방식이다. 거부되면 최신 관측을 다시 받아야 하며, 이전 available=true 값에 새 토큰만 붙여 재전송하면 안 된다.

4. Capability가 대답하는 질문

가용성 조회는 실행 승인이 아니다. 기능 명세의 존재와 지금 사용 가능한지는 별개다. 등록 여부, 제공 도메인의 준비 상태, 제공자의 연결 상태, 필요한 자원의 현재 상태를 확인한다. 미등록·미연결·미준비·미확인·점유·복구 필요를 구분하며 조회만으로 자원을 잡지 않는다. 다만 내부 Resource 상태 조회는 오래된 소유 서비스 세대를 발견하면 기존 점유를 RECOVERY_REQUIRED로 차단할 수 있다. 조회가 확보·반환·정책 승인을 하지 않는다는 뜻이지, 오래된 상태를 그대로 유지하는 순수 읽기라는 뜻은 아니다. 충돌하는 동일 ID 등록은 거부하고 제공 도메인의 세대가 바뀌면 이전 준비 정보를 사용하지 않는다.

명세에는 기능 ID·소유 서비스·필요 자원을 기록한다. 제공자 준비 상태는 DISCONNECTED(미연결), NOT_READY(연결됐으나 미준비), READY로 별도 관리한다. 준비 상태 갱신에 사용하는 토큰은 Capability가 소유 서비스의 실제 READY 세대를 확인해 발급한다. 도메인 또는 Capability가 재시작한 뒤에는 이전 토큰을 거부한다. 이는 서비스 생명주기 세대 보호이며, 같은 세대 안에서 발생하는 장치 연결별 콜백 순서까지 자동으로 판별하는 계약은 아니다. 실제 제공자 어댑터의 연결·관측 키 보존은 후속 연결에서 검증한다.

등록 목록은 기본 128개로 제한하며, 정확히 같은 명세 재등록은 멱등 처리한다. 동일 ID의 다른 명세와 제한 초과는 각각 명시적인 등록 결과로 거부한다.

실제 실행 경로는 추후 Task 접수 → Policy 검사 → Resource 확보 → 도메인 실행기로 연결해야 한다. 이번 Task Runtime 등록은 그 자동 실행 경로를 추가한 것이 아니다.

5. MR6에서 보존하는 행동과 변경하는 기본값

MR6 원본은 task_manager의 d1d8dfbc4c807a32990f4350cf09c49f159f5848을 읽는다. streaming·vitalSign·security의 카메라·주행부 충돌과 기존 보안 세션의 중지·일시정지·재개 규칙을 형식화된 입력의 특성 테스트로 보존한다. 기존 세션 제어는 신규 자원 확보와 구분한다. 이 예외가 다른 소유자의 자원 토큰을 해제할 권한을 주는 것은 아니다.

접수 정책의 순서는 기존 보안 세션 제어 우회 → 필수·명시 자원 요구의 합집합 검사 → 제품 도메인별 진입 충돌 검사다. 보안 정지에 security_session 요구가 붙은 경우도 우회하고, 일반 화면 요청에 camera 요구가 붙으면 해당 요구를 검사한다.

원본의 알 수 없는 스냅샷 허용 동작과 새 Resource의 UNVERIFIED 차단은 서로 다른 경계다. 새 자원 서비스를 원본 정책의 무조건적인 대체물로 취급하지 않는다. CPU·RAM·열 부하 정책과 AMR·Cleaning의 전체 실행 이관은 별도 후속 단계다.

6. 검증 범위와 남은 연결

검증 결과는 진행 현황의 최신 항목을 기준으로 본다. 2026-09-08 전체 재실행에서 서버 JVM 236개·SDK JVM 37개가 실패·오류·건너뜀 없이 통과했고, release Java 컴파일과 폴더·레이어 검사 및 각 회귀 검사도 통과했다. 자원 원자성·소유권·세대 차단, 기능 조회의 부작용 없음, 실제 Runtime 조립과 역순 종료를 JVM에서 검증한다. MR6 원본 250개 테스트 실행 기록은 현재 MR7 서버/SDK 검사 수와 별도다.

이후 내부 전달 어댑터 작업은 제공자 연결·TTS 전달에서 별도로 추적한다. 남은 제품 연결은 장치 상태 동기화, 생산자의 실행 키 보존, TTS의 BUSY_RETRY 호스트 재시도 연동, 도메인별 완료·정지 확인, Android 시작 호스트와 AOSP 제품 포함이다. APK 설치·실기기 경합·스피커 출력·물리 정지는 아직 완료로 주장하지 않는다.

다음 연결 순서

  1. 도메인별 장치 관측을 Resource의 새 관측 토큰에 연결한다. 재시작·반환 이후에는 실제 장치 상태를 다시 읽는다.
  2. 제공자 연결·해제와 서비스 세대를 Capability에 전달한다. 지원 목록이 있다는 이유만으로 READY를 넣지 않는다.
  3. Task 실행 경로에서 Policy 판단과 Resource 확보를 별도로 거친다. 실패 시 사유를 반환하고 작업·시도 키를 보존한다.
  4. 도메인 실행기의 완료·정리 관측을 Task에 연결한다. TTS의 재시도 응답 전달과 AMR·Cleaning의 원본 완료 조건을 각각 검증한다.
  5. 이 내부 계약을 Android 시작 호스트·권한 경계·제품 빌드에 연결한 뒤 실기기 시작·중지·장애 복구를 확인한다.

이 순서는 다음 구현의 의존 관계이며, 위 단계 전체가 이미 연결됐다는 완료 목록이 아니다.

Connections

Keyboard shortcuts

⌘K / Ctrl+KOpen command palette
/Focus search
g hGo to home
g pGo to projects
g sGo to sessions
j / kNext / prev row (tables)
?Show this help
EscClose dialogs

Structured queries

Mix key:value filters with free text in the palette:

type:sessionOnly session pages
project:llm-wikiFilter by project name (substring)
model:claudeFilter by model name (substring)
date:>2026-03-01Sessions after a date
date:<2026-04-01Sessions before a date
tags:rustPages mentioning a tag/topic
sort:dateSort results by date (newest first)

Example: type:session project:llm-wiki date:>2026-04 sort:date