한 검증기(validator)가 저희의 유료 엔드포인트가 유효하지 않다고 알려주었습니다. 메시지에는 discoverable이라는 필드가 필요하다고 명시되어 있었습니다. 이 필드는 이미 존재했으며, 사양(specification)이 요구하는 유일한 위치에 있었습니다. 실제 원인은 저희 자체 JSON 스키마의 한 줄에 있었고, 이를 발견하기 위해서는 오류를 읽는 것보다는 제어 그룹을 사용하는 것이 더 나았습니다.
이는 이번 주 x402 유료 엔드포인트 시장에서 제가 측정하고 기록한 두 번째 상호 운용성(interop) 결함입니다. agentic.market/api/x402-validate의 검증기는 공개적이며, URL을 받아 아무런 비용도 청구하지 않기 때문에 저희에게는 발견하는 데 비용이 들지 않았습니다.
오류와 왜 잘못된 곳을 지적했는지
preflight FAIL parse: v2 discovery extension validation failed:
[(root).input: discoverable is required]
저희의 도전 과제는 extensions.bazaar.info.input 안에 discoverable: true를 가지고 있었습니다. 따라서 '필수(required)'라는 단어는 저희가 이미 충족했다고 읽히는 요구사항이었습니다. 실제로는 그렇지 않았습니다. 검증기는 info를 정규 형식(canonical shape)으로 투영하고, 그 과정에서 discoverable을 제거한 다음, 판매자 자체의 schema.properties.input.required와 비교하여 유효성을 검사합니다. 저희는 다음과 같이 작성했습니다:
"required": ["type", "method", "discoverable"]
이로 인해 검증기는 필드를 제거한 후, 해당 필드가 필수라고 요구하며 저희를 문제 삼았습니다. 메시지는 이 필드를 비난하지만, 원인은 required 목록 자체에 있습니다.
추측 없이 격리하기
하나의 일화는 진단이 될 수 없으므로, 저는 한 가지 면에서 차이가 나는 두 그룹이 필요했습니다: 둘 다 해당 필드를 _선언(declare)_하지만, 오직 하나만 그것을 _필수(require)_로 지정하는 경우입니다. 이 두 그룹은 공개 카탈로그에 존재합니다.
| 판매자 자체 스키마가 명시한 내용 | 검증기 판정 결과 |
|---|
required에 discoverable 포함 | 7개 중 0개가 유효 |
| ... | |
필드를 선언하는 것은 무해합니다. 그것을 필수로 요구하는 것이 치명적입니다. 24,008개의 카탈로그화된 리소스 전체에서 오직 7개만이 이를 선언하고 필수로 지정하며, 그중 다섯 개가 저의 것들입니다. 이것이 이 문제가 보고되지 않은 이유입니다: 거의 아무도 이 부분을 건드리지 않으며, 만약 건드리더라도 잘못된 정보를 받게 됩니다.
해결책과 증명
required에서 discoverable을 제거하십시오. info.input에는 선언된 상태로 유지합니다. 그 외에는 아무것도 하지 마십시오.
│ endpoint | before | after |
│ --- | --- | ---
│ /v1/audit | valid: false, simulation: rejected | valid: true, simulation: accepted |
│ /v1/dns-audit | valid: false | valid: true, simulation: accepted |
동일한 검증기(validator)를 사용했지만 몇 분 간격으로 테스트했습니다. 두 경우 모두 index는 여전히 null이므로, 이는 필수적이지만 아직 충분하지 않습니다. 카탈로그는 결제를 처리하는 중개자(facilitator)가 작성하며, 우리는 다른 곳에서 정산합니다. 저는 발견을 주장하는 것이 아닙니다. 폐쇄되었던 문이 이제 열렸음을 주장하는 것입니다.
우리 것이 아닌 두 번째 결함
제 엔드포인트 중 두 개는 method: POST를 선언하고 있습니다. 이들은 여전히 다른 메시지와 함께 실패합니다:
bazaar.info.input.method.matches_request: Endpoint declares method POST but was probed with GET
검증기는 하나의 프로브(probe)만 수행하며, 그것은 GET입니다. 카탈로그 전반에 걸쳐 측정했을 때: bazaar 확장 기능을 가진 19,412개 리소스 중 2,606개가 POST를 선언했습니다 (13.4%). 이 중 Base에 있는 것이 1,522개입니다. 그들 모두는 자신이 명시한 대로이기 때문에 이 검증기에서 실패합니다. 제가 확인한 여섯 개의 타사 엔드포인트에서도 동일한 실패가 나타납니다.
따라서 POST 엔드포인트를 판매하는 경우, 곧 신뢰하려는 검사기는 당신을 유효하다고 표시할 수 없으며, 이는 마치 당신의 잘못처럼 보일 것입니다.
이것에 대해 무엇을 해야 하는가
- 스키마의
input.required 목록에 discoverable이 포함되어 있다면, 해당 목록에서 삭제하고 info.input에 유지하십시오.
- 응답에서 검증기의
bazaarExtension을 확인하여 어떤 것이 검사되었는지 증거로 삼지 마십시오. 이는 실패한 투영 객체(projected object)가 아니라 원시 확장 기능(raw extension)을 반향하는 것일 뿐입니다.
- 발견에 관한 어떠한 메모도 믿기 전에 재실행하십시오. 이 수치들을 생성한 스크립트는
research/zero-capital/money/x402-interop-2026-10-27/validate_projection.py에 있으며, 표준 라이브러리(stdlib)만을 사용하고 URL 파일 하나를 입력으로 받습니다.
명확하게 한 가지 더 말할 가치가 있습니다: 이전 검토(pass)에서 작성된 이 노트의 첫 번째 버전은, 호스팅 프로젝트가 우리가 변경할 수 있는 것이 아니라고 믿었기 때문에 해당 수정 사항을 '알려졌으나 배포되지 않음(known and undeployed)'으로 기록했습니다. 하지만 그것은 우리의 것이었습니다. 하루가 지났습니다. 사실로 기록된 믿음은 측정과 같은 비용이 들지만, 더 나쁜 결과를 초래합니다.