Files
qinglong/docs/adr/ADR-0515-bounded-local-console-run-log.md
T

60 lines
6.2 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-0515Local Console 的有界 Run 日志观察面
- 状态:Accepted
- 日期:2026-08-28
- 对应 RFC 切片:D-420
- 关联:ADR-0377、ADR-0378、ADR-0379、ADR-0512、ADR-0513、ADR-0514
## 背景
D-419 已让 Console Trial Kit 使用真实 Owner credential 完成示例 Task read、带 revision/content digest 围栏的显式启动、`succeeded` 终态和 bounded log marker 验证。但 marker 只由原生 CI 直接读取 HTTP API;部署者在 Web Console 里仍只能看到 Run、Step 数和 Event sequence,无法确认脚本实际输出。对连续研发约二十天后的阶段产物而言,“测试知道工作完成”不能代替“试用者能在产品面观察工作结果”。
既有 `run.log.read` 已具备 Project 掩蔽、`artifact.read` Policy、durable audit、credential re-confirm、32 KiB Application 上限和 retention/truncation 状态。缺口是一个不放大低配设备常驻成本、也不把内部 Artifact authority 暴露给浏览器的显示层。
## 决策
### 1. Run HTTP 详情只追加 latest Attempt 的低敏摘要
Local API 在既有 Run 详情中追加 `latestAttempt`:仅包含 Attempt ID、序号、状态、创建/开始/完成时间和 `logAvailable` 布尔值。它不返回 `executorHandle`、PID、Worker、Artifact ID、文件路径、错误摘要或内部 lease。
该摘要由 Local API 自己调用 `findLatestAttemptByRunId` 并严格验证 Run ownership、ID、状态和时间边界。共享 `executeBoundedRunReadProjection` 保持不变:GitNexus 将其判定为 HIGH 风险,直接修改会同时影响内建 Run read/compare Tool。Local 产品增强不得悄然改变 AI/Tool 投影语义。
### 2. Console 每次只读首个 32 KiB 窗口
用户选择 Run 时,Console 使用 `latestAttempt.id` 调用既有 authenticated log API,固定请求 `offset=0&length=32768`。返回内容必须是有界 base64,浏览器解码后只通过 `textContent` 写入 `<pre>`;不使用 HTML 插值、下载链接或 Artifact 路径。
界面明确区分:
- `available`:显示 byte range、total bytes、truncation fact,并在存在 `nextOffset` 时说明后续内容应经 API 分页读取;
- `pending`:说明日志尚未发布,可由用户显式刷新;
- `retired`:说明日志已按 retention 清理,但 Run/Event 事实仍保留;
- `not_found|unavailable`:不扩大存在性信息,也不遮蔽已经取得的 Run/Event。
Console 不新增轮询、WebSocket、timer、后台缓存或整文件下载。用户刷新仍是当前 Alpha 的资源控制边界。
### 3. 低配与集群部署边界不变
新增资产仍只进入 opt-in `edge-application-api|standalone-application-api` 和 Console Trial Kit。默认 headless 路由/NAS 不携带 Console,也不增加 listener、请求、RSS、进程或稳态 I/O。Cluster 节点继续使用独立 Cluster Control/Console authority,不复用 SQLite Attempt 或本机 Owner credential 路径。
### 4. Task mutation 不搭便车进入常驻 HTTP
现有 `task.put` 是强认证、短生命周期 CLI:一次进程只激活一个 credential fence,并在 SQLite 事务内复验 credential、Project/RoleBinding、Audit 和 mutation。常驻 HTTP 若直接复用其进程级 active fence,会引入并发凭据串线和撤销竞态。
D-420 不以单因子 Bearer 或非原子的 HTTP adapter 绕过该边界。Web Task 创建/修订必须另行设计“每请求 credential fence + 同事务 Policy/Audit/mutation”,并继续保持 headless/Cluster 分层。
## 不采用的方案
- 不修改共享 Run read projection:其 HIGH 风险上游包含内建 Run read/compare ToolLocal UI 字段不应进入通用 Tool contract。
- 不把 Artifact ID 或路径返回浏览器:Attempt ID 已足够调用受 Policy 保护的读取能力。
- 不自动轮询或推送日志:这会给低配设备增加持续请求、timer 和连接状态;当前 Alpha 由用户刷新。
- 不一次读取或渲染整份日志:日志大小不受 UI 控制,首窗口足以完成阶段自动化观察,后续仍由 API 分页。
- 不顺便开放 Web `task.put`:现有强认证事务不能安全地转换为长期进程的共享 active fence。
## 结果与验证边界
D-420 把 D-419 的“CI 能从 API 看见 marker”推进为“部署者能在 Console 看见实际输出”,同时保持 Run/Event 为独立事实源。三项离线 Console 资产现为 48,318 bytes,仍低于 192 KiB 总闭包和单文件 96 KiB 门;没有新增 workspace package、第三方依赖或默认 Profile 资源。`edge-application-api|standalone-application-api` 为 3,960,535 / 3,960,679 bytes、467 files、12 packages、90 loaded modules,距 6 MiB 分别保留 2,330,921 / 2,330,777 bytesimport RSS delta 为 14,745,600 / 14,794,752 bytes,低于 28 MiB 门。默认 headless Edge 仍为 2,669,390 bytes、325 files、3 packages、58 modules,证明没有携带 Console 增量。
定向验证包括 Local API 49/49、真实 SQLite/loopback/Bearer/Policy/Audit/log range 集成,以及 1440×960 和 390×844 的真实浏览器工作态。Local artifact 三档、Local image、package/source boundary、122-module Edge import 和 Cluster dependency audit 均 compatibleworkspace 仍为 18 packages`singleSourcePackages=[]``shallowSourcePackages=[]`。完整 backend 为 `1,650 total / 1,648 pass / 2 Linux conditional skip / 0 fail`18-package clean build/test 在允许 loopback TLS 的宿主门中退出 0。提交 `57953ec8` 的远端 QingLong 3.0 CI 为 41 success / 3 expected artifact-finalizer skip / 0 fail,独立 Kubernetes deployment live contract 为 1/1 success。
首份实际 Local Console v5 阶段产物已在后续提交 `37abfa16` 的显式 milestone run `33173769047` 闭合:44/44 job 成功,同一次 run 上传 amd64、arm64 Trial Kit 与 Local milestone index。两个大 artifact 分别为 187,712,409 / 184,944,025 bytes,索引为 5,623 bytes;重新下载的 `qinglong/alpha-local-milestone@v2` 通过 checksum 与离线 auditor,精确绑定 source、Console variant、双架构 image/archive/verification digest 和 run attempt。它证明 D-420 已形成可下载、可验真、可一键 fresh 试运行的阶段产品,但仍不声明公开 release、生产迁移、签名、LTS 或 30 天 artifact 保留期之后的长期分发。