diff --git a/charts/skillhub/README.md b/charts/skillhub/README.md
index 02c81852a..bcbe10c9c 100644
--- a/charts/skillhub/README.md
+++ b/charts/skillhub/README.md
@@ -10,7 +10,9 @@
- **安全**:TLS 证书管理、Secret 密码保护;Bitnami 数据组件默认提供 NetworkPolicy
- **可观测性**:内置 Prometheus metrics exporter
- **业务事件 Logs(默认关闭)**:`server.businessLogs.enabled`、`endpoint` 与 `headersSecretRef`(引用现有 Secret);
- 其他预算/过滤配置使用 `server.extraEnv`,不增加默认 Collector。见[完整运行手册](../../docs/business-event-logs.md)。
+ 其他预算/过滤配置使用 `server.extraEnv`,复用现有接收器,不增加 Collector 子 Chart。
+ 指标默认只暴露 health/info;`server.actuatorExposureInclude: health,info,metrics,prometheus` 可打开受保护的查询入口。
+ Secret 创建、upgrade、产生事件、管理员查询与停用见[完整运行手册](../../docs/business-event-logs.md)。
## 快速开始
diff --git a/docs/09-deployment.md b/docs/09-deployment.md
index c15034ae1..d62c0da3e 100644
--- a/docs/09-deployment.md
+++ b/docs/09-deployment.md
@@ -667,8 +667,8 @@ override 或部署平台环境变量把上述 `SPRING_SECURITY_*` 变量注入 `
| 请求关联 | 响应头和日志中的 `X-Request-Id` / `request.id` |
| 日志 | 文本或 ECS 风格 JSON,均输出到容器 stdout / stderr |
| Trace | `none`、Micrometer + OTel SDK、或外部 Java Agent 三选一 |
-| 业务事实 | 默认关闭的独立 OTLP Logs 出口;[事件目录、配置、Secret、Collector 实收查询与可靠性边界](./business-event-logs.md) |
-| 指标 | Spring Boot Actuator;Prometheus 是可选后端,不是 Trace 前置条件 |
+| 业务事实 | 默认关闭;生产 `runtime.sh business-logs-enable` / `business-logs-up`,本地 `make business-logs-demo-up`;[配置、实收查询、排障与停止](./business-event-logs.md) |
+| 指标 | 默认仅 health/info;`SKILLHUB_ACTUATOR_EXPOSURE_INCLUDE=health,info,metrics,prometheus` 后重建 server,使用管理员会话查询 |
### 10.1 通用配置
diff --git a/docs/business-event-logs.md b/docs/business-event-logs.md
index 2188caa97..2e392fcab 100644
--- a/docs/business-event-logs.md
+++ b/docs/business-event-logs.md
@@ -2,6 +2,12 @@
Default off. This is lossy analytics, NOT audit, billing, notification or installation confirmation. Use the official server image built from this change; no custom application code, vendor SDK or Collector is required. The receiver must support OTLP/HTTP protobuf Logs. / 默认关闭;用于有损分析,不替代审计、计费、可靠通知或安装确认。只需对应版本官方镜像与运维配置,Collector 可选。
+## Choose a path / 选择路径
+
+- Production: `runtime.sh business-logs-enable` connects an existing receiver; `business-logs-up` installs an optional private Collector with an explicit downstream. See [production integration](#production-integration).
+- Local trial: `make business-logs-demo-up` supports `make dev-server` or a containerized backend. See [local trial](#local-trial).
+- Both paths include configuration updates, new-event queries, metrics, troubleshooting and cleanup. Headers stay in deployment-owned files / 两条路径均包含配置更新、新事件查询、指标、排障与清理,请求头保留在部署侧。
+
## Event catalog / 事件目录 (contract version 1)
Every row requires `skillhub.event.name`, `skillhub.skill.id`, `skillhub.namespace.id`, `skillhub.visibility`, `skillhub.source`, `skillhub.actor.type`, `log.record.uid` and producer occurrence `Timestamp`. IDs are numeric except the local opaque human `user.id` and UUID UID. Actor type is `user` (including anonymous/unknown user requests) or `system`. A known human adds `user.id`; anonymous/unknown and system actors omit it. / 所有事件都有上述字段;主体类型为 user(含匿名或未知请求)或 system;已知人类操作者额外使用本实例不透明 `user.id`,匿名、未知及系统主体省略该字段。
@@ -65,28 +71,87 @@ Related existing Resource settings: `spring.application.name` (`skillhub`, envir
A generic OTLP base endpoint normally appends a signal path in OTel autoconfiguration; THIS setting is Logs-specific, uses the given URL unchanged, and requires an explicit non-root path. Invalid enabled configuration fails startup without echoing endpoint/header values. Localhost/private-network receivers are valid. Destination is trusted operator configuration, not an end-user setting: use egress firewall/NetworkPolicy and DNS controls to allow only the authorized receiver and block cloud metadata, including aliases/rebinding. The managed 1.31 OkHttp sender follows redirects and exposes no redirect switch on its public Logs exporter builder: configure the receiver not to redirect and enforce destination/HTTPS restrictions at egress. Literal validation is not a complete SSRF firewall. / 本配置不是通用 base endpoint,不追加信号路径;允许自托管内网目标。1.31 发送器会跟随重定向,公开 builder 无关闭开关,接收端应禁止重定向,并配合出口/DNS/HTTPS 策略;字面量校验不能替代防火墙。
-## Direct receiver / 直连部署
+
-For an OTLP/HTTP Logs-compatible receiver, set these on the official server container; tracing may remain off:
+## Production integration / 生产接入
-```dotenv
-SKILLHUB_BUSINESS_LOGS_ENABLED=true
-SKILLHUB_BUSINESS_LOGS_ENDPOINT=https://analytics.example.com/v1/logs
-SKILLHUB_BUSINESS_LOGS_NAMESPACE_ALLOWLIST=7,12
-SKILLHUB_BUSINESS_LOGS_EVENT_ALLOWLIST=skill.publication.effective,skill.download.prepared,skill.review.approved
+### Retrieve and apply / 获取与应用
+
+使用包含本功能的同一版本脚本、Compose 和镜像。正式发布后把 `REF`、`VERSION` 固定为同一发布标签。开发验证可使用 `main` / `edge`。脚本的 `--version ` 默认从同名 Git 标签取文件;显式 `--ref` 优先。浮动镜像别名需要显式指定文件版本。
+
+```sh
+REF=main
+VERSION=edge
+RUNTIME_HOME="$HOME/skillhub-runtime"
+curl -fsSL "https://raw.githubusercontent.com/iflytek/skillhub/$REF/scripts/runtime.sh" -o runtime.sh
+sh runtime.sh ps --home "$RUNTIME_HOME" --ref "$REF" --version "$VERSION"
+# 在仓库外编辑 $RUNTIME_HOME/.env.release:数据库、存储、管理员和公开地址。
+chmod 600 "$RUNTIME_HOME/.env.release"
+sh runtime.sh up --home "$RUNTIME_HOME" --ref "$REF" --version "$VERSION"
```
-Use the release Compose file plus deployment-controlled environment/Secret injection. Never commit real `HEADERS`; e.g. its format is `Authorization=Bearer%20` (encode comma, equals, percent and literal plus as needed; `+` decodes to space). Do not run `docker compose config` into shared logs with secrets loaded. Across trust boundaries require HTTPS and receiver-supported authentication. JVM default trusted certificates apply; for private CAs use a deployment-provided JVM truststore, not an insecure TLS bypass. mTLS can be terminated by a local Collector/proxy. / 通过部署侧 Secret 注入请求头;跨信任边界必须 HTTPS/鉴权,私有 CA 使用 JVM truststore;不要关闭 TLS 校验,不要公开渲染含密钥的 Compose 配置。
+默认 `SKILLHUB_BUSINESS_LOGS_ENABLED=false`,不启动 Collector,不创建业务日志网络,也不向接收端发送请求。已部署实例升级时先拉取包含本功能的镜像,再用 `up` 重建。仅 `restart` 不读取新的 Compose 环境变量。
-Docker Secret alternative (no credential in Compose interpolation): mount a Secret whose target filename is `skillhub.observability.business-logs.headers`, and set `SPRING_CONFIG_IMPORT=optional:configtree:/run/secrets/`. Spring config-tree keys override the lower-priority application default. Do not simultaneously define a nonempty `SKILLHUB_BUSINESS_LOGS_HEADERS`. Manage the actual Secret file outside the repository and protect access to Actuator/config diagnostics. / 可用 Docker Secret + Spring configtree,文件名即完整属性名;真实 Secret 文件放仓库外,不与非空环境变量重复设置。
+已有兼容 OTLP/HTTP protobuf Logs 接收端时,在部署侧 `.env.release` 配置过滤范围与请求头,然后执行:
-Helm exposes `server.businessLogs.enabled`, `endpoint`, and `headersSecretRef.{name,key}`. The chart references an EXISTING Secret and does not create inline header secrets. Use existing `server.extraEnv` for every tuning/filter/Resource/Trace environment variable in the table. Do not duplicate the three built-in env names in extraEnv. / Helm 提供开关、目标及现有 Secret 引用;预算/过滤等使用 `server.extraEnv`,不要重复内建环境变量。
+```sh
+sh runtime.sh business-logs-enable --home "$RUNTIME_HOME" --ref "$REF" --version "$VERSION" \
+ --logs-endpoint https://receiver.example.com/v1/logs
+# 同一 Docker 主机上的接收容器可使用已有私有网络;脚本自动检查或创建网络并重建 server。
+# sh runtime.sh business-logs-enable ... --logs-network receiver-private --logs-endpoint http://receiver:4318/v1/logs
+```
+
+`--logs-endpoint` 是完整 Logs URL,原样使用,通常以 `/v1/logs` 结尾。已有远端接收器不需要本地 Collector。容器接收器在其自身部署中声明共享的外部网络;SkillHub 侧由小型 `compose.release.business-logs.yml` 自动接入。正常 `up` 会保留这个 overlay。每个实例使用独立网络名与项目名。
+
+所有请求头保留在部署侧。应用的 `SKILLHUB_BUSINESS_LOGS_HEADERS` 是 URL 编码的 `name=value` 对,以逗号分隔。`+` 解码为空格;逗号、等号、百分号和字面量加号需编码。真实值不进入仓库、命令行、截图或共享日志。不要把加载了密钥的 `docker compose config` 输出到日志。跨信任边界使用 HTTPS 与接收端鉴权。私有 CA 使用部署提供的 JVM truststore;mTLS 可由本地 Collector / 代理终止。
+
+Docker Secret 也可挂载为 `/run/secrets/skillhub.observability.business-logs.headers`,并通过部署 overlay 设置 `SPRING_CONFIG_IMPORT=optional:configtree:/run/secrets/`。同时保持 `SKILLHUB_BUSINESS_LOGS_HEADERS` 为空。Secret 文件放在仓库外。
+
+### Optional production Collector / 可选生产 Collector
+
+此路径使用独立 Compose 项目、外部私有网络、128 MiB 内存上限和 0.5 CPU。Collector 不发布主机端口。生产配置只有明确的 `otlphttp` 下游出口,没有 JSON 文件存储。
+
+```sh
+sh runtime.sh business-logs-up --home "$RUNTIME_HOME" --ref "$REF" --version "$VERSION"
+# 首次运行创建 business-logs/.env(0600),提示填写下游后退出,不启动半配置的 Collector。
+# 在部署侧编辑 $RUNTIME_HOME/business-logs/.env:
+# SKILLHUB_BUSINESS_LOGS_DOWNSTREAM_ENDPOINT=https://receiver.example.com
+# SKILLHUB_BUSINESS_LOGS_DOWNSTREAM_HEADERS='{}'
+# 有鉴权时把 headers 改成部署侧 JSON 对象,例如 Authorization 键;不在命令行传值。
+sh runtime.sh business-logs-up --home "$RUNTIME_HOME" --ref "$REF" --version "$VERSION"
+sh runtime.sh business-logs-ps --home "$RUNTIME_HOME" --ref "$REF" --version "$VERSION"
+```
+
+下游设置是 OTLP base URL;Collector 自动追加 `/v1/logs`。应用指向 `http://business-logs-collector:4318/v1/logs`。脚本从同一 `REF` 获取根目录下的 `compose.business-logs-collector.yml`、`business-logs-collector.yaml` 和网络 overlay,自动接网并重建 server。下游负责持久存储、查询、访问控制和保留期。默认模板使用内存队列;生产容量与持久发送队列由部署方按接收系统配置。
+
+更新 `.env.release` 后,重跑 `business-logs-enable` 应用地址、过滤或指标配置。更新 `business-logs/.env` 后,重跑 `business-logs-up` 应用下游配置。脚本保留已有文件中的密钥,不覆盖 `.env`。需要自定义 Collector 管道时,维护部署方自己的 Compose / 配置文件;脚本会更新下载的模板。
+
+`--aliyun` 使用扁平 OSS 根目录。发布流程须将上述三个新文件与原有 `runtime.sh`、`compose.release.yml`、`.env.release.example` 一起上传,版本与镜像一致。OSS 根目录不是按 Git ref 划分的版本仓库,发布方负责匹配。
+
+### Produce, query and stop / 产生、查询与停止
+
+以超级管理员登录,发布一个新版本,或通过 `/api/v1/skills///download` 下载已发布技能。没有历史补发。接收端按 `skillhub.event.name=skill.publication.effective` / `skill.download.prepared` 查询新时间窗口,查看 `skillhub.skill.id`、`skillhub.namespace.id`、`log.record.uid`。OTLP 是写入协议,没有统一的读 API;生产查询使用配置的下游系统自身的查询界面或 API。下文的本地路径提供可直接执行的 JSON 查询。
+
+```sh
+sh runtime.sh business-logs-logs --home "$RUNTIME_HOME" --ref "$REF" --version "$VERSION"
+# Ctrl-C 退出跟随日志。检查固定告警和接收端健康,不输出部署密钥。
+sh runtime.sh business-logs-disable --home "$RUNTIME_HOME" --ref "$REF" --version "$VERSION"
+sh runtime.sh business-logs-down --home "$RUNTIME_HOME" --ref "$REF" --version "$VERSION"
+# 再启动:已有 SkillHub 依赖先 up,再 business-logs-up;已有下游数据和网络保留。
+```
+
+`business-logs-disable` 重建 server 并关闭导出。`business-logs-down` 只停止可选 Collector;单独停止它时应用仍会尝试导出。`down` 停止 SkillHub,保留数据卷。已配置业务日志接收端或可选 Collector 时,`clean` 也保留部署环境、密钥和 Collector 文件。彻底删除前先停两个项目,备份部署配置,再由运维显式删除自己创建的项目和网络。
+
+### Helm endpoint and Secret / Helm 接入
+
+复用已有接收器,不安装 Collector 子 Chart。先在目标 namespace 创建 Secret:`kubectl create secret generic business-logs-credentials --from-file=headers=/secure/otlp-headers.txt -n skillhub`。文件内容为应用使用的 URL 编码头,不是 Collector 的 JSON 格式。此文件由部署方管理。
```yaml
server:
+ actuatorExposureInclude: health,info,metrics,prometheus
businessLogs:
enabled: true
- endpoint: https://analytics.example.com/v1/logs
+ endpoint: https://receiver.example.com/v1/logs
headersSecretRef:
name: business-logs-credentials
key: headers
@@ -95,35 +160,78 @@ server:
value: "7,12"
```
-## Optional Collector and real receive/query example / 可选 Collector 实收查询
+将片段保存为部署侧 `business-logs-values.yaml`。执行 `helm upgrade --install skillhub charts/skillhub -n skillhub -f production-values.yaml -f business-logs-values.yaml`,再执行 `kubectl rollout status deployment/skillhub-server -n skillhub`。按上面的方式产生新事件并在下游查询。Secret 轮换后执行 `kubectl rollout restart deployment/skillhub-server -n skillhub`。停用时将 `enabled` 改为 `false` 后再次 upgrade;现有 Secret 和下游数据保留。其它预算、过滤和 Resource / Trace 配置使用 `server.extraEnv`,不重复内建变量。
-The pinned example is `docs/examples/business-event-logs/compose.yaml` (Collector contrib `0.111.0`, 128 MiB / 0.5 CPU, only local HTTP port). It writes OTLP JSON to an ephemeral file, NOT production durable storage. Do not expose its unauthenticated port externally. It is separate from release Compose and is not started by default. / 示例仅本地验证,JSON 文件随容器删除,不是生产持久存储;无鉴权端口不得对外开放,不默认随正式部署启动。
+
-From repository root, with port 4318 free:
+## Local trial / 本地试用
-```bash
-docker compose -f docs/examples/business-event-logs/compose.yaml up -d
-# Host-run app: SKILLHUB_BUSINESS_LOGS_ENDPOINT=http://127.0.0.1:4318/v1/logs
-# Docker Desktop server container: use host.docker.internal:4318 instead of localhost.
-# Linux containers: use a shared private network / explicit host-gateway routing.
-# Enable business Logs on the app; publish/approve or request an authorized published download.
-docker cp skillhub-1009-collector:/business-logs.json ./business-logs.jsonl
-jq -r '.resourceLogs[].scopeLogs[].logRecords[] | (.attributes | map({key:.key,value:(.value.stringValue // .value.intValue // .value.boolValue)}) | from_entries) as $a | [.timeUnixNano, $a["skillhub.event.name"], $a["skillhub.skill.id"], $a["log.record.uid"]] | @tsv' business-logs.jsonl
-docker compose -f docs/examples/business-event-logs/compose.yaml down
+需要 Docker Compose、JDK 21、Maven wrapper 和 jq。从源码根目录执行。示例 Collector 固定为 contrib `0.111.0`,仅发布回环地址。JSON 追加写入项目独立的本地命名卷,没有保留策略,仅用于临时验证。
+
+### Host Java process / 主机 Java 进程
+
+```sh
+make dev
+make business-logs-demo-up
+make dev-server
```
-For a source-verifiable run of the REAL production exporter wiring against the same Collector config, without bootstrapping business accounts:
+`business-logs-demo-up` 保存本地试用标记。`make dev-server` 自动使用 `http://127.0.0.1:4318/v1/logs` 并打开业务日志;无需编辑应用源码或手工设置接收地址。后端已运行时重新启动它。需要其它端口时,对整个试用过程统一设置 `SKILLHUB_BUSINESS_LOGS_DEMO_PORT`;需要并行实例时还统一设置 `SKILLHUB_BUSINESS_LOGS_DEMO_PROJECT`、`SKILLHUB_BUSINESS_LOGS_NETWORK` 和 `BUSINESS_LOGS_DEMO_STATE_DIR`。
-```bash
-cd server
-TESTCONTAINERS_RYUK_DISABLED=true ./mvnw -pl skillhub-app -am test \
- -Dtest=BusinessLogsCollectorTest -Dsurefire.failIfNoSpecifiedTests=false \
- -Dskillhub.test.evidence-dir=/absolute/operator-owned/evidence
+### Containerized backend / 容器后端
+
+先用生产路径启动一个独立试用实例。它使用同一份 release Compose 和应用配置。然后从源码根目录设置该实例的环境文件和项目名:
+
+```sh
+export BUSINESS_LOGS_BACKEND=container
+export BUSINESS_LOGS_BACKEND_PROJECT=skillhub-local-trial
+export BUSINESS_LOGS_BACKEND_ENV_FILE="$HOME/skillhub-local-trial/.env.release"
+# BUSINESS_LOGS_BACKEND_PROJECT 必须与已启动实例的 COMPOSE_PROJECT_NAME 相同。
+make business-logs-demo-up
```
-Create that evidence directory first. The test uses named disposable containers and copies the actual sink output to `collector-received.jsonl`; apply the same jq query. It exercises all nine catalog records in all three Trace configurations (SDK trace sampling 0), checks IDs, UID uniqueness, field exclusion and receiver ACK metrics. This is real exporter/receiver integration, not a claim of a complete browser/CLI deployment smoke or loading an external Java agent. / 该测试使用真实应用导出装配及真实 Collector,保存实收结果,可用相同 jq 查询;不等同于完整 Web/CLI 部署验收或真实 Java Agent 注入测试。
+Makefile 自动创建试用私有网络,通过同一个 release 网络 overlay 重建 server,并使用 `http://business-logs-collector:4318/v1/logs`。保留这些变量,以便后续命令操作同一实例。需要指定不同版本的基础 Compose 时设置 `BUSINESS_LOGS_BACKEND_COMPOSE`。此模式的启用是本地试用状态;正常生产 `runtime.sh up` 仍以 `.env.release` 为准。
-Collector is optional. Production operators choose exporters, retention, TLS/auth, memory limiter and persistent sending queues appropriate to their sink. Collector persistence cannot recover records lost before application admission. File demo has no retention policy and must be stopped after verification. / 生产出口、保留策略、持久队列由运维选择;Collector 持久化不能补回应用侧漏报,示例用后停止。
+### Query and cleanup / 查询与清理
+
+在本地界面登录管理员,发布新版本或下载已发布技能,然后执行:
+
+```sh
+make business-logs-demo-status
+make business-logs-demo-records
+make business-logs-demo-verify
+# 默认验证 skill.download.prepared;也可指定其它已产生的事件。
+make business-logs-demo-verify BUSINESS_LOGS_EXPECT_EVENT=skill.publication.effective
+# 仅取 JSON 行进行结构化查询:
+make -s business-logs-demo-records | jq -r '.resourceLogs[].scopeLogs[].logRecords[] | (.attributes | map({key:.key,value:(.value.stringValue // .value.intValue // .value.boolValue)}) | from_entries) as $a | [$a["skillhub.event.name"], $a["skillhub.skill.id"], $a["log.record.uid"]] | @tsv'
+make business-logs-demo-down
+```
+
+`records` 输出实际 JSON 行;`verify` 在缺少预期事件时返回非零。`up` 重建 Collector 以应用配置,命名卷与追加模式保留已有记录。`down` 停止进程,再次 `up` 后仍可查询原记录。主机进程模式停止后还需重启 Java 进程以关闭导出;容器模式自动重建并关闭导出。试用结束后及时停止;需要保留的记录先保存到仓库外。彻底删除时先停止后端,再用该试用项目名执行 `docker compose -p -f docs/examples/business-event-logs/compose.yaml down -v`,显式删除试用卷,最后删除已无容器连接的试用网络。命名卷不是生产存储或可靠投递保证。
+
+### Metrics enablement and admin query / 指标启用与管理员查询
+
+默认只暴露 `health,info`。即使已有业务事件,管理员访问 metrics / prometheus 也会得到 404。Compose 在 `.env.release` 设置 `SKILLHUB_ACTUATOR_EXPOSURE_INCLUDE=health,info,metrics,prometheus`,然后通过 `business-logs-enable`(收集启用时)或正常 `up` 重建 server。Helm 使用上面的 `server.actuatorExposureInclude`。主机 Java 进程则在启动前导出同名变量。不要使用 `*`。
+
+源代码验证先执行 `make build-backend`,再执行 `docker build -t skillhub-server:local -f server/Dockerfile server`,并让 runtime 的 `--server-image skillhub-server --version local --ref <对应源码ref>` 指向新镜像。正式镜像升级使用发布标签,不依赖旧镜像中的新配置。
+
+可复用浏览器中的超级管理员会话。命令行查询时,在仓库外准备仅本人可读的登录 JSON 文件,内容为管理员 username / password。以下命令不打印密码或 Cookie:
+
+```sh
+BASE=http://127.0.0.1:8080
+QUERY_DIR=$(mktemp -d)
+chmod 700 "$QUERY_DIR"
+# LOGIN_JSON=/secure/admin-login.json,文件 mode 600;由部署方创建。
+curl -fsS -c "$QUERY_DIR/cookies" "$BASE/api/v1/auth/methods" -o /dev/null
+CSRF=$(awk '$6 == "XSRF-TOKEN" { print $7 }' "$QUERY_DIR/cookies")
+curl -fsS -b "$QUERY_DIR/cookies" -c "$QUERY_DIR/cookies" -H "X-XSRF-TOKEN: $CSRF" \
+ -H 'Content-Type: application/json' --data-binary @"$LOGIN_JSON" "$BASE/api/v1/auth/local/login" -o /dev/null
+curl -fsS -b "$QUERY_DIR/cookies" "$BASE/actuator/metrics/skillhub.business.logs.enqueued"
+curl -fsS -b "$QUERY_DIR/cookies" "$BASE/actuator/prometheus"
+rm -rf "$QUERY_DIR"
+```
+
+超级管理员可查询这两个指标入口。普通用户返回 403,匿名请求返回 401。Prometheus 沿用已有 `AUDITOR` 权限;单项 metrics 仅超级管理员。未启用业务导出时不会创建这些业务计数器;启用但未产生事件时计数为零。计数器是当前进程累计值,重启后归零,含义见下表。计数器反映应用接纳 / SDK 确认,不替代下游实收查询。
## Reliability, metrics and troubleshooting / 可靠性、指标与排障
@@ -139,7 +247,7 @@ Graceful shutdown stops new admission, gives SDK drain a `shutdown-timeout` wait
OTel 1.31 treats all HTTP 2xx responses as full success and does not expose `partial_success` rejected counts. `exported` means SDK/receiver ACK, NOT downstream storage confirmation. Do not replay whole partially accepted batches. Partial rejection diagnostics and durable retries belong at the receiver; this change does not upgrade the BOM. / 1.31 不读取部分拒收数量;成功指标不代表最终落库,不整批重发部分接收的数据。
-Micrometer names on the existing protected Actuator metrics surface (Prometheus renders dots as underscores):
+Micrometer names on the existing protected Actuator metrics surface (Prometheus renders dots as underscores and appends `_total` for counters, e.g. `skillhub_business_logs_enqueued_total`):
| Metric | Unit / 含义 |
| --- | --- |
@@ -160,6 +268,8 @@ Troubleshoot using the protected Actuator counters above, this fixed warning, re
| Symptom / 现象 | Check / 排查 |
| --- | --- |
+| Metrics 404 / 指标 404 | 显式启用 exposure 列表并重建镜像/容器;指标权限与导出开关独立。默认 404 是预期行为 |
+| Demo no records / 本地无记录 | 先运行 demo-up;主机模式重启 make dev-server;容器模式确认项目名、env 文件与共享网络,避免把容器 localhost 当接收器 |
| Startup fails / 启动失败 | Enabled without endpoint, bad full URL, invalid bounds/allowlist/header encoding; do not paste config secrets / 检查目标、范围、编码,不分享 Secret |
| No records, no exporter metrics / 无记录或指标 | Default off? Environment explicitly forwarded? Container recreated? No historical backfill / 开关、透传、重建、新事件 |
| Enqueued but failed / 已入队但失败 | `/v1/logs`, HTTP/protobuf (not gRPC 4317), DNS/network/TLS/auth and receiver Logs pipeline / 路径、协议、网络及鉴权 |
diff --git a/docs/skillhub/en/guide/deployment.md b/docs/skillhub/en/guide/deployment.md
index bc2d92328..fba0a7533 100644
--- a/docs/skillhub/en/guide/deployment.md
+++ b/docs/skillhub/en/guide/deployment.md
@@ -40,13 +40,13 @@ Suite review writes are enabled by default in the single-server release Compose
## Optional business-event OTLP Logs
-Business analytics is disabled by default and independent of all three Trace modes. With the matching
-official server image, enable `SKILLHUB_BUSINESS_LOGS_ENABLED=true` and a full
-`SKILLHUB_BUSINESS_LOGS_ENDPOINT`; Collector is optional and authentication headers belong in deployment
-Secrets. See the [business-event operations guide](https://github.com/iflytek/skillhub/blob/main/docs/business-event-logs.md)
-for publication, download preparation, review, promotion, archive, visibility and yank semantics, private-ID
-scope, every setting, a real receive/query example and loss/duplicate/shutdown limits. Download preparation
-is not completion or installation; this lossy stream is not audit, billing or reliable notification.
+Business analytics stays off by default and independent of tracing. Use `runtime.sh business-logs-enable`
+for an existing receiver, or `business-logs-up` for an optional Collector with an explicit downstream.
+For a local host Java process or container backend, use `make business-logs-demo-up`.
+Metrics require the explicit `health,info,metrics,prometheus` exposure list and a server recreation.
+The [operations guide](https://github.com/iflytek/skillhub/blob/main/docs/business-event-logs.md) covers both
+paths, Helm Secrets, admin queries, troubleshooting and cleanup. Download preparation is not completion
+or installation; this lossy stream is not an audit or billing system.
## CLI device authorization URL
diff --git a/docs/skillhub/guide/deployment.md b/docs/skillhub/guide/deployment.md
index 4b17983ed..40691c222 100644
--- a/docs/skillhub/guide/deployment.md
+++ b/docs/skillhub/guide/deployment.md
@@ -40,12 +40,11 @@ Suite 审核写入在单机 release Compose 中默认开启;Suite Bundle 确
## 可选的业务事件 OTLP Logs
-业务分析默认关闭,与三种 Trace 模式独立。对应版本官方镜像可通过
-`SKILLHUB_BUSINESS_LOGS_ENABLED=true` 和完整 `SKILLHUB_BUSINESS_LOGS_ENDPOINT` 启用;
-Collector 可选,请求头凭证使用部署 Secret。发布、下载准备、审核、提升、归档、可见性和 yank 的
-精确定义、私有 ID 范围、完整配置表、实收查询示例及丢失/重复/退出限制见
-[业务事件运行手册](https://github.com/iflytek/skillhub/blob/main/docs/business-event-logs.md)。
-下载准备不是下载完成或安装成功,不能用于审计、计费或可靠通知。
+业务分析默认关闭,与 Trace 独立。生产使用 `runtime.sh business-logs-enable` 接已有接收端,
+或用 `business-logs-up` 启动有明确下游的可选 Collector。本地使用 `make business-logs-demo-up`,
+自动适配主机 Java 与容器后端。指标需显式启用 `health,info,metrics,prometheus` 并重建 server。
+[运行手册](https://github.com/iflytek/skillhub/blob/main/docs/business-event-logs.md) 提供生产接入、
+本地试用、Helm Secret、管理员查询、排障与停止步骤。下载准备不代表完成或安装成功。
## 升级、停止与排障