WebVPN v2026.0.1.65

更新记录

以下内容来自当前可执行程序内嵌的权威 CHANGELOG.md。

# 更新记录

本文件按版本记录 WebVPN 的可交付变化。版本号遵循
`2026.<major>.<minor>.<build>` 格式;源码版本定义在 `version/version.go`,
每次产生新交付构建时递增 `build`,构建时只注入提交标识和构建时间。

## 2026.0.1.65 - 2026-09-16

### 首页更新记录

- 首页顶部导航增加“更新记录”入口,打开同源 `/changelog` 页面。
- 权威 `CHANGELOG.md` 直接内嵌到单文件可执行程序,页面不维护第二份更新
  记录,也不依赖运行目录或外部静态资源。
- 更新记录内容经过 HTML 转义后在 `<pre>` 中展示;支持 `GET`、`HEAD`,
  其他方法返回 `405`。
- 增加首页入口、嵌入内容不可变、当前版本、HTTP 方法和响应正文回归。

## 2026.0.1.64 - 2026-09-16

### Fetch Request 上下文重映射

- Fetch 在处理字符串 URL、原生 Request 和运行时安装后创建的 Request 时,先把
  已有网关路由恢复为目标 URL,再按最终 credentials 模式生成唯一网关上下文。
- `Request(..., {credentials:"omit"})` 经运行时预映射为普通 `vpn-0` 后,Fetch
  仍会改为 `vpn-0-fetch-omit`;init 覆盖为 `include` 时则恢复普通 `vpn-0`。
- 增加安装后 Request、init 覆盖和已映射字符串回归,防止构造阶段的路由上下文
  抢先冻结 Fetch 的最终凭据语义。

## 2026.0.1.63 - 2026-09-16

### Fetch 凭据域隔离

- 映射后的 Fetch 即使原始 `credentials` 为 `omit`,也使用同源浏览器请求携带
  WebVPN ticket,避免同路径会话引导重定向循环。
- 原始 `omit` 语义通过网关内部路由上下文传递,不增加自定义请求头,保持
  CORS 与 `no-cors` 请求形状;上下文在恢复目标 URL 时被消费,不进入上游。
- 会话传输对该请求不注入目标 Cookie,也不保存响应 Set-Cookie;普通请求的
  目标 Cookie 发送和持久化行为保持不变。
- 增加字符串 URL、Request 输入、init 覆盖及完整网关会话回归,覆盖 ticket、
  上游 URL、请求 Cookie、响应 Cookie 和普通请求兼容性。

## 2026.0.1.62 - 2026-09-15

### 性能负载驱动响应缓冲复用

- 性能负载驱动为每个闭环 worker 复用固定 32 KiB 响应读取缓冲,继续执行完整正文
  SHA-256 校验,但不再由 `io.Copy` 为每个请求重复分配默认缓冲。
- v61 overlay A/B 在并发 `32/64/128` 共完成 12 次交错运行,失败 0;候选吞吐
  中位数提高 `69.5%/51.0%/75.2%`,每请求分配下降
  `60.8%/59.1%/61.0%`,GC 频率下降 `71.8%/70.8%/74.8%`。
- 三个候选 heap 画像均通过,`io.copyBuffer` 不再是累计分配首位;该修改只减少
  测试驱动噪声,不改变 WebVPN 生产请求、传输或响应语义。
- 增加响应正文读取必须使用 worker 所有缓冲的回归测试,防止后续改动重新引入
  每请求 32 KiB 测试分配。

## 2026.0.1.61 - 2026-09-15

### ReverseProxy 流式缓冲复用

- 为每个 WebVPN Server 的 ReverseProxy 配置固定 32 KiB 响应复制缓冲池;
  保持标准库默认复制容量,不改变响应分块、正文内容或重写行为。
- 缓冲池拒绝容量不匹配的归还值,避免大正文临时切片扩大服务器空闲内存
  保留边界;运行时仍可在内存压力下回收 sync.Pool 中的空闲缓冲。
- 24 轮交错 A/B 覆盖并发 `16/32/64`、约 624 万请求且失败为零;
  吞吐中位数分别提高 `44.9%/30.4%/31.2%`,每请求分配下降
  `30.7%/33.6%/33.7%`。
- 增加固定长度、异常容量防御和 Server 装配回归测试。

## 2026.0.1.60 - 2026-09-15

### HTTP/2 低流上限恢复

- `REFUSED_STREAM` 只表示源站没有处理当前流,不再被包装为整个 HTTP/2 协议不可用,也不再触发站点进入 HTTP/1.1 冷却。
- 安全请求继续使用网关外层唯一三次尝试预算;重试前保留已经取得源站 `SETTINGS_MAX_CONCURRENT_STREAMS` 的健康连接,使后续请求在真实流上限内排队。
- 显式 HTTP/2 连接和同 IP 跨域复用连接采用相同分类;连接级错误仍删除失效连接并进入既有协议降级路径。
- 增加低流上限并发回归及连接生命周期单元测试,防止流级拒绝再次扩大为连接失效或协议降级。

## 2026.0.1.59 - 2026-09-15

### 首次请求跨域 HTTP/2 复用

- 修复目标站协议状态未知时直接进入独立自动协商池的问题。HTTPS 目标在允许跨域复用时会先检查已有可信 HTTP/2 会话。
- 复用检查只读取现有连接;没有满足代理边界、端口、DNS、可信证书和双端策略条件的会话时,继续原有 ALPN 自动发现,不为画像强制新建 HTTP/2 连接。
- 跨域交换继续使用目标站自身的 HTTP/2 并发门禁;成功后目标状态进入 `http2_healthy`,连接别名和实际复用 authority 写入站点画像。
- 本地双域名证书回归覆盖首次访问场景;公网使用 `github.com` 与 `www.github.com` 验证同 IP、同证书、HTTP/2 会话实际复用。

## 2026.0.1.58 - 2026-09-15

### 自适应出站传输

- 增加按虚拟 origin 隔离的 HTTP/2 健康、HTTP/1.1 冷却和 HTTP/2 单探针恢复状态机。
- HTTP/2 已协商但交换不可用时,GET、HEAD、OPTIONS 在原有三次总尝试预算内切换到独立 HTTP/1.1 长连接池;非安全方法不隐式重放。
- 增加同类请求的 HTTP/2 与 HTTP/1.1 延迟窗口。只有达到最小样本、绝对差、倍数和连续窗口门槛后才进入 HTTP/1.1 冷却。
- 增加每站 HTTP/2 并发背压。许可覆盖响应正文读取和关闭生命周期,避免低流上限源站触发无界物理连接扩张。
- HTTP/1.1 生产池使用全局空闲 `512`、每站空闲 `32`、每站总连接 `64`;请求许可从 `8` 起步,在持续排队时扩容,在长期低排队时收缩到不低于 `4`。

### 站点画像与预连接

- 热门站点可配置 TCP、HTTP/1.1 和 HTTP/2 预连接;未配置连接数量时,主动画像仍会真实探测三类能力。
- 增加站点画像快照和主动刷新 Go API,输出协议状态、并发门禁、解析地址、预连接能力和跨域复用结果。
- 增加同 IP 跨域 HTTP/2 复用。复用要求同一代理边界、同一目标端口、DNS 地址匹配、可信证书覆盖目标域名,并要求来源站和目标站同时允许复用。
- HTTP Forward Proxy 使用 CONNECT 建立 HTTP/2,支持 Basic 认证;SOCKS 等自定义 Dialer 可参与 TCP 和协议预热,但不使用不可验证的远端地址做跨域复用。

### 验证

- 增加 HTTP/2 故障降级、持续性能劣化、恢复单探针、HTTP/2 正文生命周期背压、HTTP/1.1 扩缩容、热门站点画像、代理 CONNECT、虚拟目标映射和跨域复用门禁回归。
- Chromium 网络策略调研、适配边界和生产参数记录在 `reports/chromium-network-policy-and-adaptive-transport-plan-20260915.md`。

## 2026.0.1.57 - 2026-09-15

### 组件性能基准

- 增加 CompactV2 路由编解码和完整代理 URL 构建、恢复、相对引用解析基准。
- 增加 HTML `16 KiB、256 KiB、1 MiB、4 MiB` 与 CSS `16 KiB、256 KiB、1 MiB` 重写矩阵。
- 增加会话 ticket、不同 Cookie 基数、动态内存缓存、动态文件缓存和静态内存缓存基准。
- 缓存正文覆盖 `1 KiB、64 KiB、1 MiB、4 MiB`,为后续五轮正式测试和 CPU、堆、锁画像提供稳定入口。
- 本版本只增加性能测试能力;组件正式数据、完整容量曲线和长测仍以真实运行证据为准。

## 2026.0.1.54 - 2026-09-15

### 上游证书默认策略

- `webvpn-browser` 默认跳过源站证书链和主机名校验,兼容自签名、私有 CA 和使用 IP 地址访问的内网站点。
- `WEBVPN_UPSTREAM_TLS_SKIP_VERIFY=false` 可以让未单独配置的站点恢复全局证书校验。
- 站点级 `skip_certificate_verification=disable` 可以在全局默认跳过时只为该精确 origin 恢复证书校验。
- server 包继续保留严格零值;本次变化限定在可部署的浏览器产品默认值和 Compose 契约。

## 2026.0.1.53 - 2026-09-15

### 日志自然日分片

- 应用日志按中国标准时间写入 `webvpn-YYYY-MM-DD.log`,页面不可用上报随应用日志进入对应自然日分片。
- 请求追踪按同一日界线写入 `webvpn-YYYY-MM-DD.trace.jsonl`,与应用日志保持可按日期配对的文件名。
- 跨日写入串行关闭旧分片并打开新分片;同一天容器重建继续追加,不截断已有诊断。
- 故障采集器同时读取旧版固定文件和时间窗口涉及的每日分片,历史部署与新版本可以连续分析。

## 2026.0.1.51 - 2026-09-15

### 性能驱动稳定性

- 性能 worker 在统一启动屏障后各自开始完整采样周期,消除 goroutine 创建时间对短测有效时长的侵占。
- 每个已启动 worker 至少执行一次请求;系统调度繁忙时不再产生“采样阶段没有请求”的偶发失败。
- 增加纳秒级采样区间与 64 worker 的确定性回归,固定短烟测的非零样本契约。

### 继承能力

- 保留 v50 引入的默认无限制目标站点策略,以及按精确 origin 配置上游超时、证书校验和旧 TLS 兼容的部署能力。
- 保留 v49 的确定性性能驱动、HTTP/1.1 与 HTTP/2 观测、完整响应摘要校验和大正文样本。

## 2026.0.1.49 - 2026-09-15

### 性能测试执行能力

- 增加 `webvpn-perf` 独立命令,支持确定性场景、并发阶梯、预热、采样时长、重复次数、HTTP/1.1 与 HTTP/2、连接池和正文重写上限参数。
- 完整网关测试使用本地 TLS 上游,按 `direct -> gateway -> gateway -> direct` 执行,并对每条响应校验状态码、媒体类型、完整长度和 SHA-256。
- 证据输出包含环境、场景、逐轮聚合结果、吞吐与延迟、内存、连接复用、实际协议及状态式报告。
- 10 MiB Base64 HTML 使用可由普通 PNG 解码器读取的确定性图片;图片长度和 SHA-256 独立写入样本清单,不再使用重复字符模拟图片。

### 状态边界

- 本版本交付性能测试入口和本地确定性证据能力,不修改生产 HTTP/2、HTTP/1.1 连接池或自动协议降级行为。
- 完整容量阶梯、缓存矩阵、故障夹具、画像、长测和后台负载浏览器验收仍需以真实运行结果收口。

## 2026.0.1.37 - 2026-09-14

### 路由与验证工具

- 生产 codec、Mapper、浏览器 runtime 和活动探测器统一只处理 `/~sat2/` CompactV2。
- 清除活动验证链中残留的旧点分十进制解码分支;历史旧令牌只保留为“必须拒绝”的回归夹具。
- 验证工具统一为 `verify_route_codec.go`、`decode_route_tokens.go` 和 CompactV2 版 `parse_entry_url.go`,不再提供旧格式工具入口。
- `/~sat`、`/~sat/`、`/~sat/cookie/` 和 `/~sat/muyun_resource/` 均在生产服务前置返回 404。

### 构建与发布

- Go 全量测试和 `go vet` 退出码均为 0。
- Node runtime `125/125`、站点探测器 `140/140` 通过。
- 六个 Windows amd64 入口和六个 Linux amd64 入口完成构建;Linux 按契约只验证 ELF64 x86-64,不做实机运行。
- 发布目录为 `releases/20260914-v2026.0.1.37/`,完整性记录位于同目录 `SHA256SUMS`。
- 生产 `http://127.0.0.1:18094` 已运行 `2026.0.1.37`,版本和健康检查回读通过。

### 真实浏览器验收

- 使用单个可见持久 Chrome 会话打开用户指定的 `http://baidu.com/s?...` 地址,复用既有浏览器配置并持续观察 `25,115 ms`。
- 最终页面保持 `/~sat2/` 物理路径,标题为 `国将兴 必贵师而重傅_百度搜索`,文档状态为 `complete`,可见搜索结果为 10 条。
- 本轮记录 249 个网络响应,HTTP 404、HTTP 4xx/5xx、请求失败、控制台错误、页面异常和百度安全验证响应均为 0。

## 2026.0.1.35 - 2026-09-14

### 路由契约

- `~sat2` CompactV2 成为唯一活动业务路由和内部 API 命名空间。
- `~sat` 旧业务路由、旧 Cookie API 和旧动态资源 API 均不再支持;请求被明确拒绝。
- 更新 runtime、活动测试、探测策略和状态文档,删除“旧路由继续兼容”的当前契约。

### 验证状态

- Go 路由编解码、Mapper 和站点 URL 策略重点测试通过。
- Node runtime 125 项中 123 项通过;剩余 2 项需要 Windows Playwright 浏览器运行时,当前 Linux 环境缺少 Linux Chromium 可执行文件。

## 2026.0.1.33 - 2026-09-13

### 修复

- 顶层重写 HTML 文档改用 `Cache-Control: private, no-cache`,要求普通 HTTP 缓存使用前重新验证;HTML 片段、JavaScript 和 CSS 继续使用 `private, no-store`。
- 上游 `Age`、`ETag`、`Expires` 和 `Last-Modified` 继续移除;不改变 `~sat` 路由、Cookie、脚本运行时和站点特化边界。

### 验证与候选状态

- Go 全量测试、`go vet`、rewriter/server/session/transport 四包 race、123 项 Node runtime、Windows AMD64 六命令构建和 Linux AMD64 六命令交叉编译均通过;Linux 仅检查 ELF,不做实机运行。
- 候选 `127.0.0.9:18112` 实测为 `2026.0.1.33`,`/healthz` 返回 `200 ok`;生产 `localhost:18094` 仍为 `2026.0.1.20`,未切换。
- r58 在同一可见 Chrome、同一业务标签上完成首屏、第二页、后退和前进;直连与网关验证码请求均为 0,页面 JavaScript 错误均为 0,页面标题和分页文本均正常。
- 网关仍产生 2 次 `BrowsingInstanceNotSwapped`,并产生额外的顶层文档导航;`private, no-cache` 未闭合与直连相同的历史恢复方式。
- 该版本形成了“缓存策略单独调整不足”的直接验收结论,普通浏览器整体等价仍未通过,生产尚未切换。

## 2026.0.1.32 - 2026-09-13

### 修复

- 重写后的顶层 HTML 文档使用 `Cache-Control: private`,允许同一浏览器会话保留历史文档;HTML 片段、JavaScript 和 CSS 继续使用 `private, no-store`。
- 顶层重写响应继续移除上游 `Age`、`ETag`、`Expires` 和 `Last-Modified`,避免上游表示的缓存验证条件跨越网关重写版本。
- 新增缓存策略单测和可见 Chromium 历史导航诊断,不增加站点特化规则,不改变 `~sat` 路由协议。

### 验证与候选状态

- Go 全量测试、`go vet`、四包 race、123 项 Node runtime、Windows AMD64 六命令构建和 Linux AMD64 六命令交叉编译均通过;Linux 仅检查 ELF,不做实机运行。
- 候选 `127.0.0.8:18111` 实测为 `2026.0.1.32`,`/healthz` 返回 `200 ok`;生产 `localhost:18094` 仍为 `2026.0.1.20`,未切换。
- r56 同一可见 Chrome 四步复测中,直连和候选均无页面 JavaScript 错误;直连验证码请求为 0,候选验证码请求为 0;候选仍记录 2 次 `BrowsingInstanceNotSwapped`。
- r57 继续复用同一可见 Chrome 做后退/前进对照:直连没有新的顶层文档请求;候选发生 2 次顶层文档导航,响应由 Chrome 磁盘 HTTP 缓存提供,未形成新的候选上游请求。该结果把残余差异收敛为浏览器历史恢复方式差异,但尚未证明唯一代码根因。
- 普通浏览器整体等价仍未通过;没有完整验收证据前不切换生产。

## 2026.0.1.31 - 2026-09-13

### 诊断

- 请求 trace 增加物理上游 Cookie 名称、数量和请求头 SHA-256 摘要;上游 `Set-Cookie` 同样只保留名称、数量和摘要,不保存 Cookie 值。
- 诊断字段与请求 ID、尝试 ID、目标地址和阶段事件绑定,用于区分会话变化与验证码重定向;不改变 Cookie 转发、浏览器票据或上游请求行为。
- 该版本不宣称验证码根因已经解决,也不增加百度站点特化规则。

### 验证与候选状态

- Go 全量测试在正确 Node 环境下通过,`go vet`、重点 race、Node runtime、Windows 六命令构建和 Linux amd64 六命令交叉编译通过。
- 候选 `127.0.0.7:18110` 实测为 `2026.0.1.31`,`/healthz` 返回 `200 ok`;Linux 仅完成交叉编译,不做实机运行验收。
- r49 可见 Chrome 四步对照中,直连首屏、第二页、后退、前进均完成且未出现验证码;网关同四步完成,但前进阶段先出现搜索请求 302,随后加载验证码 HTML,页面错误为 0,整体普通浏览器等价仍未通过。
- 直连搜索请求记录 15–16 个浏览器 Cookie;网关浏览器侧只记录 `my_client_ticket`,v31 同时记录到物理上游请求的脱敏 Cookie 名称、数量和摘要。该差异尚未形成 Cookie 根因结论。
- r50 受控 HTTP 对照中直连和网关最终均为 HTTP 200;正文长度差异来自网关重写和运行时注入,不能替代可见 Chrome 的导航等价验收。
- 生产仍为 v20,未切换。

## 2026.0.1.30 - 2026-09-13

### 修复

- Cookie 响应解析兼容浏览器实际接受的方括号、括号、冒号和内部空格名称;仍拒绝控制字符、分号和等号。
- Cookie 名称兼容同时覆盖网关 Cookie API、会话上游 Jar 和浏览器可见 Jar,保留 HttpOnly、Secure、Domain、Path、Max-Age 等属性语义。

### 验证与候选状态

- Go 全量测试、vet、重点 race、Node runtime、Windows 六命令构建和 Linux amd64 六命令交叉编译已通过。
- 候选 `127.0.0.6:18109` 实测为 `2026.0.1.30`,健康检查通过;生产仍为 v20,未切换。
- r49 可见 Chrome 四步历史复现中,直连未出现验证码;网关前进阶段收到上游搜索 302,随后请求验证码 HTML,整体普通浏览器等价仍未通过。
- CDP 已取得浏览器侧完整 Cookie 名称和摘要;上游 Cookie 值未落盘,当前不把 Cookie、UA、并发或单一字段认定为根因。

## 2026.0.1.29 - 2026-09-13

### 修复

- 非文档 HTML 片段不再被自动补入 html/head/body;完整文档保留原解析方式,表格及选项片段使用适当父上下文。
- 保留注释、CDATA、兄弟节点和元数据;不增加站点规则、公开接口或依赖。
- 同一真实响应的浏览器对照中,首个 div 从旧候选的位置 25 恢复到 0。
- 导航验收绑定同目标直连通过记录;最终页面正常但翻页、后退重载整页时判为失败。

### 验证与候选状态

- 12 类片段、4 类完整文档反例、重复改写及 6 项导航对照回归通过;Go 全量、vet、四包 race、123 项 runtime 测试通过。
- 两类片段、六类脚本响应浏览器对照通过;五类脚本执行场景按原 200ms 条件连续三轮通过,均无跳过。
- Windows 六命令及 Linux amd64 六命令构建通过;候选 `127.0.0.5:18108` 实测 v29,健康正常。
- 公网短交互完成 11→10→11,图片和字体完成,翻页及后退均保持同文档,与直连一致。
- 既定十项长交互全部执行:直连原动作断言 10/10;候选 9/10。候选历史前进收到上游 302 验证码响应,随后一次后退也重载整页,整体等价未通过。
- 原七条正确资源地址在当前候选逐条直连、网关均返回 200;首页 tips、advert、super_load 实际从正确 CDN 目录返回 200。
- 生产仍为 v20,未切换;历史验证码触发原因不因片段修复或一次短交互通过而视为全部解决。

## 2026.0.1.28 - 2026-09-13

### 修复

- Windows TCP 在收到 HTTP 响应前发生 `read/wsarecv/10060` 时,允许既有无正文、可重放请求在原预算内恢复;有响应、正文读取、POST、取消等边界保持。
- AST 分类器按所需节点类别读取既有访问序列,保留节点身份、顺序、完整上下文和默认完整遍历。
- 固定 813624 字节输入的同机 12 次平均基准由 151.917ms 降至 129.745ms;完整输出 849182 字节及摘要不变。
- 版本递增至 `2026.0.1.28`,不修改依赖文件,不增加站点规则。

### 验证与候选状态

- 新增 18 个 transport、3 个 gateway 读取超时输入及 AST 过滤对照;Go 全量、vet、四包 race、123 项 runtime 测试通过。
- 五类脚本执行浏览器场景按原 200ms 条件连续三轮通过;六类响应浏览器对照通过,均无跳过。
- Windows 六命令及 Linux amd64 六命令构建通过,逐个核验版本或二进制格式;候选位于 `127.0.0.4:18107`。
- 同一可见 Chrome 中,两份候选记录均完成 11→10→11 的首屏、下一页和后退,标题集合完整恢复;三个原失败 CSS 本次全部返回 200。
- 首份候选记录因上游 HTML 错误页作为脚本解析而失败;该响应保持上游 200 和正文,不再合成 502。
- 第二份记录的最终页面断言通过,但翻页 XHR 实际收到上游验证码重定向,站点随后降级为整页导航。该记录不计为整体功能等价通过。
- 生产仍为 v20,未切换;剩余工作集中于既定翻页请求和错误页触发差异,不重跑历史清单。

## 2026.0.1.27 - 2026-09-13

### 修复

- 脚本请求收到真实 HTML、nosniff、空正文、语法错误或非 200 成功响应时保留上游状态、正文和 MIME,不再合成 502。
- 保留浏览器原生拒绝结果及合法 HTML 标记 JSONP 的既有兼容行为,不注入文档 runtime。
- 原始体超限、解压失败和解压后超限沿用原表示传递,原正文关闭语义保持。
- 空 HTML 脚本不再触发额外两次空文档恢复请求;文档恢复逻辑不变。

### 验证与候选状态

- 14 类响应输入、12 个空脚本识别输入及既有相关回归通过;Go 全量、vet、四包 race、123 项 runtime 测试通过。
- Windows 六命令构建、Linux amd64 六命令交叉编译通过;v27 候选运行于 `127.0.0.3:18106`,生产仍为 v20。
- 六类同响应浏览器对照通过;真实 `error.html` 在候选返回 200、`text/html`,15255 字节正文与直连摘要一致。
- 大脚本 200ms 余量执行场景本轮仍失败;不覆盖此前成功或本轮失败记录。
- 公网首屏、翻页、后退已实际操作;三个 CSS 出现响应前 TCP 读取失败,后退标题集合未完整恢复,整体验收未通过。
- 未实施站点特化、`~sat2` 或固定响应回放框架,未切换生产。

## 2026.0.1.26 - 2026-09-13

### 修复

- 排除 AST 反射空遍历;多个分类器复用同一节点与完整上下文序列,并分块保存。
- 作用域查询改为调用内区间索引与父级缓存,保持闭包、遮蔽、重赋值及相等范围优先级。
- 消除重复全文前缀扫描和复制,不改变 URL 分类、完整输出或浏览器执行顺序。
- 固定 813624 字节输入的 8 次测试中位耗时为 152.021ms;v25 已存基线为 700.400ms。输出字节数和 SHA-256 一致。

### 验证与候选状态

- 五类同条件 direct/gateway 浏览器场景连续两轮通过;v25 失败的大脚本延迟场景在 v26 通过。
- Go 全量、vet、四个重点包 race、123 项 runtime 测试通过;Windows 六命令构建和 Linux amd64 六命令交叉编译通过。
- v26 候选启动于 `127.0.0.2:18105`;生产仍为 v20,尚未切换。
- 复用原可见 Chrome 验证旧脚本页面分支,首屏、下一页和后退已执行,未出现 c 未定义或验证码。
- 首次公网验收器误计一个无链接反馈标题;原失败记录保留。修正结果计数后的复核另捕获 `error.html` 上游 200、网关重写失败后 502,整体验收仍未通过。
- 历史 404 通用修复继续保留;本轮样本没有新 404,不代替历史全量复验。

## 2026.0.1.25 - 2026-09-13

### 修复

- 撤销长 JavaScript fallback 的条件前缀错误预计算,删除 `ConditionalNetworkPrefixQuestionOffsets`,恢复对实际候选字面量的原分类。
- 固定 813624 字节脚本的 8 次本地对照中,中位耗时由 3290.442ms 降为 700.400ms;两版输出长度 849182 字节且 SHA-256 一致。
- 保留历史路径修复和独立脚本响应并发,不引入站点判断或服务器 FIFO。

### 验证与候选状态

- Go 全量测试、vet、重点 race 和 123 项 Node runtime 测试通过;Windows 六命令构建与 Linux amd64 六命令交叉编译通过。
- 候选 `127.0.0.1:18104` 的版本和健康检查通过;生产 `localhost:18094` 实测仍为 `2026.0.1.20`。
- 原可见长会话完成一次加载更多,结果 11→21、图片 43/43 解码;本次观察无页面异常、请求失败和 404。
- 另一旧脚本页面分支仍出现 `ReferenceError: c is not defined`。局部加载更多通过不代表普通浏览器整体等价通过,生产尚未切换。

## 2026.0.1.24 - 2026-09-13

### 修复

- 移除服务端按文档串行放行重写 JavaScript 的 FIFO;浏览器脚本继续按浏览器自身的加载和依赖语义执行。
- 删除 `ScriptDeliveryTicket`、每文档脚本队列和 `ScriptDeliveryWaitTimeout` 配置,避免网关按请求到达顺序制造错误脚本顺序。
- 增加慢脚本/快脚本并发回归,验证快脚本不会被慢脚本阻塞。

### 验证与候选状态

- `go test ./... -count=1`、`go vet ./...` 通过。
- Node runtime `123` 项通过。
- Windows amd64 六个命令构建通过;Linux amd64 六个命令交叉编译通过。
- 候选服务 `127.0.0.1:18103` 的 `/version` 返回 `2026.0.1.24`,健康检查通过。
- v24 公网样本脚本响应 `53/53` 为 200,未观察到新的脚本 404;普通浏览器整体等价和生产切换仍未关闭。

## 2026.0.1.22 - 2026-09-12

### 修复

- 将反向代理改为显式请求重写,不再自动把网关客户端地址附加为 `X-Forwarded-For`。
- 用户显式提供的 `Forwarded`、`X-Forwarded-For`、`X-Forwarded-Host`、`X-Forwarded-Proto` 在未声明为 `Connection` 逐跳字段时保持有序多值和空值语义。
- 保持目标 Host、原始 RequestURI、重复参数、无效转义、正文、Origin/Referer、WebSocket Upgrade 和重试行为。

### 验证与发布状态

- 16 项本地真实 HTTP 接收端回归、Go 全量、vet、185 项 runtime/探测器、Windows 构建及 Linux amd64 交叉编译通过。
- 同一 Chrome 本地接收端对照:直连 200、v21 自动 XFF 403、v22 200;三者业务请求均只发送一次。
- v22 候选服务位于 `127.0.0.1:18101`;主服务 `localhost:18094` 尚未切换。
- 百度 v22 新独立会话根页渲染正常但返回数字分页模板,未获得加载更多分支;不把该结果记作公网加载更多已修复。

### 文档契约

- 历史契约曾使用独立首个路径组件 `~sat2`(完整前缀 `/~sat2/`)区分紧凑格式;该历史方案后来收敛为只保留 `~sat2`。`~sat2` 不表示应用构建版本,也不承载 Cookie 或动态资源内部接口。
- 不识别 `~sat20`、`~sat2x` 等相似前缀;不在令牌或查询串内另加版本字段。
- 该历史方案曾允许旧 `/~sat/` 读取;当前实现已废弃旧路径,Cookie 和动态资源统一迁移到 `/~sat2/`。
- 架构图历史上展示过双命名空间;当前架构图已收敛为 `/~sat2/` 单一命名空间。
- 本次为文档更新,不产生新构建;源码版本仍为 `2026.0.1.22`,新编码尚未实施。
- 2026-09-12 文档复核保持该契约不变:紧凑格式继续使用独立 `/~sat2/`,
  该历史版本记录不代表当前兼容状态;当前入口只生成 `/~sat2/`。

## 2026.0.1.21 - 2026-09-12

### 修复

- 跨源请求的 Origin 从有效网关 Referer 还原为发起页面源,不再误写为接收端源。
- 请求入口冻结浏览器 Origin,响应只适配匹配实际发起源的 CORS 授权。
- 保持原始查询、正文和单次上游请求;外部来源、null、未提供 Origin、缺失或不匹配的跨源授权不被改成当前网关授权。

### 验证与发布状态

- 18 项来源回归、Go 全量、vet、123 项 runtime、Windows 构建和 Linux 交叉编译通过。
- 来源默认端口按浏览器规则省略;`null` 与附带路径的非 Origin 授权值保留原状。
- 同一 Chrome 本地按钮对照:直连 200、旧版 403、新版 200;原百度标签和文档未改变。
- 候选服务位于 `127.0.0.1:18099`;主服务 `localhost:18094` 尚未切换,继续保留 v20 公网失败现场。
- 本项不作为当前同源加载更多 302 或历史网络 502 的根因结论。

## 2026.0.1.20 - 2026-09-12

### 诊断修复

- 网络错误保留白名单操作阶段、网络类型、超时观察值、原因类型、系统调用及数字错误号。
- 不输出错误全文或地址;不同错误分支不混合归因,异常诊断实现退回类型摘要。
- 请求、正文、原错误对象及重试策略不变;POST 仍只发送一次,浏览器 502 正文保持原契约。

### 验证

- Go 全量、vet、123 项 runtime、Windows 构建与 Linux 交叉编译通过。
- 新回归在旧实现上证明详情缺失;新二进制真实本地连接拒绝记录原生 10061,POST 仅一次尝试。
- 已部署至 localhost:18094,原可见 Chrome 未重启。
- 网关第 2 页及历史导航四项局部检查通过,但该批没有发出原失败接口 POST,不计作历史 502 已解决。
- 原网关页面自然出现加载更多;一次滚动触发上游 302,随后收到安全验证 HTML,结果没有追加。该公网问题仍未解决。

## 2026.0.1.19 - 2026-09-12

### 修复

- HTML 注释和外来内容 CDATA 保留原始数据,避免实体解码破坏框架初始化对象。
- 真实解析树确认节点身份;EOF 结束状态、重复注释、raw-text、属性及伪注释分别处理。
- 不升级依赖,不按站点或字段名称添加规则。

### 验证

- 同次真实直连响应的 30 段数据全部保持原文;旧输出的 1 处语法错误和 11 段改变消失。
- Go 全量、vet、123 项 runtime、20 项浏览器注释边界及双平台构建通过。
- 当时部署至 localhost:18094;该版本真实交互 10/11,通过项包含原失败第 5 页。
- 一次上游 POST 以 net.OpError 结束并产生 502,具体传输原因待补证;公网加载更多分支仍待验收。

## 2026.0.1.18 - 2026-09-12

### 修复

- 查询前缀保护扩展到绝对及协议相对地址,Go 与 runtime 使用一致的拼接边界。
- 保持业务校验使用的原始 URI,最终网络请求继续由现有入口映射。
- 本地真实 PageLoadMoreService、jQuery 与原生 XHR 四场景对照通过;不代替历史公网 302 归因。

## 2026.0.1.17 - 2026-09-12

### 修复

- 保留仍在拼接参数值的根相对查询前缀,避免过早编码改变业务 URI 校验输入。
- 补充 AST、有效前缀扫描、runtime 及原生请求执行回归。

## 2026.0.1.16 - 2026-09-12

### 修复

- HTTP、Location 和 JavaScript URL 数据不再被当作 HTML 文本重复解码,保留 timestamp 等参数名和原始查询字节。
- HTML 属性只在解析阶段解码,输出阶段继续正确转义。
- 对象路径键保护覆盖方法、访问器、Unicode 接收者及对象字面量查表,控制语句后的数组网络值继续映射。
- 补充真实 HTTP 请求/重定向回归、HTML/JavaScript 边界回归和对象键实际运行结果断言。

### 验证

- Go 全量、静态检查、116 项运行时测试、Windows 构建和 Linux 交叉编译通过。
- 同一可见 Chrome 标签完成数字分页子集十项检查,全部通过;首页原三条脚本实际返回 200。
- 加载更多分支本次未复现,不将数字分页通过记成验证码问题已解决。

## 2026.0.1.15 - 2026-09-12

### 修复

- 浏览器二次源码改写保留静态对象键、计算对象键及静态成员下标。
- 模块文件表枚举所得路径保持原值,不再把首页三个模块映射到错误目录。
- 原 tips、super_load、advert 三个脚本在可见长会话中从正确 CDN 目录实际返回 200。
- 新回归校验对象键枚举及运行结果,避免“定义与读取同时改错”造成测试假通过。
- 原导航桥接调用不重复改写;Go 全量、静态检查、75 项运行时测试和 Linux 交叉编译通过。

## 2026.0.1.14 - 2026-09-12

### 修复

- 拼接中的主机名前缀保持原值,完整域名形成后再由请求入口映射。
- 修复统计图片地址被拼到编码后 host 上而产生网关 400 的问题。
- AST 和有效前缀扫描使用同一规则;完整 Origin、路径和独立请求继续映射。
- 新回归覆盖分片计数副作用、域名后缀拼接和已完成地址的边界。

## 2026.0.1.13 - 2026-09-12

### 修复

- 组件 `baseUrl/baseURL` 赋值中的内部路径保持原值,避免模块注册与查找使用不同键。
- 只追踪最终路径值,不保护条件测试、函数体或调用内的网络请求。
- 首页实际加载器对照由三条初始化异常恢复为零条。
- 动态导航按当前页面解析相对路径、查询和片段,修复提前解码导致的根路径漂移。
- 外层属性读取保留嵌套导航改写;存在显式局部 `globalThis` 绑定时不新增导航包装。

## 2026.0.1.12 - 2026-09-12

### 修复

- 动态 `Location.assign/replace` 通过 AST 与运行时协作映射,不依赖原生方法可写。
- 保留原接收者、参数求值顺序、返回值、异常和浏览器历史行为。
- 同一真实 Chrome 对照中,旧版两项越界,修复版两项保持网关与原历史语义。

## 2026.0.1.11 - 2026-09-12

### 修复

- 同端口 `localhost`、IPv4 回环和 IPv6 回环入口保持各自浏览器 Origin。
- 门户编码、请求解码、上游重定向、正文和运行时使用相同的请求内映射。
- Origin/Referer、CORS 和 Cookie 网关域名还原沿用该映射,避免中途切换别名。
- 不信任任意 Host 或 X-Forwarded-Host;非回环配置和不同端口保留既有行为。
- 增加门户至 Cookie 的端到端回归,以及多别名并发隔离回归。

## 2026.0.1.10 - 2026-09-12

### 修复

- AMD 加载器配置的静态 `paths` 保留原始路径,不再按承载脚本目录提前绝对化。
- 覆盖 `require/requirejs.config` 和 AMD 组件的 `addPaths/addConfig`。
- 字符串、静态模板、路径回退数组在正常 AST 和解析失败后的有效前缀中保持一致。
- 额外实参、普通组件同名方法及路径值中的真实网络调用继续保持原有映射。
- 同字节公网脚本的离线对照复现了七条错误地址;修复后七条均恢复原加载器目标。

## 2026.0.1.9 - 2026-09-12

### 修复

- 完整空 200 的图片、字体、音视频、JSON 及其他不透明响应保持原始状态和正文。
- 不再仅因这些响应零字节而重复上游请求,也不把它们改成网关 502。
- HTML/CSS 既有检查保留;不透明响应的正文截断错误继续沿原始读取链路传播。
- 新增零长度、空分块、连接结束定界、二进制正文和截断错误回归。

## [2026.0.1.8] - 2026-09-11

### 修复

- 修复已带 `vpn-1` 或 `vpn-11` 上下文的动态脚本基址追加
  `.js`、`.mjs`、`.cjs`、`.json`、`.wasm` 时被误拼成
  `目录/.js` 的问题。
- 保留普通路径后缀和既有 Wanfang `vpn-1.png` 路径拼接语义。
- 新增真实 Chromium 动态 `HTMLScriptElement.src` 请求断言;
  修复前请求路径为 `enhance_f636eb0/.js`,修复后为
  `enhance_f636eb0.js`。

## [2026.0.1.7] - 2026-09-11

### 修复

- 浏览器站点探测默认关闭自动化标识,避免 `navigator.webdriver` 暴露测试运行时。
- 浏览器 User-Agent、Client Hints、实际 Chromium 版本和可选系统 Chrome
  executable 保持一致,减少百度安全验证把测试浏览器识别为异常运行时。
- 增加浏览器运行时证据,记录实际 executable、版本、User-Agent 和自动化标识状态。
- 本地默认 Chromium 与系统 Chrome 百度页面复测均回到搜索路径 `/s`,未进入验证码页。

## [2026.0.1.6] - 2026-09-11

### 修复

- 修复 JavaScript 比较表达式中的渲染标记被当作网络地址改写的问题。
- 比较操作数及其字符串拼接保持原始语义;比较内部独立 `fetch` 仍在请求边界映射。
- 同一 `all_async_search_c278a9f.js` 实际脚本的本地 DOM 验证由基线 0/4 提升为 4/4。
- v6 有限根页复验不再出现 `SAN HYDRATE ERROR`;上游 `c` 缺失错误仍独立保留。
- 目标回归、Go 全量回归和六命令构建通过。

## [2026.0.1.5] - 2026-09-11

### 修复

- 修复浏览器运行时把字符串内部的 JSON 引号误当作独立源码边界,破坏初始化脚本的问题。
- 匹配完整字符串的起止位置;内嵌 JSON、注释、模板正文和转义数据保持原有内容。
- 同一次网关响应的两段实际脚本证明初始化失败会连带触发数组 `.forEach` 异常。
- 增加固定初始化、词法边界和真实 Chromium HTML 插入测试;基线 3 项全失败,修复后全通过。
- runtime 68 项、Go 全量及六命令构建通过;新公网响应未命中原初始化路径,不记为对应公网通过。

## [2026.0.1.4] - 2026-09-11

### 修复

- 修复模块加载器登记入口时,`load(load.s="./entry.js")` 的模块标识被误改写的问题。
- 以 IIFE 工厂表、加载器查表调用、作用域和第一个参数的对应关系识别入口,不添加站点特例。
- fallback 对已恢复节点使用局部语义判断;同值网络参数继续映射,精确范围改用集合查询。
- 增加 AST/fallback、静态模板、嵌套作用域、网络别名、参数位置与同名方法回归。
- 原 109 条重跑结果仍为 0 PASS、69 BLOCKED、40 INCONCLUSIVE;本地修复不替代公网验收。

## [2026.0.1.3] - 2026-09-11

### 修复

- 浏览器清理测试改用 fixture 自报 PID 和精确进程句柄,去掉全机 PID 差集与差集强制终止。
- 验证无关进程保持存活、重复关闭、无效进程标识,以及六并发真实 Chromium 清理。

## [2026.0.1.2] - 2026-09-11

### 修复

- 浏览器 worker 在默认 UA 移除 `HeadlessChrome` 时,同步设置 Chromium
  Client Hints,避免 `User-Agent`、`sec-ch-ua` 和 `navigator.userAgentData`
  暴露互相矛盾的浏览器身份。
- 增加本地 worker header 验证和百度真实页面小样本复测证据。

## [2026.0.1.1] - 2026-09-10

### 变更

- 将 WebVPN 版本号统一为 `2026.<major>.<minor>.<build>` 格式。
- 首个新格式交付版本为 `2026.0.1.1`,后续每次源码修改交付时递增 `build`。

## [0.1.0] - 2026-09-04

### 新增

- 初始化 WebVPN 版本标注,源码版本为 `0.1.0`,显示版本为 `v0.1.0`。
- 所有命令支持 `-version`、`--version` 和单独的 `version` 参数。
- 网关增加无需票据的 `GET /version` 诊断接口,返回版本、提交标识和构建时间。
- 浏览器入口页页脚显示当前版本。
- 新增 `scripts/build_release.sh`,统一构建六个 Windows 程序并注入构建元数据。
- 站点测试的 `run.json` 和 Markdown 报告记录 WebVPN 源码版本。

### 完善

- 站点测试 HTTP 请求的 User-Agent 改为带 WebVPN 版本标识的形式。
- README 增加版本查询、构建和更新记录入口。
- 增加 `rewriter/testdata` 本地 JavaScript 回归样例,并让发布构建完成后自动执行
  本地重写、正则执行和六个命令版本检查,不依赖在线站点或浏览器。

### 修复

- 延续当前修复分支对 CNKI Ajax HTML 片段重复注入运行时导致前端死循环的问题,
  并将版本信息纳入本次可验证构建。
- 修复 `RegExp()` 和 `new RegExp()` 的 URL 样式模式被重写为网关路由,导致
  `Invalid regular expression: Range out of order in character class` 的问题。

[2026.0.1.8]: https://semver.org/
[2026.0.1.7]: https://semver.org/
[2026.0.1.6]: https://semver.org/
[2026.0.1.5]: https://semver.org/
[2026.0.1.2]: https://semver.org/
[2026.0.1.4]: https://semver.org/
[2026.0.1.3]: https://semver.org/
[2026.0.1.1]: https://semver.org/
[0.1.0]: https://semver.org/