0 · 概述

本测试验证的是四方架构里的 ③ AISA verify 收费判断节点。一次"付费爬取"由四方协作:爬虫 → 阿里 ESA(收费墙)→ AISA verify(收费判断)→ AISA Agent(爬虫账户/扣费)。AISA verify 是一个纯决策接口:接收 ESA 转发的请求信息,返回"放行 / 拦截 / 该收多少钱"的决策,不返回网页内容本身(内容由 ESA 在拿到放行结果后回源取得)。

esa-pay-test.sh 用一个真实有内容的 publisher(lr-pay-crawler1.alicdn-test.com,内容 = AgentFlare 站点)做端到端验证,既断言 verify 的决策,又扮演 ESA 在放行后回源取真内容,证明"付费前 402 → 扣费后拿到真实数据"闭环成立,并系统覆盖 verify 的全部 12 种返回值。

当前状态:new-dev(esa.aisa.one)实测 44/44 断言通过;12 种返回值 12/12 覆盖(11 实测断言 + 1 文档化,见 §5)。

📘 verify 接口完整文档:https://esa.aisa.one/cdn/docs.html(本文是测试文档,聚焦覆盖测试与返回值;接口规格以该文档为准)。

1 · 四方架构与测试焦点

角色(阿里会议口径)= 系统里的职责位置
阿里云② ESA 收费墙提供开关入口;把请求 header 转给 AISA;按 AISA 返回(欠费/拒绝/放行)决定行为ESA 控制台 + EdgeScript
AISA③ verify + ④ 爬虫账户提供规则配置接口;按 ESA 请求给出处理结果;扣费记账cdn-agent(CDN + Agent 模块)
爬虫负责人crawler operator和 AISA 达成协议并付费(充值)ai_crawler_accounts,扣费方
站点(域名)负责人① publisher在 ESA 开/关收费开关;配置目录规则;收内容收入AgentFlare 运营者,ai_publishers
本测试聚焦 ③:验证 AISA verify 能否正确「接收爬虫请求信息 → 给出正确返回值 → 正确记账」。①(站点在 ESA 控制台配置)和 ②(ESA 边缘行为)不在本脚本测试范围。

2 · 测试原理

2.1 verify 是决策层 —— 决策在 AISA,执行在 ESA

真实链路:爬虫 → ESA 边缘 → (回源前)调 verify → 据 accessGranted 放行/拦截 → 放行则 ESA 回源取内容返回爬虫。verify 只回 JSON 决策。所以脚本要验证"扣费后能拿到真内容",必须自己扮演 ESA:verify 放行后,再用 curl --resolve 直接打源站把真实 .data.json 取回来断言。

关键:源站本身不设防,拦截/收费的"执行"在 ESA。
verify 只给决策(放行 / 拦截 / 收多少钱),真正的拦截、收费由 ESA 据决策执行(403 → ESA 不回源)。因此:
· 直接 curl 源站(本测试 --resolve 8.216.18.127,绕过了 ESA)访问一个被判 block/members 资源 —— 照样能拿到内容;付费资源不付费直接打源站也能拿到。这是预期,不是 bug:源站不设防,收费墙在 ESA。
· 要验证「被 block 的 URL 对爬虫真的取不到」/「不付费真的拿不到」,必须让 ESA 在链路里据 verify 的 403/402 执行拦截。有两种端到端方式:
  方式①(内网联调):阿里 ESA 前置内网域名 lr-pay-crawler1.alicdn-test.com,从阿里内网访问 → ESA 据决策拦截/收费。
  方式②(公网上线,即生产形态):阿里 ESA 前置一个真实公网站点(如 agentflare.org),从公网访问 → ESA 据决策对外执行拦截/收费。
  两种都需要 ESA 端配好 EdgeScript(回源前调 verify、并据 403/402 放行/拦截),即"打开收费墙"。区别只是内网域名/内网访问 vs 公网域名/公网访问
· 故本脚本验证的是 ③ AISA verify 的决策正确 + 内容确实存在可回源;② ESA 真正执行拦截/收费是独立的一步(上述两种方式之一)。block 步骤(Step 5.6)只断言 verify 的 403 决策、不回源取内容

2.2 一个 URL,三种收费模式(目录即定价)

publisher 的规则按目录(正则前缀)定价,pricing.json 是 AgentFlare 与 AISA 之间的接口契约(字段与 ai_publisher_rules 表 1:1)。本测试的 publisher 含全部三种模式:

模式目录(示例)verify 行为
allow 免费^/guides/.*\.(data\.json|full\.md)$200 放行,不扣费(深层数据免费可取)
pay 收费^/crypto/.*\.(data\.json|full\.md)$ $0.01按价扣费,余额够 200、不够 402
block 拦截^/members/.*\.(data\.json|full\.md)$403,无论余额(内容存在但禁止爬取)

2.3 两种运行模式(非破坏性)

模式行为用途
--existing直接用后台已配置好的规则跑断言,全程不增删验证线上/UI 手配的真实配置(爬虫真正命中的那套)
--auto-config①快照 → ②清空 → ③/discover 读 pricing.json → ④/rules/bulk-import 导入 → ⑤跑断言 → ⑥恢复①的原始规则演示完整接入闭环 + 验证 discover/bulk-import 端点
不带参数 = 只打印说明、不执行测试。必须显式给 --existing--auto-config 才会开始测,避免误跑动到后台。

3 · Publisher 接入界面(三种接入模式)

站点负责人在 ESA 点 "Charge" 进入 esa.aisa.one/cdn/content-controls.html 配置目录规则。第一次进入会让其选择"我们怎么了解你的站点内容",即下面三张模式卡片(原样取自实际界面,英文同线上)。切换模式只改变"怎么添加规则",不影响已有规则

▸ 下方为实际界面的静态再现(便于交接/直观感受);真实可交互界面见上方链接。
Auto-discovery
We scan your site for a pricing manifest (pricing.json) or, if none, your robots.txt + sitemap.xml, and propose directory rules. Fastest if your site already exposes its structure.
Recommended
Upload a list
You (or the platform) upload the path → price list directly — paste JSON / CSV or a file. Best when the directory list is curated off-platform and handed to AISA.
Manual
Auto-learning
Run in observe mode: for a while all bots are allowed and we only record which requests returned real content — then we summarize those into directory rules for you to price.
Learns over time
自动发现(推荐,抓 pricing.json/sitemap) · 上传清单(阿里/站点贴 JSON/CSV) · 自主学习(先全放行、观察日志再归纳目录)

3.1 点击 "Auto-discovery" 后(我们用的就是这个)

点第一张卡片 → 弹出一个发现动画(扫站),随后给出候选规则列表供勾选/改价/导入:

Discovering your content… Fetching pricing.json · Reading sitemap.xml · Summarizing directories…
Source: pricing.json (lr-pay-crawler1.alicdn-test.com)8 rule(s) · ☑ Select all
^/crypto/.*\.(data\.json|full\.md)$PAY$0.01
^/markets/.*\.(data\.json|full\.md)$PAY$0.01
^/social/.*\.(data\.json|full\.md)$PAY$0.005
^/predictions/.*\.(data\.json|full\.md)$PAY$0.01
^/research/.*\.(data\.json|full\.md)$PAY$0.02
^/scholar/.*\.(data\.json|full\.md)$PAY$0.02
^/guides/.*\.(data\.json|full\.md)$ALLOWFree
^/members/.*\.(data\.json|full\.md)$BLOCK
勾选后改价/改模式 → 一键导入 ai_publisher_rules

导入后这 8 条即生效,正是 §7 运行示例里 --existing 模式直接验证的那套规则(6 pay + 1 allow + 1 block)。上传/自主学习两种模式的最终产物同样是这张规则表,只是来源不同。

4 · esa-pay-test.sh 用法

# 不带参数 → 只显示说明
./esa-pay-test.sh

# 用后台已配置规则验证(非破坏性)
./esa-pay-test.sh --existing

# 自配置全链路(discover+import),跑完恢复原配置
./esa-pay-test.sh --auto-config

# 打本地 dev
API_BASE=http://localhost:3000 ./esa-pay-test.sh --auto-config

默认全程统一用一个真实内网域名(收费身份 / 回源 / 发现一致,不糊涂):

变量默认值含义
PUBLISHER_DOMAINlr-pay-crawler1.alicdn-test.comverify 里的 publisherDomain(ESA 发来的 Host)
ORIGIN_HOST / IP / SCHEMElr-pay-crawler1.alicdn-test.com / 8.216.18.127 / http扮演 ESA 回源取真内容(--resolve 到源站)
DISCOVER_DOMAIN / SCHEME= ORIGIN_HOST / ORIGIN_SCHEME--auto-config 扫描发现的域名
API_BASEhttps://esa.aisa.oneverify + publisher/agent API 入口
GATEWAY_TOKEN(已内置 esa new-dev 默认)ESA→AISA 网关鉴权 token,可 env 覆盖
该内网域名容器内解析:cdn-dev 容器 docker run 加了 --add-host=lr-pay-crawler1.alicdn-test.com:host-gateway(+autotest 子域)→ 经宿主 nginx vhost 取 AgentFlare 内容;本机 dev 经 /etc/hosts 解析。

5 · ★ AISA verify 全 12 种返回值矩阵

以下 12 种 (statusCode + error) 已对 lib/access-control/core.ts 实测确认,并在 esa-pay-test.sh Step 6 逐一断言。error 字段现已全部小写。

#statuserror触发条件脚本如何触发覆盖
1200命中 allow 规则verify /guides/*.data.json✅ 实测
2200无规则匹配(default allow)verify 一个未匹配路径 /nomatch-*.txt✅ 实测
3200付费扣费成功verify pay 资源 + crawlerAutoPrice:true,余额足✅ 实测
4402invalid_token没带 / 错误 / 禁用 token不带 X-AISA-Crawler-Token✅ 实测
5402insufficient_balance余额 < 价格全新零余额爬虫打 pay 资源✅ 实测
6402price_requiredpay 资源但不带任何价格意图(价格发现)verify pay 资源,无 autoPrice/exact/max✅ 实测
7402price_mismatchexact 模式价格与资源价不符crawlerExactPrice:"USD 9.99"(资源 $0.01)✅ 实测
8402price_too_highmax 模式预算 < 资源价crawlerMaxPrice:"USD 0.001"(资源 $0.01)✅ 实测
9400invalid_price_format价格字符串格式非法 / 币种不符crawlerExactPrice:"notaprice"✅ 实测
10403access_blocked命中 publisher block 规则verify /members/*.data.json✅ 实测
11401gateway_unauthorized网关 token 缺/错(ESA 身份,与爬虫 token 是两层独立鉴权)用错误的 Authorization: Bearer 网关 token✅ 实测*
12500internal_error服务内部异常(DB 故障等)黑盒不可主动稳定触发📄 文档化**

* 仅当本环境启用了网关鉴权(ESA_GATEWAY_TOKEN 已配,如 esa.aisa.one)才实测;灰度兼容环境(未配)无法触发,脚本自动标记为文档化覆盖。
** #12 仅在数据库/服务内部故障时返回,黑盒测试无法主动稳定触发,经代码审计(lib/http/response.ts errResponse 兜底)确认,文档化覆盖。

两层鉴权别混淆:402 invalid_token(爬虫 token 失败)和 401 gateway_unauthorized(ESA→AISA 网关 token 失败)是两条独立的鉴权链。前者是"哪个爬虫"的身份;后者是"请求是否真来自 ESA"的身份。

6 · 测试流程 Step 1–7

Step做什么
1注册 / 登录 publisher(domain = lr-pay-crawler1.alicdn-test.com)
2规则准备 —— --existing:用现有规则;--auto-config:快照→清空→/discover→/rules/bulk-import
3登录 + 充值测试爬虫(amazonbot / chatgpt / perplexitybot,各 +$100)
4付费资源三段断言:① 不带支付意图 → 402 price_required ② 带 crawlerAutoPrice → 200 + 精确扣费 ③ 扮演 ESA 回源 GET → 200 + 合法 JSON 真内容
5 / 5.5 / 5.6免费 .html/.md(默认放行)/ 免费深层数据 /guides(allow 规则)/ 拦截 /members(block:verify 返回 403,ESA 据此拦截;此步只断言 403 决策、不回源)
6AISA verify 全 12 种返回值覆盖(§4)
7汇总报告:PASS/FAIL + 12 返回值覆盖 + 本次扣费合计;--auto-config 先恢复原始规则

7 · 接口契约速查(给 ESA 对接)

verify 接口完整文档(端点详解 / 鉴权 / 全部参数 / 字段 / 在线测试):https://esa.aisa.one/cdn/docs.html。本节为对接速查,详尽规格以该文档为准。

6.1 端点 & 两层鉴权

POST /api/v1/access/verify
Authorization: Bearer <ESA_GATEWAY_TOKEN>     # ① 网关层:证明请求来自 ESA(server-to-server)
X-AISA-Crawler-Token: <crawler_token>          # ② 爬虫层:被扣费的爬虫身份
Content-Type: application/json

6.2 请求体

{
  "publisherDomain": "lr-pay-crawler1.alicdn-test.com",  // ESA 发来的 Host
  "resourceUrl":     "/crypto/binancecoin.data.json",    // 被访问资源路径
  "crawlerAgent":    "Mozilla/5.0 ... GPTBot/1.0 ...",   // 原始爬虫 UA(用于识别)
  // 价格意图三选一(pay 资源需要,否则返回 price_required):
  "crawlerAutoPrice": true,           // 自动按资源价扣费(推荐)
  "crawlerExactPrice": "USD 0.01",    // 精确价,必须等于资源价
  "crawlerMaxPrice":   "USD 0.50"     // 最高预算,需 ≥ 资源价
}

兼容别名:agentToken / agentExactPrice / agentMaxPrice / agentAutoPrice 等价于 crawler*。价格格式正则:^[A-Z]{3}\s+[0-9]+\.?[0-9]*$(如 USD 0.01)。

6.3 响应体(决策,不含内容)

{
  "accessGranted": true,           // ← ESA 据此放行/拦截的统一标志
  "statusCode": 200,               // 200/400/401/402/403/500
  "error": null,                   // 见 §5 的 12 种
  "charged": true, "chargeAmount": 0.01, "currency": "USD",
  "price": 0.01,                   // 该资源价(402 时也带)
  "crawlerIdentification": { "recognized": true, "identifier": "gptbot", "verified": null, "signed": null },
  "onboarding": "https://.../guide.html",   // 402 时引导充值
  "timestamp": "2026-..."
}
// 响应头 X-Request-Id: <requestId> —— 对账用

8 · 运行示例输出(两种模式,esa.aisa.one 实测)

下面是两种模式各完整跑一遍的真实输出(均 44 条断言全过)。

▸ 带 ▸ 说明琥珀色斜体行是额外注释,不是脚本输出,仅帮助阅读。
模式一:./esa-pay-test.sh --existing(用后台已配置规则,非破坏性)
========================================
esa-pay-test.sh — 真实 publisher 全链路验证
========================================
  模式            : 默认(用后台已配置规则,非破坏性)
  API_BASE        : https://esa.aisa.one
  Publisher domain: lr-pay-crawler1.alicdn-test.com
  Content origin  : http://lr-pay-crawler1.alicdn-test.com (--resolve → 8.216.18.127:80)
  Gateway auth    : enabled
  ▸ 说明:默认模式 —— 直接用后台已配好的规则,全程不增删(非破坏性)。

========================================
Step 1: Publisher 注册 / 登录 (domain=lr-pay-crawler1.alicdn-test.com)
========================================
✓ Publisher 登录成功 (id=18)

========================================
Step 2: 规则准备 (模式: existing)
========================================
▶ 使用后台已配置好的规则(非破坏性,不增删)
▶ 当前生效规则:
  共 8 条
    PAY	$0.01	^/crypto/.*\.(data\.json|full\.md)$
    PAY	$0.01	^/markets/.*\.(data\.json|full\.md)$
    PAY	$0.005	^/social/.*\.(data\.json|full\.md)$
    PAY	$0.01	^/predictions/.*\.(data\.json|full\.md)$
    PAY	$0.02	^/research/.*\.(data\.json|full\.md)$
    PAY	$0.02	^/scholar/.*\.(data\.json|full\.md)$
    ALLOW	$0	^/guides/.*\.(data\.json|full\.md)$
    BLOCK	$0	^/members/.*\.(data\.json|full\.md)$

========================================
Step 3: 登录 + 充值测试爬虫
========================================
  ✓ amazonbot@test.com (id=112) 已登录 + 充值 $100
  ✓ chatgptbot@test.com (id=114) 已登录 + 充值 $100
  ✓ perplexitybot@test.com (id=119) 已登录 + 充值 $100

========================================
Step 4: 付费资源 —— 402(未付) → 200(扣费) → 回源取真实内容
  ▸ 说明:付费资源三段断言 = ①未付→402 ②扣费→200 ③扮演 ESA 用 --resolve 回源取真 JSON。
========================================

▶ /crypto/binancecoin.data.json  (期望价 $0.01)
  ✅ 未付费被拦截 → 402 (price_required)
  ✅ 付费放行 → 200, 扣费 $0.01 (匹配)
  ✅ 回源 200 + 合法 JSON 真内容 {@context, analysis_md, canonical, category, data, description, facts, }

▶ /crypto/bitcoin.full.md  (期望价 $0.01)
  ✅ 未付费被拦截 → 402 (price_required)
  ✅ 付费放行 → 200, 扣费 $0.01 (匹配)
  ✅ 回源 200 + 非空内容 (2373 bytes)

▶ /markets/aapl.data.json  (期望价 $0.01)
  ✅ 未付费被拦截 → 402 (price_required)
  ✅ 付费放行 → 200, 扣费 $0.01 (匹配)
  ✅ 回源 200 + 合法 JSON 真内容 {@context, analysis_md, canonical, category, data, description, facts, }

▶ /social/regions/united-states.data.json  (期望价 $0.005)
  ✅ 未付费被拦截 → 402 (price_required)
  ✅ 付费放行 → 200, 扣费 $0.005 (匹配)
  ✅ 回源 200 + 合法 JSON 真内容 {@context, analysis_md, canonical, category, data, description, facts, }

▶ /predictions/fed-decision-in-june-825.data.json  (期望价 $0.01)
  ✅ 未付费被拦截 → 402 (price_required)
  ✅ 付费放行 → 200, 扣费 $0.01 (匹配)
  ✅ 回源 200 + 合法 JSON 真内容 {@context, analysis_md, canonical, category, data, description, facts, }

▶ /research/http-402-x402-how-ai-agents-pay-for-content.data.json  (期望价 $0.02)
  ✅ 未付费被拦截 → 402 (price_required)
  ✅ 付费放行 → 200, 扣费 $0.02 (匹配)
  ✅ 回源 200 + 合法 JSON 真内容 {@context, analysis_md, canonical, category, data, description, facts, }

▶ /scholar/mechanistic-interpretability-research-digest.data.json  (期望价 $0.02)
  ✅ 未付费被拦截 → 402 (price_required)
  ✅ 付费放行 → 200, 扣费 $0.02 (匹配)
  ✅ 回源 200 + 合法 JSON 真内容 {@context, analysis_md, canonical, category, data, description, facts, }

========================================
Step 5: 免费资源 —— verify 200 不扣费 + 回源取到内容
========================================

▶ /index.html
  ✅ 免费放行 → 200, 未扣费
  ✅ 回源 200

▶ /crypto/binancecoin.html
  ✅ 免费放行 → 200, 未扣费
  ✅ 回源 200

▶ /crypto/bitcoin.md
  ✅ 免费放行 → 200, 未扣费
  ✅ 回源 200

========================================
Step 5.5: 免费深层数据 (guides, 显式 allow 规则) —— 200 不扣费 + 回源取真 JSON
  ▸ 说明:guides 是显式 allow 规则,深层数据免费可取(区别于 Step 5 的“无规则默认放行”)。
========================================

▶ /guides/getting-started-with-http-402-pay-per-crawl.data.json
  ✅ allow 规则放行 → 200, 未扣费
  ✅ 回源 200 + 合法 JSON 真内容(免费深层)

▶ /guides/crawler-tokens-auto-pay-a-how-to.data.json
  ✅ allow 规则放行 → 200, 未扣费
  ✅ 回源 200 + 合法 JSON 真内容(免费深层)

========================================
Step 5.6: 被拦截目录 (members, block 规则) —— verify 返回 403(ESA 据此拦截)
  ▸ 说明:members 是 block 规则:verify 只给 403 决策;源站直访仍可取内容,真正拦截由 ESA 执行(见下方 ℹ)。
========================================

▶ /members/institutional-flow-report-where-smart-money-is-rotating.data.json
  ✅ block 拦截 → 403 (access_blocked),accessGranted=false

▶ /members/agent-infrastructure-landscape-vendor-deep-dive.data.json
  ✅ block 拦截 → 403 (access_blocked),accessGranted=false
  ℹ 注:此处只验证 verify 的 403 决策。源站本身不设防 —— 直接 curl 源站(绕过 ESA)仍能取到该内容,这是预期,不是 bug。
     真正的拦截由 ESA 据 403 不回源执行。端到端「URL 真被拦」需 ESA 在链路里,两种方式:
     ① ESA 前置内网域名(阿里内网联调)  ② ESA 前置公网站点 agentflare.org(生产形态)。详见 cdntest.html §2.1。

========================================
Step 6: AISA verify 全 12 种返回值覆盖
  ▸ 说明:12 种返回值逐一断言;#11 仅网关启用时实测(esa 已启用),#12 黑盒不可触发→文档化。
========================================

  ✅ #1 200 allow 规则(免费深层) → 200
  ✅ #2 200 无规则匹配(default allow) → 200
  ✅ #3 200 付费扣费成功 → 200
  ✅ #4 402 invalid_token → 402/invalid_token
  ✅ #5 402 insufficient_balance → 402/insufficient_balance
  ✅ #6 402 price_required → 402/price_required
  ✅ #7 402 price_mismatch → 402/price_mismatch
  ✅ #8 402 price_too_high → 402/price_too_high
  ✅ #9 400 invalid_price_format → 400/invalid_price_format
  ✅ #10 403 access_blocked → 403/access_blocked
  ✅ #11 401 gateway_unauthorized → 401 (错误网关 token 被拒)
  ℹ #12 internal_error(500)—— 仅 DB/服务内部故障时返回,黑盒不可主动触发,代码审计确认 → 文档化覆盖

  ▷ 返回值覆盖: 12/12  (实测断言 11 · 文档化 1)

========================================
Step 7: 汇总报告
========================================
  AISA verify 返回值覆盖: 11+1 = 12/12  (实测 11 · 文档化 1)
  本次付费扣费合计: USD 0.085
  Publisher 后台流水: https://esa.aisa.one/cdn/transactions.html

  ━━━━━━━━━━━━━━━━━━━━━━━━━
  ✅ PASS: 44
  ▸ 说明:44 条断言全过,本次扣费 $0.085。
  ❌ FAIL: 0
  ━━━━━━━━━━━━━━━━━━━━━━━━━
🎉 全部通过 — 注册→发现→定价→付费拿真内容 闭环成立
模式二:./esa-pay-test.sh --auto-config(自配置 discover+import,跑完恢复原配置)
========================================
esa-pay-test.sh — 真实 publisher 全链路验证
========================================
  模式            : --auto-config(自配置 discover+import,结束恢复原配置)
  API_BASE        : https://esa.aisa.one
  Publisher domain: lr-pay-crawler1.alicdn-test.com
  Content origin  : http://lr-pay-crawler1.alicdn-test.com (--resolve → 8.216.18.127:80)
  Gateway auth    : enabled
  ▸ 说明:自配置模式 —— 先快照→清空→discover→import,跑完恢复原配置(整体非破坏性)。

========================================
Step 1: Publisher 注册 / 登录 (domain=lr-pay-crawler1.alicdn-test.com)
========================================
✓ Publisher 登录成功 (id=18)

========================================
Step 2: 规则准备 (模式: auto-config)
========================================
▶ 已快照原始 8 条规则(结束时恢复)
  ▸ 说明:① 快照当前规则,结束时原样恢复。
▶ 清空现有规则 ...
▶ POST /api/publisher/discover (扫描 lr-pay-crawler1.alicdn-test.com) ...
  ▸ 说明:③ 调 /discover 抓 pricing.json → 解析出 8 条候选(manifest 来源)。
  ✓ 发现来源: manifest,候选规则 8 条
      PAY  ^/crypto/.*\.(data\.json|full\.md)$  $0.01
      PAY  ^/markets/.*\.(data\.json|full\.md)$  $0.01
      PAY  ^/social/.*\.(data\.json|full\.md)$  $0.005
      PAY  ^/predictions/.*\.(data\.json|full\.md)$  $0.01
      PAY  ^/research/.*\.(data\.json|full\.md)$  $0.02
      PAY  ^/scholar/.*\.(data\.json|full\.md)$  $0.02
      ALLOW  ^/guides/.*\.(data\.json|full\.md)$  
      BLOCK  ^/members/.*\.(data\.json|full\.md)$  
▶ POST /api/publisher/rules/bulk-import ...
  ✓ Imported 8 rule(s)
  ▸ 说明:④ 调 /rules/bulk-import 写入 ai_publisher_rules。
▶ 当前生效规则:
  共 8 条
    PAY	$0.01	^/crypto/.*\.(data\.json|full\.md)$
    PAY	$0.01	^/markets/.*\.(data\.json|full\.md)$
    PAY	$0.005	^/social/.*\.(data\.json|full\.md)$
    PAY	$0.01	^/predictions/.*\.(data\.json|full\.md)$
    PAY	$0.02	^/research/.*\.(data\.json|full\.md)$
    PAY	$0.02	^/scholar/.*\.(data\.json|full\.md)$
    ALLOW	$0	^/guides/.*\.(data\.json|full\.md)$
    BLOCK	$0	^/members/.*\.(data\.json|full\.md)$

========================================
Step 3: 登录 + 充值测试爬虫
  ▸ 说明:Step 3–6 与 --existing 模式完全相同(下方为真实输出,未省略)。
========================================
  ✓ amazonbot@test.com (id=112) 已登录 + 充值 $100
  ✓ chatgptbot@test.com (id=114) 已登录 + 充值 $100
  ✓ perplexitybot@test.com (id=119) 已登录 + 充值 $100

========================================
Step 4: 付费资源 —— 402(未付) → 200(扣费) → 回源取真实内容
========================================

▶ /crypto/binancecoin.data.json  (期望价 $0.01)
  ✅ 未付费被拦截 → 402 (price_required)
  ✅ 付费放行 → 200, 扣费 $0.01 (匹配)
  ✅ 回源 200 + 合法 JSON 真内容 {@context, analysis_md, canonical, category, data, description, facts, }

▶ /crypto/bitcoin.full.md  (期望价 $0.01)
  ✅ 未付费被拦截 → 402 (price_required)
  ✅ 付费放行 → 200, 扣费 $0.01 (匹配)
  ✅ 回源 200 + 非空内容 (2373 bytes)

▶ /markets/aapl.data.json  (期望价 $0.01)
  ✅ 未付费被拦截 → 402 (price_required)
  ✅ 付费放行 → 200, 扣费 $0.01 (匹配)
  ✅ 回源 200 + 合法 JSON 真内容 {@context, analysis_md, canonical, category, data, description, facts, }

▶ /social/regions/united-states.data.json  (期望价 $0.005)
  ✅ 未付费被拦截 → 402 (price_required)
  ✅ 付费放行 → 200, 扣费 $0.005 (匹配)
  ✅ 回源 200 + 合法 JSON 真内容 {@context, analysis_md, canonical, category, data, description, facts, }

▶ /predictions/fed-decision-in-june-825.data.json  (期望价 $0.01)
  ✅ 未付费被拦截 → 402 (price_required)
  ✅ 付费放行 → 200, 扣费 $0.01 (匹配)
  ✅ 回源 200 + 合法 JSON 真内容 {@context, analysis_md, canonical, category, data, description, facts, }

▶ /research/http-402-x402-how-ai-agents-pay-for-content.data.json  (期望价 $0.02)
  ✅ 未付费被拦截 → 402 (price_required)
  ✅ 付费放行 → 200, 扣费 $0.02 (匹配)
  ✅ 回源 200 + 合法 JSON 真内容 {@context, analysis_md, canonical, category, data, description, facts, }

▶ /scholar/mechanistic-interpretability-research-digest.data.json  (期望价 $0.02)
  ✅ 未付费被拦截 → 402 (price_required)
  ✅ 付费放行 → 200, 扣费 $0.02 (匹配)
  ✅ 回源 200 + 合法 JSON 真内容 {@context, analysis_md, canonical, category, data, description, facts, }

========================================
Step 5: 免费资源 —— verify 200 不扣费 + 回源取到内容
========================================

▶ /index.html
  ✅ 免费放行 → 200, 未扣费
  ✅ 回源 200

▶ /crypto/binancecoin.html
  ✅ 免费放行 → 200, 未扣费
  ✅ 回源 200

▶ /crypto/bitcoin.md
  ✅ 免费放行 → 200, 未扣费
  ✅ 回源 200

========================================
Step 5.5: 免费深层数据 (guides, 显式 allow 规则) —— 200 不扣费 + 回源取真 JSON
========================================

▶ /guides/getting-started-with-http-402-pay-per-crawl.data.json
  ✅ allow 规则放行 → 200, 未扣费
  ✅ 回源 200 + 合法 JSON 真内容(免费深层)

▶ /guides/crawler-tokens-auto-pay-a-how-to.data.json
  ✅ allow 规则放行 → 200, 未扣费
  ✅ 回源 200 + 合法 JSON 真内容(免费深层)

========================================
Step 5.6: 被拦截目录 (members, block 规则) —— verify 返回 403(ESA 据此拦截)
========================================

▶ /members/institutional-flow-report-where-smart-money-is-rotating.data.json
  ✅ block 拦截 → 403 (access_blocked),accessGranted=false

▶ /members/agent-infrastructure-landscape-vendor-deep-dive.data.json
  ✅ block 拦截 → 403 (access_blocked),accessGranted=false
  ℹ 注:此处只验证 verify 的 403 决策。源站本身不设防 —— 直接 curl 源站(绕过 ESA)仍能取到该内容,这是预期,不是 bug。
     真正的拦截由 ESA 据 403 不回源执行。端到端「URL 真被拦」需 ESA 在链路里,两种方式:
     ① ESA 前置内网域名(阿里内网联调)  ② ESA 前置公网站点 agentflare.org(生产形态)。详见 cdntest.html §2.1。

========================================
Step 6: AISA verify 全 12 种返回值覆盖
========================================

  ✅ #1 200 allow 规则(免费深层) → 200
  ✅ #2 200 无规则匹配(default allow) → 200
  ✅ #3 200 付费扣费成功 → 200
  ✅ #4 402 invalid_token → 402/invalid_token
  ✅ #5 402 insufficient_balance → 402/insufficient_balance
  ✅ #6 402 price_required → 402/price_required
  ✅ #7 402 price_mismatch → 402/price_mismatch
  ✅ #8 402 price_too_high → 402/price_too_high
  ✅ #9 400 invalid_price_format → 400/invalid_price_format
  ✅ #10 403 access_blocked → 403/access_blocked
  ✅ #11 401 gateway_unauthorized → 401 (错误网关 token 被拒)
  ℹ #12 internal_error(500)—— 仅 DB/服务内部故障时返回,黑盒不可主动触发,代码审计确认 → 文档化覆盖

  ▷ 返回值覆盖: 12/12  (实测断言 11 · 文档化 1)

========================================
恢复原始规则配置(--auto-config 收尾,保证非破坏性)
  ▸ 说明:⑥ 删掉测试导入的、按快照重建 → 回到原始 8 条,后台不被污染。
========================================
  ✓ 已恢复原始 8 条规则

========================================
Step 7: 汇总报告
========================================
  AISA verify 返回值覆盖: 11+1 = 12/12  (实测 11 · 文档化 1)
  本次付费扣费合计: USD 0.085
  Publisher 后台流水: https://esa.aisa.one/cdn/transactions.html

  ━━━━━━━━━━━━━━━━━━━━━━━━━
  ✅ PASS: 44
  ❌ FAIL: 0
  ━━━━━━━━━━━━━━━━━━━━━━━━━
🎉 全部通过 — 注册→发现→定价→付费拿真内容 闭环成立

文档随测试演进更新。最后更新:2026-06-24 · 维护:AISA。