···132132 // Set engine-specific environment variables on the workflow
133133 // These will be merged with pipeline env vars by the framework
134134 workflowEnv := map[string]string{
135135- "PATH": "/runner-bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
136135 "TANGLED_ARCHITECTURE": spec.Architecture,
137136 }
138137
+5-3
internal/jobbuilder/job_template.go
···279279 },
280280281281 // Main container: run loom-runner binary in user's image
282282+ // Use shell to prepend /runner-bin to PATH, preserving the image's PATH
282283 Containers: []corev1.Container{
283284 {
284285 Name: "runner",
285286 Image: config.Image,
286286- Command: []string{"/runner-bin/loom-runner"},
287287+ Command: []string{"/bin/sh", "-c", "export PATH=/runner-bin:$PATH && exec /runner-bin/loom-runner"},
287288 WorkingDir: "/tangled/workspace",
288289289290 SecurityContext: &corev1.SecurityContext{
···371372 }
372373373374 // Build the shell script from clone commands
374374- // Add set -e for error handling and echo for visibility
375375- script := "set -e\n" + strings.Join(config.CloneCommands, "\n") + "\necho \"Repository ready\""
375375+ // Add set -e for error handling, safe.directory config to handle ownership mismatch
376376+ // (emptyDir volumes are root-owned but we run as user 10000)
377377+ script := "set -e\ngit config --global --add advice.detachedHead false --add safe.directory /tangled/workspace\n" + strings.Join(config.CloneCommands, "\n") + "\necho \"Repository ready\""
376378377379 return corev1.Container{
378380 Name: "clone-repo",