# Plan: tenant k3s Job executor for knotless-run ## Goal Prove the execution mechanics for a `knotless-run` executor that runs one workflow run as one Kubernetes Job on a socialweb-computer tenant k3s cluster. The runner daemon stays outside the cluster. The Job pod is the unit that raises the tenant's scale demand, so a Pending Job causes a NodeClaim, the market RFP rents a VM, the pod is scheduled, and the cluster returns to zero after the run. ## Scope of this proof of concept - One Job per run, one long-lived pod, one `kubectl exec` per step. - The checkout is streamed into `/work` with tar over `kubectl exec -i`. - Shared steps are streamed into `/steps`. - Outputs are streamed back from `/outputs` and become images in the check. - A run writes a JSON result whose step fields mirror `dev.knotless.check`. - `--dry-run` prints the Job and every call. - Tests use a fake `kubectl`; no cluster is needed for `cargo test`. - A live script obtains a tenant kubeconfig through the hosted gateway with the alice credential file and `oauth-signin.ts`. Out of scope for this proof: - Patching `knotless-run` itself. - Real workflow YAML parsing. - Caches, PVCs, and artifact stores. - Secret injection. - Cancellation over XRPC. - Queue landing, which stays on a stable runner. ## Mapping to knotless's executor seam `crates/knotless-run/src/executor.rs` has: - `Executor::{Shell, Docker}` and `Session::{Shell, Docker}`. - `Executor::start(setup, log, timeout)` starts the run's container. - `Session::command(script, own)` returns the step command. - `Session::stop()` removes the container. - `run(cmd, log, timeout, cancelled)` enforces timeout and cancellation. This proof is the same shape: | knotless | This proof | |---|---| | `Setup.dir` | `--workdir`, streamed to `/work` | | `Setup.steps` | `--steps-dir`, streamed to `/steps` | | `Setup.outputs` | `--outputs`, streamed from `/outputs` | | `Setup.image` | `--image` | | `Setup.vars` | not yet; pod env or ephemeral Secret later | | `Executor::start` | `kubectl apply`, `kubectl wait` | | `Session::command` | `kubectl exec -- sh -ec