- Implement runtime refresh logic for provider resource ownership alignment - Add model queue admission service with scheduling support - Add comprehensive tests: runtime_refresh_test, provider_scheduling_test, service_internal_test - Update edge and node smoke tests for new functionality - Update dev-runtime-deploy SKILL, PHASE, SDD documents - Archive G07 task files and update priority queue - Update agent-test dev configs (edge-smoke, node-smoke, inventory)
14 KiB
14 KiB
| name | version | description |
|---|---|---|
| dev-runtime-deploy | 1.0.3 | dev 배포, dev-runtime 배포, Edge/Node dev 환경 배포 요청에서 clean sync, 전체 테스트, rebuild, 원격 배포, OpenAI-compatible capacity smoke를 수행하는 절차 |
dev-runtime-deploy
목적
dev-runtime provider pool을 제품 검증이 끝난 상태로 배포한다. 배포는 원격 checkout 동기화, 전체 테스트, 전체 rebuild, Edge/Node 재시작, provider snapshot 기반 capacity 검증까지 포함한다.
언제 호출할지
- 사용자가
dev 배포,dev-runtime 배포,배포해봐처럼 dev 환경 배포를 요청할 때 - Edge, mac-codex-node(CLI adapter + mac-mlx-vllm provider resource), GX10 vLLM node, OneXPlayer Lemonade node, RTX5090 Lemonade node로 이루어진 dev-runtime provider pool을 갱신할 때
- OpenAI-compatible
/v1/responses또는/v1/chat/completions경로가 provider capacity만큼 채워지는지 검증할 때 - dev 환경의 remote runner, node 접속 정보, provider capacity, model alias 변경을 배포 절차에 반영할 때
입력
env: 배포 대상 환경. 기본값은dev이다.model: OpenAI-compatible model alias. 지정하지 않으면 dev 환경 문서의 기준 model을 사용한다.capacity_targets: provider별 기대 capacity. 지정하지 않으면 dev 환경 인벤토리 또는agent-test/dev/*문서에서 읽는다.source_ref: 배포할 git ref. 지정하지 않으면 원격 runner의 기본 배포 branch 기준을 따른다.
먼저 확인할 것
agent-ops/rules/project/domain/testing/rules.md를 읽고 사용자 실행 파이프라인 검증 기준을 확인한다.go build -o /tmp/iop-inventory-query ./scripts/inventory-query로 current checkout query binary를 만든다./tmp/iop-inventory-query --env dev로 env projection을 먼저 확인한다.- 필요한 selector별 bounded 조회는 아래 명령으로 실행한다:
- node:
/tmp/iop-inventory-query --env dev --node <node-id-or-alias> - provider:
/tmp/iop-inventory-query --env dev --provider <provider-id> - model:
/tmp/iop-inventory-query --env dev --model <model-alias>
- node:
- 직접 실행 exit 2가 schema/file 오류일 때만 canonical inventory 전체 읽기로 fallback하고, exit 1은 zero-match로 보고한다.
- dev-runtime provider pool과 compose/local profile을 섞지 않는다. dev-runtime은 native Edge/Node runtime과 dev-runtime config를 기준으로 한다.
- Qwen vLLM/vLLM-MLX runtime option은
agent-test/dev/inventory.yaml의 provider별 값을 우선한다. 현재 tracked Qwen evidence는 mac-mlx-vllm에tool_call_parser: qwen,reasoning_parser: qwen3,default_chat_template_kwargs.enable_thinking=true가 있고, GX10 vLLM에는reasoning_parser: qwen3,default_chat_template_kwargs.enable_thinking=true가 기록되어 있다. GX10을 Pi/Cline형 agent tool-call provider로 쓰려면 먼저tools[]non-stream/stream 검증으로--tool-call-parser/--chat-template확정값을 만들고 inventory에 기록한다. Gemma 계열의tool_call_parser=gemma4,reasoning_parser=gemma4, Gemma4 chat template/profile은 dev-corp Gemma 전용이며 Qwen provider에 복사하지 않는다. - OneXPlayer SSH 접속 정보는 현재 host 기준
ssh r0bin@192.168.0.59이다.toki사용자명 또는 remote runner를 경유한 OneXPlayer 접속을 사용하지 않는다. - RTX5090 SSH는 현재 작업 호스트의 local SSH config alias
ssh iop-dev-rtx5090을 사용한다. 이 alias는 public-key batch 인증을 사용하며, host identity와 공개키 지문은 inventory의rtx5090-lemonade-node.ssh_access에서 확인한다. - 현재 구현의 completion 검증 대상은 legacy
/v1/completions가 아니라/v1/chat/completions이다./v1/completions는 route가 구현되어 있을 때만 별도 검증한다. - token, secret header, bootstrap token, private key 경로는 최종 보고에 원문으로 출력하지 않는다.
실행 절차
-
환경 인벤토리 확정
- 배포 대상 runner, repo path, Edge id, Control Plane status URL, OpenAI base URL, Edge admin URL, Node SSH 정보를 문서에서 확정한다.
- provider pool 대상 model alias와 provider별 capacity를 확정한다.
- 필수 정보가 없거나 서로 충돌하면 배포를 시작하지 말고 누락/충돌 항목을 보고한다.
-
원격 checkout clean sync
- 원격 runner checkout에서
git fetch후 배포 기준 ref로git reset --hard를 수행한다. - dirty 파일은 보존 대상으로 보지 않는다. 배포 전 clean 상태를 만든다.
- 기본 cleanup은
git clean -fd이다.git clean -fdx는 config, token, secret, runtime artifact까지 삭제할 수 있으므로 사용하지 않는다. - sync 후
git status --short --branch와git log --oneline -1을 기록한다.
- 원격 runner checkout에서
-
빌드 전 전체 테스트
- clean source 기준으로
go test ./...를 실행한다. - client/Flutter, proto, Makefile, script, config 변경이 배포 범위에 포함되면 해당 도메인 규칙의 전체 테스트도 추가한다.
- 전체 테스트가 실패하면 build/deploy를 진행하지 않고 실패 패키지와 핵심 오류를 보고한다.
- clean source 기준으로
-
전체 rebuild
- 같은 source ref에서 dev-runtime Edge binary, mac node binary, Linux ARM64 node binary, Windows AMD64 node binary를 모두 다시 빌드한다.
- stale binary가 의심되거나
config refreshsubcommand, admin port, version 출력이 맞지 않으면 clean sync부터 다시 시작한다. - 빌드 산출물 경로, timestamp, 크기, 실행 가능 여부를 기록한다.
-
빌드 후 기본 동작 테스트
- 빌드된 Edge binary로
config check,config refresh --help,config refresh --mode dry-run을 실행한다. - 빌드 후에도
go test ./...를 실행한다. 실행하지 못하면 사유와 남은 위험을 보고한다. - dry-run이
rejected또는 예상 밖restart_required를 반환하면 배포를 멈추고 config diff를 보고한다.
- 빌드된 Edge binary로
-
배포와 재시작
- Edge와 mac-codex-node(CLI adapter + mac-mlx-vllm provider vllm-mlx process)는 원격 runner에서 빌드 산출물 기준으로 재시작한다.
- GX10 node는 Linux ARM64 node binary를 배포하고 기존 node process를 재시작한다.
- OneXPlayer node는 현재 host에서
ssh r0bin@192.168.0.59로 접속한다. artifact가 remote runner에 있으면 현재 host를 통해 전달한 뒤 Windows host에서 교체한다. - OneXPlayer에서는 SSH 세션 안의
Start-Process로 장기 실행을 시작하지 않는다.Win32_Process.Create또는 동등한 세션 독립 실행 방식으로iop-node.exe --config node.yaml serve를 시작한다. - RTX5090 node는 현재 host에서
ssh iop-dev-rtx5090으로 접속한다. 사용자 의도상 부팅 지속성은 Windows 시작 배치가 담당해야 하지만, 배포 전 실제 startup chain에 IOP Node 호출이 있는지 확인하고 누락이면 blocker로 보고한다. IOP dev 배포는 Task Scheduler 항목을 생성하거나 재생성하지 않는다. 배포 직후 즉시 재시작이 필요하면C:/Users/r0bin/iop-field/run-iop-node.cmd를Win32_Process.Create또는 동등한 세션 독립 방식으로 실행하고, SSH 세션 내부의Start-Process에 장기 실행을 의존하지 않는다. - RTX5090 Lemonade는
host=0.0.0.0, CUDA backend, Q5 GGUF + Q8 KV, context262144기준을 inventory와 대조한다. localhost-only bind는 Node에서 provider endpoint에 접속할 수 없으므로 배포 완료로 보지 않는다.
-
배포 후 연결 검증
- Edge, OpenAI-compatible listener, Node TCP, admin port, Control Plane status port가 열려 있는지 확인한다.
- Control Plane status에서 Edge가 connected이고 dev-runtime 기준 4개 node가 connected인지 확인한다.
- 각 node의
provider_snapshots에서 providerid,capacity,in_flight,queued,health,served_models를 확인한다. /v1/models가 대상 model alias를 노출하는지 확인한다.
-
OpenAI-compatible capacity smoke
/v1/responses와/v1/chat/completions를 각각 검증한다. legacy/v1/completions는 구현되어 있지 않으면 실패로 보지 않는다.- 표준 부하 프롬프트는 짧은 토큰 응답을 요구하지 않는다. 700~1200 token 수준의 구조화된 답변을 유도해 요청이 동시에 관측될 시간을 만든다.
- endpoint별로 총 provider capacity + 1개 요청을 동시에 보낸다. 현재 Ornith 기준 예시는
4 + 3 + 1 = 8이므로 9개 동시 호출이다. - 환경 문서에 더 작은 aggregate smoke 기준이 남아 있더라도, 배포 완료 판정은 이 capacity+1 기준을 우선한다.
- 요청 실행 중 Control Plane status를 반복 polling하여 대상 provider들의
in_flight합이 총 capacity에 도달하고queued합이 1 이상이 되는 순간을 증거로 남긴다. - 각 provider의
in_flight가 자기 capacity를 넘지 않고, 적어도 한 번은 기대 capacity까지 차는지 확인한다. - 모든 요청 완료 후 같은 status에서 대상 provider들의
in_flight=0,queued=0으로 돌아오는지 확인한다. - Qwen 계열 reasoning/thinking 텍스트는 정상 응답으로 허용한다. exact-output match를 smoke 성공 기준으로 삼지 않는다.
- Pi/Cline형 agent/tool-call 경계를 검증할 때는 forced tool call, auto tool call, streaming
delta.tool_calls, multi-turn tool result 후 최종 답변을 provider direct와 Edge OpenAI-compatible 경로에서 나눠 확인한다. raw native marker나 reasoning text가 assistant content로 새면 해당 model/runtime의 parser/template profile 미확정으로 보고한다.
-
결과 보고
- source ref, clean sync 결과, 테스트 결과, 빌드 산출물, process/port 상태, connected node 목록, provider capacity snapshot, capacity smoke 관측값을 보고한다.
- 실패한 단계가 있으면 다음 단계를 진행했는지 여부를 명확히 구분한다.
- capacity smoke가 타이밍 문제로 관측 실패했으면 요청 성공과 별도로
capacity 관측 미충족으로 보고하고, 프롬프트 길이 또는 status polling 간격 조정을 제안한다.
실행 결과 검증
- 원격 runner checkout이 배포 기준 ref로 clean sync되었는가
- 빌드 전
go test ./...와 필요한 추가 전체 테스트가 통과했는가 - dev-runtime Edge/mac/Linux ARM64/Windows AMD64 binary가 같은 source ref에서 rebuild되었는가
- 빌드 후 config check, refresh help, refresh dry-run, 전체 테스트가 통과했는가
- Edge, mac-codex-node, GX10 vLLM node, OneXPlayer Lemonade node, RTX5090 Lemonade node가 재시작되고 4개 node(mac-codex, gx10-vllm, onexplayer-lemonade, rtx5090-lemonade)가 connected 상태인가
- OneXPlayer 접속과 실행이
r0bin@192.168.0.59및 세션 독립 실행 방식으로 수행되었는가 - RTX5090 접속이
ssh iop-dev-rtx5090public-key batch 인증으로 성공하고, 사용자 소유 startup chain의 실제 IOP Node 호출, Node process와 Edge 연결이 확인되며 Lemonade가0.0.0.0:13305에 listen하고 Task Scheduler 항목을 생성하지 않았는가 /v1/responsescapacity smoke에서 총 capacity만큼in_flight가 차고 초과 요청이 queue에 잡혔는가/v1/chat/completionscapacity smoke에서 총 capacity만큼in_flight가 차고 초과 요청이 queue에 잡혔는가- 완료 후 provider
in_flight=0,queued=0으로 회복되었는가 - 검증 실패 시: 실패 단계, 실패한 host/provider/endpoint, 관측된 snapshot, 진행 중단 여부를 보고한다.
출력 형식
dev-runtime 배포 결과
- Source: <branch/ref/commit>, clean=<yes|no>
- Pre-build tests: <command> - <pass|fail|not-run>
- Build: edge=<path>, mac-node=<path>, linux-arm64-node=<path>, windows-amd64-node=<path>
- Post-build checks: config-check=<pass|fail>, refresh-help=<pass|fail>, refresh-dry-run=<status>, tests=<pass|fail|not-run>
- Deployment: edge=<pid/status>, mac-node=<pid/status>, gx10=<pid/status>, onexplayer=<pid/status>, rtx5090=<pid/status>
- Ports: <port summary>
- Nodes: <node_id connected summary>
- Providers: <provider_id capacity/in_flight/queued/health summary>
- OpenAI-compatible: models=<pass|fail>, responses-capacity=<pass|fail>, chat-completions-capacity=<pass|fail>
- Capacity evidence: <endpoint별 max in_flight/queued snapshot>
- Blockers/Risk: <없음 또는 내용>
금지 사항
- dirty checkout이나 stale binary를 그대로 배포하지 않는다.
git clean -fdx를 기본 cleanup으로 사용하지 않는다.- 빌드 전 전체 테스트 실패 후 배포를 계속하지 않는다.
- OneXPlayer에
toki사용자명으로 접속하거나 remote runner에서 다시 OneXPlayer로 SSH 접속하지 않는다. - OneXPlayer 장기 실행을 Windows OpenSSH 세션 내부
Start-Process에 의존하지 않는다. - RTX5090 Node용 Windows Task Scheduler 항목을 생성하거나 재생성하지 않는다.
- Qwen reasoning/thinking 출력을 실패로 판정하거나 exact-output smoke를 기본 성공 기준으로 삼지 않는다.
- Qwen provider를 agent/tool-call 용도로 쓰면서 provider별
--tool-call-parser/--chat-template검증 없이 배포 완료로 선언하지 않는다. - OpenAI-compatible 요청 성공만으로 capacity 검증 성공을 선언하지 않는다. provider snapshot의
in_flight/queued관측을 함께 남긴다. - 이 프로젝트 전용 배포 절차를
agent-ops/rules/common/_templates또는 common skill에 넣지 않는다.