# HWLAB 平行 Runtime Lane 扩容规格

本文是 HWLAB `v0.x` 平行 runtime lane 的长期扩容规格。`v0.3` 之后的 `v0.4`、`v0.5`、`v0.6` 等扩容必须沿用同一模式：人工只维护 `deploy/deploy.yaml` 中的 lane 声明，然后通过 repo-owned CLI 生成或应用扩容动作；不得再为每个新 lane 复制多处代码、手写 GitOps YAML、手动拼 namespace/Secret/FRP/Tekton/Argo 对象，或恢复 D601/旧节点兼容路径。

## 标准入口

新增 lane 的配置入口是：

```bash
node scripts/hwlab-lane-expand.mjs configure --lane v03 --from v02 --write
```

该命令只写入 `deploy/deploy.yaml` 的 `lanes.<lane>` 配置，并按 lane id 推导以下稳定映射：

| 输入 | 派生结果 |
|---|---|
| `v03` | source branch `v0.3` |
| `v03` | GitOps branch `v0.3-gitops` |
| `v03` | namespace `hwlab-v03` |
| `v03` | runtime path `deploy/gitops/node/runtime-v03` |
| `v03` | artifact catalog `deploy/artifact-catalog.v03.json` |
| `v03` | Argo Application `hwlab-node-v03` |
| `v03` | Tekton Pipeline `hwlab-v03-ci-image-publish` |
| `v03` | default legacy FRP ports `19766/19767` |

后续 lane 按同一公式递增，默认端口为 `19466 + minor * 100` 和后一位 API 端口；如端口已被占用，必须在 CLI 参数中显式给出 `--web-port` / `--api-port`，并把结果写回 `deploy/deploy.yaml`，不要在 render、Tekton 或 FRP 文件里手改。

## 单一配置点

`deploy/deploy.yaml` 是平行 runtime lane 的人写配置源。每个 `lanes.<lane>` 必须包含：

- `name`、`sourceBranch`、`gitopsBranch`、`namespace`、`artifactCatalog`、`runtimePath` 和公网 endpoint 映射。
- `envReuseServices`、`bootScripts`、`serviceDeclarations`、`envRecipe`、`bootConfig` 和 per-service runtime env。
- lane 独立 SecretRef 名称，例如 `hwlab-cloud-api-v03-db`、`hwlab-v03-bootstrap-admin`、`hwlab-v03-master-server-admin-api-key`。

新增服务、调整组件边界、调整 env image 配方或变更 HWPOD alias，也只允许先改 lane 配置和 schema；planner、renderer、artifact helper 和受控发布 CLI 必须读取 `deploy.lanes.<lane>`，不得新增 `if lane === "v04"` 这类 per-lane 分支。

## GitOps 模块化与严格 TS

`v0.3` 起，GitOps 扩容逻辑不得继续堆进单个 `scripts/gitops-render.mjs`。该文件只保留历史入口兼容、参数解析和高层编排；新增或抽出的 GitOps 逻辑必须进入 `scripts/src/` 下的领域模块，并优先使用 `.ts`。

第一批严格 TS 模块是 `scripts/src/runtime-lane.ts`，负责 runtime lane 的命名、端口、endpoint、branch、catalog 和 `deploy.lanes.<lane>` 回填。该模块由 `tsconfig.gitops.json` 以 `strict`、`exactOptionalPropertyTypes`、`noUncheckedIndexedAccess` 等选项检查；验证入口是：

```bash
npm run gitops:ts:check
```

后续从 renderer、Tekton、Argo、FRP、Git mirror 或 artifact helper 继续拆出的模块，必须直接纳入该严格 TS 检查范围；不要先拆成 `.mjs` 再另开长期迁移债。`scripts/gitops-render.mjs` 因为导入 TS 模块，实际执行必须走 Bun 入口：

```bash
npm run gitops:render -- --lane v03
```

生成的 Tekton 任务和 control-plane reconciler 也必须使用 `node scripts/run-bun.mjs scripts/gitops-render.mjs ...`，不得再用裸 `node scripts/gitops-render.mjs ...`。

## 废弃路径

旧节点和 D601 旧分支/runtime 只保留归档或事故对照价值，不再是新 HWLAB runtime lane 的 CI/CD 支持对象。旧节点归档分支名是 `v0.1`；CI/CD 不再为了 `v0.1` 保持 namespace、Pipeline、GitOps branch、poller、reconciler 或 FRP 兼容。若旧对象仍存在，应通过受控 CLI 分阶段退役，不能作为 v0.3+ 发布证据。

## 验收边界

一个新 lane 只有同时满足以下条件才算扩容完成：

- 远端 source branch 和 GitOps branch 存在，并与 `deploy.lanes.<lane>` 声明一致。
- 目标 node k3s 中存在独立 namespace、Tekton Pipeline/RBAC、Argo AppProject/Application 和 runtime desired state。
- runtime namespace、SecretRef、PVC、ServiceAccount、FRP proxy、artifact catalog 和 observability 对象均使用 lane 独立命名。
- `control-plane trigger-current --lane <lane>` 能创建 commit-pinned PipelineRun，promotion 只写入对应 GitOps branch/path。
- 公网 Web/API health 命中该 lane 的 namespace 和 revision；不得用 DEV/PROD、D601 或 `v0.1` health 作为通过证据。

## 当前状态

`v0.2` 是既有加法 lane，`v0.3` 是本规格收敛后的下一条 lane。`v0.3` 之后新增 lane 时，优先使用 `scripts/hwlab-lane-expand.mjs` 从最新稳定 lane 派生配置，再补受控 CLI 的 `--lane <lane>` 验证；如果某处仍要求改 JS/TS 代码才能识别新 lane，应视为扩容抽象缺口并修通用读取逻辑，而不是复制旧分支。
