# 开发与构建执行环境 本文中的 `mdtodo` 是遗留开发运行面名;任务管理与迁移统一遵循 `$unidesk-tasktree`。 本文档是以下事项的权威出处: - NC01、D601 与 Master server 的构建执行面边界; - 持久化 `unidesk-dev` 环境; - 公开开发前端端口; - `deploy apply --env dev`; - L1 任务 worktree 向固定 workspace 的收口; - Rust backend-core 构建边界。 发布线和开发 lane 治理由 `docs/reference/release-governance.md` 与 [GitHub issue #6](https://github.com/pikasTech/unidesk/issues/6) 负责。 同一规则需要出现在其他入口时,详细规则保留在本文档,其他文档只留简短交叉引用。 ## 目标 开发环境用于在不干扰生产环境的前提下体验下一版本 UniDesk: - 生产环境继续使用 `http://74.48.78.17:18081/` 的正常公开前端。 - 开发环境通过独立的 Master server 端口 `http://74.48.78.17:18083/` 暴露。 - 开发后端和前端工作负载: - 运行在 D601 原生 k3s 的 `unidesk-dev` namespace; - 不运行在 Master server Compose stack。 - 开发 backend-core 和前端 rollout: - 使用 `origin/master:deploy.json#environments.dev` 中已推送的 Git commit; - 不使用脏 worktree。 - Rust backend-core 检查和构建: - 仍通过 `ci publish-backend-core` 使用其拥有的 D601 CI; - 开发 CD 只消费已发布镜像,不编译 Rust。 - Master server 唯一的构建例外是经过审查并显式限制并发的 backend-core 主服务上线操作。 ## 通用构建执行面 - Master server 只负责轻量源码编辑、Git 操作、状态观察和受控调度。 - 通用 Docker 镜像、仓库级检查、浏览器验证及 Rust/Go/前端重型构建默认使用 NC01。 - D601 不再是通用构建首选,只在以下事实明确成立时使用: - owning CI 或 Tekton 流水线固定运行在 D601; - 目标产物必须进入 D601 node-local registry 或原生 k3s; - 任务需要 D601 自有硬件、workspace 或运行面; - 用户明确指定 D601。 - D601 离线不得阻塞与 D601 无关的通用镜像构建;此类任务直接切到 NC01。 - NC01 上的临时构建目录和容器只用于验证,不成为源码或部署真相。 - 构建产物必须回到项目声明的镜像标签、registry、Git 或可审计交付路径。 ## 求职 Word 材料验收 - 求职相关的 Word 材料固定使用 D518 Windows 上的 Microsoft Word 作为最终视觉验收面。 - 文档可以在其他运行面生成,但交付前必须在 D518 Word 中完成以下检查: - 正常打开并重新保存后再次打开; - 核对总页数和分页位置; - 逐页检查表格边界、图片和证件照渲染; - 确认没有文字溢出、遮挡、截断或异常空白页。 - DOCX、PDF 和逐页截图通过 `$unidesk-trans` 的二进制传输入口流转。 - `python-docx` 等结构检查只能作为生成阶段校验,不能替代 D518 Word 的视觉验收。 ## D601 UniDesk 工作区 `D601:UniDesk` 的固定开发 workspace 是 D601 节点上的 `/home/ubuntu/workspace/unidesk-dev`,固定使用 `master` 分支和 `origin git@github.com:pikasTech/unidesk.git`。所有需要在 D601 上改 UniDesk 代码、做轻量语法/命令形态验证、验证 `trans`/`tran`/Code Queue runner、收敛分布式敏捷实验补丁的工作,都应先进入这个目录。 每次开始 D601 UniDesk 分布式开发、切换任务、恢复中断或上下文压缩后,先通过 UniDesk SSH 维护桥执行: ```bash trans D601:/home/ubuntu/workspace/unidesk-dev git status --short --branch trans D601:/home/ubuntu/workspace/unidesk-dev git remote -v ``` 若路径、分支或 remote 不符合预期,先修正 fixed workspace,再继续。`/home/ubuntu/cq-deploy`、Code Queue pod 内 `/root/unidesk`/`/app`、D601 上的 `/root/unidesk` 和 `/tmp/unidesk-*` 只作为部署副本、运行副本或临时实验面;运行面热修可以直接作用在 pod/容器,但必须随后把持久化修复提交到 Git remote,并在 fixed workspace 中复验。 固定 workspace 只作为 source truth 预检、fetch、受控 worktree 创建和最终同步入口。实际开发、文档修改、测试补丁和 PR 准备应在固定 repo 下的独立 worktree 中完成,例如 `/home/ubuntu/workspace/unidesk-dev/.worktree/`;该 worktree 必须通过 `bun scripts/cli.ts dev-env worktree add .worktree/ --branch --from origin/master` 从最新 `origin/master` 创建,让 `.worktreecopy` 中声明的本地配置白名单自动复制到新 worktree。使用任务专属分支或 detached worktree 隔离当前改动,结束前用 `git status` 确认只包含本任务文件。不要把 `/home/ubuntu/workspace/unidesk-dev` 根目录当作并行任务 scratch 区,也不要复用其他任务遗留 worktree。 ## D601-VM-HOST PikaPython 工作区 - PikaPython V2 的固定执行 route/workspace 是 `D601-VM-HOST:/home/ubuntu/workspace/pika_workspace`。 - `D601-VM` 是目标和 Provider ID,不是 `trans` route;`D601` 是另一节点, 两者均不得替代 `D601-VM-HOST` 执行该项目的构建、测试或 benchmark。 - 固定 workspace 保持 `master`,通过仓库 CLI 执行测试和 benchmark;根目录中的 `.worktree/` 属于任务隔离目录,状态检查和同步时必须保留。 - 进入任务或上下文恢复后的首个只读检查为: ```bash trans D601-VM-HOST:/home/ubuntu/workspace/pika_workspace git status --short --branch ``` - Master server 不作为 UniDesk 重型验证机: - 默认执行面是 NC01、CI runner 或目标运行面; - 重型验证包括仓库级 check 和 Playwright/browser smoke; - 重型构建包括镜像构建和 Rust/Go 编译; - Code Queue runner 实测也遵循同一执行面边界; - 只有 owning pipeline 或目标运行面固定属于 D601 时才使用 D601; - 唯一例外是用户或 issue 明确要求的 backend-core 主服务上线; - 该例外使用 `CARGO_BUILD_JOBS=1`、`--jobs 1` 或 CLI 内置等价方式限制并发; - 结果必须用异步 job/status/health 证据回写 issue。 - 主 server 高频控制入口包括: - `scripts/cli.ts`; - `scripts/trans`; - `scripts/tran`; - `scripts/src/ssh.ts`; - 相邻的 `trans`、`tran` 和 SSH helper。 - 这些客户端工具链可以直接在 master server `/root/unidesk` 轻量修改、提交并推送到 `origin/master`: - 例外范围只覆盖 CLI、`trans`、`tran` 客户端源码; - 同时覆盖帮助、轻量语法或命令形态验证和对应 reference 文档; - 不覆盖 `src/components/provider-gateway` 行为变更; - 不覆盖镜像构建、仓库级 check、浏览器 smoke 或其他重型验证; - 除非用户明确要求,CLI 改动不做单元测试、合同测试或新增测试脚本; - 涉及 provider-gateway 代码时,继续遵循其版本和远程升级规则。 - `trans`、`tran` 或 SSH 透传出现以下高频摩擦时,先优化 CLI 客户端: - 文件传输、stdin、chunk 或编码; - timeout; - route 或 operation 解析。 - 客户端优化应覆盖分块、校验、重试、可观测输出和帮助文档: - 使用目标 provider、pod 或 Windows route 的最小闭环证明; - 只有证据显示 client 侧无法规避边界时,才进入 provider-gateway 变更流程。 ## L1 Native 执行边界 - L1 只使用 host 上的 native API、Worker、Web 和必要基础依赖: - 服务从 owning YAML 解析固定 workspace、端口、状态目录和依赖; - 启动、停止、重启、状态和日志统一走项目受控 lifecycle CLI; - `--over-api` 直接调用该 native API,不经过 Kubernetes Service 或集群 workload。 - L1 在任何情况下都不依赖 CI/CD、GitOps、Argo、Kubernetes、镜像发布或 集群 rollout: - 正常启动、首次拉起、配置变更、合并后复测和故障处理都不等待这些系统; - 不用这些系统更新、修复或验收 L1 运行面; - 必须依赖集群对象的验证属于 L2。 - L1 始终使用本机小回环: - 通过 owning YAML 固定 native 端口完成 API、Worker、Workflow 和 Web 回归; - 同 host 可使用 YAML probe host,跨 host 使用 YAML 固定 native host; - 公共入口状态独立记录,不能成为 L1 业务门禁; - L1 任务不进入 CI/CD、Kubernetes 和 public-edge 调查或操作。 - L1 源码 provenance 是 lifecycle 状态的一部分: - 聚合 `status` 应同时披露 owning YAML 固定 repo、实际选中的 source workspace、commit 和进程工作目录一致性; - 迭代期间的 source workspace 可以是固定 workspace,也可以是 owning YAML 受控选择且属于固定 repo 的任务 worktree; - L1 完成时的 source workspace 必须回到 owning YAML 选定的固定 workspace,并满足下一节的收口合同; - 浏览器、CLI 或 smoke 命中其他 workspace 的旧代码时,结果只能证明旧运行面,不得作为当前修改的验收证据; - 状态缺少这些字段属于受控 CLI 可见性缺陷,应在当前 L1 任务内修复或登记到既有 source-worktree 改进任务,禁止用裸进程探测固化第二套验收流程。 ## L1 固定工作区收口 - 任务 worktree 只承载隔离开发和短反馈迭代: - 可以从受控 worktree 启动临时 native 进程或 HMR 预览; - 此类结果只证明迭代版本,不能证明固定 L1 运行面已经更新; - 不得因为页面、CLI 或 smoke 在任务 worktree 中通过,就宣称 L1 完成。 - 宣称 L1 完成前必须按顺序完成以下动作: - 把本任务已验收的全部语义整理为边界明确的提交; - 将该提交语义合入 owning YAML 选定的固定 L1 workspace 和其固定跟踪分支; - 保留固定 workspace 中无关的并行改动,禁止用 reset、覆盖式 checkout 或文件复制代替语义合并; - 确认没有已验收语义只留在任务 worktree、未提交 diff 或临时产物中; - 通过项目 lifecycle CLI 从固定 workspace 重载或重启受影响的 API、Worker 和 Web; - 重新读取聚合 `status`,确认 repo、workspace、commit 和进程工作目录都指向固定 L1 workspace; - 从固定端口重新执行受影响的 CLI、API、Workflow 或 Web 回归。 - HMR 不改变收口要求: - 固定 workspace 合入后由 HMR 自动更新页面,可以不做无意义的前端进程重启; - API、Worker 或未被 HMR 接管的进程仍须通过 lifecycle CLI 重载; - 最终 provenance 和回归证据必须来自固定 workspace 合入后的版本。 - L1 本地合入不等于 L2 发布: - 固定 workspace 收口不依赖 CI/CD、镜像、Kubernetes 或集群 rollout; - 后续进入 L2 时,再按项目 Git 和发布规则推送并交付同一语义。 - 固定 workspace 暂时无法完成语义合并时: - 保留任务 worktree 和提交,不得删除或丢弃; - 将 L1 状态保持为未完成并报告具体阻塞; - 不得把仍指向任务 worktree 或旧固定版本的公网地址作为完成入口交付。 - 任务 worktree 只有在固定 workspace 已吸收全部语义、固定入口回归通过且不存在未吸收提交后才能清理。 ## L1 受控 CLI 即时修复 - 执行 L1 开发、诊断或验收时,发现项目受控 CLI 存在问题即可在当前任务内即时修改: - 不需要把 CLI 缺陷降级为只读 blocker; - 不需要等待独立任务、issue 或额外授权; - 修复后继续完成原 L1 主线,不因 CLI 自身问题改用裸脚本或绕过产品入口。 - 可即时修改的范围包括: - YAML parser、参数校验和受控 lifecycle; - `--over-api` transport、状态、日志和窄查询; - 结构化输出、错误码、进度可见性和帮助文本; - 为恢复原 L1 入口所必需的相邻轻量 helper。 - 即时修改仍遵守原有边界: - owning YAML 继续是运行事实唯一来源; - 不由 CLI 缺陷推导服务端、生产、Secret、安全机制或重型构建的额外修改授权; - 修改使用正常 Git/PR 交付路径,并保护固定 worktree 中的并行改动; - 验证以具体文件语法、配置解析、目标命令和原 L1 入口最小闭环为准; - 默认不新增测试,不在 Master server 运行仓库级检查或重型 smoke。 - 以下情况属于应即时修复的 CLI 可见性问题: - 输出缺少关键状态、失败阶段或下一步; - 默认输出超过预算,导致无法完成判断。 - 修复要求: - 优先补语义化摘要、稳定 identity、分页 cursor 或 id-specific drill-down; - 禁止长期依赖 `--raw`、临时 dump、运行面反解或裸原生工具代替受控 CLI。 ## Public Dev Frontend Port The main server owns one extra public entrypoint for dev UI: ```text browser -> main-server:18083 -> dev-frontend-proxy -> prod backend-core microservice proxy -> k3sctl-adapter -> D601 k3s Service frontend-dev -> frontend-dev -> backend-core-dev ``` `dev-frontend-proxy` is an nginx sidecar in the main-server Compose project. It proxies requests to `backend-core:8080/api/microservices/k3sctl-adapter/proxy/api/services/frontend-dev/proxy...`, so D601 does not expose a new public port and the dev UI still crosses the existing UniDesk/k3sctl-adapter control boundary. The proxy is intentionally thin: it does not build frontend assets, does not talk to D601 directly, and does not contain DevOps logic. `frontend-dev` and `backend-core-dev` are registered with `k3sctl-adapter` through the managed-service catalog `src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-core.k3s.json`. The public dev port must use that cataloged Kubernetes API service-proxy path; it must not add a direct D601 public port, NodePort, or backend-core catalog entry for arbitrary k3s services. The dev public port is configured in `config.json` as `network.devFrontend.port=18083`, surfaced by `server status` as `urls.devFrontend`, and managed by `server rebuild dev-frontend-proxy`. The proxy health depends on `frontend-dev`; it can be unhealthy until the D601 dev frontend has been deployed. The unrestricted public network entries are therefore production frontend, dev frontend, and provider ingress. backend-core REST, PostgreSQL, user-service backend ports, k3s Services, NodePorts and D601 host ports remain private or explicitly restricted. Dev and production frontend authentication must use the same `config.json.auth` username, password, session secret and session TTL. The public dev and production entrypoints share the same IP/host with different ports, so the `unidesk_session` cookie is host-scoped rather than port-scoped. `deploy apply --env dev --service frontend` must sync `unidesk-dev-runtime-secrets` and `unidesk-dev-runtime-config` from the main-server config before rolling out `frontend-dev`; dev manifests may contain placeholders but must not establish a separate dev login identity. ## Desired State `deploy.json` remains the only version intent file. Dev entries live under `environments.dev` and are read from `origin/master:deploy.json`, never from a dirty local file, when using `--env dev` or `ci run-dev-e2e`. The target release-governance model is to split stable maintenance validation from high-risk master integration, for example with explicit lanes such as `dev-v1` and `dev-master`. That split is not active until `deploy.json`, deploy commands, CI, frontend labels and diagnostics support it explicitly. Until then, the documented `environments.dev` behavior remains the active contract and must not be emulated through local manifest edits or hidden branch conventions. During a `release/v1` stabilization window, this same implemented `environments.dev` lane is temporarily reserved for v1 validation. Use pushed commits and explicit `deploy.json` pins to validate v1 fixes; do not add a parallel `dev-v1`/`dev-master` schema in the middle of the stabilization window unless that split is the blocker for v1. The detailed phase rule lives in `docs/reference/release-governance.md`. The persistent dev rollout currently supports: - `backend-core`, `frontend`, `mdtodo`, `claudeqq` and `code-queue` as D601 registry artifact consumers in `unidesk-dev`. Decision Center moved to the NC01 YAML-first k8s lane and is no longer a current D601 persistent dev workload. - `baidu-netdisk` as the main-server direct user-service artifact validation sample. `deploy apply --env dev --service baidu-netdisk` consumes the D601 registry artifact and validates the main-server Compose service; it is not a persistent D601 k3s dev workload. `deploy apply --env dev --service code-queue` is intentionally dev-only and may mutate only `unidesk-dev` Code Queue scheduler/read/write/provider-egress-proxy objects. `deploy apply --env prod --service code-queue` must remain unsupported. The `environments.dev.ci` declaration and short launcher runner are owned by `docs/reference/dev-ci-runner.md`. ## Rust Backend-Core Boundary backend-core is implemented as a Rust service. The default dev and CI path compiles backend-core on D601 CI and consumes commit-pinned artifacts. The master server may inspect files, run concrete-file lightweight syntax checks, dispatch jobs and proxy traffic, but it must not run repository-level checks, Compose checks or Rust compilation for ordinary backend-core iteration. Narrow production-online exception: when a user or issue explicitly asks to put the current backend-core fix online on the main-server Compose runtime, master server may run backend-core-only Rust compilation with constrained parallelism (`CARGO_BUILD_JOBS=1`, `--jobs 1`, or the CLI's equivalent setting) and must use async job/status/health evidence. This exception does not allow repository-wide checks, Rust tests, Go builds, frontend builds, or other service builds on the master server. Allowed on the master server: - `git diff --check` and `bun --check ` - `bun scripts/cli.ts check --help` - `bun scripts/cli.ts deploy plan --env dev --service backend-core` - `bun scripts/cli.ts deploy apply --env dev --service backend-core` - `bun scripts/cli.ts ci run --revision ` - `bun scripts/cli.ts ci run-dev-e2e --wait-ms ` - for reviewed backend-core main-server online only: backend-core-specific `cargo check`/build with `CARGO_BUILD_JOBS=1`, or `bun scripts/cli.ts server rebuild backend-core` followed by `job status` polling and health verification Not allowed on the master server for this path: - repository-wide `cargo check`, `cargo build`, `cargo test`, `rustfmt`, or any Rust command outside the backend-core main-server online exception. - `bun scripts/cli.ts check --rust` without the D601 CI guard. - `bun scripts/cli.ts server rebuild backend-core` as a way to iterate Rust backend-core or replace D601 CI artifact flow. - Ad-hoc `docker build` of `src/components/backend-core/Dockerfile` on the master server outside the controlled CLI rebuild exception. `check --rust` remains a D601 CI/dev-execution command: `UNIDESK_D601_RUST_CHECK=1 bun scripts/cli.ts check --full --rust`. It deliberately fails outside that guard with an explicit explanation instead of silently compiling on the wrong host; the main-server online exception is handled by the backend-core-specific build/rebuild path, not by weakening `check --rust`. ## Dev Deploy Path `deploy apply --env dev --service backend-core|frontend|mdtodo|claudeqq|code-queue` is the controlled persistent dev rollout path for D601 dev workloads. The controller runs on the master server, but dev CD is a pull-only artifact consumer. All listed services consume CI-published commit-pinned artifacts from the D601 registry. Decision Center uses the NC01 k8s lane and GitHub storage checks instead of this D601 dev path. 1. Fetch `origin/master:deploy.json#environments.dev` and resolve the requested service commit to a full SHA. 2. Dispatch to D601 through the existing provider-gateway/Host SSH maintenance capability. 3. Require the existing registry image `127.0.0.1:5000/unidesk/:` produced by `ci publish-backend-core` for backend-core or `ci publish-user-service --service ` for user services. 4. Verify the registry manifest and image labels for service id, source commit and Dockerfile. The dry-run plan exposes the registry image, planned digest source, target, source commit and `build.willCompile=false`. 5. Import the registry artifact into native k3s containerd at `/run/k3s/containerd/containerd.sock`. 6. Apply only the selected `unidesk-dev` Service/Deployment objects from the dev manifest. 7. For `frontend`, sync auth/session settings from main-server `config.json.auth` into the dev runtime Secret/ConfigMap before rollout. 8. Stamp the Deployment with `UNIDESK_DEPLOY_*` env and `unidesk.ai/deploy-*` annotations. 9. Verify health through the Kubernetes API service proxy and require the live commit to match the requested commit. The dev path is not a fallback system. If artifact lookup, label verification, native k3s, containerd import, kubectl apply or live health verification fails, the job fails with logs. It must not fall back to `cargo build`, `docker build`, building on the master server, building source on the dev target, using a dirty worktree, direct D601 public ports, NodePort, hostPort, provider-gateway business HTTP, or another deployment command. k3s-managed health verification must use the Kubernetes API service proxy. ## DevOps Hygiene The persistent dev environment follows the shared Git-backed deployment hygiene rules in `docs/reference/devops-hygiene.md`. In particular, D601 runtime edits, dirty-worktree builds, copied scripts/images/source, direct D601 ports, NodePorts and manual smoke checks without live commit agreement must not become deployment truth. ## Standard Workflow Use this sequence for backend-core Rust and frontend dev work: 1. Preflight the fixed workspace, then create the task-scoped worktree with `bun scripts/cli.ts dev-env worktree add .worktree/ --branch --from origin/master`; keep unrelated parallel changes separated with `git status`/`git diff`. 2. Master server 只执行 diff 审查和具体文件的轻量语法检查。 - 轻量语法检查示例是 `bun --check `。 - 仓库级检查和类型检查默认在 NC01、CI 或目标运行面执行。 - Compose 检查、前端检查和 Rust 检查遵循同一执行面边界。 - 仅 D601 owning pipeline 使用 D601。 3. Commit the code from the task worktree and merge/push it to `origin/master` through the chosen lightweight PR or direct integration path; `deploy apply --env dev` cannot deploy unpushed local changes. 4. Update `deploy.json` `environments.dev.services` so `backend-core` and `frontend` point at the pushed commit, then commit and push that manifest update. 5. Preflight backend-core publication: `bun scripts/cli.ts ci publish-backend-core --commit --dry-run`. The result must have no `blockedScopes`, `wouldBuildOnD601=true`, D601 `unidesk-ci` Tekton runner metadata, D601 registry target `127.0.0.1:5000/unidesk/backend-core`, required labels for service id/source repo/source commit/Dockerfile, and `recommendedAction` pointing to the real publish command. 6. Publish the artifact first: `bun scripts/cli.ts ci publish-backend-core --commit --wait-ms 1200000` for backend-core, or `bun scripts/cli.ts ci publish-user-service --service --commit --wait-ms 1200000` for user services. 7. Verify the publish output contains non-empty `artifactSummary.digest` and `artifactSummary.digestRef`, and that the pushed image labels match `backend-core`, the source repo, source commit and Dockerfile. This verification can use the publish output and the D601 registry manifest HEAD; it must not rebuild. 8. Run `bun scripts/cli.ts deploy apply --env dev --service backend-core --dry-run` and confirm `artifactConsumer.noRuntimeSourceBuild=true`, `build.willCompile=false`, the registry image is `127.0.0.1:5000/unidesk/backend-core:`, and the target is `unidesk-dev/backend-core-dev`. 9. Run `bun scripts/cli.ts deploy apply --env dev --service backend-core` and observe the returned job with `bun scripts/cli.ts job status --tail-bytes 30000`. 10. Run `bun scripts/cli.ts deploy apply --env dev --service ` and observe the job the same way; this must consume the registry artifact and verify live deploy metadata through the service health path. 11. If the dev service catalog changes, deploy the pushed `k3sctl-adapter` commit through the controlled local manifest exception, then verify `/api/control-plane` lists `k3s/dev/unidesk-dev-core.k3s.json`. 12. Rebuild or verify `dev-frontend-proxy` on the main server with `bun scripts/cli.ts server rebuild dev-frontend-proxy` when the proxy config or port changes. 13. Manually test `http://74.48.78.17:18083/` and the dev health endpoints. 14. Run D601 CI for the commit and the dev smoke runner: `bun scripts/cli.ts ci run --revision --wait-ms ` and `bun scripts/cli.ts ci run-dev-e2e --wait-ms `. When Code Queue behavior changes, update the `code-queue` entry in `environments.dev.services` to the pushed commit before running dev artifact validation or the temporary dev smoke. ## Validation Commands Useful read-only or bounded validation commands: ```bash bun scripts/cli.ts server status bun scripts/cli.ts deploy plan --env dev bun scripts/cli.ts deploy plan --env dev --service backend-core bun scripts/cli.ts dev-env validate --manifest src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-core.k8s.yaml bun scripts/cli.ts dev-env validate --manifest src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-mdtodo.k8s.yaml bun scripts/cli.ts dev-env validate --manifest src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-claudeqq.k8s.yaml bun scripts/cli.ts dev-env validate --manifest src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-code-queue.k8s.yaml bun scripts/cli.ts ci run-dev-e2e --wait-ms 600000 bun scripts/cli.ts microservice proxy k3sctl-adapter /api/services/backend-core-dev/proxy/health --raw --full bun scripts/cli.ts microservice proxy k3sctl-adapter /api/services/frontend-dev/proxy/health --raw --full curl -fsS http://127.0.0.1:18083/health ``` When validating on D601 directly, always use the native kubeconfig explicitly: `KUBECONFIG=/etc/rancher/k3s/k3s.yaml`. The default `kubectl` context may point at Docker Desktop and is not valid for UniDesk native k3s verification.