# CLARIFY v0.14: Ingress Bootstrap Completeness **Autonomy**: full (config `autonomy.level = "full"`) **Budget**: 10 questions (used: 5 interactive, 5 auto-resolved) **Result**: all ambiguities resolved; 9 decisions (D-255..D-263) recorded in PROJECT.md ## Interactive Questions (resolved with operator) ### Q1: iptables vs nft emitter **Ambiguity**: Codebase is nft-only (D-218). Operator said "iptables used for SNAT/DNAT". **Resolution**: D-255 (partial) — Extend the existing nft emitter (`internal/emitter/nft.go`) with SNAT/MASQUERADE postrouting rules. "iptables" in the operator's description is read as "kernel NAT" — nft is the modern backend. No literal iptables emitter. **Confidence**: 0.95 ### Q2: ingress LXC lifecycle **Ambiguity**: Should the floating-IP LXC be registered as an orca-managed node or left as a one-shot external proxy? **Resolution**: D-259 — Register as a managed `linux` node (name=`ingress`, addr=`:8443`). `orca job run` pushes traefik dynamic config to it like any linux node. This makes routing-to-other-hosts work. **Confidence**: 0.92 ### Q3: Floating-IP network topology **Ambiguity**: Where does SNAT run and how does the LXC get the public IP? **Resolution**: LXC owns floating IP on eth0 (`net0 bridge=vmbr0,hwaddr=,ip=/,gw=`). nft runs inside the LXC. Matches Hetzner/OVH floating-IP-with-MAC model. **Confidence**: 0.90 ### Q4: TLS cert resolver in the image **Ambiguity**: The emitted static config references `certResolver: orca` but never declares the `certificatesResolvers.orca` block. v0.11 claimed P10 would wire step-ca but it was never implemented. **Resolution**: D-257 — Bake a `certificatesResolvers.orca.tls: { }` block pointing at a mounted `/etc/orca/step-ca-root.crt` CA file. No ACME (offline-first, R-001). If the file is absent at start, traefik logs a warning and serves plain HTTP (graceful degradation). The orca bootstrap pushes the cluster root CA into the container volume. **Confidence**: 0.90 ### Q5: Container networking **Ambiguity**: nft DNAT targets 127.0.0.1:8080/8443 on the host. How does the podman container receive that traffic? **Resolution**: D-256 — `--network host` so traefik binds 127.0.0.1:8080/8443 directly on the host (or LXC) loopback. No container port publishing. Simplest, matches the hybrid R-017 model. **Confidence**: 0.92 ### Q6: Dynamic config volume strategy **Ambiguity**: How does the podman traefik container consume dynamic config? Today `orca job run` writes `/etc/traefik/dynamic/orca-.yaml` on the host. **Resolution**: D-258 — Mount `/etc/traefik/dynamic` from host (`-v /etc/traefik/dynamic:/etc/traefik/dynamic:Z`). Zero changes to the existing `deployRemote` WriteFile path. The image's file provider watches `/etc/traefik/dynamic` as today. **Confidence**: 0.95 ## Auto-resolved questions (full autonomy, no operator interaction) ### Q7: Floating-IP mode — does the PVE host also register as a node? **Ambiguity**: In floating-IP mode, only the ingress LXC handles traffic. Does the PVE host also get registered? **Resolution**: D-259 — Yes. The PVE host registers as a `proxmox` node (for `pct`/`qm` workload dispatch). The ingress LXC registers as a `linux` node (for traefik dynamic config pushes). Both are in the registry. **Confidence**: 0.92 ### Q8: `--ingress-mode` persistence **Ambiguity**: Should `--ingress-mode` be stored on the node record so `doctor ingress` knows which check path to run? **Resolution**: D-260 — Yes. Add `IngressMode` field to `model.Node` + a schema migration (0007). Values: `""` (legacy/default for linux/localhost), `"native"`, `"floating-ip"`. **Confidence**: 0.90 ### Q9: MAC generation when `--mac` omitted **Ambiguity**: In floating-IP mode, if `--mac` is not provided, should orca generate one or require it? **Resolution**: D-261 — Interactive mode: generate a random locally-administered MAC (`02:XX:XX:XX:XX:XX`) and print it for operator confirmation. `--json` mode: require `--mac` explicitly (no silent generation — non-interactive means explicit inputs). **Confidence**: 0.88 ### Q10: Proxmox native nft DNAT target **Ambiguity**: In native mode, traefik runs inside an LXC. LXC has its own network namespace. nft DNAT to `127.0.0.1:8443` on the PVE host would NOT reach a container inside an LXC (different loopback). What's the DNAT target? **Resolution**: D-262 — The nft DNAT target is parameterized via `NftClusterConfig.DNATTarget` (default `127.0.0.1:8443`). For proxmox native mode, the DNAT target is the LXC's bridge IP (`:8443`). The LXC gets a DHCP/static bridge IP; orca discovers it after `pct start` via `pct list` or `pct inspect`. **Confidence**: 0.90 ## Additional decisions (derived from constraints, no ambiguity) ### D-263: LXC podman requirements Ubuntu 24.04 LXC template does not have podman preinstalled. Bootstrap must: 1. `pct create` with `--features nesting=1,keyctl=1` (required for podman in unprivileged LXC) 2. After LXC start: `apt-get update && apt-get install -y podman nftables` inside the LXC 3. Then `podman pull orca-traefik:` + `podman run ...` This adds ~30-60s to the join time. Documented in `docs/uat.md`. ### Image tag strategy The `orca-traefik` image uses the same version tag as the orca release (`v0.13.x` line). The podman reconciler resolves the tag from `internal/cli.version`. In dev builds (version="dev"), it falls back to `latest`. ### Registry auth The `orca-traefik` image is in the same registry/org as `orca` (`git.cloudinit.dev/coreci/`). Pulls are anonymous (REQ-045, repo is public). No `podman login` needed on workers. ## Requirements impact No new requirements beyond REQ-171..REQ-179 (already in REQUIREMENTS.md). The clarify stage confirmed scope and resolved all implementation ambiguities. The 9 decisions (D-255..D-263) are recorded in PROJECT.md.