12 KiB
补环境框架选择、xbs isolated-vm 与 Trace 复杂度评估
本文件用于进入 Node.js 补环境阶段前读取。核心原则:是否使用补环境框架由用户选择;Trace 复杂度只用于理解补环境范围、风险和优先级,不自动决定框架。
核心规则
- 进入正式补环境前必须提醒用户选择补环境框架。
- 默认不使用补环境框架;用户未明确选择时按“不使用补环境框架”继续。
- 可选项只有:不使用、isolated-vm、Node.js 内置 vm、jsEnv。
- 选择 isolated-vm 时必须使用本 Skill 随包魔改 xbs isolated-vm,并在 Context 内使用 window.xbs / globalThis.xbs。
- 平台缺失时要求用户提供匹配魔改构建产物或改选框架;Node ABI 不匹配时先读取
node-version-recovery.md,提示 xbs isolated-vm 兼容 Node.js v26.3.1,检测 nvm 并征得用户同意是否安装 / 切换兼容 Node,用户拒绝或切换后仍失败时才要求匹配构建产物或改选框架;不要自动 npm 安装或退回 npm 原版 isolated-vm。 - 不要把旧 addon.node 桥接进 isolated-vm;该模式下 addon-first 表达为 xbs native-first。
- 最终项目只保留用户选择的 runtime;未选择 isolated-vm 时不得复制 xbs-isolated-vm/ 或 isolated_vm.node。
补环境前询问模板
请确认本次补环境是否使用补环境框架:
1. 不使用补环境框架,默认
2. 使用 isolated-vm:加载本 Skill 随包魔改 xbs isolated-vm,在隔离 Context 内使用 window.xbs / globalThis.xbs 提供 createProtoChains、createNativeFunction、createGetter、createSetter、createNativeCollection、getMimeTypesAndPlugins、createUndetectable 等 native-first 能力;兼容 Node.js v26.3.1,进入前会自检当前 Node ABI,ABI 不匹配时先询问是否通过 nvm 安装 / 切换 v26.3.1
3. 使用 Node.js 内置 vm:轻量、无需额外安装,但隔离弱于 isolated-vm
4. 使用 jsEnv:请先提供 jsEnv 项目路径、安装方式、入口文件和使用文档;未检测通过前不会复制 jsEnv runtime 或虚构 API
如果你不明确选择,我将按“不使用补环境框架”继续。
说明:Trace 复杂度评估只用于理解补环境范围、风险点和优先级,不会自动决定是否使用补环境框架。
记录到 case/notes/补环境框架选择.md、阶段报告和最终项目总结。记录字段至少包括:框架选择、选择来源、Node 版本、Node ABI、平台、xbs 自检结果、是否发生切换、切换原因;如发生 ABI 不兼容,记录 nvm 检测结果、用户是否同意切换 Node.js v26.3.1、重新自检结果或用户拒绝原因。
Trace 复杂度评估
如果存在 RuyiTrace NDJSON、run_with_trace.js 产生的 JSONL、missing-env.json 或其他环境访问日志,必须用日志辅助理解复杂度。复杂度评估只用于:
- 判断补环境范围。
- 排定 WebAPI 补齐优先级。
- 识别指纹、异步、状态和真实性检测风险。
- 写入阶段报告。
复杂度评估不得用于自动选择 isolated-vm、vm、jsEnv 或“不使用框架”。
node scripts/analyze_trace_complexity.js --case-dir case --markdown
node scripts/analyze_trace_complexity.js --trace case/ruyi-trace/logs/trace.ndjson --json
node scripts/analyze_trace_complexity.js --trace case/tmp/env-trace.jsonl --markdown
isolated-vm(随包魔改 xbs isolated-vm)
适用:用户明确选择 isolated-vm,或普通上下文后续遇到难以解决的环境检测并且用户确认切换。
必须读取:
- assets/runtime-frameworks/isolated-vm-runtime.js
- references/xbs-isolated-vm-api.md
- scripts/check_xbs_isolated_vm.js
随包二进制路径:assets/runtime-frameworks/xbs-isolated-vm/-/isolated_vm.node。
随包二进制导出形态可能是 require(binaryPath) 直接返回 isolated-vm API,也可能返回 { ivm };runtime 必须先归一化为含 Isolate / ExternalCopy 的对象,不得假设 require(binaryPath).Isolate 一定存在。
选择 isolated-vm 后必须先运行;如果 ABI 不兼容,再运行 Node 版本兼容检查并按用户确认结果处理:
node --no-node-snapshot scripts/check_xbs_isolated_vm.js --markdown
node --no-node-snapshot scripts/check_xbs_isolated_vm.js --strict --json
node scripts/check_node_runtime_compat.js --target isolated-vm --markdown
检测内容必须包含:当前 Node 版本、ABI、平台、二进制路径、是否加载成功、window === globalThis、window.xbs 是否存在、17 个 xbs 核心 API 是否齐全、xbs.dom.createDocument 是否可用、基础 DOM smoke test 是否通过。ABI 不兼容时不得直接改选或降级,先询问用户是否通过 nvm 安装 / 切换 Node.js v26.3.1;用户拒绝后才允许提供匹配构建产物或改选不使用框架 / vm / jsEnv。
window.xbs 期望 API:
clearProtoChainRegistry
createGetter
createInterceptor
createNativeCollection
createNativeFunction
createNativeObject
createProtoChains
createSetter
createUndetectable
deletePrivate
deleteProtoChainRegistryEntry
getMimeTypesAndPlugins
getPrivate
getProtoChainRegistry
hasPrivate
setPrivate
throwTypeError
补环境代码必须运行在 isolated-vm Context 内,优先使用 xbs.createProtoChains、xbs.createNativeFunction、xbs.createGetter、xbs.createSetter、xbs.createNativeCollection、xbs.getMimeTypesAndPlugins、xbs.createUndetectable、xbs.setPrivate / getPrivate 等 API。
xbs DOM 入口要求
xbs.dom.createDocument(options)是当前 xbs DOM 的唯一公开入口;不要使用已删除的 attachDocument、detachDocument、installConstructors、getConstructors、createElement、createIframeDocument、attachIframeDocument、detachIframeDocument、patchApi、removeApi、createProfile、getProfile、listProfiles、snapshotSurface、restoreSurface、getLastError 等旧 API。createDocument()支持url、html、skeleton、omitApis、disabledApis、removedApis、features.documentAll、features.iframeContentDocument;profile参数已删除,不得继续传入。- 默认不会把
document挂到window,补环境代码必须按 case 需要自行安装window.document。 - DOM 构造函数不会默认挂到
window,但 document / element 实例自身应具备正确内部构造函数和原型链,例如document.constructor.name === "HTMLDocument"。 - 禁用 DOM API 必须在创建 document 前通过
omitApis或features声明,不要运行时强删已经发布的不可配置属性。 document.all默认由xbs.dom.createDocument()提供,期望满足typeof document.all === "undefined"、Boolean(document.all) === false、document.all == null、document.all.length、item()、namedItem()与[object HTMLAllCollection]等行为;禁用时使用omitApis: ["document.all"]或features.documentAll: false。- 只有不使用
createDocument()而手写 document 时,才手动使用xbs.createUndetectable(callback, handlers)创建document.all;此时必须把length / item / namedItem / Symbol.toStringTag放到HTMLAllCollection.prototype,handlers 未命中时返回{ intercept: false }放行原型链,不要把这些属性定义为document.all自有属性。 - iframe 不再使用旧
createIframeDocument()/attachIframeDocument();iframe 的contentDocument/contentWindow由 iframe 元素按需创建,禁用时使用omitApis: ["HTMLIFrameElement.prototype.contentDocument"]。 - 当前 DOM 是补环境基础实现,不是完整浏览器内核;真实布局、CSSOM、MutationObserver、Canvas、WebGL 等仍按本 Skill 对应指纹 / 高强度 diff 流程补齐。
Context 内示例:
const chain = xbs.createProtoChains([
{ name: "EventTarget", length: 0, constructorBehavior: "allow" },
{
name: "Navigator",
length: 0,
prototypeParent: "EventTarget",
constructorBehavior: "illegal",
callBehavior: "illegal",
constructorErrorMessage: "Illegal constructor",
callErrorMessage: "Illegal constructor",
instanceFactoryName: "createNavigator",
},
]);
Object.defineProperty(chain.Navigator.prototype, "userAgent", {
get: xbs.createGetter("userAgent", 0, function () {
return __fixture__.navigator.userAgent;
}),
enumerable: true,
configurable: true,
});
globalThis.navigator = chain.createNavigator();
isolated-vm 文件化补环境加载模式
- isolated-vm 底层执行的仍然是源码字符串,但最终交付源码必须是普通文件;宿主 runtime 负责读取文件内容并传给
compileScriptSync(source, { filename })。 - 禁止把主要补环境代码集中写入
String.raw大字符串、CORE_SCRIPT、BROWSER_OBJECTS_SCRIPT或script-browser-objects.js这类聚合脚本。 - runtime 必须提供或等价实现
runFile(relativePath, options)和runFiles(fileList, options),默认从项目根目录或显式sourceRoot读取 UTF-8 文件,并限制路径不能逃逸 sourceRoot。 runFile必须给 isolated-vm 编译选项传入可读filename,让错误栈能定位到src/env/browser-objects/navigator.js、document.js、canvas.js等具体文件。install-env.js只做装配:设置 fixture / config / 宿主桥接引用,按 manifest 顺序调用runtime.runFiles([...]),再执行极小的安装入口。- Context 内不要直接实现 CommonJS
require来加载本地文件;除非用户明确要求复杂模块系统,默认采用宿主按顺序注入文件的方式,简单、安全、可审计。 - 文件组织建议:
src/env/core/放 descriptor、cookie-store、native helper;src/env/browser-objects/放 window、navigator、document、location、screen、xhr、storage;src/env/fingerprint/放 canvas、webgl、audio、dom-geometry。 - 质量检查必须运行
scripts/check_code_quality.js --case-dir case --markdown;如果检测到大段String.rawWebAPI 脚本或缺少文件化模块,应先重构再交付。
Node.js 内置 vm
用户明确选择 vm 时才使用 assets/runtime-frameworks/vm-runtime.js。仍需显式构造干净 context,不得暴露 process、Buffer、require、module、global,也不得把 vm 当强安全边界。
jsEnv
用户明确选择 jsEnv 时才使用 assets/runtime-frameworks/jsenv-runtime.js。必须先确认 jsEnv 项目路径、版本、安装命令、入口模块、初始化函数、如何注入 env、如何加载目标 JS、如何调用 signer、如何释放资源;未提供文档时只能生成待适配模板,不能虚构 API。
最终项目复制规则
- 不使用框架:不得复制 vm-runtime.js、isolated-vm-runtime.js、jsenv-runtime.js、xbs-isolated-vm/。
- 选择 vm:复制 runtime-factory.js 和 vm-runtime.js。
- 选择 isolated-vm:复制 runtime-factory.js、isolated-vm-runtime.js 和 xbs-isolated-vm/-/isolated_vm.node;用户提供替换二进制时复制到相对结构或通过配置引用,不要把本机绝对路径写入最终产物。
- 选择 jsEnv:复制 runtime-factory.js、jsenv-runtime.js,并根据用户文档补 adapter。
二次提醒触发条件
如果默认未使用框架,但后续出现普通上下文无法阻断 Function("return this")()、constructor.constructor、Realm / intrinsic 差异、全局对象污染、多 fixture 互相影响等问题,暂停并询问是否切换。不得自动启用框架。
交付检查
- 框架选择已记录。
- Trace 复杂度评估已写入阶段报告(如果存在 Trace)。
- 选择 isolated-vm 时已记录 xbs 自检、Node ABI、平台、二进制来源;如 ABI 不兼容,已记录 nvm + Node.js v26.3.1 恢复流程、用户选择和重新检测结果。
- 选择 isolated-vm 时最终代码在 Context 内优先使用 xbs API,没有桥接旧 addon.node;补环境源码按真实文件模块组织,并由 runtime.runFile / runtime.runFiles 注入 Context,没有大段
String.raw作为主要实现。 - 未选择 isolated-vm 时最终项目不含 xbs-isolated-vm/、isolated_vm.node 或 isolated-vm runtime。
- 未选择框架时最终项目不含 vm-runtime.js、isolated-vm-runtime.js、jsenv-runtime.js。