Files
qinglong/docs/adr/ADR-0530-bounded-local-panel-capability-bootstrap.md
T

54 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR-0530:有界 Local 面板能力发现与启动适配
- 状态:AcceptedD-428 exact Console 双架构阶段实物已交付)
- 日期:2026-09-02
- 关联 RFCQL-RFC-0001 D-428、D-427、D-423、D-424
## 背景
ADR-0529 已交付认证后的只读 `/api/crons` Adapter,但现有 2.x 面板启动时还会读取 `/api/system``/api/system/config``/api/user`,并假设用户名/密码登录、Local Storage JWT、完整菜单和 WebSocket 可用。仅有 Cron API 时,页面仍不能安全接入;若伪造完整 2.x 能力,则会把尚未实现的写操作、Env、Script、Subscription 和日志入口暴露给用户。
因此第二切片必须先让页面明确发现“这是 QingLong 3.0、当前 Profile 有哪些能力”,再只启用已闭合的页面和认证方式。兼容层继续是翻译边界,不恢复旧 Express Service、JWT authority 或数据库直写。
## 决策
### 能力与启动契约
- Local API 新增公开只读 `GET /api/health``GET /api/system``GET /api/v3/capabilities`。它们只接受无 body 的 exact path 与可选单个数字 `t`,仅返回版本、Local Profile、认证种类、能力开关和有界预算,不返回 principal、credential、Project 数据或存储路径。
- `GET /api/user``GET /api/system/config` 继续走正式 Bearer authentication、`task.read` Policy、durable audit 和 credential reconfirmoperation 固定为 `panel.user.get``panel.system.config.get`,且面板身份只接受 User principalservice credential 失败关闭。
- capability schema 固定为 v1。Edge 最多暴露 64 条 Cron、16 KiB 日志块;Standalone 最多 256 条 Cron、32 KiB 日志块;单页最多 64 条。Cluster 不复用该 Local capability shell,后续由独立 Panel Gateway 发布其能力。
- 明确声明 `legacyLogin=false``legacyMutations=false``subscriptions=false``scripts=false``environmentVariables=false``webSocket=false`。现有 v3 Task/Trigger/Run/Log 读 API 可以存在,但本切片的旧页面只启用 Crontab 只读投影。
### 现有面板源码降级
- 面板在登录页同源读取 `/api/v3/capabilities`;只有严格匹配 v1 契约才进入 QingLong 3.0 模式,否则保持 2.x 行为。
- QingLong 3.0 模式只接受 `ql3c_` API Credential。凭据只保存在当前 JavaScript 模块内存,通过 Authorization Bearer 发送;不写 Local Storage、Cookie、IndexedDB 或 URL,刷新和关闭页面后必须重新输入。
- 成功读取 `/api/user` 后进入 `/crontab`。菜单只保留登录、错误页和定时任务;不建立 WebSocket,不请求 Cron View、Subscription 或非空搜索/排序。
- Crontab 只展示名称、命令描述符、状态和计划;隐藏创建、选择、批量操作、详情、脚本跳转、日志和全部写 Modal。分页被 capability budget 限制,最后一个不足整页的 Edge/Standalone 窗口仍可读取。
- 2.x 模式的数据流、Local Storage token、登录接口、菜单和页面行为保持不变。
## 部署与资源边界
- 默认 headless 产物不包含 `@qinglong/local-api` 或旧面板,不新增端口、连接、timer、watcher、后台进程或稳态内存。
- 旧面板仍不进入 headless 产物。Console opt-in 镜像只装配经过闭包裁剪与哈希锁定的静态资源:240 files、11,947,127 bytes,上限为 256 files / 13 MiB / 单文件 3 MiB`.gz` 副本与 Monaco Editor 不进入产物。
- 装配后的 `/``/login``/crontab``/error` 服务受限旧面板,原生 3.0 管理 Console 固定保留在 `/console`,二者共享同一个 loopback Local API,不启动第二个 Web 服务。
- 静态资源使用 64 KiB streamEdge 的 API admission 为 4、静态资源 admission 为 16Standalone 分别为 32/64。两类请求共享 drain 生命周期但不互相挤占预算,避免旧 Umi 并行加载 chunk 时饿死 API 或收到 503。
- 旧 Umi 前端暂用 Node 20 构建只是 legacy migration toolchain,不改变 QingLong 3.0 Node 24 runtime、双架构镜像或支持等级。该过渡门必须在 CI 中独立命名,不能让 Node 20 定义新 package 的运行时兼容性。
- Edge 与 Standalone 使用同一代码、不同预算;Cluster 节点不加载 Local SQLite/POSIX authority,也不通过本 Adapter 访问控制面。
## 验证与剩余门禁
本地装配候选已经通过 12-package Console closure、719 files / 16,162,123 bytes(上限 768 files / 20 MiB)镜像审计,以及面板 240-file 哈希/磁盘闭包复核。最终 arm64 Edge 镜像 `sha256:27472cf1bdd66d9fa4e937622ef69d4e36f74918a759de62818b4e59d265714c` 已完成 fresh setup/replay、Owner provision/challenge/claim/presentation/ack、首个 Task 执行与日志标记、graceful stop、SQLite integrity 和 HTTP 200/401 边界,结果为 `compatible=true`
真实浏览器已验证现有页面使用内存中的 `ql3c_` credential 完成 `/login``/crontab`53 个同源静态请求全部为 200`/api/health``/api/system``/api/v3/capabilities``/api/user``/api/system/config``/api/crons` 均为 200;最终镜像同时验证 `/console` 原生管理台与 `/login` 旧页面共存。旧页面仍引用的外部图标/装饰图片被严格 CSP 阻止,页面功能可用但这些装饰会缺失;本阶段不为消除装饰错误而放宽网络或 CSP。
提交 `fa730da0912d0e3c503697e7816aa0b14fa02165` 的普通主 CI [run 33597913690](https://github.com/whyour/qinglong/actions/runs/33597913690) 为 42 success / 3 expected condition skip / 0 fail;显式 Console artifact [run 33597938992](https://github.com/whyour/qinglong/actions/runs/33597938992) 为 43 success / 2 expected skip / 0 fail。该 run 交付 amd64/arm64/milestone artifact `9834695619`/`9834657575`/`9834716653`,大小 `239011275`/`234410955`/`6797` bytes,保留至 2026-10-02;下载后的 milestone `SHA256SUMS` 与 v7 auditor 均通过并返回 `compatible=true`。D-428 因此闭合为可直接试运行的 exact 双架构阶段页面产物。
仍未完成:
1. 把旧面板引用的外部图标和装饰图片转为受审本地资产,做到严格 CSP 下无外部请求;
2. Run/Log 入口由 ADR-0531 以规范 v3 API 的 caller-driven 客户端桥接继续推进;
3. 写操作必须逐项映射到 3.0 revision、Policy、presence/approval、audit 和 mutation fence,不能用通配兼容路由一次性开放。
本 ADR 声明的是“已有 exact 双架构阶段产物可装配并实跑现有面板的受控子集”,不是 Public Release,也不声明完整 2.x 面板可以零修改直连。