# Dev CI Runner `ci run-dev-e2e` is the single manual entry for dev desired-state smoke verification. It is deliberately smaller than a DevOps control plane: the CLI starts one Git-controlled runner on D601, D601 creates a temporary CI namespace, Tekton runs the smoke check, and the result is written back as files that the CLI can inspect. ## Goal The runner exists to prove the dev desired state without interrupting production: - Dev/prod isolation: temporary namespaces and dev manifests must not mutate `unidesk`, `unidesk-dev`, production PostgreSQL, production Deployments, production Services or main-server Compose services. - Version determinism: all runner inputs come from the pushed `origin/master` commit that supplied `deploy.json` and `origin/master:deploy.json#environments.dev`. - D601 execution: Git fetch, Tekton PipelineRun creation, Kubernetes polling and e2e log collection happen on D601, not on the main master. - CLI observability: the submit command returns a `runId`, result directory and next commands; `ci logs ` can recover status after the local CLI exits. - CI only: the flow may create CI-owned temporary resources, but it must not deploy backend-core, frontend, Code Queue, Decision Center, k3sctl-adapter or any other direct/managed service. ## Non-Goals Do not add a long-lived DevOps service, run broker, webhook listener or second desired-state file for this phase. Do not turn Host SSH into a general deployment system. Future full-stack dev rollout or CD can reuse the same desired-state principles, but it must be designed as a separate controlled deployment path after this smoke runner is stable. ## Manifest Contract `deploy.json` remains the only desired-state file. The dev environment may contain one non-service CI declaration: ```json { "schemaVersion": 2, "environments": { "dev": { "ci": { "repo": "https://github.com/pikasTech/unidesk", "scriptPath": "scripts/ci/dev-e2e.sh", "timeoutMs": 1800000 }, "services": [] } } } ``` `scriptPath` must be a repo-relative `scripts/ci/*.sh` path. Inline shell bodies, arbitrary script paths, local dirty scripts and separate `develop.json` or CI manifest files are forbidden. The script is fetched from the same full 40-character manifest commit that supplied `deploy.json`, so the runner logic is auditable and rollbackable with the desired state. ## Execution Path The automatic path is intentionally single and narrow: 1. CLI fetches `origin/master` and reads `origin/master:deploy.json#environments.dev`. 2. CLI records the full manifest commit and generates a DNS-safe `runId`. 3. CLI sends a short launcher through backend-core `/api/dispatch` using the existing `host.ssh` provider capability for D601. 4. D601 creates `/tmp/unidesk-ci/` and `/home/ubuntu/.unidesk/runs/`. 5. D601 fetches the manifest commit from GitHub through the node-local provider-gateway WS egress proxy at `http://127.0.0.1:18789`. 6. D601 extracts the runner with `git show : > /tmp/unidesk-ci//runner.sh` and executes it. 7. The runner creates the Tekton PipelineRun in `unidesk-ci`, waits for completion when requested, and writes `result.json`, `launcher.log`, `runner.log`, PipelineRun JSON and pod logs under `/home/ubuntu/.unidesk/runs//`. The CLI must not upload the runner script body. The submitted launcher may contain only repo, full commit, script path, run id, environment, timeout and keep-namespace settings plus the fixed fetch/execute wrapper. If k3s, Tekton or the provider egress proxy is unavailable, the run fails with visible logs; it must not fall back to an alternate deployment path. ## Runner Contract The Git-controlled script must accept: ```bash scripts/ci/dev-e2e.sh \ --run-id \ --repo-url \ --desired-ref master \ --manifest-commit \ --environment dev \ --result-dir /home/ubuntu/.unidesk/runs/ \ --timeout-ms \ [--keep-namespace] ``` The current script creates a Tekton `PipelineRun` for `pipeline/unidesk-dev-namespace-e2e`, stores the generated PipelineRun name in `pipelinerun.txt`, and writes a final `result.json` with `ok`, `status`, `runId`, `manifestCommit`, `pipelineRun`, `temporaryNamespace` and `finishedAt`. ## Commands Start a run and return after dispatch: ```bash bun scripts/cli.ts ci run-dev-e2e ``` Start a run and wait up to ten minutes for completion: ```bash bun scripts/cli.ts ci run-dev-e2e --wait-ms 600000 ``` Inspect run files on D601: ```bash bun scripts/cli.ts ci logs ``` Regular Tekton CI remains documented in `docs/reference/ci.md`; deployment desired-state and target-side build rules remain documented in `docs/reference/deploy.md`.