{
  "test_id": "T38",
  "verdict": "pass",
  "observed": "run 1은 typed_config @type이 아예 알려지지 않은 EnvoyFilter를 썼다가 istiod의 admission webhook(validation.istio.io)에서 'referenced type unknown'으로 차단되어 Envoy까지 도달하지 못했다. run 2에서는 실존하는 등록된 확장 타입(envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit)을 쓰되 token_bucket.max_tokens=0으로 설정해 구조적으로는 유효한 TypedStruct이지만 proto 제약조건(PGV, uint32 gt:0)을 위반하는 페이로드로 바꿨다. 이 EnvoyFilter는 client 워크로드에만 적용되도록 workloadSelector app:client로 스코프했고, admission webhook을 통과해 클러스터에 생성됐다('envoyfilter.networking.istio.io/broken-filter-client-only created', 경고만 출력). 적용 후 istiod 로그에 'ADS:LDS: ACK ERROR client.istio-vt-t38-r2-... Internal:Error adding/updating listener(s) ...: Proto constraint validation failed (LocalRateLimitValidationError.TokenBucket ... MaxTokens: value must be greater than 0)'가 반복적으로 남아, istiod가 실제로 LDS를 push했고 client의 Envoy가 이를 진짜로 NACK했음을 확인했다. Istio 1.30의 istioctl proxy-status 요약 테이블은 더 이상 타입별 SYNCED/STALE 컬럼을 노출하지 않아(SUBSCRIBED TYPES 개수만 표시) 원래 커맨드 5(칼럼이 STALE로 표시)는 문자 그대로는 관측되지 않았지만, 'istioctl proxy-status client.<ns>'(단일 프록시 sync diff)로 동등하거나 더 정밀한 신호를 얻었다: 결과가 'Clusters Match / Listeners Don't Match'였고, client->echo 트래픽이 실제로 타는 outbound 리스너 0.0.0.0_80에 대해 istiod가 계산한 의도된 리스너(activeState 비교 대상)에는 local_ratelimit 필터가 포함돼 있는 반면, Envoy가 실제로 서빙 중인 activeState에는 그 필터 없이 router로 바로 이어지는 이전(정상) 구성이 그대로 남아 있었고, 별도의 errorState 블록에 실패한 시도(local_ratelimit 포함 리스너 전체)와 lastUpdateAttempt 타임스탬프, 그리고 정확히 동일한 'Proto constraint validation failed ... MaxTokens: value must be greater than 0' 에러 문자열이 기록돼 있었다. 즉 istiod 계산 단계는 문제없이 통과했고 Envoy가 실제로 그 config를 받고 나서 거부했다는 뜻이라 admission-webhook 차단과는 명백히 다른, 진짜 NACK 경로다. 이 모든 시간 동안 before_nack=200, after_nack=200(재확인 curl 포함 200)로 client->echo 트래픽은 끊김 없이 200을 유지했다. 즉 Envoy는 NACK한 리스너 업데이트를 폐기하되 라이브 트래픽에 반영하지 않고, 직전 정상 config(activeState)로 계속 서빙했다 - fail-safe 동작이 direct하게 확인됐다.",
  "adaptation_note": "harness-notes.md CORRECTION(2026-07-05) 적용: curl은 FQDN(*.svc.homelab.local) 대신 SHORT k8s 서비스명(http://echo/)으로 실행 - 정상적으로 vhost/RDS와 매치되어 200 확인. 이 테스트에는 Istio 리소스 host나 ServiceEntry가 없어 svc.cluster.local 치환이나 외부호스트 대체는 해당사항 없음. 테스트별 가이던스(webhook 통과 + Envoy NACK 페이로드 탐색)에 따라 스펙의 원본 EnvoyFilter(불명 Any 타입)를 폐기하고 LocalRateLimit(max_tokens=0, PGV gt:0 위반) 페이로드로 교체 - 1회 시도만에 admission 통과 + 실제 NACK 재현 성공, 추가 시도 불필요.",
  "claims": [
    {
      "doc": "xds__note-data-plane-sync-state",
      "cid": "C10",
      "empirical": "supports-claim",
      "note": "istiod가 실제로 LDS push -> client Envoy가 PGV 제약 위반으로 실제 NACK(ADS:LDS ACK ERROR 로그) -> Envoy activeState는 여전히 NACK 이전 정상 리스너를 서빙, errorState에 실패한 시도만 기록 -> client->echo curl이 before/after 모두 200 유지. Envoy가 NACK한 설정을 버리지 않고 직전 good config로 계속 서빙한다는 주장을 직접 관측으로 확인."
    },
    {
      "doc": "blog:xds-envoy_xds-api-layers",
      "cid": "C10",
      "empirical": "supports-claim",
      "note": "동일 관측. 추가로 istiod의 admission-time 검증(type resolution만 체크, PGV 값 제약은 미체크)과 Envoy의 config-ingestion-time PGV 검증이 서로 다른 레이어에서 동작함을 보여줘, 왜 어떤 잘못된 EnvoyFilter는 webhook에서 막히고(run1 사례) 어떤 것은 webhook을 통과해 진짜 xDS NACK 경로까지 가는지(run2 사례)를 구분하는 근거가 됐다."
    }
  ]
}
