diff --git a/deploy/console/ql3-cluster-copilot/README.md b/deploy/console/ql3-cluster-copilot/README.md index c7c946aa..a792d2e1 100644 --- a/deploy/console/ql3-cluster-copilot/README.md +++ b/deploy/console/ql3-cluster-copilot/README.md @@ -125,6 +125,15 @@ and private key, and issue a short-lived strong User assertion with only the D-374 canonical `/api/v3/workers/management`; the Console cannot accept the legacy credential-management path or a credential mutation command file. +To enable Plugin Package installation observation, copy +`package-management-client-config.example.json` to +`package-management-client.json`, install its CA, and issue a short-lived +strong User assertion with only `package.manage` into +`package-management-assertion.jwt`. Its endpoint is fixed to the canonical +`/api/v3/plugin-packages/management`. This authority is independent of the +Project, Run and Worker files; the Console exposes no Package command file or +lifecycle mutation. + Create an independent 256-bit browser session key without placing its value in argv or an environment variable: @@ -143,6 +152,9 @@ Apply the same rule to `worker-management-client.json`, `worker-management-ca.pem`, `worker-management-client.crt`, `worker-management-client.key` and `worker-management-assertion.jwt` when Worker observation is enabled. +Apply the same rule to `package-management-client.json`, +`package-management-ca.pem` and `package-management-assertion.jwt` when Package +observation is enabled. Every file must be a current-owner, non-symlink, canonical regular file. The session file contains exactly 43 base64url characters and no newline. It is a @@ -176,6 +188,13 @@ Worker observation uses its own pair: --worker-management-assertion /absolute/private/ql3-copilot-console/worker-management-assertion.jwt ``` +Package observation also uses an independent pair: + +```sh +--package-management-config /absolute/private/ql3-copilot-console/package-management-client.json \ +--package-management-assertion /absolute/private/ql3-copilot-console/package-management-assertion.jwt +``` + It validates every configured private authority and performs one unauthenticated TLS 1.3 `GET /readyz`. It does not open the Console listener or reveal paths, endpoint, credential, Project or Cluster identity. @@ -222,6 +241,14 @@ read; each listed Worker can be inspected only by another explicit click. The projection contains bounded lifecycle, compatibility, architecture, protocol and capacity facts, but no credential, raw capability, label or Secret. +Explicit Package management authority adds `package_list|package_inspect`, for +a maximum vocabulary of twenty operations when every optional authority is +enabled. The list is fixed at 16 installations with click-only pagination and +click-only inspection. The product projection includes Package version, +installation state, availability and bounded recovery codes, but omits +installation IDs, locks, record digests, transport identity and every Package +mutation. Package authority remains disabled by default. + ## Export a redacted evidence bundle After at least one successful read, **Export redacted bundle** creates one @@ -276,8 +303,10 @@ read-only private mount; all certificate paths in the config must point into that mount. `disabled` is the only default and unknown values fail closed. Worker observation follows the independent `QL3_COPILOT_CONSOLE_WORKER_MANAGEMENT=enabled` switch and reads only its -Worker config/assertion pair. Enabling one management authority does not enable -the other. +Worker config/assertion pair. Package observation follows +`QL3_COPILOT_CONSOLE_PACKAGE_MANAGEMENT=enabled` and reads only its Package +config/assertion pair. Enabling one management authority does not enable either +of the others. | Resource class | Memory | CPU | PIDs | Console reads | | --- | ---: | ---: | ---: | ---: | diff --git a/deploy/console/ql3-cluster-copilot/docker-loopback.sh b/deploy/console/ql3-cluster-copilot/docker-loopback.sh index af60715c..b8e37f6f 100755 --- a/deploy/console/ql3-cluster-copilot/docker-loopback.sh +++ b/deploy/console/ql3-cluster-copilot/docker-loopback.sh @@ -26,6 +26,7 @@ port=${QL3_COPILOT_CONSOLE_PORT-} resource_class=${QL3_COPILOT_CONSOLE_RESOURCE_CLASS-compact} run_management=${QL3_COPILOT_CONSOLE_RUN_MANAGEMENT-disabled} worker_management=${QL3_COPILOT_CONSOLE_WORKER_MANAGEMENT-disabled} +package_management=${QL3_COPILOT_CONSOLE_PACKAGE_MANAGEMENT-disabled} printf '%s' "$image" | grep -Eq '^[A-Za-z0-9][A-Za-z0-9._/-]{0,191}@sha256:[0-9a-f]{64}$' || fail printf '%s' "$network" | grep -Eq '^[A-Za-z0-9][A-Za-z0-9_.-]{0,62}$' || fail @@ -67,6 +68,10 @@ case "$worker_management" in disabled|enabled) ;; *) fail ;; esac +case "$package_management" in + disabled|enabled) ;; + *) fail ;; +esac set -- docker run --rm --pull never --init --read-only \ --network "$network" \ @@ -103,6 +108,12 @@ if [ "$worker_management" = enabled ]; then --worker-management-assertion /var/run/secrets/qinglong3/copilot-console/worker-management-assertion.jwt fi +if [ "$package_management" = enabled ]; then + set -- "$@" \ + --package-management-config /var/run/secrets/qinglong3/copilot-console/package-management-client.json \ + --package-management-assertion /var/run/secrets/qinglong3/copilot-console/package-management-assertion.jwt +fi + if [ "$mode" = check ]; then set -- "$@" --check fi diff --git a/deploy/console/ql3-cluster-copilot/host-environment.example.json b/deploy/console/ql3-cluster-copilot/host-environment.example.json index 403e625b..f273be05 100644 --- a/deploy/console/ql3-cluster-copilot/host-environment.example.json +++ b/deploy/console/ql3-cluster-copilot/host-environment.example.json @@ -5,5 +5,6 @@ "QL3_COPILOT_CONSOLE_PORT": "5701", "QL3_COPILOT_CONSOLE_RESOURCE_CLASS": "compact", "QL3_COPILOT_CONSOLE_RUN_MANAGEMENT": "disabled", - "QL3_COPILOT_CONSOLE_WORKER_MANAGEMENT": "disabled" + "QL3_COPILOT_CONSOLE_WORKER_MANAGEMENT": "disabled", + "QL3_COPILOT_CONSOLE_PACKAGE_MANAGEMENT": "disabled" } diff --git a/deploy/console/ql3-cluster-copilot/package-management-client-config.example.json b/deploy/console/ql3-cluster-copilot/package-management-client-config.example.json new file mode 100644 index 00000000..0d802b07 --- /dev/null +++ b/deploy/console/ql3-cluster-copilot/package-management-client-config.example.json @@ -0,0 +1,7 @@ +{ + "schemaVersion": 1, + "endpoint": "https://replace-cluster-api.example.com:8443/api/v3/plugin-packages/management", + "servername": "replace-cluster-api.example.com", + "caFile": "/absolute/private/ql3-copilot-console/package-management-ca.pem", + "requestTimeoutMs": 5000 +} diff --git a/deploy/containers/ql3-cluster-admin/Dockerfile b/deploy/containers/ql3-cluster-admin/Dockerfile index fbe0c78b..88e5e07a 100644 --- a/deploy/containers/ql3-cluster-admin/Dockerfile +++ b/deploy/containers/ql3-cluster-admin/Dockerfile @@ -89,6 +89,8 @@ COPY --chmod=0444 deploy/console/ql3-cluster-copilot/run-management-client-confi share/ql3-copilot-console/run-management-client-config.example.json COPY --chmod=0444 deploy/console/ql3-cluster-copilot/worker-management-client-config.example.json \ share/ql3-copilot-console/worker-management-client-config.example.json +COPY --chmod=0444 deploy/console/ql3-cluster-copilot/package-management-client-config.example.json \ + share/ql3-copilot-console/package-management-client-config.example.json COPY --chmod=0444 deploy/console/ql3-cluster-copilot/host-environment.example.json \ share/ql3-copilot-console/host-environment.example.json diff --git a/docs/QINGLONG_3_0_ARCHITECTURE_RFC.md b/docs/QINGLONG_3_0_ARCHITECTURE_RFC.md index c59056d5..0240ffd8 100644 --- a/docs/QINGLONG_3_0_ARCHITECTURE_RFC.md +++ b/docs/QINGLONG_3_0_ARCHITECTURE_RFC.md @@ -11,6 +11,24 @@ 最新增量证据(2026-08-20): +- D-376/ADR-0469(已接受):在既有 operator-workstation、loopback-only Copilot Console 内增加可选 Plugin Package installation + 观察,而不新增 workspace package、服务、端口或集群工作负载。Browser/BFF 只增加固定 `package_list|package_inspect` 与 + `/api/v1/package-management/installations|installation`;上游复用 canonical `/api/v3/plugin-packages/management` client,独立 + `--package-management-config|assertion` 必须成对提供,launcher 仅在 + `QL3_COPILOT_CONSOLE_PACKAGE_MANAGEMENT=enabled` 时启用,默认报告 `packageManagementAuthority=disabled`。list 固定 16 项、只接受 + nullable `afterPackageName` 并由用户点击翻页;inspect 只读取用户选中的 canonical Package。没有 propose、decide、install、reinstall、 + upgrade、rollback、disable、uninstall、caller limit/filter、自动翻页、poller、retry、queue、cache、watcher、WebSocket/SSE 或后台 timer。 + 产品投影只保留 Package/version、install operation/state、target generation、availability、recovery/failure/quarantine code 与时间/version, + 丢弃 installation/lock/record digest 和 transport request identity;浏览器证据继续使用 bundle-local typed alias。实现只在现有 + `@qinglong/cluster-admin` 的 `plugin-package/management` 与 `copilot-console` 内聚目录扩展,workspace 仍为 18 packages、没有新增依赖, + `singleSourcePackages=[]`、`shallowSourcePackages=[]`。专项回归 `56/56`;Cluster Admin 全量 + `438 total / 435 pass / 3 conditional skip / 0 fail`;legacy backend 当前工作树全量与 18-package clean build/逐包测试均单次退出 0。 + package boundary、Cluster dependency、Edge import、Cluster/Worker deployment、Console 与 Console distribution 七项审计全部 + compatible/passed;Cluster Admin 为 `129 source / 128 nested`。14 档 Local artifact audit 全部 compatible,基础 Edge/Standalone 仍为 + `2,598,669 / 2,598,747` bytes、57 loaded modules,Application+AI 为 `4,501,822 / 4,501,954` bytes,MCP 为 + `7,324,601 / 7,324,709` bytes,证明 Package Console authority 未进入低配路由设备闭包。本切片不改变 schema、ACL、repository、role、 + Pool、连接或 failover 语义,因此不重跑且不重新占有 PostgreSQL HA 证明;D-373/D-374 PostgreSQL 18.6 arm64 HA `146/146`、timeline + `1→2` 仅作为相邻既有基线,后续数据库语义变化必须重跑。 - D-375/ADR-0468(已接受):在既有 operator-workstation、loopback-only Copilot Console 内接入 D-374 通用 Worker management 的两个只读产品操作,而不是新增包、服务或集群工作负载。Browser/BFF 只新增固定 `worker_list|worker_inspect` 与 `/api/v1/worker-management/workers|worker`,上游只走 canonical diff --git a/docs/adr/ADR-0469-optional-console-package-installation-observation.md b/docs/adr/ADR-0469-optional-console-package-installation-observation.md new file mode 100644 index 00000000..818ea371 --- /dev/null +++ b/docs/adr/ADR-0469-optional-console-package-installation-observation.md @@ -0,0 +1,77 @@ +# ADR-0469:Copilot Console 显式可选 Package Installation 只读观察 + +- 状态:Accepted +- 日期:2026-08-20 +- 关联 RFC:QL-RFC-0001 D-376、D-14、D-16、D-107 +- 关联 ADR:ADR-0142、ADR-0191、ADR-0462、ADR-0468 + +## 上下文 + +Cluster Plugin Package management 已提供经过认证的 canonical HTTPS/client 边界和有界 installation inventory。运维人员需要在现有 +Copilot Console 中把 Run、Worker 与 Package 安装状态放在同一个只读现场账本中观察,但浏览器不能持有 Package assertion、选择上游 +command/path,也不能把管理生命周期变成持续轮询或默认常驻能力。 + +新建 Package Console 服务或 workspace package 会复制 session、TLS、镜像、分发和资源生命周期;把完整 Package management command +file 暴露给 Console 又会把 propose、decide、install、upgrade、rollback 和 lifecycle mutation 带入只读诊断面。低配路由设备也不应因 +Cluster 工作站能力增加任何 importer、常驻内存或连接成本。 + +## 决策 + +1. 在既有 `@qinglong/cluster-admin/copilot-console` 增加 `package_list` 与 `package_inspect`,分别只接受固定 BFF route + `/api/v1/package-management/installations` 与 `/api/v1/package-management/installation`。浏览器不能提供上游 path、method、command + file 或 caller limit。 +2. Package authority 使用独立 `--package-management-config` 与 `--package-management-assertion`;二者必须成对存在,config 必须指向 + canonical `/api/v3/plugin-packages/management`。它不复用 Project、Run 或 Worker credential/assertion。 +3. 未提供该 authority 时原有 Console 行为不变并报告 `packageManagementAuthority=disabled`。宿主 launcher 只有在 + `QL3_COPILOT_CONSOLE_PACKAGE_MANAGEMENT=enabled` 时添加这对 owner-private 文件;三个可选 management authority 互不隐式启用。 +4. `package_list` 固定最多 16 项,只接受 nullable `afterPackageName`,下一页必须由用户点击。`package_inspect` 只读取用户明确选择的 + canonical Package。禁止自动翻页、批量 inspect、poller、retry、queue、cache、watcher、WebSocket/SSE 和后台 timer。 +5. BFF 复用现有严格 Plugin Package management client validator,并增加 in-memory one-shot command 入口;一次点击只产生一次上游 POST。 + caller request ID 只作为 inspection identity,management transport request ID 不返回浏览器。 +6. 产品投影只包含 Package name/version、install operation/state、target generation、availability、recovery/failure/quarantine code、record + version 和时间。installation ID、active/previous lock digest、record digest、assertion、authentication 与 transport identity 均不进入产品响应。 +7. 浏览器证据包对 Project、Package、request 与 digest 使用 bundle-local typed alias,只保留固定枚举、数字、布尔和容器字段;未知字段与 + free text 继续删除,且不声明 server signature、durable audit 或 action authority。 +8. 本切片不新增 workspace package、external dependency、binary、监听端口、Kubernetes workload、Ingress、数据库 schema/role/Pool 或 + 持久状态。实现留在现有 `plugin-package/management` 与 `copilot-console` 内聚目录;Edge/Standalone 不导入 Cluster Admin。 + +## 被拒绝的替代方案 + +### 新建 Package Console package 或服务 + +拒绝。两个 caller-driven 只读操作没有独立部署、版本或资源生命周期,不足以承担新的 package/daemon。复用现有工作站 Console 可保持包数、 +镜像和 session 边界稳定。 + +### 将完整 Package command file 暴露给浏览器 + +拒绝。现有 command vocabulary 同时包含高风险 mutation。固定 list/inspect command builder 和固定 BFF route 才能从结构上证明只读,而不是 +依赖 UI 隐藏按钮。 + +### 默认启用 Package authority + +拒绝。Project observation 与 `package.manage` 是不同权限域。默认 disabled、成对私有文件和独立 launcher switch 让未启用部署不读取 assertion +也不打开 Package connection。 + +### 自动刷新或自动遍历全部 installations + +拒绝。持续 inventory 会隐藏数据库和网络负载,在小型管理节点上尤其不合适。固定 16 项与点击翻页使每次 authority use 都可见、可限界。 + +## 升级与回滚 + +- 旧启动方式不传 Package 参数时行为不变。启用者先安装 canonical config、CA 与短期 assertion,再显式打开 launcher switch。 +- 回滚到 ADR-0468 只移除 Package tab、两条 BFF route 和可选参数;canonical manager/client、installation repository 与数据均不变化,无迁移。 +- 未来若加入 install/upgrade/rollback、跨 Project inventory、历史指标或实时流,必须另立 mutation authority、审计、配额、retention 和资源预算 + ADR,不能在本只读 BFF 上渐进扩大。 + +## 验证与证据 + +- Console/CLI/product/evidence/launcher 专项回归 `56/56`,覆盖 exact route、固定 16 项、click-only cursor、canonical TLS 1.3 request、独立 + authority 默认关闭、transport/durable identity 隔离、证据脱敏和 mutation/remote-listener/ambient-authority 拒绝。 +- `@qinglong/cluster-admin` 全量 `438 total / 435 pass / 3 conditional skip / 0 fail`;legacy backend 当前工作树全量与 18-package clean + build/逐包测试均单次退出 0。 +- package boundary、Cluster dependency、Edge import、Cluster/Worker deployment、Console 与 distribution 七项审计全部 compatible/passed。 + workspace 保持 18 packages、`singleSourcePackages=[]`、`shallowSourcePackages=[]`;Cluster Admin 为 `129 source / 128 nested`,无新增依赖。 +- 14 档 Local artifact audit 全部 compatible。基础 Edge/Standalone 为 `2,598,669 / 2,598,747` bytes、57 loaded modules; + Application+AI 为 `4,501,822 / 4,501,954` bytes;MCP 为 `7,324,601 / 7,324,709` bytes。Package Console authority 未进入低配制品。 +- 本切片没有 PostgreSQL schema、ACL、repository、role、Pool、连接或 failover 变化,不重跑也不重新占有物理 HA 证明;仅引用 D-373/D-374 + PostgreSQL 18.6 arm64 HA `146/146`、timeline `1→2` 相邻基线。数据库语义变化时必须重跑。 diff --git a/docs/adr/README.md b/docs/adr/README.md index 4324f96f..f539aa9e 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -472,6 +472,7 @@ | [ADR-0466](./ADR-0466-bounded-worker-session-compatibility-observation.md) | 有界 Worker Session 兼容性观察 | Accepted | | [ADR-0467](./ADR-0467-generic-worker-management-product-entry.md) | 通用 Worker Management 产品入口与兼容路径 | Accepted | | [ADR-0468](./ADR-0468-optional-console-worker-observation.md) | 可选 Console Worker 只读观察 | Accepted | +| [ADR-0469](./ADR-0469-optional-console-package-installation-observation.md) | 可选 Console Package Installation 只读观察 | Accepted | ## 规则 diff --git a/packages/ql3-cluster-admin/README.md b/packages/ql3-cluster-admin/README.md index 3b2c9d0f..f71e328f 100644 --- a/packages/ql3-cluster-admin/README.md +++ b/packages/ql3-cluster-admin/README.md @@ -8,8 +8,10 @@ Console is a loopback-only read BFF serving digest-bound static assets. Neither opens database or Kubernetes authority, enters the legacy 2.x Web application, or resides in `cluster-control`. -The Console accepts thirteen exact Run, Task, Workflow and Copilot reads. The -browser cannot provide an upstream path or HTTP method, and every list page and +The Console accepts thirteen default Run, Task, Workflow and Copilot reads, +plus independently enabled Run cancellation, Worker and Plugin Package +installation observations, for at most twenty exact operations. The browser +cannot provide an upstream path or HTTP method, and every list page and detail/evidence read requires an explicit click. Its Cluster API credential stays in a canonical owner-private file and is reread for each upstream request; browser JavaScript receives only a separate session token which cannot diff --git a/packages/ql3-cluster-admin/assets/copilot-console/app.js b/packages/ql3-cluster-admin/assets/copilot-console/app.js index 9fa0c76e..65dfd520 100644 --- a/packages/ql3-cluster-admin/assets/copilot-console/app.js +++ b/packages/ql3-cluster-admin/assets/copilot-console/app.js @@ -11,6 +11,8 @@ run_cancellation_inspect: '/api/v1/run-management/cancellation-inspect', worker_list: '/api/v1/worker-management/workers', worker_inspect: '/api/v1/worker-management/worker', + package_list: '/api/v1/package-management/installations', + package_inspect: '/api/v1/package-management/installation', run_list: '/api/v1/observe/run-list', run_read: '/api/v1/observe/run', run_event_list: '/api/v1/observe/run-events', @@ -31,6 +33,8 @@ run_cancellation_inspect: '取消诊断', worker_list: 'Worker 目录', worker_inspect: 'Worker 详情', + package_list: 'Package 安装目录', + package_inspect: 'Package 安装详情', run_list: 'Run 目录', run_read: 'Run 详情', run_event_list: 'Run Events', @@ -131,6 +135,10 @@ result.afterWorkerId = null; } else if (operation === 'worker_inspect') { result.workerId = value('worker-id'); + } else if (operation === 'package_list') { + result.afterPackageName = null; + } else if (operation === 'package_inspect') { + result.packageName = value('installation-package-name'); } else if (operation === 'run_list') { result.afterCreatedAtMs = null; result.afterRunId = null; @@ -188,6 +196,11 @@ typeof fact.nextAfterWorkerId === 'string' ) { next.afterWorkerId = fact.nextAfterWorkerId; + } else if ( + operation === 'package_list' && + typeof fact.nextAfterPackageName === 'string' + ) { + next.afterPackageName = fact.nextAfterPackageName; } else if (operation === 'run_list' && fact.hasMore === true && fact.next) { next.afterCreatedAtMs = fact.next.createdAtMs; next.afterRunId = fact.next.runId; @@ -260,6 +273,23 @@ }); return; } + if (operation === 'package_list' && Array.isArray(fact.installations)) { + fact.installations.forEach(function (installation) { + if (!installation || typeof installation.packageName !== 'string') { + return; + } + const button = document.createElement('button'); + button.type = 'button'; + button.textContent = '显式检查 ' + installation.packageName; + button.addEventListener('click', function () { + document.getElementById('installation-package-name').value = + installation.packageName; + void execute('package_inspect'); + }); + entry.append(button); + }); + return; + } if ( operation !== 'run_cancellation_blocked_list' || !Array.isArray(fact.items) diff --git a/packages/ql3-cluster-admin/assets/copilot-console/evidence-bundle.js b/packages/ql3-cluster-admin/assets/copilot-console/evidence-bundle.js index 437ef127..7f2686ae 100644 --- a/packages/ql3-cluster-admin/assets/copilot-console/evidence-bundle.js +++ b/packages/ql3-cluster-admin/assets/copilot-console/evidence-bundle.js @@ -33,6 +33,8 @@ 'run_cancellation_inspect', 'worker_list', 'worker_inspect', + 'package_list', + 'package_inspect', 'run_list', 'run_read', 'run_event_list', @@ -54,6 +56,8 @@ run_cancellation_inspect: ['projectId', 'requestId', 'runId'], worker_list: ['afterWorkerId', 'projectId', 'requestId'], worker_inspect: ['projectId', 'requestId', 'workerId'], + package_list: ['afterPackageName', 'projectId', 'requestId'], + package_inspect: ['packageName', 'projectId', 'requestId'], run_list: [ 'afterCreatedAtMs', 'afterRunId', @@ -122,6 +126,7 @@ afterStepRunId: 'step', afterTaskId: 'task', afterWorkerId: 'worker', + afterPackageName: 'package', artifactId: 'artifact', attemptId: 'attempt', contentDigest: 'digest', @@ -131,6 +136,7 @@ id: 'identifier', modelId: 'model', nextAfterWorkerId: 'worker', + nextAfterPackageName: 'package', outputRef: 'artifact', packageName: 'package', projectId: 'project', @@ -170,6 +176,8 @@ 'runtimes', 'worker', 'workers', + 'installation', + 'installations', 'usage', 'workflow', 'workflows', @@ -207,6 +215,12 @@ 'status', 'supportTier', 'operatingSystem', + 'availability', + 'failureReason', + 'installOperation', + 'quarantineReason', + 'recoveryAction', + 'state', ]); const safeEnumValues = new Set([ 'accepted', @@ -302,13 +316,31 @@ 'ok', 'unavailable', 'workflow', + 'not_active', + 'install', + 'reinstall', + 'upgrade', + 'rollback', + 'resume_stage', + 'resume_activation', + 'inspect_activation', + 'source_unavailable', + 'source_mismatch', + 'stage_failed', + 'activation_failed', + 'activation_fact_conflict', + 'approval_expired', + 'policy_fence_changed', + 'resource_exhausted', + 'suspected_key_compromise', + 'confirmed_key_compromise', ]); const sensitiveKey = /credential|token|authorization|secret|session|password|cookie|private|keyring/iu; const freeTextKey = /text|content|stdout|stderr|command|input|output|environment|reason|error|message|description|name|path|url|uri|host|endpoint/iu; const numericKey = - /^(?:schemaVersion|version|revision|sequence|attempt|priority|limit|offset|size|total|count|exitCode|pending|leased|retryWait|dispatched|blocked|due|expiredLease|identityMismatch|pidMismatch|unsupported|invalid|availableSlots|maxConcurrentRuns|cpuCores|[A-Za-z0-9_]*(?:AtMs|TimeMs|DurationMs|Bytes|Tokens|Micros|Sequence|Version|Count|Limit|Offset|Size|Total))$/u; + /^(?:schemaVersion|version|revision|sequence|attempt|priority|limit|offset|size|total|count|exitCode|pending|leased|retryWait|dispatched|blocked|due|expiredLease|identityMismatch|pidMismatch|unsupported|invalid|availableSlots|maxConcurrentRuns|cpuCores|targetGeneration|[A-Za-z0-9_]*(?:AtMs|TimeMs|DurationMs|Bytes|Tokens|Micros|Sequence|Version|Count|Limit|Offset|Size|Total))$/u; const schemaValue = /^[a-z0-9][a-z0-9./_-]{0,126}@[a-z0-9._-]{1,16}$/u; class ClusterConsoleEvidenceBundleError extends TypeError { diff --git a/packages/ql3-cluster-admin/assets/copilot-console/index.html b/packages/ql3-cluster-admin/assets/copilot-console/index.html index 54513a21..97a27415 100644 --- a/packages/ql3-cluster-admin/assets/copilot-console/index.html +++ b/packages/ql3-cluster-admin/assets/copilot-console/index.html @@ -24,7 +24,7 @@
本机只读 BFF - Run · Task · Workflow · Worker · Copilot + Run · Task · Workflow · Worker · Package · Copilot
@@ -33,7 +33,7 @@

Observation coordinates

选择要读取的事实

-

每次按钮点击只发起一次有界 GET。页面不创建、取消、重试、轮询或缓存任何任务。

+

每次按钮点击只发起一次有界读取。页面不创建、安装、升级、回滚、取消、重试、轮询或缓存任何任务。

@@ -53,6 +53,7 @@ + @@ -81,6 +82,20 @@ + +