iop/agent-ops/skills/project/dev-corp-runtime-deploy/SKILL.md
2026-07-27 10:39:27 +09:00

28 KiB

name version description
dev-corp-runtime-deploy 1.0.12 dev-corp 배포, public digitalplatform Edge와 내부 DGX/Mac Studio provider pool 배포 및 OpenAI-compatible capacity smoke 절차

dev-corp-runtime-deploy

목적

dev-corp provider pool을 현재 dev-runtime과 같은 구조로 배포한다. 배포는 runner checkout 준비, source clean sync, 테스트, dev-corp runtime rebuild, public Edge/Node 재시작, provider snapshot 기반 capacity 검증까지 포함한다. 현재 dev-corp Edge runtime은 iop.ai.kr이며, mac-mini는 source/build/provider SSH runner로만 사용한다.

언제 호출할지

  • 사용자가 dev-corp 배포, dev-corp runtime 배포, 회사 dev 환경 배포처럼 dev-corp 환경 배포를 요청할 때
  • public iop.ai.kr Edge와 DGX Spark 01/02 vLLM node, Mac Studio vLLM-MLX node로 이루어진 provider pool을 갱신할 때
  • dev-corp model alias, provider endpoint, provider capacity, node 접속 정보를 배포 절차에 반영할 때
  • dev-corp OpenAI-compatible /v1/chat/completions 경로가 provider capacity만큼 채워지는지 검증할 때

입력

  • env: 배포 대상 환경. 기본값은 dev-corp이다.
  • model: OpenAI-compatible model alias. 지정하지 않으면 agent-test/inventory-dev-corp.yamlmodel.aliases에 기록된 model-specific alias를 사용한다.
  • capacity_targets: provider별 기대 capacity. 지정하지 않으면 agent-test/inventory-dev-corp.yaml의 target 후보 값을 사용한다.
  • source_ref: 배포할 git ref. 지정하지 않으면 mac-mini checkout의 기본 배포 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-corp로 env projection을 먼저 확인한다.
  • 필요한 selector별 bounded 조회는 아래 명령으로 실행한다:
    • node: /tmp/iop-inventory-query --env dev-corp --node <node-id-or-alias>
    • provider: /tmp/iop-inventory-query --env dev-corp --provider <provider-id>
    • model: /tmp/iop-inventory-query --env dev-corp --model <model-alias>
  • 직접 실행 exit 2가 schema/file 오류일 때만 canonical inventory 전체 읽기로 fallback하고, exit 1은 zero-match로 보고한다.
  • dev-corp Edge 배포/검증 통로는 iop.ai.kr이다. mac-mini runner/provider 관리 경유지를 Edge 배포, OpenAI-compatible smoke, Node edge_addr, bootstrap 기본 URL로 잡지 않는다.
  • dev-corp provider pool과 compose/local/dev-runtime profile을 섞지 않는다. dev-corp provider pool은 public iop.ai.kr Edge와 dev-corp config를 기준으로 한다.
  • mac-mini에 /Users/fe/agent-work/iop-dev-corp checkout이 없으면 배포를 시작하지 말고 checkout 생성과 source sync를 setup blocker로 보고한다.
  • mac-mini에서 Spark Ornith 192.168.2.2:8003, 192.168.2.4:8005와 Mac Studio Gemma4 192.168.2.3:8004/health/v1/models가 성공하는지 확인한다.
  • Edge config의 OpenAI-compatible adapter endpoint는 각 Node process 기준으로 평가된다. direct preflight는 192.168.2.x 주소로 하되, Edge가 Node에 내려주는 provider endpoint는 node-local 127.0.0.1:<provider-port>를 우선한다.
  • DGX Spark 01/02와 Mac Studio Node의 Edge addr은 iop.ai.kr:18087이다. mac-mini local route 또는 reverse SSH tunnel은 현재 기준 잘못된 Edge addr이며 명시적인 rollback/장애 비교 외에는 사용하지 않는다.
  • gemma4:26bornith:35b alias, 그리고 현재 provider별 capacity는 agent-test/inventory-dev-corp.yaml의 최신 검증 상태를 기준으로 판단한다. 현재 방향은 Gemma4는 Mac Studio, Ornith는 Spark 01/02 provider pool이다. 새 배포에서 Edge config 반영과 capacity smoke가 통과하기 전에는 새 결과를 확정값으로 보고하지 않는다.
  • DGX Spark vLLM provider의 catalog capacity 4262144 token request 4개가 항상 context 100%를 채우는 보장이 아니다. dev-corp 운영 기준은 호출당 prompt+generated KV가 최대 context의 50-70%라는 가정이다. capacity 4, max context 262144에서 KV 524,288 tokens / full-context concurrency 2.0x는 lower bound이고, 운영 target은 KV 734,004-786,432 tokens / full-context concurrency 2.8x-3.0x이다. 이 값이 4.0x가 아니라는 이유만으로 under-capacity로 판정하지 않되, 2.0x-2.8x는 workload-specific smoke 없이는 운영 적합으로 보지 않는다. vLLM에는 vLLM-MLX식 --max-kv-size가 없으므로 실제 KV cache는 gpu_memory_utilization 적용 후 startup log의 GPU KV cache sizeMaximum concurrency for 262,144 tokens per request로 검증한다. 2026-07-13 기준 Ornith Spark01은 8003, --gpu-memory-utilization 0.47, KV 783,347, full-context 2.99x; Spark02는 8005, --gpu-memory-utilization 0.50, KV 1,074,276, full-context 4.10x이다.
  • provider catalog admission queue timeout은 queue_timeout_ms=0으로 비활성화하고, Node openai_compat_instances adapter queue/request budget은 long reasoning/long-context 요청을 위해 queue_timeout_ms=1800000, request_timeout_ms=1800000으로 유지한다.
  • DGX Spark 02 Ornith endpoint는 Docker publish 때문에 host 192.168.2.4:8005 -> container 8000이다. 8000, 8001, 8002, 8004를 Spark02 Ornith 기본 endpoint로 쓰지 않는다.
  • Mac Studio 192.168.2.3:8005 DiffusionGemma endpoint는 secondary provider 후보이며 기본 pool에 자동 포함하지 않는다.
  • Mac Studio 192.168.2.3:8004 provider catalog type은 openai_compat이고 실제 runtime은 vLLM-MLX이다. provider catalog capacity는 5로 유지하고, vLLM-MLX runtime은 vllm-mlx=0.4.0, 호출당 최대 context window 262144, requested KV 262144x3 기준으로 runtime headroom --max-num-seqs 6, --prefill-batch-size 6, --completion-batch-size 6, --max-request-tokens 262144, --max-kv-size 786432을 사용한다. Continuous batching은 필수로 유지하고, Gemma4 MLLM/prefix-cache 불안정성을 피하기 위해 --disable-prefix-cache를 둔다. Gemma4 agent/tool-call profile은 현재 지원되는 --enable-auto-tool-choice, --tool-call-parser gemma4, --reasoning-parser gemma4, --default-chat-template-kwargs '{"enable_thinking":true}'를 함께 둔다.
  • Mac Studio 192.168.2.3:8004 vLLM-MLX runtime은 2026-06-25 기준 detached screen session vllm_mlx_8004로 관리한다. 이 host는 Python pyexpat 로딩에 DYLD_LIBRARY_PATH=/opt/homebrew/opt/expat/lib가 필요하므로 재시작 명령에 반드시 포함한다.
  • 현재 구현의 completion 검증 대상은 legacy /v1/completions가 아니라 /v1/chat/completions이다. /v1/completions는 route가 구현되어 있을 때만 별도 검증한다.
  • dev-corp current runtime은 OpenAI-compatible bearer token이 켜져 있다. smoke는 token 원문을 출력하지 말고 OPENAI_API_KEY=$(cat build/dev-corp-runtime/.secrets/openai_api_key) 또는 --api-key-file로 실행한다.
  • token, secret header, bootstrap token, private key 경로는 최종 보고에 원문으로 출력하지 않는다.
  • 원격 host의 보안 정책 때문에 scp/rsync 같은 파일 전송 프로토콜이 Operation not permitted로 막히면 권한·ACL·보안 정책을 완화하거나 재시도하지 않는다. 산출물과 config는 SSH 표준 입력 스트림으로 canonical target과 같은 디렉터리에 새 remote candidate 파일을 생성하는 절차를 사용한다.

known/current runtime update notes

  • DGX Spark 01/02의 requested KV 262144x2는 vLLM에서 직접 --max-kv-size로 표현하지 않는다. --max_num_batched_tokens는 scheduler iteration budget이므로 KV cache 총량으로 취급하지 않는다. dev-corp 기준은 --max-model-len 262144gpu_memory_utilization 적용 후 startup log의 KV cache/concurrency 확인이다.
  • capacity/KV 해석 기준은 agent-test/inventory-dev-corp.yamlmodel.capacity_planning_policy를 우선한다. catalog capacity는 일반 요청 admission/queue target이고, Maximum concurrency for 262,144 tokens per request는 full-context upper-bound 진단값이다. capacity 4 기준 2.0x는 lower bound, 2.8x-3.0x는 운영 target이다. 4.0x 미만이라는 이유만으로 실패로 보고하지 않되, 2.8x 미만은 workload-specific smoke 없이 운영 적합으로 보고하지 않는다.
  • queue timeout 해석 기준은 agent-test/inventory-dev-corp.yamlmodel.timeout_policy를 우선한다. provider catalog queue_timeout_ms=0은 provider admission queue timeout을 두지 않는다는 뜻이고, adapter instance의 queue_timeout_ms=1800000은 backend request budget과 같은 30분 장기 요청 예산이다.
  • Historical Spark Gemma4/FP4 profile note: explicit --max-num-batched-tokens 524288를 revive하는 경우 first profile 중 FP4 MoE token-per-expert 기본 한계에 걸릴 수 있으므로 VLLM_MAX_TOKENS_PER_EXPERT_FP4_MOE=4194304를 유지한다. 현재 Spark Ornith Docker profile의 active capacity source로 취급하지 않는다.
  • Historical Spark Gemma4 venv note: DGX Spark 01 Gemma4 0.24.0 venv profile을 revive하는 경우에만 /home/digitalcommerce_dgx_spark_01/vllm_env_0_24_0/bin을 PATH 앞에 둔다. 현재 Spark Ornith provider는 Docker vllm/vllm-openai:nightly-aarch64 기준이다.
  • DGX Spark 01/02 Ornith Docker image는 vllm/vllm-openai:nightly-aarch64이고 container command에는 serve를 중복으로 넣지 않는다. Spark01은 host 8003 -> container 8000, Spark02는 host 8005 -> container 8000 기준이다.
  • Spark Ornith parser/tool-call profile은 capacity/KV 튜닝과 별개로 agent 동작 가능성을 결정한다. DGX Spark 01/02 Ornith는 --enable-auto-tool-choice --tool-call-parser qwen3_xml --reasoning-parser qwen3 --trust-remote-code --runner generate를 둔다. Gemma4는 Mac Studio vLLM-MLX 8004만 기본 대상으로 하며 별도 chat template override 없이 --continuous-batching --disable-prefix-cache --enable-auto-tool-choice --tool-call-parser gemma4 --reasoning-parser gemma4 --default-chat-template-kwargs '{"enable_thinking":true}'를 둔다.
  • 모델별 parser/template 값은 섞지 않는다. Gemma 계열은 tool_call_parser=gemma4, reasoning_parser=gemma4, Gemma4 tool chat template 또는 vLLM-MLX 기본 template kwargs를 사용한다. Qwen 계열은 dev-runtime 문서의 tool_call_parser=qwen, reasoning_parser=qwen3, Qwen 전용 chat template 검증값을 따르며 Gemma4 parser/template을 재사용하지 않는다.
  • Mac Studio는 DYLD_LIBRARY_PATH=/opt/homebrew/opt/expat/lib 없이 Python pyexpat import가 실패할 수 있다. screen session vllm_mlx_8004 안에서 이 환경변수를 export한 뒤 시작한다.
  • Mac Studio vLLM-MLX는 /Users/dc_dev/vllm-env-0.4.0/bin/python 환경의 vllm-mlx=0.4.0, mlx=0.32.0, mlx-lm=0.31.3, mlx-vlm=0.6.4, transformers=5.12.1, huggingface-hub=1.22.0로 동작한다. --continuous-batching은 유지하고 --disable-prefix-cache를 추가했으며, /health, /v1/models, 직접 API non-stream/stream auto tool-call, streaming multi-turn tool-result final answer를 확인했다.
  • Mac Studio vLLM-MLX의 현 값은 "구동 가능한 최종 체크포인트"로 취급한다. 추가 미세 조정은 새 포트/새 venv 또는 명시적 rollback 지점을 둔 별도 실험으로만 수행하고, Spark 01/02 vLLM 설정과 함께 변경하지 않는다. 알려진 잔여 이슈는 Gemma4 thought channel delimiter가 최종 content에 누수될 수 있는 점이며, 이 경우 serving 옵션을 계속 흔들기보다 Edge/provider adapter sanitizer로 containment 하는 방향을 우선 검토한다.
  • 2026-07-13 기준 Spark Gemma4 8002/8004 runtime은 내린 상태로 보고, Spark 01/02는 Ornith 8003/8005를 IOP provider로 둔다. Gemma4는 Mac Studio 192.168.2.3:8004 provider만 기본 대상으로 둔다.
  • 2026-07-13 재확인 기준 DGX Spark 01 Ornith는 Docker iop-vllm-ornith35b-fp8, host 8003, --gpu-memory-utilization 0.47로 동작하며 startup log에서 GPU KV cache 783,347 tokens, full-context concurrency 2.99x를 확인했다. DGX Spark 02 Ornith는 host 8005, --gpu-memory-utilization 0.50으로 동작하며 GPU KV cache 1,074,276 tokens, full-context concurrency 4.10x를 확인했다.
  • 2026-07-02 mac-mini native Control Plane 18002/19004/19005 관측값은 historical evidence다. 2026-07-09 현재 dev-corp Edge source of truth는 public iop.ai.kr이고, current runner에서 public host SSH와 public Control Plane status 접근은 확인되지 않았다.
  • 2026-07-13 기준 dev-corp provider-pool Edge OpenAI-compatible capacity smoke 표준은 public https://digitalplatform.iop.ai.kr/v1/chat/completions에서 ornith:35b 9/6, gemma4:26b 9/6 동시 요청이다. Direct Edge listener http://digitalplatform.iop.ai.kr:18086/v1도 같은 backend로 동작하지만 사용자-facing 기본값으로 쓰지 않는다. /v1/responses는 capacity 성공 기준이 아니라 selected provider 지원 여부와 IOP raw passthrough/relay 동작을 분리해 보고한다.
  • 2026-07-13 live status 기준 DGX Spark 01/02와 Mac Studio node는 iop.ai.kr:18087로 연결되어 있으며, provider snapshot은 Spark01 Ornith capacity 4, Spark02 Ornith capacity 4, Mac Studio Gemma4 capacity 5이다. 같은 날 model-specific smoke에서 ornith:35b 9/6, gemma4:26b 9/6 요청이 모두 성공했고 완료 후 in_flight=0, queued=0, healthy로 회복했다.

실행 절차

  1. 환경 인벤토리 확정

    • 배포 대상 runner, repo path, Edge id, Control Plane status URL, OpenAI base URL, Edge admin URL, Node SSH 정보를 agent-test/inventory-dev-corp.yaml에서 확정한다.
    • public OpenAI/base, bootstrap/artifact, Edge-Node TCP는 기본적으로 iop.ai.kr 경로를 사용한다. mac-mini runner/provider 관리 경로로 Edge를 배포하거나 Node를 붙이는 것은 기본 금지이며, 사용자가 mac-mini local 비교를 명시 요청한 경우에만 별도 비교로 진행한다.
    • provider pool 대상 model alias와 provider별 capacity target을 확정한다.
    • 필수 정보가 없거나 서로 충돌하면 배포를 시작하지 말고 누락/충돌 항목을 보고한다.
  2. provider direct preflight

    • mac-mini에서 DGX Spark 01 Ornith http://192.168.2.2:8003/v1/models, DGX Spark 02 Ornith http://192.168.2.4:8005/v1/models, Mac Studio Gemma4 http://192.168.2.3:8004/v1/models를 확인한다.
    • 각 endpoint가 기대 served_model을 노출하는지 확인한다.
    • DGX Spark 02가 provider port down과 SSH banner exchange timeout을 동시에 보이면 runtime 추가 조작을 보류하고, SSH 회복 후 process/log부터 확인한다.
    • 실패한 provider는 Edge config에 넣지 않거나 배포 blocker로 보고한다.
  3. mac-mini checkout clean sync

    • mac-mini 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 --branchgit log --oneline -1을 기록한다.
  4. 빌드 전 테스트

    • clean source 기준으로 go test ./...를 실행한다.
    • client/Flutter, proto, Makefile, script, config 변경이 배포 범위에 포함되면 해당 도메인 규칙의 테스트도 추가한다.
    • 테스트가 실패하면 build/deploy를 진행하지 않고 실패 패키지와 핵심 오류를 보고한다.
    • mac-mini 또는 로컬 PATH에 Go가 없으면 시스템 전역 설치 대신 build/.tools 같은 ignored runtime 경로에 임시 Go toolchain을 두고 사용한다.
  5. dev-corp runtime rebuild

    • 같은 source ref에서 dev-corp Control Plane binary, Edge binary, mac node binary, Linux ARM64 node binary를 다시 빌드한다.
    • mac-mini에서 직접 빌드할 수 없으면 같은 source ref 기준으로 로컬에서 빌드한 뒤 SSH 표준 입력 스트림으로 mac-mini canonical target과 같은 디렉터리의 새 candidate 경로에 생성한다. scp/rsync 전송 재시도나 권한 완화는 하지 않는다.
    • Windows AMD64 node binary는 dev-corp 기본 provider pool 대상이 아니다.
    • stale binary가 의심되거나 config refresh subcommand, admin port, version 출력이 맞지 않으면 clean sync부터 다시 시작한다.
    • 빌드 산출물 경로, timestamp, 크기, 실행 가능 여부를 기록한다.
  6. 빌드 후 config check

    • 빌드된 Edge binary로 config check, config refresh --help, config refresh --mode dry-run을 실행한다.
    • dry-run이 rejected 또는 예상 밖 restart_required를 반환하면 배포를 멈추고 config diff를 보고한다.
  7. 배포와 재시작

    • Control Plane이 public host에서 운용되는 경우 iop.ai.kr:18002/19004/19005 dev-corp port를 기준으로 확인한다. mac-mini local Control Plane은 dev-corp Edge source of truth가 아니다.
    • Edge는 public iop.ai.kr host에서 18085/18086/18087을 기준으로 재시작/확인한다. mac-mini runner runtime은 dev-corp Edge source of truth가 아니다.
    • 보안 전송 차단 시 SSH stdin candidate 표준: scp/rsync 같은 파일 전송 프로토콜이 Operation not permitted로 차단되면 권한을 올리거나 전송을 재시도하지 않는다. canonical target과 같은 디렉터리에 timestamp 또는 고유 suffix를 붙인, 아직 존재하지 않는 candidate 경로를 먼저 정한다. 같은 filesystem에 두어야 이후 mv 전환이 가능하다.
    • source artifact는 ssh <target> 'umask 077; tee /absolute/path/to/target.candidate >/dev/null' < /absolute/path/to/local-artifact처럼 SSH stdin으로 candidate를 생성한다. config는 <config-generator> | ssh <target> 'umask 077; tee /absolute/path/to/config.candidate >/dev/null'처럼 생성 결과만 stream으로 보낸다. candidate path는 canonical target과 같은 디렉터리의 새 경로로 치환하며, token·config 원문을 command argument, 터미널 출력, command history, 배포 보고에 남기지 않는다.
    • cutover 전에 source와 remote candidate의 SHA-256과 byte length를 비교한다. macOS에서는 shasum -a 256, Linux에서는 sha256sum을 사용한다. candidate의 소유자와 mode도 확인하고, 실행 binary는 검증 후에만 chmod 755로 전환하며 secret-bearing config는 0600을 유지한다. 불일치 또는 preflight 실패 시 cutover하지 않는다.
    • 현재 실행 파일은 보존한 채 candidate의 --help와 필요한 config check를 먼저 통과시킨다. 전환은 같은 filesystem에서 canonical 파일을 timestamp backup으로 mv한 뒤 candidate를 canonical path로 mv한다. restart 또는 readiness 실패 시 backup을 canonical path로 다시 mv하여 즉시 rollback한다.
    • DGX Spark 01/02는 Linux ARM64 node binary를 mac-mini 경유로 배포하고 기존 node process를 재시작한다.
    • Mac Studio는 macOS node binary를 mac-mini 경유로 배포하고 기존 node process를 재시작한다.
    • provider runtime 옵션을 갱신하는 배포라면 DGX Spark 01은 /home/digitalcommerce_dgx_spark_01/start_vllm_ornith35b_docker_8003.sh 기준으로 Docker container iop-vllm-ornith35b-fp8를 재생성한다. 핵심 옵션은 --max-model-len 262144, --gpu-memory-utilization 0.47, --max-num-seqs 4, --port 8000, --enable-prefix-caching, --enable-auto-tool-choice, --tool-call-parser qwen3_xml, --reasoning-parser qwen3, --trust-remote-code, --runner generate이다.
    • provider runtime 옵션을 갱신하는 배포라면 DGX Spark 02는 /home/dplab/start_vllm_ornith35b_docker_8005.sh 기준으로 Docker container iop-vllm-ornith35b-fp8를 재생성한다. 핵심 옵션은 --max-model-len 262144, --gpu-memory-utilization 0.50, --max-num-seqs 4, --port 8000, --enable-prefix-caching, --enable-auto-tool-choice, --tool-call-parser qwen3_xml, --reasoning-parser qwen3, --trust-remote-code, --runner generate이다.
    • provider runtime 옵션을 갱신하는 배포라면 Mac Studio는 screen -dmS vllm_mlx_8004 안에서 DYLD_LIBRARY_PATH=/opt/homebrew/opt/expat/lib를 export한 뒤 /Users/dc_dev/vllm-env-0.4.0/bin/python -m vllm_mlx.cli serve--continuous-batching, --max-num-seqs 6, --prefill-batch-size 6, --completion-batch-size 6, --chunked-prefill-tokens 1024, --disable-prefix-cache, --max-kv-size 786432, --max-request-tokens 262144, --enable-auto-tool-choice, --tool-call-parser gemma4, --reasoning-parser gemma4, --default-chat-template-kwargs '{"enable_thinking":true}'로 재기동한다.
    • Node bootstrap은 Edge의 node register가 출력한 OS별 완성 명령을 우선한다. Node edge_addriop.ai.kr:18087이어야 한다. node-local provider endpoint 또는 별도 IOP_HOME이 필요한 경우에는 ~/iop-dev-corp-field/node.yaml을 수동 배치할 수 있고, token 원문은 로그/보고에 남기지 않는다.
  8. 배포 후 연결 검증

    • Edge, OpenAI-compatible listener, Node TCP, admin port, Control Plane status port가 열려 있는지 확인한다.
    • public Control Plane status가 접근 가능하면 Edge가 connected이고 dev-corp 기준 3개 provider node가 connected인지 확인한다.
    • public Control Plane status가 접근 가능하면 각 node의 provider_snapshots에서 provider id, capacity, in_flight, queued, health, served_models를 확인한다. 접근할 수 없으면 Node log의 registered with edge/connected to edge와 public OpenAI-compatible smoke 결과를 연결 증거로 분리 보고한다.
    • /v1/models가 대상 model alias를 노출하는지 확인한다.
  9. OpenAI-compatible capacity smoke

    • /v1/chat/completions를 검증한다. Provider-pool passthrough 경계를 바꾼 배포라면 selected provider가 지원하는 OpenAI-compatible extension field 예: chat_template_kwargs가 IOP에서 거부되지 않고 provider로 전달되는지도 확인한다. /v1/responses는 capacity 성공 기준이 아니라 provider-dependent passthrough/relay 검증으로 분리한다. legacy /v1/completions는 route가 구현되어 있지 않으면 실패로 보지 않는다.
    • 표준 부하 프롬프트는 700~1200 token 수준의 구조화된 답변을 유도해 요청이 동시에 관측될 시간을 만든다.
    • model-specific smoke를 실행한다. ornith:35b는 Spark01/02 합산 capacity 8 기준 9개와 6개 동시 요청을 보내고, gemma4:26b는 Mac Studio capacity 5 기준 9개와 6개 동시 요청을 보낸다.
    • Control Plane status가 접근 가능하면 요청 실행 중 반복 polling하여 대상 provider들의 in_flight가 각 model capacity에 도달하고 초과 요청이 queue에 들어가는지 증거로 남긴다. 짧은 요청에서는 polling이 queued 순간을 놓칠 수 있으므로 HTTP 성공, max in_flight, 최종 회복을 함께 판정한다.
    • public Control Plane status가 접근 가능하면 각 provider의 in_flight가 자기 capacity를 넘지 않고, 적어도 한 번은 기대 capacity까지 차는지 확인한다.
    • public Control Plane status가 접근 가능하면 모든 요청 완료 후 같은 status에서 대상 provider들의 in_flight=0, queued=0으로 돌아오는지 확인한다. 접근할 수 없으면 model-specific HTTP 성공 결과와 Node 연결 로그만으로 smoke 통과와 capacity snapshot 미관측을 구분한다.
    • Gemma 계열 reasoning/tool-parser 텍스트는 정상 응답으로 허용한다. exact-output match를 smoke 성공 기준으로 삼지 않는다.
    • agent/tool-call 경계를 검증할 때는 forced tool call, auto tool call, streaming delta.tool_calls, multi-turn tool result 후 최종 답변을 provider direct와 Edge OpenAI-compatible 경로에서 나눠 확인한다. provider direct가 통과하고 Edge 경유만 실패하면 provider runtime option 문제가 아니라 Edge/Node relay 또는 validation 경계 문제로 분리한다.
  10. 결과 보고

  • source ref, clean sync 결과, 테스트 결과, 빌드 산출물, process/port 상태, connected node 목록, provider capacity snapshot, capacity smoke 관측값을 보고한다.
  • 실패한 단계가 있으면 다음 단계를 진행했는지 여부를 명확히 구분한다.
  • capacity smoke가 타이밍 문제로 관측 실패했으면 요청 성공과 별도로 capacity 관측 미충족으로 보고하고, 프롬프트 길이 또는 status polling 간격 조정을 제안한다.

실행 결과 검증

  • mac-mini checkout이 배포 기준 ref로 clean sync되었는가
  • provider direct endpoint 3개가 mac-mini에서 /health/v1/models에 성공했는가
  • 빌드 전 go test ./...와 필요한 추가 테스트가 통과했는가
  • dev-corp Control Plane/Edge/mac/Linux ARM64 binary가 같은 source ref에서 rebuild되었는가
  • 빌드 후 config check, refresh help, refresh dry-run이 통과했는가
  • Edge와 3개 provider node가 재시작되고 connected 상태인가
  • /v1/chat/completions model-specific capacity smoke에서 각 model/provider capacity까지 in_flight가 차고 초과 요청이 queue에 잡혔는가
  • 완료 후 provider in_flight=0, queued=0으로 회복되었는가
  • 검증 실패 시: 실패 단계, 실패한 host/provider/endpoint, 관측된 snapshot, 진행 중단 여부를 보고한다.

출력 형식

dev-corp runtime 배포 결과
- Source: <branch/ref/commit>, clean=<yes|no>
- Provider preflight: dgx01=<pass|fail>, dgx02=<pass|fail>, mac-studio=<pass|fail>
- Pre-build tests: <command> - <pass|fail|not-run>
- Build: control-plane=<path>, edge=<path>, mac-node=<path>, linux-arm64-node=<path>
- Post-build checks: config-check=<pass|fail>, refresh-help=<pass|fail>, refresh-dry-run=<status>
- Deployment: control-plane=<pid/status>, edge=<pid/status>, dgx01=<pid/status>, dgx02=<pid/status>, mac-studio=<pid/status>
- Ports: <port summary>
- Nodes: <node_id connected summary>
- Providers: <provider_id capacity/in_flight/queued/health summary>
- OpenAI-compatible: models=<pass|fail>, chat-completions-capacity=<pass|fail>, provider-native-field-passthrough=<pass|fail|not-run>, responses-provider-pool=<pass|provider-unsupported|fail|not-run>
- Capacity evidence: <endpoint별 max in_flight/queued snapshot>
- Blockers/Risk: <없음 또는 내용>

금지 사항

  • mac-mini checkout이 없거나 dirty/divergent 상태인데 배포를 계속하지 않는다.
  • 사용자가 명시적으로 요청하지 않았는데 mac-mini runner/provider 관리 경로를 dev-corp Edge runtime, Node edge_addr, bootstrap 기본 URL, OpenAI-compatible base URL로 사용하지 않는다.
  • git clean -fdx를 기본 cleanup으로 사용하지 않는다.
  • 빌드 전 테스트 실패 후 배포를 계속하지 않는다.
  • scp/rsync가 보안 정책으로 차단됐을 때 권한·ACL·보안 도구를 변경하거나 sudo로 우회하지 않는다. 같은 filesystem의 새 SSH stdin candidate 생성, checksum 검증, mv cutover/rollback 절차를 사용한다.
  • umask 077으로 생성된 실행 binary를 0600 상태로 기동하지 않는다. checksum 검증 후 필요한 실행 권한만 부여한다.
  • DGX Spark 02 Ornith provider endpoint를 192.168.2.4:8000, 8001, 8002, 8004로 잘못 사용하지 않는다. 현재 기본은 192.168.2.4:8005이다.
  • Mac Studio secondary 8005 endpoint를 별도 alias/capacity 결정 없이 기본 provider pool에 포함하지 않는다.
  • Mac Studio 8004 vLLM-MLX runtime 재시작 방식을 확인하지 않고 provider process를 임의 종료하지 않는다.
  • node02처럼 tunnel 예외가 필요한 경우를 제외하고 Node bootstrap 기본 경로에서 수동 token 치환, named env parameter, 수동 node.yaml 작성을 요구하지 않는다.
  • Gemma reasoning/tool-parser 출력을 실패로 판정하거나 exact-output smoke를 기본 성공 기준으로 삼지 않는다.
  • OpenAI-compatible 요청 성공만으로 provider snapshot capacity 관측 성공을 선언하지 않는다. public Control Plane status가 접근 가능할 때만 in_flight/queued 관측 성공을 함께 남기고, 접근할 수 없으면 capacity snapshot 미관측으로 분리 보고한다.
  • 이 프로젝트 전용 배포 절차를 agent-ops/rules/common/_templates 또는 common skill에 넣지 않는다.