# SelfMedia 运维入口

## 管理员凭据分发

- 在 owner-only 文件中维护凭据：
  - `/root/.unidesk/.env/unified-admin-password.txt` 只保存统一管理员密码；
  - `/root/.unidesk/.env/selfmedia-access.env` 保存以下非密码键：
    - `SELFMEDIA_ADMIN_USERNAME`；
    - `SELFMEDIA_API_KEY`；
    - `SELFMEDIA_SESSION_SECRET`。
- 不用 `cat`、`source`、`env`、Pod env 或 Secret decode 检查值。
- 先预检 sourceRef、键和 fingerprint：

```bash
bun scripts/cli.ts secrets plan --config config/secrets-distribution.yaml --scope selfmedia --target selfmedia-nc01
```

- 提交异步同步作业：

```bash
bun scripts/cli.ts secrets sync --config config/secrets-distribution.yaml --scope selfmedia --target selfmedia-nc01 --confirm
```

- 使用返回的 job ID 查询，直到终态：

```bash
bun scripts/cli.ts job status <job-id> --tail-bytes 12000
```

- confirmed sync 默认只返回 source/Secret fingerprint、键和 rollout 摘要；只有一次性下钻时才使用 `--full`，不得让默认输出因超限隐藏 ready 证据。

- 再核对目标 Secret 的键存在性：

```bash
bun scripts/cli.ts secrets status --config config/secrets-distribution.yaml --scope selfmedia --target selfmedia-nc01
```

- `consumerRollout` 是凭据生效合同：
  - `selfmedia` Deployment 通过 Secret `subPath` 挂载凭据；
  - 后端在启动时加载管理员凭据和 session secret；
  - `sync` 必须按 YAML 重启消费者，并通过多次短连接轮询等待 ready；
  - 总等待时限和轮询间隔分别由 `timeoutSeconds`、`pollIntervalSeconds` 声明；
  - 只更新 Secret 而没有成功 rollout 时，不得声称新账号已生效。

## 自动交付观察

- SelfMedia PaC consumer 为 `selfmedia-nc01`：

```bash
bun scripts/cli.ts platform-infra pipelines-as-code status --target NC01 --consumer selfmedia-nc01
bun scripts/cli.ts platform-infra pipelines-as-code history --target NC01 --consumer selfmedia-nc01 --limit 10
```

- 只有失败归因时才按具体 PipelineRun 下钻：

```bash
bun scripts/cli.ts platform-infra pipelines-as-code debug-step --target NC01 --consumer selfmedia-nc01 --id <pipeline-run-id>
```

- 正常发布只由 `pikainc/selfmedia` 的 GitHub PR merge 触发，不执行 bootstrap、apply、trigger-current、mirror sync、人工 PipelineRun 或 Argo refresh/sync。

## Temporal native 与部署态验收

- native 开发面只使用仓库统一 CLI：
  - `native prepare` 准备受控依赖和本地状态；
  - `native start|stop|status|logs temporal|worker|api|web` 分别管理四个独立组件；
  - `native smoke` 是首选的一键验收，覆盖 local CLI、`--over-api`、Temporal task queue、独立 API/Worker 和 HMR Web；
  - 一键 smoke 成功时，不再分别重复提交 local/over-api 作业、查询组件状态或探测 Web。

```bash
bun scripts/selfmedia-cli.ts native smoke
```

- 部署态从 API Deployment 内使用同一 CLI，不复制 Secret 值：
  - 第一步提交轻量 Temporal 作业并记录输出中的 job、workflow 和 run identity；
  - 第二步按精确 job ID 查询终态；
  - `succeeded` 且 `orchestration.engine=temporal`、`mode=runtime` 才证明 API、Temporal 和独立 Worker 链路可用。

```bash
trans <TARGET>:k3s:<NAMESPACE>:deployment:<API_DEPLOYMENT> exec --cwd /app -- \
  env SELFMEDIA_API_BASE_URL=http://127.0.0.1:4317/api/v1 \
  SELFMEDIA_API_KEY_FILE=/run/secrets/selfmedia-access/api-key \
  bun scripts/selfmedia-cli.ts smoke run --over-api

trans <TARGET>:k3s:<NAMESPACE>:deployment:<API_DEPLOYMENT> exec --cwd /app -- \
  env SELFMEDIA_API_BASE_URL=http://127.0.0.1:4317/api/v1 \
  SELFMEDIA_API_KEY_FILE=/run/secrets/selfmedia-access/api-key \
  bun scripts/selfmedia-cli.ts job status <JOB_ID> --over-api
```

- 只有任务明确要求媒体业务回归时才再提交真实阶段：
  - 正确语法是 `step run <阶段> --edition <期次> --over-api`；
  - 禁止使用不存在的 `step <阶段>` 形式；
  - 作业因既有素材或内容质量门禁失败时，分别记录编排链是否完成和业务检查结果，不把内容失败误判为 Temporal 链路故障。

```bash
trans <TARGET>:k3s:<NAMESPACE>:deployment:<API_DEPLOYMENT> exec --cwd /app -- \
  env SELFMEDIA_API_BASE_URL=http://127.0.0.1:4317/api/v1 \
  SELFMEDIA_API_KEY_FILE=/run/secrets/selfmedia-access/api-key \
  bun scripts/selfmedia-cli.ts step run <STEP> --edition <EDITION_ID> --over-api
```

- `<TARGET>`、`<NAMESPACE>` 和 `<API_DEPLOYMENT>` 必须从 `config/selfmedia.yaml` 选择，不把一次性运行面事实写回命令模板。
- rollout 后的判定顺序：
  - 先等待 Argo `Synced/Healthy` 和四个 Deployment Ready；
  - 再执行部署态 smoke；
  - Worker 在 Temporal 尚未监听时重启属于启动依赖竞态，应按产品 issue 处理；
  - 不能仅凭最终 Ready 隐去 restart 证据。

## 源码侧制品刷新

- 先按任务类型选择入口：
  - owning YAML 已完成预期变更，只需把 desired 刷新到消费仓时，不执行前置 `plan` 或 `check`；
  - 直接执行一次 `write`，再执行一次 `check` 和一次有界 Git diff；
  - 漂移来源未知时，先执行 `check`，根据 `firstDrift` 定位 owning YAML 或 renderer，再决定是否执行 `write`。
- 从 owning YAML 与 consumer 的 `sourceArtifact` 声明读取 `<NODE>`、`<consumer>` 和制品路径：
  - `<source-worktree>` 必须是消费仓的绝对 Git worktree；
  - 禁止从 live Pipeline/PipelineRun 反向导出 desired；
  - 通用合同以 [PaC 源码侧制品同步](../../unidesk-cicd/references/gitea-pac.md#pac-源码侧制品同步) 为权威出处。
- 已知配置刷新只执行以下最短闭环：

```bash
bun scripts/cli.ts platform-infra pipelines-as-code source-artifact write --target <NODE> --consumer <consumer> --source-worktree <source-worktree> --confirm
bun scripts/cli.ts platform-infra pipelines-as-code source-artifact check --target <NODE> --consumer <consumer> --source-worktree <source-worktree>
git -C <source-worktree> diff --name-only -- <artifact-path-from-write-output>
git -C <source-worktree> diff --check -- <artifact-path-from-write-output>
```

- 验收只读取有界证据：
  - `write` 的 `files.written` 必须只包含预期 source artifact；
  - `check` 必须为 `source.status=aligned` 且 `provenanceAligned=true`；
  - 业务目标值从 owning YAML 读取，aligned/provenance 证明生成制品与该 desired 一致；
  - 常规验收不展开内嵌 base64、大段脚本或完整 YAML diff，也不手写临时 payload 解码器。
- PR 合并后只观察正常自动交付；源码侧制品刷新不触发 PipelineRun、mirror、Argo 或运行面写入。

## 公网原入口验收

- 从 `config/selfmedia.yaml#delivery.targets.NC01.deployment` 读取公网 host、端口和健康路径，不在脚本中复制配置值。
- 无凭据检查：
  - `/` 返回 `200`；
  - `/healthz` 返回 `200`；
  - `/api/v1/system` 返回 `401`；
  - `/api/v1/terminal/status` 返回 `401`。
- 使用 owner 提供的新账号完成浏览器登录；不得把账号密码写入命令历史、截图、报告、issue 或日志。
- 登录后核对 WebTerm 打开、Codex session resume、统一 CLI 请求和流水线 job 状态；不使用终端访问 Kubernetes、Docker socket、ServiceAccount token 或宿主路径。
