12 KiB
12 KiB
Milestone: Agent Task 동적 실행 Target Selector
위치
- Roadmap: ROADMAP.md
- Phase: PHASE.md
목표
정적 PLAN-{lane}-GNN.md / CODE_REVIEW-{lane}-GNN.md 분류 결과를 실행 시점의 시간대, quota 상태, 이전 실패와 작업 상태에 결합해 결정적인 adapter + target 선택으로 변환한다.
선택 결과는 작업 단위로 고정·보존하고, 대상 전환이 필요할 때도 논리적 컨텍스트와 공통 실패 예산을 이어받아 독립 작업을 끝까지 drain하는 실행 경계를 확립한다.
상태
[진행중]
승격 조건
- 없음
구현 잠금
- 상태: 해제
- SDD: 필요
- SDD 문서: SDD.md
- SDD 사유: 시간·quota 기반 선택, 작업 단위 route 고정, adapter 간 failover, 재시도 예산과 task-local blocker 상태 전이를 변경한다.
- 잠금 해제 조건: 아래 체크리스트
- SDD 잠금이 해제되어 있다
- SDD 사용자 리뷰가 없거나 승인/해결되었다
- Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다
- Evidence Map이 완료 시
Roadmap Completion과 최종 검증 evidence로 검증 가능하게 연결되어 있다
- 결정 필요: 없음
범위
- task file 경로를 필수 입력으로 받고 worker/review stage를 판별해 정규화된 JSON으로
adapter + target, 후보 rank, 선택 근거, quota snapshot, selfcheck 여부, 평가 시각과 적용 rule을 반환하는 결정적 selector local-G01~G06은iop/ornith:35b,local-G07~G08은 KST 주간 Gemini 3.6 Flash (Medium)·야간 Laguna로 선택하는 실행 정책- 기존 정적 lane/G route를 유지하면서
cloud-G01~G06을 Gemini 3.6 Flash Low/Medium/High로,cloud-G07~G08을 Opus로,cloud-G09~G10을 Codex로 선택하는 실행 정책 - 모든 공식
CODE_REVIEW-*를 Codexgpt-5.6-solxhigh로 고정하고 worker target 선택과 분리하는 실행 정책 - 기존 Go CLI usage checker를 중복 파싱하지 않고 좁은 JSON probe로 연결한 cloud quota의
available | exhausted | unknown정규화와 local target의unbounded / not_applicable처리 task/plan/tag세대 단위 route 고정, dispatcher 재시작 후 재개, 확정된 provider target 불가 때만 adapter 전환하는 논리적 컨텍스트 이전, 동일 stage에서 target 전환 전후에 공유하는 자동 실패 예산 10회- 사용자 리뷰와 반복 실패 또는 eligible target 부재로 중단된 task 및 그 의존 task만 차단하고 독립적인 dependency-ready task는 끝까지 실행하는 drain 정책
- 실제 완료 target이 local model일 때만 selfcheck를 실행하고 cloud model 완료에는 selfcheck를 추가하지 않는 정책
- target별 인위적인 동시 실행 상한을 두지 않고 dependency-ready task를 처리량 우선으로 dispatch하는 정책
기능
Epic: [selector] 결정적 실행 대상 선택
정적 task route와 실행 시점 상태를 재현 가능한 adapter + target 결정으로 변환하는 capability를 묶는다.
- [selector-contract] task file을 필수 입력으로 받는 별도 selector가 worker/review stage, lane/grade, 선택 target, candidate rank, reason code, quota snapshot, selfcheck와
evaluated_at을 안정적인 JSON 계약으로 반환한다. 검증: 동일한 task 세대·시간 구간·quota snapshot·이전 결정은 동일한 route 결과를 내고 invalid filename/stage는 명시적 입력 오류로 종료한다. - [time-route]
local-G07~G08은 KST[07:00,23:00)에 Gemini 3.6 Flash (Medium),[23:00,07:00)에 Laguna를 최초 target으로 선택한다. 검증: 네 KST 경계 matrix가 canonical adapter+target을 반환한다. - [grade-route]
local-G01~G06은 Piiop/ornith:35b,local-G07~G08은 시간대별 Gemini 3.6 Flash (Medium) 또는 Laguna, cloudG01~G06은 Gemini 3.6 Flash Low/Medium/High,G07~G08은 Opus,G09~G10은 Codex로 선택하며 모든 공식 CODE_REVIEW는 Codexgpt-5.6-solxhigh로 고정한다. 검증: worker local/cloudG01~G10과 CODE_REVIEW route matrix가 빈 구간 없이 canonical adapter/target으로 해석된다. - [quota-input] 좁은 JSON quota probe가 기존 Go usage checker의 overall/model-specific remaining 신호를 재사용해 cloud quota를
available | exhausted | unknown으로 정규화하고, local target은quota_mode=unbounded,quota_status=not_applicable로 표현한다. 검증: target/profile의 required cap 중 하나라도 0이면 exhausted, required cap이 모두 확인되고 양수이면 available, 누락·충돌·parse 실패는 unknown이며 unknown 후보는 각 work unit에서 runtime quota 결과가 확정될 때까지 1회만 admission하되 target 전역 cap을 만들지 않고 generic stderr만으로 quota/provider 장애를 추정하지 않는다.
Epic: [continuation] 고정·Failover·중단 전파
시간 경계나 dispatcher 재시작에도 작업 identity를 유지하고, 실패가 전체 작업 그래프를 불필요하게 멈추지 않게 한다.
- [route-pin] 최초 선택 결과를 PLAN의
task/plan/tag세대에 고정·보존하고 시간 경계, PLAN 본문 갱신 또는 dispatcher 재시작만으로 활성/재개 작업의 target을 바꾸지 않는다. 검증: 주야간 경계를 넘긴 재개와 재시작이 persisted route를 유지하며 명시적 failover event만 target을 변경하고 새 plan/tag 세대만 새 최초 선택을 만든다. - [context-failover] 확정된 provider quota/rate-limit, context/output limit, model unavailable 또는 transport disconnect로 현재 target을 계속 쓸 수 없을 때만 주간 Gemini는 Laguna로, 야간 Laguna는 quota가 남은 Gemini Medium으로 한 번 논리적 컨텍스트를 이전한다. 그 밖의 실패는 같은 target에서 복구하고, 야간 Gemini quota가 없으면 해당 task를 중단한다. 검증: PLAN/locator, 이전 normalized output·raw log, 현재 workspace가 다음 adapter 입력에 연결되고 same-Pi session만 native resume을 사용하며 시간·quota 회복이나 실패 횟수만으로 이전 target에 bounce하거나 cloud로 승격하지 않는다.
- [failure-budget] 자동 복구 실패 예산 10회를 같은 work unit의 동일 stage에서 target 전환 전후에 공유하되, 실패 횟수는 target 전환 또는 cloud 승격 조건으로 쓰지 않는다. 검증: target 전환 후에도 해당 stage의 누적 실패 횟수가 보존되고 stage 성공 시에만 초기화되며 10회 도달 또는 eligible target 부재 시 해당 task가 terminal blocker가 된다.
- [dependency-drain] user review가 해당 task의 진행을 실제로 막는 경우와 terminal blocker가 된 경우에만 그 task 및 의존 task를 중단하고, 독립적인 dependency-ready task는 완료될 때까지 dispatch한다. 검증: 병렬 DAG에서 한 branch의 review/blocker가 다른 독립 branch의 완료를 막지 않는다.
Epic: [integration] Dispatcher와 검증 통합
selector 결정을 오케스트레이션 루프의 단일 실행 기준으로 사용하고 정책 drift를 자동 검증한다.
- [dispatch-integration]
orchestrate-agent-task-loopdispatcher가 정적finalize-task-routing결과를 다시 분류하지 않고task/plan/tag세대에 저장된 selector decision으로 worker/review 최초 실행, resume과 failover를 수행한다. 검증: 시간 경계와 재시작을 포함한 dispatcher 통합 테스트에서 invocation, persisted target과 transition history가 일치한다. - [selfcheck-policy] selfcheck 여부를 task lane이 아니라 실제 worker 완료 target의 local/cloud 성격으로 결정하고, local selfcheck는 새 route를 평가하지 않고 그 완료 target을 그대로 사용한다. 검증: Gemini→Laguna 완료는 Laguna selfcheck를 실행하고 Laguna→Gemini 완료와 모든 cloud target 완료는 selfcheck를 실행하지 않는다.
- [throughput-policy] selector와 dispatcher는 target별 정적 semaphore를 정책으로 강제하지 않고 모든 dependency-ready task를 dispatch하며, quota 조회는 scheduling admission batch 안에서 snapshot id와 관측 시각이 같은 결과로 재사용한다. 검증: 서로 독립적인 동일 target task가 인위적 target cap 없이 admission되고 quota 조회 실패는 해당 batch의
unknown으로 격리된다. - [audit-tests] 선택, 고정, failover, quota, 실패 예산, blocker 전파를 reason code와 work unit identity로 추적할 수 있고 단위·통합 테스트 및 운영 설명이 정책 matrix와 일치한다.
완료 리뷰
- 상태: 없음
- 요청일: 없음
- 완료 근거: 기능 Task와 검증 evidence가 아직 충족되지 않았다. 사용자 결정과 SDD gate는 완료되어 구현 잠금은 해제되었다.
- 검토 항목:
- 모든 기능 Task와 Task 안의 검증이 충족되었다
- selector JSON, dispatcher persisted state와 usage checker 경계가 SDD와 일치한다
Roadmap Completion이 SDD Evidence Map의 시나리오를 모두 가리킨다
- agent-ui 상태 반영: 해당 없음
- 리뷰 코멘트: 없음
범위 제외
finalize-task-routing이 소유하는 PLAN/CODE_REVIEW lane 및 G 등급 판정 변경- 공식 CODE_REVIEW의 Codex 고정 route와 독립 review lifecycle 변경
- cloud provider별 quota 구매, credential/account 회전, billing API 신규 연동
- local model의 가상 quota 또는 비용 제한
- adapter 간 native session 호환을 가장하는 전송
- 모델별 인위적인 처리량 상한과 시간 변화만으로 활성 작업을 재라우팅하는 동작
- 알림 UI, Control Plane dashboard, 외부 webhook 완성
작업 컨텍스트
- 관련 경로:
agent-ops/skills/project/orchestrate-agent-task-loop/SKILL.md,agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py,agent-ops/skills/project/orchestrate-agent-task-loop/scripts/select_execution_target.py,agent-ops/skills/project/orchestrate-agent-task-loop/tests,apps/node/internal/adapters/cli/status,apps/edge/internal/service/node_command.go - 표준선(선택): 실행 정책은 모델명이 아니라
adapter + target으로 표현하고, selector는 결정적 상태 판별을, skill은 호출 시점과 결과 소비 절차를 소유한다. - 표준선(선택): route는 시간 단위가 아니라 work unit 단위로 고정한다. 시간은 최초 선택 입력일 뿐이며 활성 작업의 변경 사유가 아니다.
- 표준선(선택): work unit의 selector identity는 PLAN의
task/plan/tag세대이며 PLAN 본문 변경은 새 선택을 만들지 않는다. worker, selfcheck, review는 실패 예산을 공유하지 않는 별도 stage다. - 표준선(선택): cross-adapter continuation은 PLAN/locator, 이전 출력과 로그, 현재 workspace를 이용한 logical context transfer이며 native session transfer로 표현하지 않는다.
- 표준선(선택): local quota가 무제한이라는 뜻은 quota admission을 하지 않는다는 뜻이며, 자동 실패 예산 10회와 terminal blocker 규칙은 그대로 적용한다. 실패 횟수는 target 전환 또는 cloud 승격 근거가 아니다.
- 큐 배치: 현재 진행 작업으로 전역 실행 순서 첫 항목
- 선행 작업:
finalize-task-routing이 생성하는 정적 PLAN/CODE_REVIEW lane/G 파일명 계약 - 후속 작업: CLI Agent 사용량 알림과 자동 이어받기 MVP의 사용자 알림 표면
- 확인 필요: 2026-07-26 사용자 결정으로
local-G07~G08canonical 정책은 주간 Gemini ↔ 야간 Laguna이며, 단일 Gemini/no-Laguna 정책을 사용하지 않는다.