# Milestone: 공통 Agent Task Runtime과 Desktop Agent

## 위치

- Roadmap: [ROADMAP.md](../../../../ROADMAP.md)
- Phase: [PHASE.md](../../../../phase/automation-runtime-bridge/PHASE.md)

## 목표

현재 Python 기반 스킬이 모델 호출로 수행하는 Agent Task 감시·선택·실행·복구 루프를 프로덕션 Go runtime으로 이전하고, Node와 독립 Desktop Agent가 동일한 공통 CLI Provider 및 AgentTaskManager 구현을 사용하게 한다.
기능을 축소한 초기판이 아니라 현재 마일스톤, 동작 중인 Python dispatcher, Node CLI runtime에서 확인되는 실행·quota·오류·관측 동작을 동등성 기준으로 삼으며, Desktop Agent는 Edge 없이 app-owned 설정과 프로젝트별 override로 이미 agent-ops 작업 체계를 가진 여러 workspace의 마일스톤을 순차 실행한다.

## 상태

[폐기]

## 폐기 사유

- 공통 runtime, Flutter Desktop과 배포를 한 번에 구현하는 결합 범위는 더 이상 실행하지 않는다.
- 공통 runtime·자동 실행 loop·개인 장비용 agent binary는 [IOP Agent CLI Runtime](../../../../phase/automation-runtime-bridge/milestones/iop-agent-cli-runtime.md), local proto-socket UI는 [Flutter Desktop Control UI](../../../../phase/automation-runtime-bridge/milestones/flutter-desktop-control-ui.md)와 [Unity 3D Desktop Character](../../../../phase/automation-runtime-bridge/milestones/unity-3d-desktop-character.md)로 분할·대체됐다.
- 독립적으로 남은 구현 범위가 없으므로 이 문서와 SDD는 이관 근거만 보존하고 archive한다.

## 승격 조건

- 없음

## 구현 잠금

- 상태: 잠금
- SDD: 필요
- SDD 문서: [SDD.md](../../../sdd/automation-runtime-bridge/shared-agent-task-runtime-desktop-agent/SDD.md)
- SDD 사유: 공통 runtime 추출, Node/Desktop host 경계, config schema, provider process lifecycle, 상태 복구, 자동 실행, 실제 로그인 환경 smoke를 함께 변경한다.
- 잠금 해제 조건: 아래 체크리스트
  - [ ] SDD 잠금이 해제되어 있다.
  - [ ] SDD 사용자 리뷰가 없거나 승인·해결되었다.
  - [ ] Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다.
  - [ ] Evidence Map이 완료 시 `Roadmap Completion`과 최종 검증 evidence로 검증 가능하게 연결되어 있다.
- 결정 필요: 폐기로 종결. [D01 범위 이관 기록](../../../sdd/automation-runtime-bridge/shared-agent-task-runtime-desktop-agent/user_review_0.log)은 [Flutter Desktop Control UI](../../../../phase/automation-runtime-bridge/milestones/flutter-desktop-control-ui.md) 범위이며 IOP Agent CLI 결정 항목이 아니다.

## 범위

- `packages/go` 아래 공통 runtime이 CLI Provider 실행, emitter/stream 해석, session/resume, quota 상태, 오류 분류, process 관측과 AgentTaskManager를 단일 구현으로 소유하고 Node와 Desktop Agent가 host adapter로 소비한다.
- Node 내부의 기존 CLI provider 구현을 공통 runtime으로 이동해 Node에는 현재 `RunRequest`/`RunEvent`, config, command/status 경계를 연결하는 얇은 bridge만 남긴다. Node와 Desktop에 provider를 중복 선언하거나 복사하지 않는다.
- Python dispatcher와 selector는 실행 의존성이 아니라 동작·정책·관측 오류의 참조 evidence로만 사용한다. 최종 runtime은 Python process나 monitoring skill 없이 동작한다.
- 등록 project의 agent-ops가 Milestone·Plan·Code Review skill/rule과 작업 파일 의미를 소유한다. 공통 runtime은 이를 복사·내장하거나 IOP 소유 skill로 재정의하지 않고, 이미 생성된 project-local 작업 상태와 선택된 작업 지시를 실행 입력으로 소비한다. 실행 감시, heartbeat, 오류 판정과 다음 agent 호출은 AgentTaskManager runtime이 소유한다.
- 공통 runtime의 project workflow adapter는 project-owned artifact contract에 따라 actual completing provider/model과 persisted route identity, active PLAN/CODE_REVIEW pair, task/plan/tag identity를 검증하고, active CODE_REVIEW 파일의 worker 소유 필수 섹션·미작성 placeholder·구현 체크리스트 완료 여부를 versioned 정규식/구조 matcher 규칙으로 판정한다. 이 submission gate는 Pi 전용이 아니라 declared worker provider/model, local/cloud execution class와 one-shot/persistent 방식 전체에 동일하게 적용한다. USER_REVIEW는 파일 존재만으로 멈추지 않고 project contract의 상태·유형·대상·차단 근거·미해결 결정·재개 조건이 실제 다음 단계를 막을 때만 stop state로 정규화하며 불완전·충돌 문서는 task-state error로 표면화한다. selfcheck는 completing route policy가 요구할 때만 같은 target으로 실행하고 새 route를 고르지 않는다. 모델로 내용을 재평가하거나 skill 원문을 내장하지 않고, 동일 matcher gate를 통과한 worker 결과만 공식 review에 넘긴다.
- Pi selfcheck process가 성공 종료한 뒤에도 동일 matcher가 CODE_REVIEW 미완성을 반환하면 `selfcheck_done` 또는 review-ready로 전환하지 않는다. runtime은 완료된 selfcheck attempt의 native session/context locator를 보존하고 matcher snapshot, incomplete ordinal과 prompt dispatch intent를 먼저 durable하게 기록한 뒤 새 route·새 session·quota probe 없이 같은 Pi selfcheck context를 resume해 `The code review file has not been filled in. Fill in every missing implementation-owned field in {CODE_REVIEW_PATH}. Do not perform the official review.`를 영문으로 보낸 다음 matcher를 다시 실행한다. 각 ordinal의 정상 전송은 exactly-once이고 host restart에서는 기록된 live/terminal attempt를 먼저 reconcile하며 delivery outcome이 불명확하면 같은 prompt를 무작정 재전송하지 않고 task-local blocker로 표면화한다. matcher 통과 시에만 `selfcheck_done`, repair `validated`, pending intent 제거 및 official-review work-ready 전이를 하나의 checkpoint commit으로 확정한다. 이 evidence repair는 기존 selfcheck incomplete budget에 누적하며 context/task/plan/tag/review identity가 없거나 불일치하면 fresh context로 대체하지 않고 task-local error/blocker로 표면화한다.
- 공식 review lifecycle은 review artifact가 provider에 노출되는지 preflight하고 정확한 verdict section, 새 review artifact와 filesystem progress, USER_REVIEW/후속 plan/완료 archive 상태를 함께 판정한다. no-progress fingerprint는 plan이 선언한 write-set source와 review/finding artifact만 사용하고 runtime 소유 WORK_LOG/heartbeat 갱신은 진척으로 세지 않는다. review agent의 금지된 제어 동작, 무변경 반복, 잘못된 PASS/WARN/FAIL finalization과 verdict 이후 crash/restart 복구 실패는 typed blocker/error로 표면화한다.
- 일반 사용자 요청을 direct/Plan/Milestone으로 분류하고 IOP가 소유한 작업 의미로 사용자 agent에 합성 tool call을 주입해 작업 파일을 만드는 기능은 [에이전트 작업 루프 오케스트레이션 MVP](../../../../phase/automation-runtime-bridge/milestones/agent-workflow-loop-orchestration-mvp.md)의 별도 책임이다. 이 runtime은 그 오케스트레이션의 공통 실행 기반이 될 수 있지만 진입 요청 라우터나 Plan/Milestone skill 소유자가 되지 않는다.
- 동등성 기준은 구현 계획 시점의 [Agent Task 동적 실행 Target Selector](agent-task-runtime-target-selector.md), 관련 active `WORK_LOG.md`, Python dispatcher/selector, Node CLI runtime과 Go usage checker를 함께 대조해 고정한다. 충돌 시 Milestone/SDD, 현재 agent-contract, 참조 구현 순으로 우선한다.
- 사용자 환경에 선언된 provider가 실제 실행 대상이다. runtime은 현재 Node와 선행 Milestone이 지원하는 one-shot/persistent CLI, Codex, Claude, Antigravity/Agy, OpenCode, Pi 등 provider profile과 emitter family를 공통 catalog에서 해석하며 임의의 축소된 고정 목록만 지원하지 않는다.
- 외부 표기는 `codex/gpt-5.6-sol-xhigh`처럼 provider/model/profile을 사용자가 이해할 수 있는 공식 계열 이름으로 표현한다. Desktop config/event/UI는 generic `cli` adapter를 주 식별자로 노출하지 않고, 내부 Node bridge만 기존 `adapter + target`과 안정된 provider/profile id를 유지한다.
- provider 인증과 credential은 각 CLI가 소유한다. 앱은 binary/version/authenticated readiness를 조회·검증할 뿐 로그인, token 저장, 계정 전환을 관리하지 않는다.
- app-owned YAML config tree가 provider catalog, 기본 정책과 명시 등록 project별 custom override를 모두 소유한다. workspace 안의 YAML은 runtime 설정 권위가 아니며, project override는 app registry id 아래에서 scalar/map을 key 기준으로 덮어쓰고 순서가 의미인 selection rule array는 전체 교체한다.
- 선택 엔진은 기본 provider와 조건부 rule array를 평가해 정확히 하나의 provider/model을 반환한다. 시간, quota/token 잔량, agent/stage/lane/grade, capability, 알려진 실패 상태를 조건으로 사용할 수 있고 겹치는 조건은 선언 순서가 우선한다. Node와 Desktop은 공통 evaluator를 사용하되 서로 다른 정책 문서를 주입할 수 있다.
- 외부 선택 결과는 provider/model 하나만 노출하되 내부 persisted route plan은 최초 ordered candidate 집합, candidate별 eligibility/rejection reason, 적용 rule/priority, used history와 transition을 `task/plan/tag` 세대에 함께 고정한다. persisted schema, selected/candidate/used-history identity 또는 stage/work-unit pin이 손상·불일치하면 현재 정책으로 조용히 재선택하지 않고 명시 오류로 중단한다.
- 선행 selector Milestone의 KST 경계, G01~G10 worker matrix, 공식 review 고정 route, 단방향 failover와 used-target bounce 금지 및 completing-target 기반 selfcheck를 Node 호환 policy fixture로 이식한다.
- Python dispatcher의 stage별 10회 자동 실패 예산, local selfcheck incomplete·review no-progress 10회 blocker, work-unit/candidate별 unknown 1회 admission, target/write-set dispatch barrier 부재, tool phase 밖 3분 silence inspection과 새 tool/file/state 변화 없는 동일 normalized chunk 3회 반복의 observation-only 처리, contract-valid USER_REVIEW를 Node 호환 behavior fixture로 이식한다. 이 fixture들은 Node 기본 호환 입력이며 공통 core에 모델명·예산·threshold를 하드코딩하거나 Desktop/project 정책을 고정하지 않는다.
- config file watcher가 revision을 검증하며, 실행 중인 agent는 시작 시점 snapshot으로 끝까지 수행한다. 유효한 변경은 다음 agent 호출부터 적용하고 잘못된 변경은 명시적 config error로 표면화하며 영향을 받는 새 dispatch를 중단한다.
- quota/usage는 현재 Go usage checker와 Python의 검증된 해석을 기준으로 `available | exhausted | unknown | not_applicable`과 관측 근거를 제공한다. 같은 provider credential/profile의 quota는 app 전체 project가 공유하고 동일 admission batch는 같은 immutable snapshot을 재사용한다. probe 재사용 identity는 credential/profile, adapter, target, status command/profile과 ordered required-cap set을 모두 포함하며, 최초 worker admission에서 필요한 후보만 조회한다. local-first 선택 뒤의 cloud 후보, persisted resume, selfcheck와 공식 review를 선행 probe하지 않고 조회 오류는 해당 provider key에서 `unknown`으로 격리해 다른 provider/project key로 확산시키지 않는다. unknown 후보의 1회 admission 사용 이력은 work-unit/candidate에 durable하게 귀속해 batch 교체나 host 재시작으로 초기화하지 않는다.
- 앱은 workspace의 소유자가 아니라 관리 주체다. 프로젝트는 명시 등록하며 app-owned provider/global 설정과 project override를 관리하고, `agent-task`, `agent-roadmap`, `priority-queue.md`, `WORK_LOG.md`와 project-local log가 작업 상태의 source of truth가 된다.
- 자동 실행은 기본 on이며 사용자가 언제든 중단할 수 있다. 등록 프로젝트의 기존 agent-ops 작업 상태에 남은 agent-task가 있으면 먼저 이어서 처리하고, 없으면 기존 agent-roadmap/priority-queue.md의 최상위 ready Milestone을 선택해 project-owned plan/review/완료 지시를 순차 실행한다. 일반 사용자 요청에서 새 Milestone/Plan을 분류·생성하는 진입 동작은 수행하지 않는다.
- AgentTaskManager는 최초 선택, persisted resume, dependency와 blocker 상태를 실제 실행과 같은 판정기로 조회하는 read-only preview를 제공한다. preview는 checkpoint, route/history, failure budget, blocker/recovery intent, quota cache와 project 파일을 만들거나 바꾸지 않고 provider process도 시작하지 않으며 여러 ready task의 결과를 task-local로 격리한다.
- 서로 다른 등록 project/workspace instance는 병렬 실행할 수 있다. 같은 저장소를 clone/worktree/branch로 여러 경로에 둔 경우도 canonical workspace instance를 분리해 동시에 관리하며, 한 instance 안에서는 dependency와 work-unit route pin을 따른다.
- canonical workspace instance마다 invocation 권한을 가진 AgentTaskManager는 하나뿐이다. manager lease와 schema-versioned checkpoint는 원자적으로 갱신하고 충돌·손상·판독 불가 상태를 오류로 표면화하며, 재시작 시 execution/attempt identity와 process start identity로 살아 있는 child를 재사용·관측해 중복 호출하지 않는다. scheduler 자체 오류가 발생해도 이미 실행 중인 독립 agent를 즉시 취소하지 않고 종료까지 drain하거나 다음 host가 명시적으로 인계한다.
- project workflow adapter는 단일 active PLAN/CODE_REVIEW pair, contract-valid USER_REVIEW stop state, task/plan/tag identity와 split dependency의 정확한 완료 근거를 실행 전 판정한다. 한 work unit의 invalid state·blocker·review preflight 실패는 dependency-independent sibling과 다른 project의 진행을 막지 않으며, scheduler는 dependency-ready work set을 같은 target이나 overlapping/unknown plan write-set을 이유로 직렬화하지 않고 계속 소진하며 동일 work-unit 중복 attempt만 막는다.
- Gemini를 실행하는 Agy adapter를 포함한 각 provider codec은 raw stream/status에서 provider별 강한 quota evidence를 판정해 normalized failure를 내보낸다. AgentTaskManager는 provider 문자열을 다시 해석하지 않고 이 typed result만 작업 전이 입력으로 사용하며 generic·불완전 evidence는 unknown/generic 오류로 표면화한다.
- 실행 중 provider-confirmed quota exhaustion은 admission snapshot을 복제·변조하지 않고 base snapshot을 참조하는 별도 runtime quota observation으로 기록한다. 현재 work unit은 이 observation을 즉시 사용하고 app quota service는 같은 credential/profile key를 무효화·갱신해 후속 admission에 반영하되, 이미 admission된 sibling route는 바꾸지 않는다.
- AgentTaskManager는 같은 work-unit id, persisted candidate 순서와 사용 이력을 보존해 다음 unused eligible target으로 failover하고 session locator와 logical context를 이전한다. 대체 target이 없으면 해당 work unit만 typed blocker로 두며, 사용자 재시도 또는 auto-run policy가 허용한 quota 상태 갱신에서도 새 initial route를 계산하지 않고 persisted route 안에서만 복구한다. 복구 evidence는 execution/attempt, stage/role, terminal failure class, selected route와 readable locator의 workspace/task/PLAN/raw/normalized artifact identity가 모두 현재 blocker와 일치할 때만 승인하고, validated context handoff는 decision/history/quota와 하나의 fault-atomic transition으로 저장한다.
- logical continuation은 route commit과 첫 invocation 사이 restart에도 durable pending handoff 또는 attempt locator에서 복원되어야 한다. 새 attempt locator에 source context와 handoff identity가 durable하게 기록된 뒤에만 pending handoff를 exactly once 소비하며, validation·selection·context 준비·checkpoint save 어느 단계가 실패해도 key 존재 여부를 포함한 blocked work unit의 exact pre-state와 정상 sibling 전체 state를 보존한다.
- 실패 예산은 work-unit/stage identity에 귀속해 자동 target 변경·failover·host 재시작을 지나도 유지하고 해당 stage의 검증된 성공에서 초기화한다. 명시적 identity-matched `retry_blocked`만 blocker와 해당 stage budget을 초기화하며 persisted route/history는 보존한다. worker와 review budget은 서로 독립이고 failure count 자체를 새 route 선택 입력으로 사용하지 않는다. same-target retry는 선언된 bounded backoff를 따르고 stop/cancel에서 즉시 해제되며 restart가 이미 예정·수행한 retry를 중복 실행하지 않는다.
- 현재 Python에서 검증된 raw/normalized stream, heartbeat, PID/process-group, session locator, silence inspection, exact tool-call/result phase, cancellation, route pin, logical context transfer, failure budget, dependency drain, review-control 위반 감지와 알려진 provider 오류 예외를 공통 runtime 동등성 matrix에 흡수한다. 동일 normalized chunk의 연속 반복은 새 tool/file/state 변화가 없을 때 observation으로만 기록하고 그 신호만으로 종료·block·retry·failover하지 않는다. Python의 함수명·marker·state key는 계약으로 복사하지 않고 관측된 상태 전이와 불변 조건만 Go 타입·테스트로 옮긴다. 최종 parity audit는 한 work unit의 select→pin/resume→same-target recovery 또는 failover→quota/budget/review blocker→selfcheck/completion을 rule/candidate/reason/quota/transition evidence로 연결하고 stale Python monitoring 의존성과 정적 route/cap 문구를 검출한다.
- 오류는 모두 runtime event와 project log에 표면화한다. 알려진 오류만 선언된 policy에 따라 retry/failover하고, unknown 오류는 추정 복구하지 않고 해당 work unit을 명시적으로 중단한다.
- 프로젝트별 최소 관측 로그는 각 프로젝트의 `agent-log` 계열 경로에 보존하고 현재 수준보다 축소하지 않는다. provider/model 선택, quota snapshot, config revision, runtime build, process/session locator, stream/heartbeat, failure evidence, retry/failover, stop/completion을 동일 execution/attempt identity로 추적한다. task-group `WORK_LOG.md`는 `seq | time | loop | event | task | role | attempt | model | result | locator` 순서의 runtime-owned START/FINISH timeline이다. 각 attempt의 `loop`는 그 `task`의 현재 active PLAN/CODE_REVIEW pair가 향후 archive될 suffix 회차로 START 전에 checkpoint/ledger/locator에 고정한다. 같은 task에 `plan_*.log`와 `code_review_*.log`가 각각 0~10까지 있고 pair identity/count가 일치하면 current-pair attempt는 11이며, review가 실행 중 pair 11을 archive하고 follow-up pair 12를 만들더라도 그 attempt의 FINISH는 locator에 고정된 loop 11을 사용한다. 같은 pair의 worker/selfcheck/review retry·resume은 loop를 유지하고 `attempt`만 증가하며, follow-up pair가 생성된 뒤 시작하는 새 attempt부터 loop 12가 된다. 선행 task 완료로 2·3, 이어서 5·6처럼 dependency-ready frontier가 동적으로 확장되어도 하나의 active `WORK_LOG`를 유지하되 서로 다른 task 행은 각자의 loop를 기록한다. `work_log_N.log`의 N은 task-group timeline 자체의 archive 회차로 task별 loop와 독립이며 같은 task group의 모든 월별 exact archive suffix 최대값 다음 수(없으면 0)를 별도로 고정한다. `locator`는 pinned task loop와 native context/session id를 포함한 attempt 메타데이터의 권위 포인터이므로 `context_id`를 별도 `WORK_LOG` 컬럼으로 중복하지 않는다. runtime ledger와 project-owned 완료 archive를 재시작 후 대조하고, 동적으로 확장된 lineage의 모든 task에 유일한 valid `complete.log`가 있으며 ready/running/pending follow-up·blocker와 마지막 writer가 모두 없는 terminal closure에서만 `WORK_LOG.md`를 고정된 다음 `work_log_N.log`로 archive한 뒤 완료 attempt 임시 로그를 정리한다.
- Desktop Agent는 Go runtime host, YAML 운영 entry, app-owned registry/state와 Flutter macOS shell을 포함한다. UI 설정 화면은 scaffold만 두지만 설치 산출물에는 runtime binary, 기본 YAML과 Flutter macOS app wrapper가 함께 있어야 한다.
- Desktop Agent는 기본적으로 provider별 approval bypass를 사용하며 사용자 승인 flow를 추가하지 않는다. 자동 연결·실행은 설정으로 끌 수 있게 하되 최초 기본값은 켜짐이다.
- 단위·통합 fake provider 검증과 별도로 실제 로그인된 CLI 환경에서 provider discovery, 짧은 실행, stream, quota/status, cancel, 재호출을 확인하는 macOS smoke를 완료 근거로 남긴다.

## 기능

### Epic: [shared-core] 공통 Runtime과 Host 경계

Node와 Desktop Agent가 하나의 실행 구현을 공유하고 각 제품에는 host 책임만 남기는 기반을 만든다.

- [ ] [provider-runtime] 공통 Go runtime이 CLI process 실행, profile/renderer/emitter, stream/session, quota/status와 cancellation을 소유하고 현재 지원 provider family를 단일 catalog로 제공한다. 검증: Node와 Desktop target이 같은 provider conformance suite를 통과하고 host별 provider 구현 복제가 없다.
- [ ] [agent-task-manager] 공통 AgentTaskManager가 project filesystem 상태, work-unit identity, route pin, plan/review loop, sequential Milestone 실행과 stop/resume을 모델 감시 없이 수행하고 같은 판정기의 read-only preview를 제공한다. 검증: supervisor 모델 호출 없이 남은 task 우선과 priority queue 다음 작업 선택이 결정적으로 재현되며 initial/resume preview 전후의 checkpoint, route/history, budget, blocker/intent, quota cache와 project 파일이 deep-equal이고 provider process가 시작되지 않는다.
- [ ] [workflow-ownership-boundary] AgentTaskManager는 project-owned agent-ops 작업 파일과 이미 선택된 작업 지시만 실행하며 일반 요청의 direct/Plan/Milestone 분류, IOP 소유 skill, 합성 tool call 기반 작업 파일 생성을 구현하지 않는다. 검증: 기존 작업 파일 dispatch는 동작하고 일반 요청 입력만으로는 runtime이 Milestone/Plan을 분류하거나 생성하지 않으며 별도 오케스트레이션 경계가 유지된다.
- [ ] [host-boundary] Node bridge와 Desktop host가 동일 runtime API를 사용하되 Node는 기존 wire/config/command mapping을, Desktop은 app lifecycle/registry/local events를 소유한다. 검증: Edge를 포함하지 않은 Desktop 실행과 기존 Node run/session/status 경로가 모두 같은 core를 통과한다.
- [ ] [parity-cutover] 현재 Milestone·SDD, finalized/active work evidence, Python dispatcher/selector와 Node 구현을 provider, scheduler, workflow artifact, review/finalization, process/session, quota/error 영역별로 inventory하고 각 동작을 `absorb | replace | not-applicable`로 판정한 뒤 공통 runtime으로 cutover한다. loop 컬럼이 없는 과거 archived `work_log_N.log`는 immutable history로 유지하고, 같은 task group의 active legacy `WORK_LOG.md`가 남아 있으면 기존 owner가 drain/archive하기 전에는 새 runtime이 mixed-schema 행을 append하거나 ownership을 넘겨받지 않는다. 검증: 전체 Node compatibility policy/behavior fixture와 한 work unit의 end-to-end audit chain을 포함해 미분류 동작이 없고 모든 absorb/replace 행에 Go test 또는 field-smoke evidence가 연결되며 stale Python monitoring 의존성·정적 route/cap 문구와 Node provider 중복이 남지 않는다. legacy archive byte equality와 active legacy log cutover blocker도 검증한다.

### Epic: [provider-policy] Provider Catalog와 선택 정책

사용자별로 다른 선언 provider와 app/project 정책을 한 번의 결정적 선택으로 연결한다.

- [ ] [provider-catalog] YAML 선언과 read-only discovery가 binary, version, authenticated readiness, model/profile capability를 공통 provider catalog로 정규화하고 공식 계열 이름과 내부 identity를 매핑한다. 검증: 누락·미인증·미지원 model/profile은 추정 fallback 없이 명시 오류가 된다.
- [ ] [config-ownership] app-owned YAML 안의 기본값과 project registry별 override, file watcher, revision snapshot과 next-invocation 적용 규칙을 구현한다. 검증: 실행 중 변경은 현재 agent에 영향을 주지 않고 다음 호출부터 적용되며 invalid revision은 새 dispatch를 config error로 중단한다.
- [ ] [selector-policy] 공통 selector가 default와 ordered conditional rules를 평가해 외부에는 정확히 하나의 provider/model을 반환하고 Node/Desktop별 정책 차이를 허용하며, 내부에는 ordered candidates, eligibility/rejection, rule/priority, used history와 transition을 가진 persisted route plan을 고정한다. 검증: 겹친 조건은 array 순서가 우선하고 Node 호환 KST/G01~G10/공식 review route와 failover/selfcheck policy fixture가 빈 구간 없이 통과하며 결과·candidate evidence·reason/config revision이 audit log와 checkpoint에서 일치한다. malformed policy, persisted schema와 selected/candidate/used-history 또는 stage/work-unit identity 불일치는 silent reselection 없이 typed error가 된다.
- [ ] [quota-admission] 기존 Go usage checker와 검증된 Python 해석을 공통 quota/status 입력으로 흡수하고 app-global 공유 quota, immutable admission batch snapshot과 unknown 격리를 제공한다. 검증: full probe identity가 같은 조회만 재사용하고 required caps/command/profile이 다르면 분리하며, 최초 worker가 필요한 후보만 probe하고 local-first 뒤 cloud·persisted resume·selfcheck·공식 review는 zero-probe다. parser 오류는 해당 key의 `unknown`으로 격리되어 work-unit/candidate별 한 번만 시도되고 그 사용 이력이 batch·restart를 넘어 보존되며, 다른 provider key를 차단하거나 target-global cap이 되지 않고 local은 `not_applicable`이며 generic stderr만으로 exhausted를 추정하지 않는다.
- [ ] [runtime-quota-failover] provider adapter의 confirmed quota failure를 base admission snapshot과 분리된 runtime observation으로 받아 같은 persisted candidate 순서·사용 이력의 다음 unused eligible target으로 failover한다. 검증: provider-agnostic primary/alternate/no-alternate conformance와 Gemini/Agy positive·negative fixture가 locator/context와 work-unit 보존, app-global key 갱신, 원본 batch·in-flight sibling 불변 및 alternate 부재 시 task-local blocker를 확인한다.

### Epic: [workspace-scheduling] Workspace 소유권과 Scheduling

여러 workspace를 app이 관리하면서 각 project의 작업 순서와 실행 identity를 보존한다.

- [ ] [workspace-registry] 명시 등록 project와 clone/worktree/branch별 canonical workspace instance를 app registry에서 관리하고 project filesystem source of truth와 연결한다. 검증: 같은 저장소의 서로 다른 경로가 충돌 없이 별도 queue/log/session identity를 가진다.
- [ ] [workspace-runtime-ownership] canonical workspace마다 하나의 active manager만 invocation 권한을 가지도록 lease를 획득하고 schema-versioned checkpoint를 원자적으로 저장하며 runtime build/config revision과 process start identity로 live child를 추적·인계한다. 검증: 중복 host/manager, PID 재사용, 손상 checkpoint, scheduler 예외와 host restart matrix에서 split-brain·중복 agent 호출 없이 충돌/손상이 명시 오류가 되고 이미 실행 중인 agent는 drain 또는 단일 인계된다.
- [ ] [task-order] 자동 실행이 등록 project의 기존 agent-ops 작업 상태에서 남은 agent-task를 우선하고 없으면 기존 priority-queue.md의 최상위 ready Milestone부터 project-owned plan/review/완료 지시를 수행한다. 검증: task 잔여·빈 task·blocked dependency·사용자 stop matrix에서 선택과 종료가 일관되고 일반 요청에서 새 작업 파일을 생성하지 않으며, 명시 요청한 task group이 관측·persist된 적이 없으면 empty completion이 아니라 typed state error가 된다.
- [ ] [workflow-state-drain] project workflow adapter가 active pair·contract-valid USER_REVIEW·task identity·split dependency topology를 실행 전에 검증하고 scheduler가 target 또는 plan write-set barrier 없이 dependency-ready work set을 소진한다. 검증: duplicate/incomplete pair, filename-only·불완전·충돌 USER_REVIEW, malformed identity, missing/ambiguous predecessor는 해당 work unit만 대기·차단하며 overlapping/unknown write-set이나 같은 target의 independent sibling/project와 이미 실행 중인 agent는 계속 진행되고 동일 task 중복 attempt만 배제되며 선행 완료 뒤 follow-up이 정확히 한 번 시작된다.
- [ ] [concurrency-stop] 서로 다른 workspace instance는 병렬로 실행하고 같은 instance는 dependency/route pin을 지키며, 사용자 stop은 process group과 session을 취소해 후속 자동 호출을 막는다. 검증: 병렬 project, 동일 repo clone, graceful stop과 강제 종료 smoke가 중복 실행을 남기지 않는다.

### Epic: [recovery-finalization] 복구와 Review/완료 확정

route와 실행 evidence를 fault-atomic하게 복구하고 project-owned review/finalization을 정확히 한 번 완료한다.

- [ ] [session-recovery] config revision, task/plan/tag 세대의 persisted route plan, process/session locator, logical context handoff와 failure budget을 보존해 crash/restart 뒤 현재 filesystem 상태에서 재개한다. 본문·시간·config 변화만으로 pinned route를 바꾸지 않고, native resume은 identity와 provider/profile이 호환되는 같은 session에만 사용하며 cross-adapter는 locator가 가리키는 동일 workspace/attempt의 readable PLAN/raw/normalized artifact로 logical transfer한다. 검증: compatible native resume, cross-adapter transfer, commit-before-invoke·locator-before-consume restart, malformed/tampered route plan, 범위 밖·누락·mismatch artifact와 checkpoint save fault matrix가 중복 실행·foreign session 혼입·silent reselection 없이 현재 stage와 pending handoff를 복원하거나 in-memory/on-disk exact pre-state를 보존한 명시 오류가 된다.
- [ ] [review-artifact-lifecycle] project workflow adapter가 모든 worker provider 종료부터 official review 전까지 actual completing target과 persisted route, PLAN/CODE_REVIEW pair·identity 및 active CODE_REVIEW의 worker-owned 필수 섹션/placeholder/체크리스트를 동일한 versioned 정규식/구조 matcher로 검사하고, completing route policy의 selfcheck까지 충족한 작업만 official review로 전이한다. review preflight, exact verdict, 새 artifact/fingerprint, no-progress budget과 PASS archive·WARN/FAIL follow-up·USER_REVIEW 및 restart recovery를 검증한다. pinned selfcheck 대상 worker는 actual completing target·persisted route와 PLAN/CODE_REVIEW pair·task/plan/tag identity를 먼저 검증한 뒤 selector 재평가 없이 selfcheck를 수행하고, 그 성공 결과에 worker-owned field matcher를 적용한다. Pi selfcheck가 성공했지만 matcher가 미완성을 반환하면 직전 성공 selfcheck의 native context를 같은 locator로 resume해 고정 영문 evidence-repair prompt를 보내고 matcher를 재실행한다. 검증: Pi를 포함한 declared provider/model과 local/cloud·one-shot/persistent worker 전체가 동일 matcher matrix를 통과해야 하며 runtime identity mismatch·placeholder·unchecked·pair/identity mismatch에서는 bounded 보완 또는 task-local blocker가 되고 official review invocation은 0회다. Pi evidence repair는 동일 native session/context·route/config identity를 유지하고 새 selector·quota probe·session 없이 수행한다. 각 incomplete ordinal은 matcher snapshot과 prompt dispatch intent/attempt identity를 먼저 저장해 정상 경로에서 prompt를 exactly-once 보내며 restart는 live/terminal attempt를 reconcile하고 delivery outcome 불명 상태를 blind resend 없이 task-local blocker로 만든다. 첫 selfcheck에서 이미 완성됐으면 재프롬프트 0회이고, 보완 뒤 통과하면 selfcheck pin·pending repair 해제와 official-review work-ready를 원자적으로 commit한 뒤 review 1회가 된다. 반복 미완성·restart에서는 durable incomplete budget과 pending repair를 exactly-once 복원하고, cancel은 이를 보존한 채 stopped/resumable로 전이하며, identity mismatch는 fresh-context fallback 없는 task-local blocker가 된다. selfcheck는 completing target을 재사용한다. active/archive recovery source는 exact basename grammar, ASCII numeric suffix ordering, regular-file와 work-unit identity로 결정하며 mtime이나 유사 이름을 사용하지 않는다. no-progress fingerprint는 plan write-set source와 review/finding artifact만 포함해 runtime WORK_LOG/heartbeat-only 변경이 budget을 초기화하지 않는다. 체크 표시만 있는 허위 완료·artifact 비노출·임의 위치 verdict·무변경 review·잘못된 archive는 통과하지 않고 재시작에도 정상 PASS만 한 번 완료된다.
- [ ] [blocked-failover-recovery] typed blocker, persisted route/work-unit/selected-target identity와 readable retry evidence package의 execution/attempt·stage/role·terminal failure·artifact identity가 모두 일치할 때만 복구 intent를 만들고 사용자 재시도 또는 policy-authorized status refresh에서 기존 route의 unused alternate와 현재 blocked target에 허용된 same-target retry만 재평가한다. 검증: malformed/missing/mismatched locator 또는 role/failure/attempt identity는 marker 없는 pinned same-target resume으로 남고 현재 시각 정책으로 새 candidate를 만들거나 이미 떠난 target으로 bounce하지 않는다. selector/context/transition/attempt save 실패에는 key 존재 여부를 포함한 기존 decision/history/intent/pending handoff와 정상 sibling의 in-memory/on-disk 전체 state가 보존되며, successful handoff는 attempt locator 기록 뒤 한 번만 소비되어 exact continuation으로 이어진다.
- [ ] [stage-failure-budget] work-unit/stage별 budget을 route decision과 함께 durable하게 유지하고 자동 target 변경·failover·restart에서는 누적하며 해당 stage 성공에서 초기화한다. 명시적 identity-matched `retry_blocked`는 blocker와 해당 stage budget만 초기화하고 route/history는 보존한다. same-target retry는 bounded backoff policy를 사용한다. 검증: primary/alternate와 restart가 하나의 worker budget을 공유하고 review budget과 분리되며 한도 소진은 task-local blocker가 되고 failure count가 selector 재평가나 새 initial route를 유발하지 않는다. backoff는 상한을 지키고 stop/cancel에서 즉시 해제되며 restart 후 같은 retry가 중복 실행되지 않는다.
- [ ] [completion-ledger-reconciliation] runtime 소유 execution/attempt START·FINISH ledger, active filesystem, archive baseline과 valid `complete.log`를 재조정해 exactly-once completion을 확정한다. task-group `WORK_LOG`의 각 attempt에는 해당 task의 active PLAN/CODE_REVIEW pair archive 회차인 `loop`를 START 전에 pin하고 matching FINISH에도 같은 값을 기록한다. locator가 pinned loop와 context/session id를 포함한 attempt 메타데이터를 소유하며 별도 `context_id` 컬럼은 만들지 않는다. 검증: `11+10_unknown_isolation` task에 paired `plan_*.log`/`code_review_*.log` suffix 0~10과 active pair가 있으면 그 pair의 worker/selfcheck/review START·FINISH 행은 loop 11이다. 동일 pair의 retry·restart는 loop 11과 locator identity를 유지하고 attempt만 증가한다. WARN/FAIL review가 실행 중 pair를 suffix 11에 exactly-once archive하고 follow-up pair를 만들어도 그 review FINISH는 11이며, follow-up pair의 다음 START부터 12가 된다. 동시에 실행되는 다른 task는 자신의 active-pair loop를 같은 `WORK_LOG`에 기록한다. task group에 기존 `work_log_0.log`~`work_log_2.log`가 있다면 이 task loop와 무관하게 현재 timeline의 terminal archive는 `work_log_3.log`다. verdict/partial-pair-archive 사이 crash, task 소실, 새 completion archive 없음·복수 archive, orphan START, 마지막 writer와 `WORK_LOG` archive 이동 실패 matrix에서 false completion이나 로그 유실 없이 재시도 가능 오류를 남기고, 동적 DAG terminal closure 뒤에만 고정된 `work_log_3.log` archive 및 attempt-log cleanup을 수행한다. active pair metadata·plan/review count·checkpoint/locator/row loop 또는 timeline archive ordinal 불일치는 추정 renumber 없이 명시 오류가 된다.

### Epic: [failure-observe] 오류·관측·로그 동등성

모델 감시 없이도 현재 Python dispatcher가 제공하는 최소 운영 가시성과 예외 처리를 runtime으로 흡수한다.

- [ ] [stream-observer] stdout/stderr 분리, raw/normalized stream, heartbeat, provider phase와 exact tool-call/result activity, silence/repetition inspection, PID/start token/process group, session locator와 completion 단일화를 공통 runtime event로 제공한다. 검증: fake emitter와 실제 CLI smoke에서 delta 순서, matching tool call/result가 모두 닫힌 phase, tool-running/awaiting-model/silent 상태를 구분하고 출력 silence 또는 반복 normalized chunk만으로 live process를 종료·block·retry·failover하지 않으며 단일 terminal, 취소와 orphan 부재를 확인한다.
- [ ] [failure-taxonomy] provider codec이 context limit, provider quota, model unavailable, connection/stream disconnect, generic error와 process termination을 provider별 fixture로 typed failure에 정규화하고 AgentTaskManager가 review-control violation 및 work-unit blocker와 결합한다. 검증: Gemini/Agy의 structured quota/429/rate-limit positive fixture와 generic·불완전·target 불일치 negative fixture가 올바른 class/source를 반환하며 manager가 raw 문자열을 재분류하지 않는다.
- [ ] [project-logs] provider/model decision, persisted route plan/rule/candidate/reason, admission snapshot id, runtime quota observation id, app-global quota refresh, config revision, process/session locator, typed blocker, recovery/failover transition과 completion을 project `agent-log`에서 execution/work-unit identity로 추적한다. 검증: 한 work unit의 selection부터 terminal까지 provider failure와 manager transition의 연결 근거가 누락되지 않고 secret/raw credential이 기록되지 않는다.
- [ ] [surface-errors] invalid config/provider/auth/model/capability와 unknown runtime 오류를 Desktop event/UI scaffold 및 Node event에 모두 표면화하고 unknown은 자동 추정 복구하지 않는다. 검증: 오류 matrix가 silent fallback이나 무한 retry 없이 terminal 상태와 로그를 남긴다.

### Epic: [desktop-delivery] Desktop Agent와 실제 환경 검증

Edge 없이 실행되는 macOS 제품 껍데기와 설치·운영 기준을 제공한다.

- [ ] [desktop-host] Desktop Go host가 app-owned project registry/config/state, file watcher, auto-run toggle과 common runtime lifecycle을 제공한다. 검증: Edge나 Python process 없이 여러 등록 workspace를 시작·중단·재시작할 수 있다.
- [ ] [flutter-shell] Flutter macOS shell이 Desktop runtime binary와 기본 YAML을 포함한 설치 가능한 app bundle로 패키징되고 최소 status/error/stop surface를 가진다. 검증: clean macOS 사용자 경로에서 설치·실행할 수 있고 D01에서 확정한 창 닫기·명시 종료·로그인 시작 lifecycle과 child process ownership을 지킨다.
- [ ] [yaml-operations] UI 설정 화면 없이도 YAML 생성·조회 기반 보조 설정, validation, reload와 project override를 운영할 수 있고 이후 UI가 같은 config service를 사용할 scaffold가 있다. 검증: YAML roundtrip과 read-only discovery 결과가 동일 schema로 조회된다.
- [ ] [logged-in-smoke] 실제 로그인된 지원 CLI 환경에서 discovery, 짧은 agent 실행, stream, quota/status, cancel, next invocation config 적용과 project log를 검증한다. 검증: smoke manifest가 실행 provider/model, 환경, 결과와 evidence 경로를 기록한다.

## 완료 리뷰

- 상태: 폐기
- 요청일: 없음
- 완료 근거: 결합 범위를 독립 구현하지 않고 IOP Agent CLI Runtime과 후속 Flutter·Unity Milestone으로 분할·대체하기로 확정했다.
- 검토 항목:
  - [ ] 모든 기능 Task와 Task 안의 검증이 충족되었다.
  - [ ] 동등성 matrix에 Python 참조, Node 기존 동작, 선행 selector/provider/routing Milestone 결과가 반영되었다.
  - [ ] runtime Gemini quota failover와 blocker 복구가 provider/manager 책임 분리, admission snapshot 불변성, app-global 후속 갱신, persisted route, locator/context 및 exactly-once intent 소비까지 검증되었다.
  - [ ] 외부 단일 selection과 내부 persisted route plan의 strict schema/identity 검증, 전체 Node compatibility policy/behavior fixture 및 provider-agnostic failover가 일관되게 검증되었다.
  - [ ] full quota probe identity와 initial-worker-only/zero-probe 규칙, read-only preview의 state/filesystem deep equality와 invocation 0회가 검증되었다.
  - [ ] locator package identity, durable two-phase continuation handoff, commit/invoke restart와 save fault exact rollback 및 sibling isolation이 검증되었다.
  - [ ] bounded/cancellable backoff와 end-to-end selector audit trace, stale Python monitoring/static route/cap zero-match 근거가 남았다.
  - [ ] Pi를 포함한 모든 declared worker provider/model·execution 방식에 동일한 CODE_REVIEW 정규식/구조 제출 gate가 적용되고 official review의 verdict/progress/finalization 상태 전이가 project-owned artifact contract 기준으로 검증되었다.
  - [ ] Pi selfcheck 후 CODE_REVIEW 미완성은 직전 성공 selfcheck의 동일 native context에 고정 영문 보완 prompt를 보내 재검증하며, matcher 통과 전 review 0회·통과 뒤 1회, ordinal별 prompt 중복 방지, restart의 live/terminal/unknown-delivery 조정, 성공 시 selfcheck pin·pending repair 원자 해제와 budget/identity 오류의 fresh-context fallback 부재가 검증되었다.
  - [ ] workspace single-owner, live child 인계, dependency drain과 stage failure budget이 restart·오류 상황에서도 중복 호출이나 독립 branch 취소 없이 검증되었다.
  - [ ] runtime ledger, valid completion archive와 task-group `WORK_LOG`/attempt-log 정리가 last-writer 및 exactly-once 기준으로 재조정되고, 각 attempt의 START·FINISH가 동일한 pinned task/pair `loop`를 사용하며 같은 pair retry에서는 유지되고 follow-up pair의 다음 START에서만 증가한다. 서로 다른 task의 loop는 같은 `WORK_LOG`에서 독립적이고 별도로 고정된 `work_log_N.log` archive 회차와 혼동하지 않으며 context/session id는 locator 메타데이터에서 조회된다.
  - [ ] Node와 Desktop이 동일 provider/runtime conformance suite를 통과하고 중복 provider 구현이 없다.
  - [ ] 실제 로그인된 macOS smoke와 project-local log evidence가 남아 있다.
- agent-ui 상태 반영: 해당 없음
- 리뷰 코멘트: 미완료 기능 Task는 후속 Milestone의 범위와 검증 기준으로 이관되며, 이 Milestone 자체의 구현 완료를 주장하지 않는다.

## 범위 제외

- Desktop Agent에 Edge, Control Plane 또는 기존 Personal Edge runtime을 포함하는 구성
- Python dispatcher/selector 코드를 production runtime에서 import, 실행, 번역 호출하거나 진행 중 Python process 상태를 승계하는 migration
- CLI 로그인, credential/token 저장, 계정 회전과 billing 구매 자동화
- provider/model/선택/프로젝트 설정 전체를 편집하는 완성형 Flutter UI. 이번 범위는 향후 같은 config service를 감싸는 scaffold까지다.
- Windows와 Linux 패키지, macOS code signing/notarization과 외부 배포 채널
- 사용자 승인 prompt, interactive approval gate와 per-action 권한 정책
- 외부 webhook/메신저 알림, Control Plane dashboard와 중앙 로그 집계
- 원격 terminal tunnel, Edge를 통한 원격 workspace 제어, oto scheduler/CI-CD
- agent-ops를 사용하지 않는 일반 사용자 요청의 direct/Plan/Milestone 분류, IOP 소유 Milestone/Plan skill 실행과 사용자 agent에 대한 합성 tool call 주입. 이는 [에이전트 작업 루프 오케스트레이션 MVP](../../../../phase/automation-runtime-bridge/milestones/agent-workflow-loop-orchestration-mvp.md)의 범위다.
- agent-ops 공통 스킬 자체를 runtime monitoring loop로 사용하거나 공통 skill/rule 원문을 변경하는 작업

## 작업 컨텍스트

- 관련 경로: `packages/go/agentruntime`, `apps/node/internal/adapters/cli`, `apps/node/internal/runtime`, `apps/desktop-agent`, `apps/desktop-agent-ui`, `packages/go/config`, `agent-ops/skills/project/orchestrate-agent-task-loop`, `agent-task`, `agent-roadmap`
- 표준선(선택): 공통 구현은 `packages/go/agentruntime`에 두고 Node와 Desktop host가 의존한다. provider-specific codec은 core 내부 확장점일 수 있지만 host app에 복제하지 않는다.
- 표준선(선택): Python은 동작과 오류 사례의 참조이며 production dependency가 아니다. 아직 Python에 없는 선택 엔진은 [Agent Task 동적 실행 Target Selector](agent-task-runtime-target-selector.md), [CLI Agent Group Grade Routing](../../../../phase/automation-runtime-bridge/milestones/cli-agent-group-grade-routing.md)과 승인된 SDD를 기준으로 Go에서 구현한다.
- 표준선(선택): Python의 active pair 검사, contract-valid USER_REVIEW, local selfcheck, exact verdict/fingerprint, no-progress와 finalization 판정은 흡수하되 Pi에만 적용되던 CODE_REVIEW 정규식 완료 gate, non-empty checkbox 판정과 cloud worker 사전 gate 부재는 동등성 기준으로 복사하지 않는다. Go workflow adapter는 provider/model/execution class와 무관하게 같은 versioned 정규식/구조 matcher로 필수 worker-owned field를 검사하고 semantic correctness는 공식 review agent에 맡긴다. write-set은 review progress fingerprint 입력이지 dispatch barrier가 아니며 runtime WORK_LOG/heartbeat만 바뀐 것은 review progress가 아니다.
- 표준선(선택): 관측된 Pi 보완 fixture는 작업·검증·selfcheck가 끝났어도 CODE_REVIEW가 미완성이면 직전 성공 selfcheck native context에 짧은 영문 지시를 다시 보내 파일을 완성하는 동작이다. 이 fixture는 모든 provider에 적용하는 matcher gate를 약화하지 않고 Pi profile의 same-context evidence-repair policy로 흡수하며, 새 selfcheck session이나 새 route를 만드는 현재 Python 반복 동작은 parity 대상으로 삼지 않는다.
- 표준선(선택): Python의 non-blocking workspace lock, 임시 파일 교체, PID/start token/attempt marker와 archive baseline은 구현을 복사하지 않고 workspace lease, atomic versioned checkpoint, live execution identity와 completion reconciliation 계약으로 대체한다. 손상 상태를 빈 상태로 초기화하거나 시간 경과만으로 stale process를 판정하지 않는다.
- 표준선(선택): `WORK_LOG`는 agent가 작성하는 완료 주장 문서가 아니라 runtime-owned 실행 timeline이다. `seq`는 한 로그 안의 event 순서, `loop`는 해당 attempt가 시작한 task의 active PLAN/CODE_REVIEW pair archive 회차, `attempt`는 그 pair 안의 task/role별 호출 회차다. loop는 START 전에 locator/ledger에 pin하고 pair가 실행 중 archive·교체되더라도 matching FINISH까지 유지한다. 같은 pair의 retry·restart·blocker 복구는 loop를 유지하고 attempt만 증가하며 WARN/FAIL follow-up pair의 다음 attempt에서 loop가 증가한다. 병렬 task는 각자의 loop를 같은 timeline에 기록하고, `work_log_N.log`의 N은 같은 task group의 전체 월별 archive에서 별도로 계산·고정하는 timeline archive 회차이므로 task loop와 별개다. locator가 pinned loop와 context/session id를 포함한 attempt 메타데이터를 소유하므로 별도 context id 컬럼은 두지 않는다. split group의 동적으로 확장된 lineage가 terminal closure에 도달하고 마지막 writer와 모든 task의 유일한 valid completion archive가 확인된 뒤에만 project archive로 이동한다.
- 표준선(선택): 구현 계획 직전에 [Agent Task 동적 실행 Target Selector](agent-task-runtime-target-selector.md)의 최종 PASS·`complete.log` evidence를 다시 freeze한다. 미종결 active plan/review는 결함·검증 후보로만 참고하고 Python 내부 함수명이나 persisted key 자체를 Go parity 요구로 승격하지 않는다.
- 표준선(선택): 외부 RouteDecision은 하나의 provider/model을 반환하지만 checkpoint의 persisted route plan은 ordered candidates, eligibility/rejection, rule/priority, used history와 transition을 보존하고 malformed/tampered identity를 silent reselection하지 않는다. 선행 selector의 KST/G01~G10/공식 review/failover/selfcheck는 Node compatibility policy fixture다. Python의 10회 budget/no-progress, unknown-once, no-target/write-set-barrier, 3분 silence와 3회 exact-repeat observation 및 USER_REVIEW 판정은 별도 behavior fixture다. 둘 다 공통 core나 Desktop 정책에 하드코딩하지 않는다.
- 표준선(선택): quota probe는 credential/profile, adapter, target, status command/profile과 ordered required caps 전체가 같을 때만 재사용한다. 최초 worker의 필요한 후보만 조회하고 local-first 뒤 cloud, persisted resume, selfcheck와 공식 review는 선행 probe하지 않으며 unknown admission 사용은 work-unit/candidate에 durable하게 기록한다.
- 표준선(선택): Python dry-run은 read-only preview의 동일 판정/no-side-effect fixture로 흡수하고 CLI flag나 출력 형식은 복사하지 않는다.
- 표준선(선택): validated retry evidence package는 execution/attempt·stage/role·failure·route·artifact identity를 함께 검증한다. durable pending handoff/attempt locator의 two-phase continuation이 commit/invoke restart와 save fault를 견디며, same-target retry는 bounded/cancellable policy를 따른다.
- 표준선(선택): app config는 provider/global/project override의 운영 소유권을 가지고, project filesystem은 작업 상태의 source of truth다. workspace 안의 runtime config를 권위로 사용하거나 app store가 `agent-task`/roadmap 원문을 중앙 복제하지 않는다.
- 표준선(선택): Desktop은 Flutter가 관리하는 local Go sidecar process를 기본 topology로 삼고, Node는 동일 library를 in-process로 사용한다. 정확한 IPC와 lifecycle 계약은 SDD 잠금에서 고정한다.
- 표준선(선택): 설정 merge는 app-owned defaults 뒤 app registry의 project override를 적용하며 ordered rule array는 전체 교체한다. 현재 실행은 immutable revision을 사용하고 hot reload는 다음 agent invocation 경계에서만 활성화한다.
- 표준선(선택): 자동 실행과 approval bypass는 기본 on이다. auth는 CLI가 소유하고 app은 이미 인증된 실행만 사용한다.
- 큐 배치: 폐기되어 전역 큐에서 제외하고 [IOP Agent CLI Runtime](../../../../phase/automation-runtime-bridge/milestones/iop-agent-cli-runtime.md) -> [Flutter Desktop Control UI](../../../../phase/automation-runtime-bridge/milestones/flutter-desktop-control-ui.md) -> [Unity 3D Desktop Character](../../../../phase/automation-runtime-bridge/milestones/unity-3d-desktop-character.md)로 대체한다.
- 선행 작업: [Agent Task 동적 실행 Target Selector](agent-task-runtime-target-selector.md), [Pi CLI Provider Integration](../../../../phase/automation-runtime-bridge/milestones/pi-cli-provider-integration.md), [CLI Agent Group Grade Routing](../../../../phase/automation-runtime-bridge/milestones/cli-agent-group-grade-routing.md)
- 후속 작업: [Flutter Desktop Control UI](../../../../phase/automation-runtime-bridge/milestones/flutter-desktop-control-ui.md), [Unity 3D Desktop Character](../../../../phase/automation-runtime-bridge/milestones/unity-3d-desktop-character.md), [에이전트 작업 루프 오케스트레이션 MVP](../../../../phase/automation-runtime-bridge/milestones/agent-workflow-loop-orchestration-mvp.md), Windows/Linux packaging, 외부 알림·운영 dashboard, signing/notarization과 배포 채널
- 확인 필요: 현재 없음. Desktop background lifecycle은 [Flutter Desktop Control UI](../../../../phase/automation-runtime-bridge/milestones/flutter-desktop-control-ui.md)의 승격 조건에서 검토한다.
