# PikaOA 开发与测试运行面 ## 配置真相 - PikaOA 平台配置唯一真相是 `config/pikaoa.yaml`。 - 正式交付与临时测试运行面职责分离: - `delivery.targets` 只描述正式 CI/CD、GitOps、运行 namespace、数据库和公网暴露; - `testRuntime.targets` 只描述专用测试集群上的临时后端运行面。 - 禁止把现有节点推断成 PikaOA 专用测试集群。 - `testRuntime.targets` 为空时表示当前没有获准的测试运行面: - `plan` 和 `status` 返回 `configured=false`、`mutation=false`; - `start` 和 `stop` 在任何远端调用前失败。 ## 受控入口 ```bash bun scripts/cli.ts pikaoa test-target plan bun scripts/cli.ts pikaoa test-target status bun scripts/cli.ts pikaoa test-target start --target --instance --commit --confirm bun scripts/cli.ts pikaoa test-target stop --target --instance --confirm ``` - `plan` 是本地只读渲染入口,不接受 `--dry-run`。 - `start` 和 `stop` 只在显式 `--confirm` 后执行。 - `--config ` 可用于 fixture 或本地 override;`validationOnly=true` 的 target 永远不连接 route。 - 默认输出是紧凑文本;`--output json` 或 `--json` 输出单一 JSON 文档。 - 长启动使用提交与短轮询分离的远程任务: - `start --confirm` 只提交由 `target/instance` 唯一定位的启动任务,返回 `start-submitted`、`jobId`、namespace 和 `mutation=true`; - 相同 `target/instance/commit` 重复提交只返回已有任务状态,不再启动并行任务; - 相同 `target/instance` 改用其他 commit 时返回 `start-instance-conflict`,操作者应使用新 instance; - `status` 返回 `running/succeeded/failed/canceled`、当前阶段、时间、终态 code、exit code 和有界事件尾部; - `status` 的运行面查询只使用 YAML 声明的短 request timeout,不进入启动等待循环。 - 远程任务事实只保存在 target YAML `taskState.rootPath` 对应的单一状态目录: - `taskState.statusRequestTimeoutSeconds` 控制短查询预算; - `taskState.logTailLines` 控制事件尾部上限; - 不建立第二数据库、控制器、租约或独立锁服务。 ## 临时运行面 - namespace 固定由 YAML `namespacePrefix` 和 CLI `--instance` 组成。 - namespace、API、Worker、临时 PostgreSQL、Service 和 Secret 都带以下可审计标签: - `app.kubernetes.io/managed-by=unidesk-pikaoa-test-target`; - `pikaoa.unidesk.io/test-runtime=true`; - `pikaoa.unidesk.io/target=`; - `pikaoa.unidesk.io/instance=`。 - `stop` 删除前重新校验 target、instance 和 managed-by 标签,只删除精确实例 namespace。 - `stop` 发现同一实例的启动任务仍在运行时,先写入精确任务的取消请求,再删除 namespace;返回 `startTaskDisposition` 说明是 `cancel-requested`、`cancel-already-requested`、`already-terminal` 或 `not-found`。 - 正式 namespace 保护集合来自以下 YAML 字段: - `delivery.targets.*.namespace`; - `delivery.targets.*.ci.namespace`。 - 测试入口不得渲染或删除保护集合中的任何对象。 - PostgreSQL 使用 namespace 内的临时存储,namespace 删除后测试数据随之清理。 - 临时数据库连接只由 target YAML 渲染: - `database.name`、`database.username` 和 `database.schema` 都是必填 PostgreSQL identifier; - renderer 使用结构化 URL 参数写入 `sslmode` 和 `search_path`,不提供隐藏 schema 默认值; - 缺少 schema 或形状不合法时,在任何 route 调用前返回具名配置错误。 - 附件运行参数与 namespace 内的临时 PVC 来自 target YAML: - `runtime.attachment.storageRoot` 和 `runtime.attachment.maxBytes` 直接写入严格 runtime YAML; - PVC 名称、容量、StorageClass 和 access mode 只从同一 target 声明读取; - API 挂载该 PVC,删除临时 namespace 时一并删除 PVC。 - 空数据库启动固定分为三个受控阶段: - 先渲染基础对象并等待 namespace 内 PostgreSQL 就绪; - 再使用 `source.images.migration` 和 `migration.command` 运行产品内置 `pikaoa migrate up` Job; - 迁移 Job 完成后才创建 API 和 Worker Deployment 并等待 rollout。 - PostgreSQL、迁移 Job 或业务 Deployment 失败会返回具名失败码,不会静默进入下一阶段。 - TTL 和清理策略来自 target YAML: - TTL 写入 namespace annotation; - 当前 `cleanup.mode=delete-namespace`,由显式 `stop` 执行; - `cleanup.requireOwnershipLabels=true` 时,删除前必须校验归属标签; - 不建立额外控制器或长期状态库。 ## Secret 与可观测性 - Secret 值只从 YAML `sourceRef` 读取并写入目标 Secret。 - CLI 输出只显示 `sourceRef`、`targetKey`、presence 和 fingerprint,始终保持 `valuesPrinted=false`。 - `plan` 的数据库投影只显示 schema 和 DSN 参数 presence,不显示完整 DSN、用户名、密码或参数值。 - 含 Secret 的 runner 文件使用 owner-only 权限,运行后立即删除;manifest 只在 runner 的临时目录存活,终态前由 trap 清理。 - 状态和事件只记录公开 ID、阶段、typed code 和时间,不保存命令 stderr、DSN、manifest 正文或 Secret 值。 - Secret 缺失会在连接测试集群前阻塞 `start`。 - 迁移 Job、API 和 Worker 从同一 Secret key 挂载严格的 PikaOA runtime YAML,数据库 schema 与 `search_path` 因此保持一致。 - OTel endpoint、Prometheus scrape、指标路径和探针全部由 target YAML 声明。 - 配置一致性、镜像/commit 漂移和 OTel exporter 失败只产生 `blocking=false` warning,不作为 MVP 门禁。 ## 本地验收 `config/fixtures/pikaoa-test-target.yaml` 只用于本地验证: - 证明 namespace、选择器、附件 PVC、迁移 Job、工作负载和 Secret 引用的渲染结果; - 证明 TTL、OTel、Prometheus 和正式 namespace 保护; - fixture target 固定为 `validationOnly=true`,不得用于真实集群操作。 ```bash bun scripts/cli.ts pikaoa test-target plan \ --config config/fixtures/pikaoa-test-target.yaml \ --target TEST01 \ --instance issue-2046 \ --commit 0123456789abcdef \ --output json ```