SoC TaskManager Vendor Implementation Workbook
이 장은 업체가 실제로 구현해야 할 작업을 deliverable 단위로 정리한다.
업체 설명 순서는 Before/After Change Model로 구조 변화를 설명한 뒤, 이 workbook에서 실제 구현/검증 항목을 확인하는 방식이 좋다.
업체 구현 목표
Multi-source ingress
-> Source trace normalization
TaskManager API
-> Bundle validation
-> Policy/admission
-> Queue/workflow
-> Executor binding
-> Domain execution
-> Event callback
-> Reason contract
-> Planning context
-> Test evidence
필수 API
| API | 필수 여부 | 설명 |
|---|---|---|
submitTask |
필수 | 단일 task 등록 |
submitWorkflow |
필수 | 순차/병렬 workflow 등록 |
getTaskStatus |
필수 | task 상세 조회 |
listTasks |
필수 | task 목록 조회 |
getQueueStatus |
필수 | queue 상태 조회 |
cancelTask |
필수 | task 취소 |
getTaskManagerStatus |
필수 | manager 상태 조회 |
getDevicePlanningContext |
필수 | 상위 planner/server가 실행 전 참고할 기기 상태 snapshot |
classifyTaskIngress |
권장 | method 성격 분류 |
updateTaskProgress |
권장 | 외부 domain executor 진행률 반영 |
필수 ingress source
| Source | 필수 여부 | 설명 |
|---|---|---|
cloud_a2a |
필수 | Cloud LLM planner가 만든 task/workflow |
mqtt_server |
필수 | 서버/MQTT 명령으로 내려온 task/workflow |
app_remote |
필수 | 앱/리모컨/외부 UI에서 들어온 제어 |
local_voice |
권장 | 온디바이스 로컬 음성 parser/bridge 결과 |
internal_schedule |
권장 | 예약/자동화/보호 정책이 만든 system task |
Sample 1: Cloud A2A 단일 task
method = submitTask
source = cloud_a2a
taskMethod = setAirCleanerOperation
cloud_workflow_id = wf_20260623_001
cloud_step_id = step_2
cloud_plan_id = plan_001
action = 1
mode = 2
speed = 2
strictValidation = true
기대 동작:
TaskManager가 cleaning queue에 task 등록
-> setAirCleanerOperation executor 실행
-> onTaskEvent RUNNING/COMPLETED 또는 FAILED
-> event에 cloud_workflow_id/cloud_step_id 보존
Sample 2: MQTT 서버 단일 task
method = submitTask
source = mqtt_server
external_command_id = cmd_98765
mqtt_message_id = mqtt_abc_001
taskMethod = setMoveTo
positionName = 거실
strictValidation = true
기대 동작:
TaskManager가 movement queue에 task 등록
-> 이동 executor 실행
-> onTaskEvent에 external_command_id/mqtt_message_id 보존
-> Cloud replan이 아니라 서버 ack/status/report 대상으로 처리
Sample 3: 복합 workflow
method = submitWorkflow
source = cloud_a2a
workflowName = living_room_clean_then_bedroom_move
cloud_workflow_id = wf_multi_001
subTasks = [
{ taskMethod = setMoveTo, positionName = 거실 },
{ taskMethod = setAirCleanerOperation, action = 1, mode = 2, speed = 2 },
{ taskMethod = setMoveTo, positionName = 안방 }
]
기대 event:
WORKFLOW_STEP_STARTED currentStepIndex=0 currentStepMethod=setMoveTo
WORKFLOW_STEP_COMPLETED currentStepIndex=0 currentStepMethod=setMoveTo
WORKFLOW_STEP_STARTED currentStepIndex=1 currentStepMethod=setAirCleanerOperation
WORKFLOW_STEP_COMPLETED currentStepIndex=1 currentStepMethod=setAirCleanerOperation
WORKFLOW_STEP_STARTED currentStepIndex=2 currentStepMethod=setMoveTo
WORKFLOW_STEP_COMPLETED currentStepIndex=2 currentStepMethod=setMoveTo
WORKFLOW_COMPLETED 또는 COMPLETED
필수 event payload
method = "onTaskEvent"
eventName
taskId / task_id
taskMethod / task_method
taskState / status
executionMode
source
origin
caller
external_command_id / externalCommandId
mqtt_message_id / mqttMessageId
app_request_id / appRequestId
schedule_id / scheduleId
progress
stage
message
currentStepIndex
currentStepMethod
workflowName
taskErrorCode
taskReason
reason_code / reasonCode
reason_params / reasonParams
recoverability
suggested_action / suggestedAction
requires_cloud_decision / requiresCloudDecision
cloud_workflow_id / cloudWorkflowId
cloud_step_id / cloudStepId
cloud_plan_id / cloudPlanId
cloud_output_key / cloudOutputKey
실패 event sample
method = onTaskEvent
eventName = FAILED
taskId = task_17
taskMethod = setMoveTo
taskState = FAILED
source = mqtt_server
external_command_id = cmd_98765
mqtt_message_id = mqtt_abc_001
reason_code = PATH_BLOCKED
reason_params = {
target_location_name = 거실
}
recoverability = user_action_required
suggested_action = ASK_USER_CLEAR_PATH
requires_cloud_decision = true
source별 해석:
| source | 처리 |
|---|---|
cloud_a2a |
필요 시 planner replan 또는 사용자 확인 질문 |
mqtt_server |
서버에 실패 report, 필요 시 앱 push/user notification |
app_remote |
앱 UI에 실패 상태와 조치 안내 |
internal_schedule |
schedule retry/cancel 정책 |
필수 reason code
TIMEOUT
INTERRUPTED
USER_CANCELLED
DEVICE_BUSY
RESOURCE_LIMIT
STATE_CONDITION_FAILED
CAPABILITY_UNAVAILABLE
PATH_BLOCKED
ROOM_NOT_FOUND
LOW_BATTERY
SENSOR_ERROR
UNKNOWN
업체 제출 evidence
| Evidence | 필수 여부 | 설명 |
|---|---|---|
| API bundle sample | 필수 | submitTask, submitWorkflow, onTaskEvent 정상/실패 sample |
| Unit test result | 필수 | TaskManager core, reason, validation |
| Integration test result | 필수 | workflow, queue, executor binding |
| Instrumented test result | 필수 | Android runtime Bundle/callback |
| Logcat trace | 필수 | 실제 callback 흐름 |
| Failure case trace | 필수 | PATH_BLOCKED, ROOM_NOT_FOUND, LOW_BATTERY 등 |
| Diff summary | 필수 | 원본 대비 수정 파일/이유 |
| Open questions | 필수 | 미확정 domain method, state, reason |
Diff summary 제출 양식
업체는 원본 대비 변경 내역을 아래 형태로 제출한다.
| 파일 | 변경 유형 | 변경 이유 | 테스트 |
|---|---|---|---|
MainApi.java |
hook 추가 | TaskManager API 선처리 | legacy passthrough test |
TaskManager.java |
신규/수정 | task/workflow lifecycle | unit/integration |
TaskPolicyRegistry.java |
정책 추가 | method별 queue/mode/timeout | policy unit |
TaskExecutorBootstrap.java |
executor binding | domain 연결 | executor integration |
DevicePlanningContextProvider.java |
상태 snapshot | 실행 전 context 제공 | context sample |
업체 구현 범위 체크리스트
| ID | 항목 | 완료 기준 |
|---|---|---|
| TM-01 | MainApi hook | TaskManager API는 선처리, legacy method는 기존 실행 |
| TM-02 | submitTask | accepted/rejected/result payload 확인 |
| TM-03 | submitWorkflow | subTask 순서와 step event 확인 |
| TM-04 | queue policy | movement/cleaning/ai/settings/update queue 분리 |
| TM-05 | validation | strictValidation에서 필수 slot 누락 차단 |
| TM-06 | executor binding | skeleton이 아닌 실제 domain 호출 연결 |
| TM-07 | reason mapping | 대표 실패 reason code mapping |
| TM-08 | planning context | battery/map/location/cleaning/movement/task_manager/capability snapshot |
| TM-09 | source trace | Cloud/MQTT/App/예약 id가 event까지 보존 |
| TM-10 | logcat evidence | 실제 기기 또는 instrumented trace 제출 |
업체에게 전달할 작업 요청서 형태
아래 내용을 그대로 업체 작업 요청 범위로 사용할 수 있다.
요청 1: TaskManager Hook 연결
MainApi.executeMethod(...) 진입 시 TaskManager.handleControlMethod(...)를 먼저 호출한다.
TaskManager가 처리한 method는 즉시 return한다.
처리하지 않은 method는 기존 executeMethodInternal(...) 경로로 유지한다.
완료 증거:
submitTask가 TaskManager에서 처리되는 log- 기존 legacy method가 TaskManager 미처리 후 정상 동작하는 log
요청 2: Multi-source Task API 구현
Cloud A2A, MQTT server, App/Remote, Local Voice, Internal Schedule source를 구분한다.
모든 source는 submitTask/submitWorkflow API를 공통 사용한다.
source별 trace id는 onTaskEvent까지 보존한다.
완료 증거:
cloud_workflow_id보존 samplemqtt_message_id보존 sampleapp_request_id보존 sample
요청 3: Workflow와 Step Event 구현
submitWorkflow는 subTasks를 순차 실행한다.
각 step마다 currentStepIndex/currentStepMethod를 event에 포함한다.
step 실패 시 parent workflow 실패 event에 reason_code를 포함한다.
완료 증거:
- 3-step workflow 정상 trace
- 2번째 step 실패 trace
subTaskStates,subTaskResultssample
요청 4: Domain Executor Adapter 구현
TaskExecutorRegistry에 movement, cleaning, LLM/TTS, IoT, update executor를 등록한다.
executor는 기존 domain handler를 호출하는 adapter로 구현한다.
domain business logic은 TaskManager에 중복 구현하지 않는다.
완료 증거:
setMoveTo실제 이동 domain 연결 tracesetAirCleanerOperation기존 청정 handler 연결 trace- cancel/stop method 연결 trace
요청 5: Reason/Context Contract 구현
domain error를 표준 reason_code로 변환한다.
reason_params, recoverability, suggested_action을 event에 포함한다.
getDevicePlanningContext는 실행 전 판단에 필요한 device snapshot을 제공한다.
완료 증거:
PATH_BLOCKED,ROOM_NOT_FOUND,LOW_BATTERY,DEVICE_BUSYsample- battery/map/location/cleaning/movement/task_manager/capabilities context sample
업체 Q&A 예상 질문
| 질문 | 답변 |
|---|---|
기존 setAirCleanerOperation을 없애야 하나 |
아니다. 외부 source가 직접 호출하지 않고 TaskManager task로 감싼 뒤 기존 handler를 호출한다. |
| MQTT 명령도 Cloud A2A를 거쳐야 하나 | 아니다. MQTT source도 DeviceAgent TaskManager API로 직접 task 등록 가능해야 한다. |
COMPLETED event를 Cloud로 올려야 하나 |
Cloud source라면 상태 relay는 가능하지만 LLM 재판단은 필요 없다. MQTT/App은 ack/status/report로 처리한다. |
| 실패 reason은 문자열이면 되나 | 안 된다. 표준 reason_code와 reason_params가 필요하다. |
| workflow 등록 시 모든 조건을 미리 확인해야 하나 | 아니다. 필수 slot만 사전 검증하고, runtime 조건은 각 step 실행 시점에 확인한다. |
| get/status 조회도 task queue에 넣나 | 대부분 DIRECT query 또는 planning context로 처리한다. |
인수 기준
PASS 조건:
submitTaskaccepted 후 반드시 terminal event가 온다.submitWorkflow는 subtask 순서와currentStepIndex를 event에 반영한다.- 실패 event에는
reason_code와requires_cloud_decision이 들어간다. - source trace field가 event까지 보존된다.
- Cloud source는
cloud_workflow_id계열 trace를 보존한다. - MQTT source는
external_command_id또는mqtt_message_id계열 trace를 보존한다. getDevicePlanningContext가 Cloud planner 또는 서버 정책 판단 전에 호출 가능한 snapshot을 제공한다.- unit/integration/instrumented/logcat evidence가 제출된다.
FAIL 조건:
- method만 실행하고 event를 보내지 않는다.
- 실패 이유가 자유 자연어 문자열뿐이다.
- queue/workflow 없이 복합명령을 즉시 함수 호출로만 처리한다.
- source trace field가 사라진다.
- Cloud LLM 전용으로만 구현되어 MQTT/App/예약 source가 같은 TaskManager API를 타지 못한다.
- TaskManager API는 있으나 실제 domain executor와 연결되지 않는다.