누적된 잠금·승인·증거 체인이 구현과 완료를 반복 차단해 작업 비용을 키웠다. 보안·데이터 손상·명시적 외부 의존성만 차단 조건으로 남기고 로드맵과 스킬의 기본 흐름을 단순화한다.
20 KiB
| test_env | test_profile | domain | verification_type | last_rule_updated_at |
|---|---|---|---|---|
| dev | edge-smoke | edge | smoke | 2026-08-15 |
edge-smoke dev 테스트
읽기 조건
apps/edge/**변경 또는 edge registry, transport, service, console, OpenAI-compatible/A2A 입력 표면 dev 검증 판단이 필요한 경우
적용 범위
apps/edge/cmd/edge/**apps/edge/internal/bootstrap/**apps/edge/internal/transport/**apps/edge/internal/service/**apps/edge/internal/events/**apps/edge/internal/input/**apps/edge/internal/openai/**apps/edge/internal/opsconsole/**apps/edge/internal/node/**
분류
- domain: edge
- verification_type: smoke
- scope: edge 실행 그룹, node registry, input surface baseline
환경
- host: local checkout. dev runtime, external CLI, shared port evidence가 필요하면 원격 runner를 사용한다.
- port: compose Edge-Node TCP transport
19003; dev artifact/bootstrap HTTP 후보18082, dev Edge OpenAI-compatible HTTP 후보18083, dev Edge metrics 후보19101. - runtime: Go
1.24 - package manager: Go modules / Makefile
- docker: unit/smoke quick check는 Docker를 요구하지 않는다. compose dev 검증은
docker compose --env-file .env.dev.example ...로 수행한다. - external service: dev artifact/base URL 후보
http://toki-labs.com:18082, compose Edge runtime 주소 후보toki-labs.com:19003, dev-runtime provider pool native Edge 주소 후보toki-labs.com:18084 - model endpoint: dev OpenAI-compatible base URL 후보
http://toki-labs.com:18083/v1 - credential: token/secret 원문은 문서에 기록하지 않는다.
dev-runtime provider pool 인벤토리
dev-runtime provider pool과 4-node 연결 상태를 점검할 때는 agent-test/inventory-dev.yaml의 machine-readable 값을 우선하고, 원격 runner ssh toki@toki-labs.com의 /Users/toki/agent-work/iop-dev checkout을 기준으로 한다.
Claude Anthropic-compatible 단일 요청 Agent 실행을 검증할 때는 Claude가 보낸 실제 Edge /v1/messages ingress POST 수를 계수한다. PASS 기준은 정확히 1회이며, 같은 endpoint·사용자 요청·Claude 세션 또는 logical request id 하나는 이를 대체하지 않는다. Harness는 supervised child에만 CLAUDE_CODE_MAX_RETRIES=0과 CLAUDE_CODE_DISABLE_TERMINAL_TITLE=1을 고정해 SDK retry와 별도 session-title Messages 요청을 제거하고 parent/user Claude 설정은 변경하지 않는다. IOP 내부 Plan/Work/Review provider 응답은 선택적 문자열 message.reasoning_content를 검증 후 폐기하며 stage 결과, artifact, caller 응답, 관측 로그에 보존하지 않는다. Gemini extra_content.google.thought_signature는 Plan/Review의 정확한 비공개 구조에서만 허용한다. terminal text signature는 폐기하고 Review tool-call signature는 같은 요청의 다음 Gemini assistant tool-call message에만 그대로 되돌려 보내며 Work, artifact, 결과, 로그에는 남기지 않는다. plan/work/review를 caller나 외부 test harness가 각각 호출하거나 Claude-facing tool_use/tool result continuation으로 이어 간 과거 다중 요청 실험은 protocol bridge와 model/provider 연결 evidence로만 보존하고 단일 요청 acceptance로 재사용하지 않는다. 이 경로의 stage와 workspace tool loop는 IOP Edge와 operator가 승인한 IOP Node가 소유하며 Agent-Ops dispatcher와 Pi를 실행 경로 또는 test harness로 사용하지 않는다. 현재 구현은 darwin|linux Node catalog와 exact host matching만 지원하고 Windows는 fail-closed다; 선택된 dev runner의 OS는 실행 evidence일 뿐 caller-visible 기능 selector가 아니다.
- Edge config:
build/dev-runtime/edge.yaml - Edge id:
edge-toki-labs-dev - Control Plane HTTP:
http://127.0.0.1:18001 - bootstrap HTTP:
http://toki-labs.com:18082 - Edge OpenAI-compatible base URL:
http://toki-labs.com:18083/v1 - Edge-Node TCP transport:
toki-labs.com:18084 - active model aliases:
ornith:35b(GX10/OneXPlayer, raw capacity7),ornith-fast(RTX5090),qwen3.6:35b(mac-mlx-vllm). RTX5090은ornith:35b후보가 아니며laguna-s:2.1은 stopped rollback 자산이라 active provider capacity가 없다. - host Pi dispatcher profile:
agent-test/inventory-agent.yaml의environments.dev.agents.pi기준. 현재 기본 provider/model/thinking level은iop/glm-5.2/high이고, dispatcher local-model route는iop/ornith:35b/high다. 두 모델 모두 IOP Edgehttp://toki-labs.com:18083/v1을 사용하며 Pi local direct providers는 제거된 상태다. credential 원문 대신 같은 inventory의 SOPStoken_ref만 기준으로 삼는다. - provider/model separation: GX10 Ornith는
qwen3_xml/qwen3, mac Qwen은qwen/qwen3, Lemonade Ornith는 저장된 runtime profile을 사용한다. stopped Laguna의poolside_v1profile이나 dev-corpgemma4profile을 이들 active provider에 섞지 않는다.
노드 후보:
- mac CLI + MLX provider node:
mac-codex-node/mac-codex- SSH/user:
ssh toki@toki-labs.com - 목적:
cliadapter,codex app-server+mac-mlx-vllmprovider resource - workspace:
/Users/toki/agent-work/iop-workspace/nomadcode - MLX vLLM provider:
mac-mlx-vllm- provider endpoint:
http://127.0.0.1:8002/v1 - served model:
mlx-community/Qwen3.6-35B-A3B-4bit - capacity baseline:
2 - priority baseline:
2 - workdir:
/Users/toki/agent-work/iop-mlx-vllm - runtime baseline:
vllm-mlx,--max-num-seqs 2,--max-kv-size 262144,--max-request-tokens 262144,--use-paged-cache --paged-cache-block-size 64 --max-cache-blocks 4096,--enable-auto-tool-choice --tool-call-parser qwen --reasoning-parser qwen3,--default-chat-template-kwargs {"enable_thinking": true} - KV policy: per-call window bound
262144, one full context-size setting - long-context admission baseline:
total_context_tokens=262144,long_context_capacity=1(KV budget262144fits one full 262144-window request; long slot count is not the normal capacity2)
- provider endpoint:
- SSH/user:
- GX10 vLLM node:
gx10-vllm-node/gx10-vllm- SSH/user:
ssh toki@192.168.0.91 - provider endpoint:
http://192.168.0.91:8001/v1 - served model:
ornith:35b - capacity baseline:
4 - priority baseline:
1 - runtime baseline: image
vllm/vllm-openai:nightly-aarch64, modeldeepreinforce-ai/Ornith-1.0-35B-FP8revision1ab57ce0b44950e498a88756f40ad1ed4d0f30ca,--served-model-name ornith:35b,--max-model-len 262144,--max-num-seqs 4,--gpu-memory-utilization 0.50,--enable-prefix-caching,--enable-auto-tool-choice --tool-call-parser qwen3_xml,--reasoning-parser qwen3,--trust-remote-code,--language-model-only,--override-generation-config '{"temperature":0.6,"top_p":0.95,"top_k":20}' - long-context admission baseline: conservative
total_context_tokens=1048576,long_context_capacity=4; current startup reports GPU KV cache1173993tokens and full-context concurrency4.48x. - runtime ownership: active container는
iop-vllm-ornith35b-fp8; stoppediop-vllm-laguna-s21은 명시적 rollback 전용이며 provider capacity에 포함하지 않는다. - reasoning baseline:
chat_template_kwargs.enable_thinking으로 model-native reasoning을 제어하고qwen3_xml/qwen3parser를 사용한다. - workspace:
/home/toki/iop-gx10-vllm
- SSH/user:
- OneXPlayer Lemonade node:
onexplayer-lemonade-node/onexplayer-lemonade- SSH/user:
ssh r0bin@192.168.0.59 - 접속 기준: 현재 작업 호스트에서 직접 SSH
- Node provider endpoint:
http://127.0.0.1:8001/v1(OneX host-local llama backend) - Lemonade lifecycle endpoint:
http://192.168.0.59:13305/v1 - served model:
ornith:35b(--alias); backend model은Ornith-1.0-35B-GGUF-llamacpp-tp1-Q5_K_M - capacity baseline:
3 - priority baseline:
2 - load baseline: checkpoint
LordNeel/Ornith-1.0-35B-GGUF-llamacpp-tp1:Q5_K_M, backendvulkan, ctx size524288,llamacpp_args="--spec-type none --alias ornith:35b -cb -fa on -b 4096 -ub 1024 --kv-unified --temp 0.6 --top-p 0.95 --top-k 20",save_options=true - long-context admission baseline:
total_context_tokens=524288,long_context_capacity=2; 고정-np없이/slots가 자동 slot 4개와 각n_ctx=262144를 보고하고 Edge normal capacity는3으로 제한한다. - workspace:
C:/Users/r0bin/iop-field
- SSH/user:
- RTX5090 Lemonade node:
rtx5090-lemonade-node/rtx5090-lemonade- SSH/user:
ssh iop-dev-rtx5090 - 접속 기준: 현재 작업 호스트의 local SSH config alias와 public-key batch 인증
- provider endpoint:
http://192.168.0.111:13305/v1 - served model:
Ornith-1.0-35B-GGUF-llamacpp-tp1-Q5_K_M - capacity baseline:
1 - priority baseline:
0 - load baseline: backend
cuda, Q5 GGUF, Q8 KV, ctx size262144,llamacpp_args="--chat-template-kwargs '{\"preserve_thinking\":true}' --kv-unified --min-p 0.00 --repeat-penalty 1.0 --spec-type none --temp 0.6 --top-k 20 --top-p 0.95 -b 512 -cb -ctk q8_0 -ctv q8_0 -fa on -np 1 -ub 256", Lemonadehost=0.0.0.0 - long-context admission baseline:
total_context_tokens=262144,long_context_capacity=1 - process baseline: IOP 관련 Windows 부팅 자동 실행은 비활성이고, 수동
remote-llm-toggle.ps1이 Lemonade Server, Ornith, IOP Node를 순차 UP/DOWN한다. Startup shortcut, Run entry, Task Scheduler, Windows service는 IOP dev 배포가 생성·재생성하지 않는다. - workspace:
C:/Users/r0bin/iop-field
- SSH/user:
GX10은 Ornith FP8 vLLM을 사용하고 OneXPlayer와 RTX5090 Lemonade는 Ornith Q5 GGUF를 사용한다. stopped Laguna 컨테이너와 poolside_v1 profile은 rollback 전용이며 active provider에 섞지 않는다.
OneXPlayer Lemonade Node는 원격 runner나 Edge host에서 다시 SSH하거나 proxy process로 띄우지 않는다. 현재 작업 호스트에서 OneXPlayer Windows host에 ssh r0bin@192.168.0.59로 직접 접속한 뒤 generated PowerShell bootstrap을 실행한다.
RTX5090 Lemonade Node도 원격 runner나 Edge host를 경유하지 않는다. 현재 작업 호스트에서 ssh iop-dev-rtx5090으로 public-key batch 접속한다. Windows 부팅 owner는 없으며 RemoteLLM_mode.ahk의 유일한 Run은 수동 remote-llm-toggle.ps1 호출이다. 기본 Toggle은 operator 동작에만 쓰고 자동 검증은 -Action Status|Up|Down을 명시한다. UP 완료는 Lemonade 0.0.0.0:13305, 정확한 Ornith profile, llama slot 1/n_ctx=262144, Node의 Edge 연결을 모두 확인하고, DOWN 완료는 Node/Lemonade/llama process와 port가 모두 사라진 상태로 판정한다.
mac-mlx-vllm provider는 mac-codex-node 소속 resource로, Edge host와 같은 macOS host에서 vllm-mlx process로 실행한다. vllm-mlx API는 외부에 직접 노출하지 않고 127.0.0.1:8002에 bind하며, Edge OpenAI-compatible adapter가 local bearer header로 호출한다. 운영 파일은 /Users/toki/agent-work/iop-mlx-vllm/vllm-mlx.pid, logs/vllm-mlx.stdout.log, logs/vllm-mlx.stderr.log를 기준으로 한다. Docker와 macOS 여유 메모리를 고려해 capacity는 2를 기본선으로 유지한다.
GX10/OneXPlayer/RTX5090 Ornith sampling은 temperature=0.6, top_p=0.95, top_k=20 기준을 유지한다. GX10은 qwen3_xml/qwen3 parser와 chat_template_kwargs.enable_thinking을 사용하고, Edge/Pi smoke는 high reasoning과 off zero-reasoning 및 tool-call을 각각 검증한다.
명령
- setup:
- lint:
- unit:
go test ./apps/edge/... - smoke:
./scripts/e2e-smoke.sh는 기본 포트 임시 설정을 쓰는 보조 smoke이므로 dev 포트 override 필요 여부를 먼저 확인한다. - e2e:
make test-e2e는 보조 smoke이며 full-cycle 실제 구동을 대체하지 않는다. - model: dev OpenAI-compatible profile을 띄운 경우
iop-edge smoke openai --base-url http://127.0.0.1:18083 - full-cycle: repo 내부 edge-node 진단,
iop-edge smoke openai, OpenAI-compatible 입력 표면 수동 검증
최소 검증
- 변경한 edge 패키지 또는
go test ./apps/edge/...를 실행한다. - registry, service, transport, console, HTTP/A2A 입력 표면을 바꾼 경우 edge-node 메시지 2회 왕복과 command 응답을 확인한다.
- OpenAI-compatible 경계를 바꾼 경우 dev
18083기준iop-edge smoke openai또는 동등한/healthz,/v1/models,/v1/responses확인으로 edge service와 node adapter 경로 수렴을 확인한다. - runtime
edge.yaml에서openai.enabled=true이면openai.provider_id가 현재 CLI/provider identity와 일치하는지config check로 검증한다. 이 값이 빠진 candidate는 배포하지 않는다. - OpenAI-compatible tool-call 경계(
apps/edge/internal/openai/**의 text tool-call 합성/validation)를 바꾼 경우 dev18083/v1/chat/completions에 Pi/Cline형tools[]요청을 non-stream/stream 각각 최소 1회 보내 raw text tool-call boundary smoke를 수행한다. token은 원격 환경 변수에서 주입하고 원문을 명령/로그/보고에 남기지 않는다. - dev provider-pool tool-call drift를 확인할 때는 active model group별 provider만 섞는다.
ornith:35bgroup은gx10-vllm/onexplayer-lemonadedirect와 Edge alias를 검증하고, RTX5090은ornith-fast에서만 검증한다. Qwen group은mac-mlx-vllmdirect와 Edgeqwen3.6:35b를 사용하며 stopped Laguna는 active drift 표본에 포함하지 않는다. - bootstrap/artifact 경계를 바꾼 경우 dev artifact/base URL 후보
18082가 local/test18080field baseline을 덮어쓰지 않는지 확인한다.
보조 검증
./scripts/e2e-smoke.sh는 edge-node 최소 생존 확인에 사용한다../scripts/e2e-openai-ollama.sh는 OpenAI-compatible Ollama 입력 표면 보조 확인에 사용한다.
판정 기준
- node 등록,
/nodes, console 메시지 전송, 기대 payload를 포함한[node-*-message]출력, 같은 run의 complete event가 확인된다. - node 로컬
[node-message]payload 라인 목록과 edge[node-*-message]payload 라인 목록이 run별로 내용/순서까지 동일해야 한다. - edge complete는 같은 run의 마지막
[node-*-message]이후에만 정상이다. - OpenAI-compatible smoke에서
/healthz,/v1/models,/v1/responses가 기대 상태로 응답한다. - raw text tool-call boundary smoke: Pi/Cline형
tools[]요청에서 응답 body와 SSE delta 어디에도<tool_call>,{{,<|mask_end|>원문이 성공 content로 남지 않는다. 요청tools[]에 있는 valid raw text tool-call은message.tool_calls(또는 streamdelta.tool_calls)와finish_reason: "tool_calls"로 정규화되고, unknown tool hallucination이나 malformed 블록은 성공 content가 아니라 non-streamtool_validation_error(HTTP 502) 또는 SSEtool_validation_error이벤트로 끝난다. non-stream/strict buffered stream은 bounded retry 후 차단을 확인한다. 세부 payload와 계약은docs/edge-local-dev-guide.md의 Raw text tool-call boundary smoke와agent-contract/outer/openai-compatible-api.md를 따른다. - raw boundary smoke evidence는 tracked 문서가 아니라 ignored run 위치(
agent-test/runs/**)나 code-review output path에 저장하고, 저장물에도 token 원문을 남기지 않는다. - provider-pool dispatch는
in_flight >= capacity인 provider를 후보에서 제외하고, 남은 후보 중 가장 낮은in_flight레벨을 먼저 선택한다. 같은in_flight레벨 안에서는 낮은 priority 값과 rotation으로 분산한다. - dev-runtime managed capacity smoke는 같은 principal token으로 authenticated route alias를 먼저 조회한다. explicit
resource_selector는 정확히 그 provider 하나만,defaultselector는 route profile/upstream과 model group이 모두 일치하는 healthy provider만 eligible pool로 본다. 현재ornith:35b는 GX104+ OneXPlayer3,ornith-fast는 RTX50901이며 다른 provider capacity를 더하지 않는다. Chat/Responses를 alias별로 실행하고 eligible totalcapacity + 1요청에서 provider별 exact peak와 queue를 확인한다. - managed smoke는 실제 emitted request JSON의 Unicode rune 수와
runes/4 + runes/16estimate를 계산하고long_context_threshold_tokens와 대조한다. normal qualification은capacity, 별도 long-context 시나리오는long_context_capacity를 사용한다. 장문 반복/liveness payload로 normal capacity를 증명하거나 normal 요청으로 long slot을 증명하지 않는다. stopped Laguna는 capacity가 없고, unprojected Qwenqwen3.6:35b만 기존 model-group capacity2기준을 유지한다. - capacity smoke 완료 후 대상 provider의
in_flight=0,queued=0회복을 확인한다. - long-context admission 시나리오(normal 10-way, mixed long/normal, all-long-slot-full)와 최종 회복 근거는
agent-test/dev/long-context-admission-smoke.md와scripts/e2e-long-context-admission-smoke.sh를 사용한다. /v1/responses와/v1/chat/completions는 각각 짧은 입력에서 7001200 token 수준의 구조화된 응답을 유도하고 provider-native thinking을 제한하며 50100ms 간격으로 status를 polling한다. 각 요청의 HTTP 200, endpoint-native success terminal 정확히 1개,[DONE]정확히 1개, selected provider의 eligible capacity 미초과, exact peak와 queue, 최종 0 회복을 별도 증거로 남긴다.- 2026-08-15
ornith:35bdefault pool Chat 검증은 8/8 HTTP 200과 정상 terminal, GX10peak in_flight=4, OneXPlayerpeak in_flight=3, 합산 peak7, queue peak2, RTX peak0, final0/0으로 통과했다. 별도 Responses 검증은 5/5 HTTP 200과 각response.completed는 확인됐지만[DONE]terminal이 누락되어 fail-closed로 미통과 상태다. 이 미통과를 Responses capacity 완료 근거로 사용하지 않는다. - managed smoke invocation마다 ignored
agent-test/runs/**아래 mode0700unique directory와 immutable run id를 생성한다. manifest가 소유하고 현재 run/dispatch 이후 생성된 request/result/status만 판정하며 stale/missing/foreign-run body는 실패한다. tracked/review evidence에는 sanitized summary의 run id, script hash, alias, selected provider, endpoint, computed shape/class, terminal count, peak/queue/final counter, outcome만 허용하고 token/header, route/slot id, prompt, response body와 출력은 기록하지 않는다. - Qwen provider-pool smoke는 thinking/reasoning 텍스트가 포함될 수 있다. 추론 출력 자체를 실패로 보지 말고 HTTP 성공, model alias, final marker 포함 여부, provider node log/run count 증가로 판정한다. 응답 전체가 특정 token과 정확히 같은지 비교하는 strict exact-match는 이 profile의 기본 판정으로 쓰지 않는다.
- Qwen provider를 agent/tool-call 용도로 검증할 때는 일반 chat smoke와 별도로 forced tool call, auto tool call, streaming
delta.tool_calls, multi-turn tool result 후 최종 답변을 확인한다. raw native marker나 reasoning text가 assistant content로 새면 해당 model/runtime의 parser/template profile 미확정으로 보고한다. - Qwen runtime에는 Qwen 전용 parser/template 검증값만 사용한다. dev-corp Gemma 계열의
tool_call_parser=gemma4,reasoning_parser=gemma4, Gemma4 chat template/profile을 Qwen provider에 복사하지 않는다. - bootstrap 사용자 명령은 완성된 URL과 positional token 하나만 포함한다.
기준 출력 예시
edge> /nodes
[edge] sent run_id=...
[node-*-message] IOP_EXPECTED_REPLY
[node-*-event] complete
차단 기준
- dev host 또는 Edge-Node TCP port 접근이 불가능하다.
- 외부 CLI profile 검증에 필요한 CLI 설치, 계정, provider 상태가 없다.
- dev artifact/model/metrics 포트가 기존 field baseline과 충돌한다.
- Node 등록 시
openai_compat adapter instance key "<provider-id>" conflicts with provider id가 발생한다. 이는 agent orchestration 차단이 아니라 Edge config mapper 또는 stale binary 문제다. provider/adapter 정의를 삭제하지 말고 candidate source identity와go test -race ./apps/edge/internal/node를 확인한 뒤 Edge를 먼저 교체한다.
보고 항목
- 실행한 명령:
- 성공한 검증:
- 실패/차단된 검증:
- 생략 사유:
- 남은 위험:
금지 사항
- secret, token, 개인 endpoint 원문은 tracked 파일에 기록하지 않는다.
- field baseline 포트(
18080,18081,19090,19092)를 dev 전용 포트로 재사용하지 않는다.