- Refactor plan, code-review, finalize-task-routing, refine-local-plans, router skills - Add agent-workflow-loop-orchestration skill and plan agent configs - Update roadmap: knowledge-tool-optimization milestones, stream-evidence-gate-core SDD - Add stream-evidence-gate-core task, archive, and Go streamgate package - Update dev-test inventory (edge/node smoke), agent-contract, edge-local-dev-guide - Deprecate USER_REVIEW for output-validation-filters SDD
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으로 접속한다. 2026-07-23 기준 IOP Node의 실제 부팅 chain은 user StartupIOP Node.lnk -> cmd.exe -> C:/Users/r0bin/iop-field/run-iop-node.cmd -> iop-node.exe serve --config node.yaml이다.startup.lnk -> startup.bat -> oto -> AHK는 별도 호스트 자동화이며 IOP Node의 부팅 owner나 검증 근거가 아니다. 특히 AHK에 남은IOP Dev Node RTX5090 LemonadeTask Scheduler 호출은 제거된 task를 가리킨다. 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 인증으로 성공하고,IOP Node.lnk -> run-iop-node.cmd -> iop-node.exe실제 chain, Node process와 Edge 연결이 확인되며 Lemonade가0.0.0.0:13305에 listen하고 Task Scheduler 항목을 생성하지 않았는가. AHK automation chain은 Node 시작 증거로 쓰지 않는다. /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에 넣지 않는다.