mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
feat(ql3): verify cluster evidence offline
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
|
||||
最新增量证据(2026-08-16):
|
||||
|
||||
- D-331/ADR-0423(已接受):`@qinglong/cluster-admin` 在既有 `copilot-console/` 职责目录增加独立 TypeScript evidence verifier,并以第 11 个静态产品命令 `ql3-cluster-admin evidence-verify --bundle=/absolute/evidence.json` 交付。它只通过 no-follow/stable descriptor 读取一个最大 512 KiB 的 canonical absolute UTF-8 JSON,拒绝 BOM、CRLF、minified、duplicate-key、symlink、relative path 与读取中漂移;独立固定检查 exact bundle/request shape、13 operations、16-entry/8 MiB/64-item/depth/key ceiling、安全字段白名单和顺序 typed alias,再重算不含 `contentDigest` 的 canonical SHA-256。结果明确只证明 `bundleDigest=verified`;没有原始 fact 时逐条 digest 为 `not_recomputed_without_raw_facts`,server signature/attestation/durable audit 均未验证且 action authority 为 none。实现不读 stdin/environment/context,不联网、不写文件、不新增 package、依赖、route、listener、数据库、Kubernetes workload 或 Edge/Standalone closure。定向门 18/18,Cluster Admin 387 pass/3 条件 skip,18-package clean build/test 退出 0,backend 1,225 pass/2 条件 skip/0 fail。真实 arm64 Admin image `qinglong3-cluster-admin:d331-local` 为 344,567,527 bytes,在 non-root/read-only/network-none/no-capability/no-new-privileges/0.25 CPU/128 MiB/32 PIDs 下验证 11 个命令、有效 bundle、tamper rejection 与零 verifier file write。npm pack dry-run 为 250 files、271,238-byte tarball、1,690,196-byte unpacked;结构/依赖/部署/发布/Console 审计零 finding,workspace 保持 18 package、无 single/shallow package,Cluster Admin 122 个源码中 121 个位于领域目录。14 档 Local artifact 全部 compatible,默认 Edge/Standalone 仍为 2,589,890/2,589,968 bytes。因本门没有 schema/migration/SQL/role/Pool/连接拓扑变化,不重复冒充执行 HA,复用紧邻 D-330 PostgreSQL 18.6 arm64 142/142、timeline `1→2` 基线。下一门应完成公开 release digest 的外部工作站 ceremony,不得给 verifier 增加上传、签名或行动能力。
|
||||
- D-330/ADR-0422(已接受):同一 loopback-only Cluster field ledger 现可由用户显式导出纯浏览器本地的脱敏 evidence bundle。导出只消费本页已逐次读取的最近 16 条、最多 8 MiB canonical fact,不调用 upstream/BFF、补读详情/分页、轮询、上传或持久化;固定 sanitizer 只保留 operation、非权威本机观察时间、安全枚举/boolean/有界 number、结构计数/分页事实、per-bundle typed alias 与原始 fact canonical byte count/SHA-256,自由文本、名称、路径/URL/command/input/output/environment、reason/error/message、credential/token/session/authorization、未知字段及 Copilot model text 一律省略。bundle 固定为 UTF-8 `qinglong/cluster-console-redacted-evidence-bundle@v1` JSON、最大 512 KiB,顶层 self-digest 明确不是 server signature/audit/action authority;生成器作为第 4 个 digest-bound asset 留在既有 `@qinglong/cluster-admin`,不增加 package、依赖、Cluster/BFF route、数据库、对象存储、Kubernetes workload 或 Edge/Standalone closure。定向门 24/24,Cluster Admin 382 pass/3 条件 skip,完整 18-package test 退出 0,backend 1,224 pass/2 条件 skip/0 fail。真实浏览器以恶意 HTML、credential-like 值、私有路径和 Copilot model text 验证纯文本与零泄漏;3 次显式读取后导出 3,611-byte 可复算 JSON,upstream 计数仍为 3,390×844 无横向溢出且 0 console error/warning。真实 arm64 Admin image `qinglong3-cluster-admin:d330-local` 为 344,543,263 bytes,在 non-root/read-only/network-none/no-capability/no-new-privileges/0.25 CPU/128 MiB/32 PIDs 下验证 10 个产品命令、原生/host-published Console、第 4 个 asset 与内置分发。npm pack dry-run 为 246 files、267,731-byte tarball、1,665,996-byte unpacked;package/dependency/Edge import/Cluster deployment/image release/Console/distribution 审计零 finding。workspace 保持 18 package、`singleSourcePackages=[]`、`shallowSourcePackages=[]`,1,199 个源码中 1,181 个位于职责目录。14 档 Local artifact 全部 compatible,默认 Edge/Standalone 精确保持 2,589,890/2,589,968 bytes、315 files、56 modules,application+AI 保持 4,493,043/4,493,175 bytes,MCP 保持 7,315,930/7,316,038 bytes。PostgreSQL 18.6 arm64 physical HA 142/142、timeline `1→2`,报告 SHA-256 `c9feb83c98ad2269c7649bd0869921d9dee7cfd00c9bc1a8a7879d81630d37c7`,证据审计与 Docker 残留均为零;本 Gate 没有 schema、migration、SQL、role、Pool 或连接拓扑变化。下一独立 Gate 应交付公开 release digest 的外部工作站 ceremony,或提供独立、离线、无 authority 的 evidence bundle verifier;不得为导出增加服务端聚合、稳定跨包标识、自动抓取或上传能力。
|
||||
- D-329/ADR-0421(已接受):同一 loopback-only Console/BFF 已扩展为 Cluster field ledger,固定提供 Copilot `inspect|output`、Run list/detail/events/steps、Task list/detail、Workflow list 与 Workflow Run list/detail/events/steps 共 13 个显式只读 operation;browser 仍不能提交 upstream URL/method/header/credential。服务端 exact contract 负责 ID/cursor/limit 校验和 path/query 生成,并复用既有 owner-private `ql3c_`、TLS 1.3、request-ID、2 MiB response 与低敏错误 transport;通用 Project read grammar 只接受审核过的 Run/Task/Workflow GET,拒绝 mutation、absolute URL 与 path traversal。UI 采用仅存内存的 evidence ledger,每次按钮只执行一次读取,分页只在 `hasMore|truncated` 携带 cursor 时由用户显式触发,没有自动 detail cascade、poller、WebSocket/SSE、retry、queue、cache 或后台 timer。实现继续留在 `@qinglong/cluster-admin`,workspace 维持 18 package,部署 credential 推荐只授予 `run.read|task.read|artifact.read`;不回接 2.x Web/session、不新增 Cluster route/schema/SQL/Pool/Kubernetes resident service,也不进入 Edge/Standalone closure。13-operation contract、Console/CLI/TLS 定向门 23/23,Cluster Admin 378 pass/3 条件 skip,完整 18-package test 退出 0,backend 1,223 pass/2 条件 skip/0 fail。真实浏览器完成 Run/Task/Workflow 读取、显式下一页、恶意 HTML 纯文本、390×844 与零 console error/warning,并发现、修正 `[hidden]` 被 panel layout 覆盖的问题;真实 arm64 Admin image `qinglong3-cluster-admin:d329-local` 为 344,518,724 bytes,在 non-root/read-only/network-none/no-capability/no-new-privileges/0.25 CPU/128 MiB/32 PIDs 下验证 10 个产品命令、原生/host-published Console 与内置分发文件。npm pack dry-run 为 245 files、262,246-byte tarball、1,642,267-byte unpacked;package/dependency/Cluster deployment/image release/Console/distribution 审计零 finding,workspace 为 18 package 且无 single-source/shallow package。14 档 Local artifact 全部 compatible;默认 Edge/Standalone 精确保持 2,589,890/2,589,968 bytes、315 files、56 modules,application+AI 保持 4,493,043/4,493,175 bytes,MCP 保持 7,315,930/7,316,038 bytes。本 Gate 无 schema、migration、SQL、role、Pool、连接或 HA 拓扑变化,继续引用 D-323 PostgreSQL 18.6 arm64 physical HA 142/142、timeline `1→2` 基线。下一独立 Gate 应把现场 evidence 升级为可下载的显式脱敏诊断包,或补公开 release digest 的外部工作站 ceremony;不得增加浏览器代理权、自动全量抓取或把 Console 变为 Kubernetes 常驻服务。
|
||||
- D-328/ADR-0420(已接受):Cluster Copilot Console 的 operator-workstation 分发已冻结为既有 `qinglong3-cluster-admin@sha256:…` 多架构 OCI,而不是再发布 Node archive、安装器镜像或第 19 个 workspace package。Admin release workflow 已有 amd64/arm64 原生构建、production dependency audit、BuildKit provenance/SBOM、OS vulnerability scan、扫描后 OCI merge、keyless Cosign signature,以及绑定 repository/workflow/source commit/source tag 的 GitHub provenance、CycloneDX 和 OS-vulnerability attestations;新增 `verify-release.sh` 要求 image digest、40-hex revision 与 `refs/tags/v3.*`,独立复验 exact workflow certificate identity、GitHub OIDC issuer、三类 predicate、OCI bundle 并拒绝 mutable tag、branch ref 与 self-hosted builder。已签名 image filesystem 现在携带 `0555` launcher/verifier 和 `0444` 文档/配置模板,因此 signature 同时覆盖宿主启动路径,不存在第二套依赖树。原生 Console 默认继续只监听 `127.0.0.1` ephemeral port;只有显式 `--container-published-loopback` 加固定高端口才允许容器 network namespace 内监听 `0.0.0.0`,并仍对外报告 `publishedHostAddress=127.0.0.1`。reviewed launcher 只接受 immutable digest、canonical private root、显式命名网络和 `compact|standard` 两档资源,拒绝 `bridge|default|host|none`;`check` 不 publish,`serve` 唯一映射为 `127.0.0.1:<port>:<port>/tcp`,同时固定 non-root `10001:10001`、read-only root、drop ALL、no-new-privileges、8 MiB noexec tmpfs、一个只读 authority mount、`--pull never`、3 秒 stop,compact 为 192 MiB/0.25 CPU/32 PIDs,standard 为 512 MiB/1 CPU/64 PIDs。启动器/验签器/分发审计与 Console 定向门 30/30;release/OCI/SBOM 定向门 75/75,package/dependency/Edge/Cluster deployment/Console distribution 审计全部零 finding。Cluster Admin 376 pass/3 条件 skip,完整 18-package clean build/test 退出 0,backend 1,223 pass/2 条件 skip/0 fail。npm pack dry-run 保持 245 files、258,591-byte tarball、1,616,582-byte unpacked。真实 arm64 image `qinglong3-cluster-admin:d328-local` 为 344,492,529 bytes,验证 10 个产品命令、镜像内五项分发文件及 mode、原生 loopback Console;新增 named-network 现场门选择一个空闲高端口并以 exact `127.0.0.1:P:P` 发布,宿主真实读取页面,同时复验 read-only/non-root/no-capability/no-new-privileges 边界与容器/网络清理。14 档 Local artifact 全部 compatible;默认 Edge/Standalone 仍精确为 2,589,890/2,589,968 bytes、315 files、56 modules,application+AI 仍为 4,493,043/4,493,175 bytes,MCP 仍为 7,315,930/7,316,038 bytes,证明工作站分发没有进入低配路由设备闭包。workspace 保持 18 package、`singleSourcePackages=[]`、`shallowSourcePackages=[]`,Cluster Admin 120 个源码中 119 个位于嵌套职责目录。本 Gate 无 schema、migration、SQL、role、Pool、连接或 HA 拓扑变化,继续引用 D-323 PostgreSQL 18.6 arm64 physical HA 142/142、timeline `1→2` 基线。下一独立 Gate 应在同一 Console/BFF ownership 下增加只读 Run/Task/Workflow 观察面,或补公开 release tag 的外部工作站 ceremony;不得把容器内部 listener 误当宿主 LAN authority、引入第二分发依赖树或把 Console 变成 Kubernetes 常驻服务。
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# ADR-0423:独立、离线且无 Authority 的 Cluster Evidence Verifier
|
||||
|
||||
- 状态:Accepted
|
||||
- 日期:2026-08-16
|
||||
- 关联 RFC:QL-RFC-0001 D-331、Phase 2
|
||||
- 扩展:ADR-0422
|
||||
|
||||
## 背景
|
||||
|
||||
ADR-0422 的浏览器生成器能计算 evidence bundle 顶层 SHA-256,但同一段浏览器代码自验只能发现传输后的普通改写,不能独立证明固定结构、脱敏字段和 typed alias 约束没有被放宽。把 bundle 上传到 Cluster、第三方 SaaS 或新的服务端 verifier 会重新引入网络、credential、持久化和来源混淆;为一个文件校验器再拆 workspace package 也会扩大低配设备元数据与供应链审计面。
|
||||
|
||||
## 决策
|
||||
|
||||
1. 在既有 `@qinglong/cluster-admin` 的 `copilot-console/` 职责目录实现独立 TypeScript verifier,通过 `ql3-cluster-admin evidence-verify --bundle=/absolute/evidence.json` 和同包 direct binary `ql3-copilot-evidence-verify` 交付。它是第 11 个静态产品命令,不新增 package、生产依赖、route、listener、数据库、对象存储、Kubernetes workload 或常驻进程。
|
||||
2. verifier 只读取一个用户显式给出的 canonical absolute regular file。它使用 read-only、no-follow descriptor,限制路径为 4 KiB、文件为 512 KiB,并在读取前后复验 device/inode/mode/owner/size/time;不读取 stdin、environment 或 operator context,不建立网络连接,不写文件。
|
||||
3. 输入必须是 fatal UTF-8、无 BOM、固定 two-space pretty JSON 且带单个末尾换行。JSON round-trip 必须逐字节相等,从而拒绝 duplicate key、CRLF、minified/alternate whitespace 和非规范序列化。
|
||||
4. verifier 独立重写并固定校验 `qinglong/cluster-console-redacted-evidence-bundle@v1` 的 exact shape、13 个 operation/request field 集合、1..16 entries、8 MiB raw canonical 总量、64-item array、16-depth/256-key 上限、安全 enum/boolean/number/container allowlist、顺序 typed alias 与固定无 authority 声明。未知字段、自由文本、错误/message、路径、credential、model output 或虚假 signature/attestation 均失败关闭。
|
||||
5. verifier 独立 canonicalize 不含 `contentDigest` 的 bundle 并重算 SHA-256,返回 `qinglong/cluster-console-evidence-verification@v1`。结果只声明 `bundleDigest=verified`;由于 bundle 刻意不携带原始 fact,逐条 `rawFact.sha256` 明确为 `not_recomputed_without_raw_facts`。`serverSignature|attestation|durableAudit` 均为 `not_verified`,`actionAuthority=none`。
|
||||
6. 成功输出只含 schema、digest、entry/byte count 与上述 limitation;失败输出只含稳定 code 和通用消息,不回显文件路径、原始标识或输入内容。usage/invalid 分别退出 64/65。
|
||||
7. verifier 只随 Cluster Admin npm/OCI 分发,继续不进入 Edge、Standalone、AI 或 MCP Local artifact closure。它不把浏览器观察升级为集群来源证明,也不替代 release signature/provenance 或人工审阅。
|
||||
|
||||
## 不选择
|
||||
|
||||
- **复用浏览器生成器作为 CLI verifier**:会让生成和验证共享同一实现错误,缺少真正的交叉实现证据。
|
||||
- **把原始 fact 一并放进 bundle 以复算逐条 digest**:会重新泄漏本门刻意剔除的用户命名、路径、错误和模型文本。
|
||||
- **服务端上传验证**:需要新 route、网络和保存策略,并容易被误解为服务端背书。
|
||||
- **单独拆 `@qinglong/evidence-verifier` package**:没有独立部署或依赖边界,反而违反 18-package 硬上限和包内领域目录策略。
|
||||
|
||||
## 验收
|
||||
|
||||
1. 浏览器生成器输出必须由独立 verifier 接受;digest 改写、即使重新签顶层 digest 的结构扩宽、alias gap、虚假证明、总量/sequence 漂移必须拒绝。
|
||||
2. BOM、CRLF、minified、duplicate-key、relative path、symlink 和超限文件必须拒绝;成功/失败 CLI 都不得回显输入路径和私有样本。
|
||||
3. Console 架构审计必须拒绝 verifier 的 network、write、stdin 和 environment authority;package boundary 必须保持 18 packages、零 single/shallow package。
|
||||
4. 真实 Admin image 必须在 non-root、read-only root、network none、drop ALL、no-new-privileges、128 MiB、0.25 CPU、32 PIDs 下完成有效验证、tamper rejection 和零 verifier file write。
|
||||
5. Cluster Admin、18-package、backend、npm pack、dependency/deployment/release 与全部 Local artifact 门通过后才接受本决策。
|
||||
|
||||
## 验收结果
|
||||
|
||||
2026-08-16,D-331 完成以下发布门并接受本决策:
|
||||
|
||||
- 生成器/独立 verifier 与产品/架构审计定向门 18/18;Cluster Admin 完整测试 387 pass、3 条件 skip、0 fail,18-package clean build/test 退出 0,backend 1,225 pass、2 条件 skip、0 fail。
|
||||
- 有效浏览器 bundle 的结构、typed alias、顶层 digest 与 limitation 由独立 TypeScript 实现验证;tamper、重新计算顶层 digest 后的自由文本扩宽、alias gap、虚假 server signature、raw byte/sequence 漂移,以及 BOM/CRLF/minified/duplicate-key/symlink/relative/oversize 输入全部失败关闭。成功和失败输出均未泄漏私有文件名、路径或原始标识。
|
||||
- 真实 arm64 `qinglong3-cluster-admin:d331-local` 为 344,567,527 bytes;在 UID/GID 10001、只读根、network none、drop ALL、no-new-privileges、0.25 CPU、128 MiB 与 32 PIDs 下通过 11 个产品命令、原生/host-published Console、有效验证、tamper rejection 和 verifier 零额外文件写。
|
||||
- npm pack dry-run 为 250 files、271,238-byte tarball、1,690,196-byte unpacked。package/dependency/Edge import/Cluster deployment/image release/Console/distribution 审计零 finding;workspace 保持 18 packages、`singleSourcePackages=[]`、`shallowSourcePackages=[]`,1,201 个源码中 1,183 个位于职责目录,Cluster Admin 为 122/121。
|
||||
- 14 档 Local artifact 全部 compatible;默认 Edge/Standalone 精确保持 2,589,890/2,589,968 bytes、315 files、56 modules,application+AI 保持 4,493,043/4,493,175 bytes,MCP 保持 7,315,930/7,316,038 bytes,证明 verifier 没有进入路由设备闭包。
|
||||
- 本门没有 schema、migration、SQL、role、Pool 或连接拓扑变化,因此不重复冒充执行 PostgreSQL HA;复用紧邻 D-330 已完成的 PostgreSQL 18.6 arm64 142/142、timeline `1→2` 物理 HA 基线。下一独立门仍是公开 release digest 的外部工作站验证 ceremony,而不是给 verifier 增加上传、签名或行动能力。
|
||||
@@ -426,6 +426,7 @@
|
||||
| [ADR-0420](./ADR-0420-signed-admin-oci-console-workstation-distribution.md) | 以签名 Admin OCI 分发 Cluster Copilot 工作站 Console | Accepted |
|
||||
| [ADR-0421](./ADR-0421-explicit-cluster-run-task-workflow-observation-console.md) | 显式 Cluster Run、Task 与 Workflow 观察台 | Accepted |
|
||||
| [ADR-0422](./ADR-0422-browser-local-redacted-cluster-evidence-bundle.md) | 浏览器本地生成的脱敏 Cluster Evidence Bundle | Accepted |
|
||||
| [ADR-0423](./ADR-0423-independent-offline-cluster-evidence-verifier.md) | 独立、离线且无 Authority 的 Cluster Evidence Verifier | Accepted |
|
||||
|
||||
## 规则
|
||||
|
||||
|
||||
Reference in New Issue
Block a user