{
  "config": {
    "argv": [
      "/opt/hostedtoolcache/node/20.20.2/x64/bin/node",
      "/home/runner/work/dr-card-web/dr-card-web/node_modules/.bin/playwright",
      "test",
      "tests/e2e/test-gate.spec.ts"
    ],
    "configFile": "/home/runner/work/dr-card-web/dr-card-web/playwright.config.ts",
    "rootDir": "/home/runner/work/dr-card-web/dr-card-web/tests/e2e",
    "failOnFlakyTests": false,
    "forbidOnly": true,
    "fullyParallel": true,
    "globalSetup": null,
    "globalTeardown": null,
    "globalTimeout": 0,
    "grep": {},
    "grepInvert": null,
    "maxFailures": 0,
    "metadata": {
      "ci": {
        "commitHref": "https://github.com/sanchuang-dev/dr-card-web/commit/1c08c34457fc5ffe2343bd705a2f2c587ee037e0",
        "commitHash": "1c08c34457fc5ffe2343bd705a2f2c587ee037e0",
        "prHref": "https://github.com/sanchuang-dev/dr-card-web/pull/212",
        "prTitle": "release(test): 晋级 HTTPS 商城 Demo 修复与仓库文档",
        "prBaseHash": "25ebe33ca26334ac94f731ebd4dacf921daf0be9",
        "buildHref": "https://github.com/sanchuang-dev/dr-card-web/actions/runs/38346573966"
      },
      "gitCommit": {
        "shortHash": "1c08c34",
        "hash": "1c08c34457fc5ffe2343bd705a2f2c587ee037e0",
        "subject": "Merge e5244e77973b2cb9c9b322f806c2791fc2e1b51d into 25ebe33ca26334ac94f731ebd4dacf921daf0be9",
        "body": "Merge e5244e77973b2cb9c9b322f806c2791fc2e1b51d into 25ebe33ca26334ac94f731ebd4dacf921daf0be9\n",
        "author": {
          "name": "Tomz Dang",
          "email": "dangjingtao@163.com",
          "time": 1791865684000
        },
        "committer": {
          "name": "GitHub",
          "email": "noreply@github.com",
          "time": 1791865684000
        },
        "branch": "HEAD"
      },
      "gitDiff": "diff --git a/AGENTS.md b/AGENTS.md\nindex 05aba21..ecc8097 100644\n--- a/AGENTS.md\n+++ b/AGENTS.md\n@@ -1,6 +1,6 @@\n # AGENTS.md\n \n-本文件是 `dr-card-ui` 仓库的全局智能体施工指南，适用于在本仓库内工作的 AI 编码、设计与测试智能体。\n+本文件是 `sanchuang-dev/dr-card-web` 仓库的全局智能体施工指南，适用于在本仓库内工作的 AI 编码、设计与测试智能体。\n \n ## 1. 项目定位\n \ndiff --git a/README.md b/README.md\nindex f5cb212..7e8fbda 100644\n--- a/README.md\n+++ b/README.md\n@@ -1,6 +1,6 @@\n # 卡博士 App 内嵌 H5\n \n-`dr-card-ui` 是 **卡博士原生 App 内嵌的 H5 前端工程**。项目最初用于高保真 UI 施工，目前已经进入正式工程开发阶段：继续保留 Mockplus / `preview` 作为 UI 真相，同时在 `dev` 接入真实 API、业务状态和 JSBridge，并通过 App WebView 联调后进入生产。\n+`dr-card-web`（内部 npm 包名仍为 `dr-card-ui`）是 **卡博士原生 App 内嵌的 H5 前端工程**。项目最初用于高保真 UI 施工，目前已经进入正式工程开发阶段：继续保留 Mockplus / `preview` 作为 UI 真相，同时在 `dev` 接入真实 API、业务状态和 JSBridge，并通过 App WebView 联调后进入生产。\n \n ## 分支节奏\n \ndiff --git a/docs/deploy/oss-credential-isolation.md b/docs/deploy/oss-credential-isolation.md\nnew file mode 100644\nindex 0000000..9606dfb\n--- /dev/null\n+++ b/docs/deploy/oss-credential-isolation.md\n@@ -0,0 +1,42 @@\n+# OSS 发布密钥环境隔离 · 2026-10-13\n+\n+关联：[OPS #209](https://github.com/sanchuang-dev/dr-card-web/issues/209)、[发布验收 #171](https://github.com/sanchuang-dev/dr-card-web/issues/171)。\n+\n+## 当前事实与完成度\n+\n+- GitHub Environment 分支准入已经直接设置并读回：`oss-ui: preview`、`oss-dev: dev`、`oss-test: test`、`oss-production: prod`。\n+- **尚未完成真实密钥隔离。** `oss-ui/dev/test` 目前没有各自独立 RAM AccessKey 的 Environment Secrets；仓库级 `OSS_ACCESS_KEY_ID/OSS_ACCESS_KEY_SECRET` 仍存在。生产环境有自己的同名 Secrets。\n+- GitHub 的同名 Secret 查找顺序是 **Environment > Repository > Organization**。所以给环境新增同名 Secret 后会优先使用它，但在删除仓库级 Secret 前仍可能出现意外 fallback。不得仅凭 job 的 Environment 名称宣称密钥隔离完成。\n+- 迁移到 `sanchuang-dev/dr-card-web` 后的 OSS `dev` 推送已经成功过（Run [#38337673847](https://github.com/sanchuang-dev/dr-card-web/actions/runs/38337673847)，41 文件校验），但这次使用的仍可能是仓库级密钥；它不是 RAM 范围隔离的证明。\n+\n+## 三套非生产 RAM 身份（不得共用同一 AccessKey）\n+\n+| GitHub Environment | 唯一分支 | RAM 用户建议名 | 唯一允许的 OSS 对象前缀 | 示例权限策略 |\n+| --- | --- | --- | --- | --- |\n+| `oss-ui` | `preview` | `kbs-web-ui-deployer` | `kbs-sdl/kbs-web/ui/*` | [oss-ui.json](./ram-policies/oss-ui.json) |\n+| `oss-dev` | `dev` | `kbs-web-dev-deployer` | `kbs-sdl/kbs-web/dev/*` | [oss-dev.json](./ram-policies/oss-dev.json) |\n+| `oss-test` | `test` | `kbs-web-test-deployer` | `kbs-sdl/kbs-web/test/*` | [oss-test.json](./ram-policies/oss-test.json) |\n+\n+建议用专用 RAM 用户，**仅关联本表对应的自定义策略**，不关联 `AliyunOSSFullAccess` 等广泛授权。每个身份签发一个独立 AccessKey。策略只授予该前缀 `ListObjects`（限制 Prefix 条件）、`GetObject`、`PutObject`；默认**没有** `DeleteObject` 和跨环境权限。阿里云 RAM 官方示例：[基于 RAM Policy 控制 OSS 访问](https://help.aliyun.com/zh/oss/user-guide/access-control-base-on-ram-policy)。\n+\n+> 以上示例基于当前 `scripts/deploy-oss-web-nonprod.mjs` 的上传与逐文件下载验证。首次真实部署时如果因缺少其它非破坏性 Action 失败，依据实际 OSS 错误做最小增补，不直接授予全 Bucket 写权限。单独确认 RAM 用户未获得继承的宽权限。\n+\n+## 无中断切换顺序\n+\n+1. 阿里云 RAM 管理员���建三套独立身份与策略；分别生成 AccessKey，不把密钥写到 Issue、PR、日志、仓库、`.env.*` 或 `VITE_*`。\n+2. 分别进入 [GitHub Environments](https://github.com/sanchuang-dev/dr-card-web/settings/environments) 的 `oss-ui` / `oss-dev` / `oss-test`，写入 **Environment secrets**（不是 Variables）：\n+   - `OSS_ACCESS_KEY_ID`\n+   - `OSS_ACCESS_KEY_SECRET`\n+3. 用匹配分支的受控 push（`preview`、`dev`、`test`）完成各环境 OSS 文件读回与公司域名 `build-meta.json` SHA 验证；这些 push 会真发布，请按正常晋级纪律安排，**不得为了验证直接推送生产**。\n+4. 在 RAM 权限验证中确保：`dev` 密钥不能读/写 `test` 或 `prod` 等其它前缀，`test` 和 `ui` 同理；不得做有破坏性的“拒绝性测试”。\n+5. 所有新凭据验证通过且确认没有旧密钥依赖或在途 workflow 后，删除**仓库级** `OSS_ACCESS_KEY_ID` / `OSS_ACCESS_KEY_SECRET`，让凭据只能来自各自环境；再次受控部署复验。\n+6. 检查旧仓库级密钥对应的阿里云 RAM AK 是否仍被其它系统依赖；确认迁移后由云账号管理员禁用/轮换旧 AK。**仅从 GitHub 删除 Secret 不等于 RAM AK 失效。**\n+\n+## 生产与非敏感变量\n+\n+- `oss-production` 已有独立同名 Environment Secrets，且只允许 `prod` 分支。其 RAM 身份还需核验最小权限和历史/回滚实际需要的 `DeleteObject` 边界；**本次不改生产 IAM、Secrets、触发规则或历史数据**。\n+- `OSS_API_BASE_URL`、`OSS_PUBLIC_ORIGIN`、`OSS_PROD_API_BASE_URL`、`OSS_PROD_PUBLIC_ORIGIN`、`VITE_API_BASE_URL` 是前端构建可见 URL；应当保留为 GitHub Variables（不是 Secrets），并检查目标环境和继承优先级。\n+- `OSS_PUBLIC_ORIGIN` 在仓库和 `oss-test` 的环境列表中没有单独看到，但历史 test 部署成功；可能由**组织级 Variables** 提供。当前组织级读取被 403 拒绝，在有组织管理权限者核实前，不要用旧 Cloudflare 域名覆盖它。\n+- `CLOUDFLARE_API_TOKEN`、`OPENCODE_API_KEY` 等供应商令牌仍为 Secrets；`CLOUDFLARE_ACCOUNT_ID` 只是账号标识，保留 Secret 也不影响安全。\n+\n+**状态：GitHub 环境分支隔离已完成；RAM 独立 AK 签发、Environment Secrets 配置、跨前缀权限验证与仓库级旧 Secret 退役均未完成。**\ndiff --git a/docs/deploy/oss-production.md b/docs/deploy/oss-production.md\nindex 14a4e20..792f959 100644\n--- a/docs/deploy/oss-production.md\n+++ b/docs/deploy/oss-production.md\n@@ -2,7 +2,7 @@\n \n ## 事实与边界\n \n-- 前端仓库：`dangjingtao/dr-card-ui`。\n+- 前端仓库：`sanchuang-dev/dr-card-web`。\n - OSS Bucket：`kbs-sdl`，地域：`cn-guangzhou`，API Endpoint：`https://oss-cn-guangzhou.aliyuncs.com`。\n - 构建：`npm run build:prod`，构建产物：`dist/`。\n - 发布来源：仅 `prod` 分支。晋级沿用 `preview → dev → test → prod`，不得跳级。\ndiff --git a/docs/deploy/ram-policies/oss-dev.json b/docs/deploy/ram-policies/oss-dev.json\nnew file mode 100644\nindex 0000000..94f0d45\n--- /dev/null\n+++ b/docs/deploy/ram-policies/oss-dev.json\n@@ -0,0 +1,28 @@\n+{\n+  \"Version\": \"1\",\n+  \"Statement\": [\n+    {\n+      \"Effect\": \"Allow\",\n+      \"Action\": [\n+        \"oss:ListObjects\"\n+      ],\n+      \"Resource\": \"acs:oss:*:*:kbs-sdl\",\n+      \"Condition\": {\n+        \"StringLike\": {\n+          \"oss:Prefix\": [\n+            \"kbs-web/dev/\",\n+            \"kbs-web/dev/*\"\n+          ]\n+        }\n+      }\n+    },\n+    {\n+      \"Effect\": \"Allow\",\n+      \"Action\": [\n+        \"oss:GetObject\",\n+        \"oss:PutObject\"\n+      ],\n+      \"Resource\": \"acs:oss:*:*:kbs-sdl/kbs-web/dev/*\"\n+    }\n+  ]\n+}\ndiff --git a/docs/deploy/ram-policies/oss-test.json b/docs/deploy/ram-policies/oss-test.json\nnew file mode 100644\nindex 0000000..56dd2ad\n--- /dev/null\n+++ b/docs/deploy/ram-policies/oss-test.json\n@@ -0,0 +1,28 @@\n+{\n+  \"Version\": \"1\",\n+  \"Statement\": [\n+    {\n+      \"Effect\": \"Allow\",\n+      \"Action\": [\n+        \"oss:ListObjects\"\n+      ],\n+      \"Resource\": \"acs:oss:*:*:kbs-sdl\",\n+      \"Condition\": {\n+        \"StringLike\": {\n+          \"oss:Prefix\": [\n+            \"kbs-web/test/\",\n+            \"kbs-web/test/*\"\n+          ]\n+        }\n+      }\n+    },\n+    {\n+      \"Effect\": \"Allow\",\n+      \"Action\": [\n+        \"oss:GetObject\",\n+        \"oss:PutObject\"\n+      ],\n+      \"Resource\": \"acs:oss:*:*:kbs-sdl/kbs-web/test/*\"\n+    }\n+  ]\n+}\ndiff --git a/docs/deploy/ram-policies/oss-ui.json b/docs/deploy/ram-policies/oss-ui.json\nnew file mode 100644\nindex 0000000..d201977\n--- /dev/null\n+++ b/docs/deploy/ram-policies/oss-ui.json\n@@ -0,0 +1,28 @@\n+{\n+  \"Version\": \"1\",\n+  \"Statement\": [\n+    {\n+      \"Effect\": \"Allow\",\n+      \"Action\": [\n+        \"oss:ListObjects\"\n+      ],\n+      \"Resource\": \"acs:oss:*:*:kbs-sdl\",\n+      \"Condition\": {\n+        \"StringLike\": {\n+          \"oss:Prefix\": [\n+            \"kbs-web/ui/\",\n+            \"kbs-web/ui/*\"\n+          ]\n+        }\n+      }\n+    },\n+    {\n+      \"Effect\": \"Allow\",\n+      \"Action\": [\n+        \"oss:GetObject\",\n+        \"oss:PutObject\"\n+      ],\n+      \"Resource\": \"acs:oss:*:*:kbs-sdl/kbs-web/ui/*\"\n+    }\n+  ]\n+}\ndiff --git a/docs/design/design-baseline.md b/docs/design/design-baseline.md\nindex cf227a6..dba6733 100644\n--- a/docs/design/design-baseline.md\n+++ b/docs/design/design-baseline.md\n@@ -2,7 +2,7 @@\n \n ## 项目定位\n \n-`dr-card-ui` 当前是 **卡博士原生 App 内嵌 H5 前端工程**。设计工作不再只服务于静态高保真演示，而是要在真实 WebView、真实数据、真实宿主能力接入后仍保持稳定的视觉与交互结论。\n+`dr-card-web`（npm 包名仍为 `dr-card-ui`）当前是 **卡博士原生 App 内嵌 H5 前端工程**。设计工作不再只服务于静态高保真演示，而是要在真实 WebView、真实数据、真实宿主能力接入后仍保持稳定的视觉与交互结论。\n \n 因此设计基线同时约束两件事：\n \ndiff --git a/docs/engineering/repository-transfer-2026-10-13.md b/docs/engineering/repository-transfer-2026-10-13.md\nnew file mode 100644\nindex 0000000..cd55db0\n--- /dev/null\n+++ b/docs/engineering/repository-transfer-2026-10-13.md\n@@ -0,0 +1,30 @@\n+# 2026-10-13 · GitHub 仓库所有权转移验收记录\n+\n+> 当前仓库：`sanchuang-dev/dr-card-web`；来源：`dangjingtao/dr-card-ui`。原生 GitHub Transfer + 同时重命名，不是新建仓库或复制历史。\n+\n+## 已有只读证据（转移后）\n+\n+- GitHub 仓库 ID 未变：`1341342340`；目标 owner 为 `sanchuang-dev`；当前连接可管理员访问。\n+- 分支提交保持不变：`main@aec60b6e`、`preview@4df9cf0e`、`dev@2605a6e9`、`test@25ebe33c`、`prod@7895d1c4`。\n+- Issue #82 / #171、未合并 PR #198 均可在新路径读取；七个 Workflow YAML 仍在。\n+- 旧 GitHub 仓库地址经 API 解析到新 owner；现有历史 Issue/PR 链接由 GitHub 重定向。历史审计快照保留当时仓库名称，**不要全量改写历史证据**。\n+- 公网只读探测：`https://kbs.3cgroup.cn/kbs-web/{dev,test,prod/last}/` 分别 HTTP 200；`https://test.dr-card-ui.pages.dev/` HTTP 200。\n+- `/kbs-web/test/build-meta.json` 仍是迁移前已成功发布的 `test@25ebe33ca26334ac94f731ebd4dacf921daf0be9`、Run `38235724425.1`。**这证明旧站未中断，但不证明迁移后新运行能部署。**\n+\n+## 尚需实际验证的切换门槛\n+\n+- [ ] 在新 owner 的 PR 上观察 GitHub Build/Test gate 是否真实运行成功，不能仅看转移前历史 Actions。\n+- [ ] 在新 owner 的 PR 上观察 OpenCode / Codex / 其他审查 App 的授权与执行；不把 Review skipped 视为 PASS。\n+- [ ] Cloudflare Git 集成是否会对新仓库、新 PR 产生构建/检查；若失效，由有权限者重新授权或绑定，旧 Cloudflare 项目和域名不删除。\n+- [ ] 新 owner 的 `oss-ui` / `oss-dev` / `oss-test` / `oss-production` GitHub Environments、Secrets、Variables 的可用性，经**受控新分支提交/部署**验证；不读取/输出密钥明文，也不以旧成功 Run 代替。\n+- [ ] 新 owner 上的 `dev` 非生产 OSS push 成功后，核对公开 `build-meta.json` SHA 与 readback；`test` 仅在正常晋级后验证。\n+- [ ] 生产发布、Health Gate、历史与回滚链路独立验证；未经明确授权不向 `prod` 推送。\n+- [ ] 协作成员检查本地 Git `origin` 或自动化里的旧 repository slug。GitHub 会重定向，但建议主动改为 `https://github.com/sanchuang-dev/dr-card-web.git`；不自动修改其他人的工作区。\n+\n+## 保持不变的边界\n+\n+- `preview` 是独立 UI 事实源，不要求与 `dev/test/prod` 同 SHA；只按既定晋级规则操作。\n+- OSS Bucket `kbs-sdl`、固定 URL `kbs.3cgroup.cn/kbs-web/`、Cloudflare 项目地址、原 App WebView 地址不随仓库更名改变。\n+- 不删旧 OSS 目录，不改 Git 历史，不重新建 Issue/PR，不重置任一分支。\n+\n+本记录用于迁移验收与后续追踪；尚未逐项勾选的外部部署/授权行为不得表述为已通过。\ndiff --git a/docs/testing/test-plan.md b/docs/testing/test-plan.md\nindex de05bff..a590570 100644\n--- a/docs/testing/test-plan.md\n+++ b/docs/testing/test-plan.md\n@@ -1,6 +1,6 @@\n # 卡博士 App 内嵌 H5 测试与验收方案\n \n-> 适用仓库：`dangjingtao/dr-card-ui`\n+> 适用仓库：`sanchuang-dev/dr-card-web`\n >\n > 适用主链路：`preview → dev → test → prod`\n >\n@@ -10,7 +10,7 @@\n \n ## 1. 目标\n \n-`dr-card-ui` 是 **卡博士 App 内嵌 H5 前端**。它既需要在浏览器中独立开发和预览，也需要最终运行在 Android / iOS App WebView 中，并与真实业务 API、Native JSBridge 协作。\n+`dr-card-web`（npm 包名仍为 `dr-card-ui`）是 **卡博士 App 内嵌 H5 前端**。它既需要在浏览器中独立开发和预览，也需要最终运行在 Android / iOS App WebView 中，并与真实业务 API、Native JSBridge 协作。\n \n 因此，本项目不能用“浏览器打开正常”代替完整验收。\n \ndiff --git a/docs/workflow/branch-strategy.md b/docs/workflow/branch-strategy.md\nindex a356468..0a9e8ac 100644\n--- a/docs/workflow/branch-strategy.md\n+++ b/docs/workflow/branch-strategy.md\n@@ -1,6 +1,6 @@\n # 卡博士 H5 分支与发布节奏\n \n-`dr-card-ui` 已从高保真 UI 工程进入正式 **App 内嵌 H5 前端**阶段。长期分支固定为：\n+`dr-card-web` 已从高保真 UI 工程进入正式 **App 内嵌 H5 前端**阶段（npm 包名暂保留为 `dr-card-ui`）。长期分支固定为：\n \n ```text\n preview → dev → test → prod\ndiff --git a/docs/workflow/engineering-workflow.md b/docs/workflow/engineering-workflow.md\nindex 2198131..0afaba8 100644\n--- a/docs/workflow/engineering-workflow.md\n+++ b/docs/workflow/engineering-workflow.md\n@@ -2,7 +2,7 @@\n \n ## 项目定位\n \n-dr-card-ui 是卡博士移动 APP 高保真 UI 工程。\n+`dr-card-web`（原仓库 `dr-card-ui`）的本文件记录卡博士移动 APP 高保真 UI 阶段的工程工作方式，正式 H5 的现行工程规则优先遵循 `AGENTS.md`。\n \n 目标不是搭建完整业务系统，而是：\n \ndiff --git a/src/pages/MallWebView.tsx b/src/pages/MallWebView.tsx\nindex 341b6d6..3147f75 100644\n--- a/src/pages/MallWebView.tsx\n+++ b/src/pages/MallWebView.tsx\n@@ -6,10 +6,10 @@\n  * 不跳出 App / H5 外层界面。\n  *\n  * 2026-10-12：当前地址仅用于效果预览，不代表正式商城接入方案。\n- * 保留用户提供的 http scheme，不自动改写为 https；鉴权透传、cleartext/mixed-content\n- * 及目标站 iframe 策略仍需在真实 App WebView 内单独验证。\n+ * test 页面由 HTTPS 承载，商城效果地址使用已验证可达的 HTTPS，避免混合内容被浏览器拦截。\n+ * 鉴权透传、第三方站内混合资源及 iframe 策略仍需真实 App WebView 验收。\n  */\n-const MALL_H5_URL = 'http://scmzhds07.m.demo.webportal.top/?_sc=1'\n+const MALL_H5_URL = 'https://scmzhds07.m.demo.webportal.top/?_sc=1'\n \n export default function MallWebView() {\n   return (",
      "actualWorkers": 2
    },
    "preserveOutput": "always",
    "projects": [
      {
        "outputDir": "/home/runner/work/dr-card-web/dr-card-web/test-results/artifacts",
        "repeatEach": 1,
        "retries": 1,
        "metadata": {
          "ci": {
            "commitHref": "https://github.com/sanchuang-dev/dr-card-web/commit/1c08c34457fc5ffe2343bd705a2f2c587ee037e0",
            "commitHash": "1c08c34457fc5ffe2343bd705a2f2c587ee037e0",
            "prHref": "https://github.com/sanchuang-dev/dr-card-web/pull/212",
            "prTitle": "release(test): 晋级 HTTPS 商城 Demo 修复与仓库文档",
            "prBaseHash": "25ebe33ca26334ac94f731ebd4dacf921daf0be9",
            "buildHref": "https://github.com/sanchuang-dev/dr-card-web/actions/runs/38346573966"
          },
          "gitCommit": {
            "shortHash": "1c08c34",
            "hash": "1c08c34457fc5ffe2343bd705a2f2c587ee037e0",
            "subject": "Merge e5244e77973b2cb9c9b322f806c2791fc2e1b51d into 25ebe33ca26334ac94f731ebd4dacf921daf0be9",
            "body": "Merge e5244e77973b2cb9c9b322f806c2791fc2e1b51d into 25ebe33ca26334ac94f731ebd4dacf921daf0be9\n",
            "author": {
              "name": "Tomz Dang",
              "email": "dangjingtao@163.com",
              "time": 1791865684000
            },
            "committer": {
              "name": "GitHub",
              "email": "noreply@github.com",
              "time": 1791865684000
            },
            "branch": "HEAD"
          },
          "gitDiff": "diff --git a/AGENTS.md b/AGENTS.md\nindex 05aba21..ecc8097 100644\n--- a/AGENTS.md\n+++ b/AGENTS.md\n@@ -1,6 +1,6 @@\n # AGENTS.md\n \n-本文件是 `dr-card-ui` 仓库的全局智能体施工指南，适用于在本仓库内工作的 AI 编码、设计与测试智能体。\n+本文件是 `sanchuang-dev/dr-card-web` 仓库的全局智能体施工指南，适用于在本仓库内工作的 AI 编码、设计与测试智能体。\n \n ## 1. 项目定位\n \ndiff --git a/README.md b/README.md\nindex f5cb212..7e8fbda 100644\n--- a/README.md\n+++ b/README.md\n@@ -1,6 +1,6 @@\n # 卡博士 App 内嵌 H5\n \n-`dr-card-ui` 是 **卡博士原生 App 内嵌的 H5 前端工程**。项目最初用于高保真 UI 施工，目前已经进入正式工程开发阶段：继续保留 Mockplus / `preview` 作为 UI 真相，同时在 `dev` 接入真实 API、业务状态和 JSBridge，并通过 App WebView 联调后进入生产。\n+`dr-card-web`（内部 npm 包名仍为 `dr-card-ui`）是 **卡博士原生 App 内嵌的 H5 前端工程**。项目最初用于高保真 UI 施工，目前已经进入正式工程开发阶段：继续保留 Mockplus / `preview` 作为 UI 真相，同时在 `dev` 接入真实 API、业务状态和 JSBridge，并通过 App WebView 联调后进入生产。\n \n ## 分支节奏\n \ndiff --git a/docs/deploy/oss-credential-isolation.md b/docs/deploy/oss-credential-isolation.md\nnew file mode 100644\nindex 0000000..9606dfb\n--- /dev/null\n+++ b/docs/deploy/oss-credential-isolation.md\n@@ -0,0 +1,42 @@\n+# OSS 发布密钥环境隔离 · 2026-10-13\n+\n+关联：[OPS #209](https://github.com/sanchuang-dev/dr-card-web/issues/209)、[发布验收 #171](https://github.com/sanchuang-dev/dr-card-web/issues/171)。\n+\n+## 当前事实与完成度\n+\n+- GitHub Environment 分支准入已经直接设置并读回：`oss-ui: preview`、`oss-dev: dev`、`oss-test: test`、`oss-production: prod`。\n+- **尚未完成真实密钥隔离。** `oss-ui/dev/test` 目前没有各自独立 RAM AccessKey 的 Environment Secrets；仓库级 `OSS_ACCESS_KEY_ID/OSS_ACCESS_KEY_SECRET` 仍存在。生产环境有自己的同名 Secrets。\n+- GitHub 的同名 Secret 查找顺序是 **Environment > Repository > Organization**。所以给环境新增同名 Secret 后会优先使用它，但在删除仓库级 Secret 前仍可能出现意外 fallback。不得仅凭 job 的 Environment 名称宣称密钥隔离完成。\n+- 迁移到 `sanchuang-dev/dr-card-web` 后的 OSS `dev` 推送已经成功过（Run [#38337673847](https://github.com/sanchuang-dev/dr-card-web/actions/runs/38337673847)，41 文件校验），但这次使用的仍可能是仓库级密钥；它不是 RAM 范围隔离的证明。\n+\n+## 三套非生产 RAM 身份（不得共用同一 AccessKey）\n+\n+| GitHub Environment | 唯一分支 | RAM 用户建议名 | 唯一允许的 OSS 对象前缀 | 示例权限策略 |\n+| --- | --- | --- | --- | --- |\n+| `oss-ui` | `preview` | `kbs-web-ui-deployer` | `kbs-sdl/kbs-web/ui/*` | [oss-ui.json](./ram-policies/oss-ui.json) |\n+| `oss-dev` | `dev` | `kbs-web-dev-deployer` | `kbs-sdl/kbs-web/dev/*` | [oss-dev.json](./ram-policies/oss-dev.json) |\n+| `oss-test` | `test` | `kbs-web-test-deployer` | `kbs-sdl/kbs-web/test/*` | [oss-test.json](./ram-policies/oss-test.json) |\n+\n+建议用专用 RAM 用户，**仅关联本表对应的自定义策略**，不关联 `AliyunOSSFullAccess` 等广泛授权。每个身份签发一个独立 AccessKey。策略只授予该前缀 `ListObjects`（限制 Prefix 条件）、`GetObject`、`PutObject`；默认**没有** `DeleteObject` 和跨环境权限。阿里云 RAM 官方示例：[基于 RAM Policy 控制 OSS 访问](https://help.aliyun.com/zh/oss/user-guide/access-control-base-on-ram-policy)。\n+\n+> 以上示例基于当前 `scripts/deploy-oss-web-nonprod.mjs` 的上传与逐文件下载验证。首次真实部署时如果因缺少其它非破坏性 Action 失败，依据实际 OSS 错误做最小增补，不直接授予全 Bucket 写权限。单独确认 RAM 用户未获得继承的宽权限。\n+\n+## 无中断切换顺序\n+\n+1. 阿里云 RAM 管理员���建三套独立身份与策略；分别生成 AccessKey，不把密钥写到 Issue、PR、日志、仓库、`.env.*` 或 `VITE_*`。\n+2. 分别进入 [GitHub Environments](https://github.com/sanchuang-dev/dr-card-web/settings/environments) 的 `oss-ui` / `oss-dev` / `oss-test`，写入 **Environment secrets**（不是 Variables）：\n+   - `OSS_ACCESS_KEY_ID`\n+   - `OSS_ACCESS_KEY_SECRET`\n+3. 用匹配分支的受控 push（`preview`、`dev`、`test`）完成各环境 OSS 文件读回与公司域名 `build-meta.json` SHA 验证；这些 push 会真发布，请按正常晋级纪律安排，**不得为了验证直接推送生产**。\n+4. 在 RAM 权限验证中确保：`dev` 密钥不能读/写 `test` 或 `prod` 等其它前缀，`test` 和 `ui` 同理；不得做有破坏性的“拒绝性测试”。\n+5. 所有新凭据验证通过且确认没有旧密钥依赖或在途 workflow 后，删除**仓库级** `OSS_ACCESS_KEY_ID` / `OSS_ACCESS_KEY_SECRET`，让凭据只能来自各自环境；再次受控部署复验。\n+6. 检查旧仓库级密钥对应的阿里云 RAM AK 是否仍被其它系统依赖；确认迁移后由云账号管理员禁用/轮换旧 AK。**仅从 GitHub 删除 Secret 不等于 RAM AK 失效。**\n+\n+## 生产与非敏感变量\n+\n+- `oss-production` 已有独立同名 Environment Secrets，且只允许 `prod` 分支。其 RAM 身份还需核验最小权限和历史/回滚实际需要的 `DeleteObject` 边界；**本次不改生产 IAM、Secrets、触发规则或历史数据**。\n+- `OSS_API_BASE_URL`、`OSS_PUBLIC_ORIGIN`、`OSS_PROD_API_BASE_URL`、`OSS_PROD_PUBLIC_ORIGIN`、`VITE_API_BASE_URL` 是前端构建可见 URL；应当保留为 GitHub Variables（不是 Secrets），并检查目标环境和继承优先级。\n+- `OSS_PUBLIC_ORIGIN` 在仓库和 `oss-test` 的环境列表中没有单独看到，但历史 test 部署成功；可能由**组织级 Variables** 提供。当前组织级读取被 403 拒绝，在有组织管理权限者核实前，不要用旧 Cloudflare 域名覆盖它。\n+- `CLOUDFLARE_API_TOKEN`、`OPENCODE_API_KEY` 等供应商令牌仍为 Secrets；`CLOUDFLARE_ACCOUNT_ID` 只是账号标识，保留 Secret 也不影响安全。\n+\n+**状态：GitHub 环境分支隔离已完成；RAM 独立 AK 签发、Environment Secrets 配置、跨前缀权限验证与仓库级旧 Secret 退役均未完成。**\ndiff --git a/docs/deploy/oss-production.md b/docs/deploy/oss-production.md\nindex 14a4e20..792f959 100644\n--- a/docs/deploy/oss-production.md\n+++ b/docs/deploy/oss-production.md\n@@ -2,7 +2,7 @@\n \n ## 事实与边界\n \n-- 前端仓库：`dangjingtao/dr-card-ui`。\n+- 前端仓库：`sanchuang-dev/dr-card-web`。\n - OSS Bucket：`kbs-sdl`，地域：`cn-guangzhou`，API Endpoint：`https://oss-cn-guangzhou.aliyuncs.com`。\n - 构建：`npm run build:prod`，构建产物：`dist/`。\n - 发布来源：仅 `prod` 分支。晋级沿用 `preview → dev → test → prod`，不得跳级。\ndiff --git a/docs/deploy/ram-policies/oss-dev.json b/docs/deploy/ram-policies/oss-dev.json\nnew file mode 100644\nindex 0000000..94f0d45\n--- /dev/null\n+++ b/docs/deploy/ram-policies/oss-dev.json\n@@ -0,0 +1,28 @@\n+{\n+  \"Version\": \"1\",\n+  \"Statement\": [\n+    {\n+      \"Effect\": \"Allow\",\n+      \"Action\": [\n+        \"oss:ListObjects\"\n+      ],\n+      \"Resource\": \"acs:oss:*:*:kbs-sdl\",\n+      \"Condition\": {\n+        \"StringLike\": {\n+          \"oss:Prefix\": [\n+            \"kbs-web/dev/\",\n+            \"kbs-web/dev/*\"\n+          ]\n+        }\n+      }\n+    },\n+    {\n+      \"Effect\": \"Allow\",\n+      \"Action\": [\n+        \"oss:GetObject\",\n+        \"oss:PutObject\"\n+      ],\n+      \"Resource\": \"acs:oss:*:*:kbs-sdl/kbs-web/dev/*\"\n+    }\n+  ]\n+}\ndiff --git a/docs/deploy/ram-policies/oss-test.json b/docs/deploy/ram-policies/oss-test.json\nnew file mode 100644\nindex 0000000..56dd2ad\n--- /dev/null\n+++ b/docs/deploy/ram-policies/oss-test.json\n@@ -0,0 +1,28 @@\n+{\n+  \"Version\": \"1\",\n+  \"Statement\": [\n+    {\n+      \"Effect\": \"Allow\",\n+      \"Action\": [\n+        \"oss:ListObjects\"\n+      ],\n+      \"Resource\": \"acs:oss:*:*:kbs-sdl\",\n+      \"Condition\": {\n+        \"StringLike\": {\n+          \"oss:Prefix\": [\n+            \"kbs-web/test/\",\n+            \"kbs-web/test/*\"\n+          ]\n+        }\n+      }\n+    },\n+    {\n+      \"Effect\": \"Allow\",\n+      \"Action\": [\n+        \"oss:GetObject\",\n+        \"oss:PutObject\"\n+      ],\n+      \"Resource\": \"acs:oss:*:*:kbs-sdl/kbs-web/test/*\"\n+    }\n+  ]\n+}\ndiff --git a/docs/deploy/ram-policies/oss-ui.json b/docs/deploy/ram-policies/oss-ui.json\nnew file mode 100644\nindex 0000000..d201977\n--- /dev/null\n+++ b/docs/deploy/ram-policies/oss-ui.json\n@@ -0,0 +1,28 @@\n+{\n+  \"Version\": \"1\",\n+  \"Statement\": [\n+    {\n+      \"Effect\": \"Allow\",\n+      \"Action\": [\n+        \"oss:ListObjects\"\n+      ],\n+      \"Resource\": \"acs:oss:*:*:kbs-sdl\",\n+      \"Condition\": {\n+        \"StringLike\": {\n+          \"oss:Prefix\": [\n+            \"kbs-web/ui/\",\n+            \"kbs-web/ui/*\"\n+          ]\n+        }\n+      }\n+    },\n+    {\n+      \"Effect\": \"Allow\",\n+      \"Action\": [\n+        \"oss:GetObject\",\n+        \"oss:PutObject\"\n+      ],\n+      \"Resource\": \"acs:oss:*:*:kbs-sdl/kbs-web/ui/*\"\n+    }\n+  ]\n+}\ndiff --git a/docs/design/design-baseline.md b/docs/design/design-baseline.md\nindex cf227a6..dba6733 100644\n--- a/docs/design/design-baseline.md\n+++ b/docs/design/design-baseline.md\n@@ -2,7 +2,7 @@\n \n ## 项目定位\n \n-`dr-card-ui` 当前是 **卡博士原生 App 内嵌 H5 前端工程**。设计工作不再只服务于静态高保真演示，而是要在真实 WebView、真实数据、真实宿主能力接入后仍保持稳定的视觉与交互结论。\n+`dr-card-web`（npm 包名仍为 `dr-card-ui`）当前是 **卡博士原生 App 内嵌 H5 前端工程**。设计工作不再只服务于静态高保真演示，而是要在真实 WebView、真实数据、真实宿主能力接入后仍保持稳定的视觉与交互结论。\n \n 因此设计基线同时约束两件事：\n \ndiff --git a/docs/engineering/repository-transfer-2026-10-13.md b/docs/engineering/repository-transfer-2026-10-13.md\nnew file mode 100644\nindex 0000000..cd55db0\n--- /dev/null\n+++ b/docs/engineering/repository-transfer-2026-10-13.md\n@@ -0,0 +1,30 @@\n+# 2026-10-13 · GitHub 仓库所有权转移验收记录\n+\n+> 当前仓库：`sanchuang-dev/dr-card-web`；来源：`dangjingtao/dr-card-ui`。原生 GitHub Transfer + 同时重命名，不是新建仓库或复制历史。\n+\n+## 已有只读证据（转移后）\n+\n+- GitHub 仓库 ID 未变：`1341342340`；目标 owner 为 `sanchuang-dev`；当前连接可管理员访问。\n+- 分支提交保持不变：`main@aec60b6e`、`preview@4df9cf0e`、`dev@2605a6e9`、`test@25ebe33c`、`prod@7895d1c4`。\n+- Issue #82 / #171、未合并 PR #198 均可在新路径读取；七个 Workflow YAML 仍在。\n+- 旧 GitHub 仓库地址经 API 解析到新 owner；现有历史 Issue/PR 链接由 GitHub 重定向。历史审计快照保留当时仓库名称，**不要全量改写历史证据**。\n+- 公网只读探测：`https://kbs.3cgroup.cn/kbs-web/{dev,test,prod/last}/` 分别 HTTP 200；`https://test.dr-card-ui.pages.dev/` HTTP 200。\n+- `/kbs-web/test/build-meta.json` 仍是迁移前已成功发布的 `test@25ebe33ca26334ac94f731ebd4dacf921daf0be9`、Run `38235724425.1`。**这证明旧站未中断，但不证明迁移后新运行能部署。**\n+\n+## 尚需实际验证的切换门槛\n+\n+- [ ] 在新 owner 的 PR 上观察 GitHub Build/Test gate 是否真实运行成功，不能仅看转移前历史 Actions。\n+- [ ] 在新 owner 的 PR 上观察 OpenCode / Codex / 其他审查 App 的授权与执行；不把 Review skipped 视为 PASS。\n+- [ ] Cloudflare Git 集成是否会对新仓库、新 PR 产生构建/检查；若失效，由有权限者重新授权或绑定，旧 Cloudflare 项目和域名不删除。\n+- [ ] 新 owner 的 `oss-ui` / `oss-dev` / `oss-test` / `oss-production` GitHub Environments、Secrets、Variables 的可用性，经**受控新分支提交/部署**验证；不读取/输出密钥明文，也不以旧成功 Run 代替。\n+- [ ] 新 owner 上的 `dev` 非生产 OSS push 成功后，核对公开 `build-meta.json` SHA 与 readback；`test` 仅在正常晋级后验证。\n+- [ ] 生产发布、Health Gate、历史与回滚链路独立验证；未经明确授权不向 `prod` 推送。\n+- [ ] 协作成员检查本地 Git `origin` 或自动化里的旧 repository slug。GitHub 会重定向，但建议主动改为 `https://github.com/sanchuang-dev/dr-card-web.git`；不自动修改其他人的工作区。\n+\n+## 保持不变的边界\n+\n+- `preview` 是独立 UI 事实源，不要求与 `dev/test/prod` 同 SHA；只按既定晋级规则操作。\n+- OSS Bucket `kbs-sdl`、固定 URL `kbs.3cgroup.cn/kbs-web/`、Cloudflare 项目地址、原 App WebView 地址不随仓库更名改变。\n+- 不删旧 OSS 目录，不改 Git 历史，不重新建 Issue/PR，不重置任一分支。\n+\n+本记录用于迁移验收与后续追踪；尚未逐项勾选的外部部署/授权行为不得表述为已通过。\ndiff --git a/docs/testing/test-plan.md b/docs/testing/test-plan.md\nindex de05bff..a590570 100644\n--- a/docs/testing/test-plan.md\n+++ b/docs/testing/test-plan.md\n@@ -1,6 +1,6 @@\n # 卡博士 App 内嵌 H5 测试与验收方案\n \n-> 适用仓库：`dangjingtao/dr-card-ui`\n+> 适用仓库：`sanchuang-dev/dr-card-web`\n >\n > 适用主链路：`preview → dev → test → prod`\n >\n@@ -10,7 +10,7 @@\n \n ## 1. 目标\n \n-`dr-card-ui` 是 **卡博士 App 内嵌 H5 前端**。它既需要在浏览器中独立开发和预览，也需要最终运行在 Android / iOS App WebView 中，并与真实业务 API、Native JSBridge 协作。\n+`dr-card-web`（npm 包名仍为 `dr-card-ui`）是 **卡博士 App 内嵌 H5 前端**。它既需要在浏览器中独立开发和预览，也需要最终运行在 Android / iOS App WebView 中，并与真实业务 API、Native JSBridge 协作。\n \n 因此，本项目不能用“浏览器打开正常”代替完整验收。\n \ndiff --git a/docs/workflow/branch-strategy.md b/docs/workflow/branch-strategy.md\nindex a356468..0a9e8ac 100644\n--- a/docs/workflow/branch-strategy.md\n+++ b/docs/workflow/branch-strategy.md\n@@ -1,6 +1,6 @@\n # 卡博士 H5 分支与发布节奏\n \n-`dr-card-ui` 已从高保真 UI 工程进入正式 **App 内嵌 H5 前端**阶段。长期分支固定为：\n+`dr-card-web` 已从高保真 UI 工程进入正式 **App 内嵌 H5 前端**阶段（npm 包名暂保留为 `dr-card-ui`）。长期分支固定为：\n \n ```text\n preview → dev → test → prod\ndiff --git a/docs/workflow/engineering-workflow.md b/docs/workflow/engineering-workflow.md\nindex 2198131..0afaba8 100644\n--- a/docs/workflow/engineering-workflow.md\n+++ b/docs/workflow/engineering-workflow.md\n@@ -2,7 +2,7 @@\n \n ## 项目定位\n \n-dr-card-ui 是卡博士移动 APP 高保真 UI 工程。\n+`dr-card-web`（原仓库 `dr-card-ui`）的本文件记录卡博士移动 APP 高保真 UI 阶段的工程工作方式，正式 H5 的现行工程规则优先遵循 `AGENTS.md`。\n \n 目标不是搭建完整业务系统，而是：\n \ndiff --git a/src/pages/MallWebView.tsx b/src/pages/MallWebView.tsx\nindex 341b6d6..3147f75 100644\n--- a/src/pages/MallWebView.tsx\n+++ b/src/pages/MallWebView.tsx\n@@ -6,10 +6,10 @@\n  * 不跳出 App / H5 外层界面。\n  *\n  * 2026-10-12：当前地址仅用于效果预览，不代表正式商城接入方案。\n- * 保留用户提供的 http scheme，不自动改写为 https；鉴权透传、cleartext/mixed-content\n- * 及目标站 iframe 策略仍需在真实 App WebView 内单独验证。\n+ * test 页面由 HTTPS 承载，商城效果地址使用已验证可达的 HTTPS，避免混合内容被浏览器拦截。\n+ * 鉴权透传、第三方站内混合资源及 iframe 策略仍需真实 App WebView 验收。\n  */\n-const MALL_H5_URL = 'http://scmzhds07.m.demo.webportal.top/?_sc=1'\n+const MALL_H5_URL = 'https://scmzhds07.m.demo.webportal.top/?_sc=1'\n \n export default function MallWebView() {\n   return (",
          "actualWorkers": 2
        },
        "id": "chromium-mobile",
        "name": "chromium-mobile",
        "testDir": "/home/runner/work/dr-card-web/dr-card-web/tests/e2e",
        "testIgnore": [],
        "testMatch": [
          "**/*.@(spec|test).?(c|m)[jt]s?(x)"
        ],
        "timeout": 30000
      }
    ],
    "quiet": false,
    "reporter": [
      [
        "line",
        null
      ],
      [
        "html",
        {
          "outputFolder": "playwright-report",
          "open": "never"
        }
      ],
      [
        "json",
        {
          "outputFile": "test-results/playwright-results.json"
        }
      ]
    ],
    "reportSlowTests": {
      "max": 5,
      "threshold": 300000
    },
    "shard": null,
    "tags": [],
    "updateSnapshots": "missing",
    "updateSourceMethod": "patch",
    "version": "1.63.0",
    "workers": 2,
    "webServer": null
  },
  "suites": [
    {
      "title": "test-gate.spec.ts",
      "file": "test-gate.spec.ts",
      "column": 0,
      "line": 0,
      "specs": [
        {
          "title": "@test-gate build identity matches the production-like test policy",
          "ok": true,
          "tags": [
            "test-gate"
          ],
          "tests": [
            {
              "timeout": 30000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "chromium-mobile",
              "projectName": "chromium-mobile",
              "results": [
                {
                  "workerIndex": 0,
                  "parallelIndex": 0,
                  "status": "passed",
                  "duration": 72,
                  "errors": [],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-10-13T04:29:10.300Z",
                  "annotations": [],
                  "attachments": []
                }
              ],
              "status": "expected"
            }
          ],
          "id": "37c772ca39f4c8e5dd7a-c3b6e0ce5d8c5d8734e5",
          "file": "test-gate.spec.ts",
          "line": 31,
          "column": 1
        },
        {
          "title": "@test-gate browser entry does not start the app router",
          "ok": true,
          "tags": [
            "test-gate"
          ],
          "tests": [
            {
              "timeout": 30000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "chromium-mobile",
              "projectName": "chromium-mobile",
              "results": [
                {
                  "workerIndex": 1,
                  "parallelIndex": 1,
                  "status": "passed",
                  "duration": 1334,
                  "errors": [],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-10-13T04:29:10.277Z",
                  "annotations": [],
                  "attachments": []
                }
              ],
              "status": "expected"
            }
          ],
          "id": "37c772ca39f4c8e5dd7a-8ed37c8041402a2a6b34",
          "file": "test-gate.spec.ts",
          "line": 40,
          "column": 1
        },
        {
          "title": "@test-gate / shows the unsupported-host notice in a browser",
          "ok": true,
          "tags": [
            "test-gate"
          ],
          "tests": [
            {
              "timeout": 30000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "chromium-mobile",
              "projectName": "chromium-mobile",
              "results": [
                {
                  "workerIndex": 0,
                  "parallelIndex": 0,
                  "status": "passed",
                  "duration": 1380,
                  "errors": [],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-10-13T04:29:10.450Z",
                  "annotations": [],
                  "attachments": []
                }
              ],
              "status": "expected"
            }
          ],
          "id": "37c772ca39f4c8e5dd7a-b030d57053896c93a550",
          "file": "test-gate.spec.ts",
          "line": 51,
          "column": 3
        },
        {
          "title": "@test-gate /profile shows the unsupported-host notice in a browser",
          "ok": true,
          "tags": [
            "test-gate"
          ],
          "tests": [
            {
              "timeout": 30000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "chromium-mobile",
              "projectName": "chromium-mobile",
              "results": [
                {
                  "workerIndex": 1,
                  "parallelIndex": 1,
                  "status": "passed",
                  "duration": 1126,
                  "errors": [],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-10-13T04:29:11.971Z",
                  "annotations": [],
                  "attachments": []
                }
              ],
              "status": "expected"
            }
          ],
          "id": "37c772ca39f4c8e5dd7a-8605535a2807e17fcccc",
          "file": "test-gate.spec.ts",
          "line": 51,
          "column": 3
        },
        {
          "title": "@test-gate /settings shows the unsupported-host notice in a browser",
          "ok": true,
          "tags": [
            "test-gate"
          ],
          "tests": [
            {
              "timeout": 30000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "chromium-mobile",
              "projectName": "chromium-mobile",
              "results": [
                {
                  "workerIndex": 0,
                  "parallelIndex": 0,
                  "status": "passed",
                  "duration": 1088,
                  "errors": [],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-10-13T04:29:11.998Z",
                  "annotations": [],
                  "attachments": []
                }
              ],
              "status": "expected"
            }
          ],
          "id": "37c772ca39f4c8e5dd7a-4a2fdc9884c1725de4f8",
          "file": "test-gate.spec.ts",
          "line": 51,
          "column": 3
        },
        {
          "title": "@test-gate gated browser entry issues no business API request",
          "ok": true,
          "tags": [
            "test-gate"
          ],
          "tests": [
            {
              "timeout": 30000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "chromium-mobile",
              "projectName": "chromium-mobile",
              "results": [
                {
                  "workerIndex": 0,
                  "parallelIndex": 0,
                  "status": "passed",
                  "duration": 1047,
                  "errors": [],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-10-13T04:29:13.107Z",
                  "annotations": [],
                  "attachments": []
                }
              ],
              "status": "expected"
            }
          ],
          "id": "37c772ca39f4c8e5dd7a-09f38a2b8ed735e192d8",
          "file": "test-gate.spec.ts",
          "line": 65,
          "column": 1
        },
        {
          "title": "@test-gate injected native host bypasses the notice and starts the app",
          "ok": true,
          "tags": [
            "test-gate"
          ],
          "tests": [
            {
              "timeout": 30000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "chromium-mobile",
              "projectName": "chromium-mobile",
              "results": [
                {
                  "workerIndex": 1,
                  "parallelIndex": 1,
                  "status": "passed",
                  "duration": 1122,
                  "errors": [],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-10-13T04:29:13.117Z",
                  "annotations": [],
                  "attachments": []
                }
              ],
              "status": "expected"
            }
          ],
          "id": "37c772ca39f4c8e5dd7a-8caf237c4d42513fff2f",
          "file": "test-gate.spec.ts",
          "line": 80,
          "column": 1
        }
      ]
    }
  ],
  "errors": [],
  "stats": {
    "startTime": "2026-10-13T04:29:09.413Z",
    "duration": 4886.389,
    "expected": 7,
    "skipped": 0,
    "unexpected": 0,
    "flaky": 0
  }
}