commit 83c69a22d7228eaf54e77e14510c517f091af119
Author: Coder Agent <coder@agents.omni>
Date: Thu Feb 12 16:27:47 2026
Omni/Bild+Ide: exit code 2 for nothing-to-build
- bild now exits 2 for 'nothing to build' (no targets or all non-buildable)
- previously exited 1, same as build failure, forcing callers to grep stderr
- add explicit check when all targets are skipped (was silently exiting 0)
- dev-review-release.sh checks exit code instead of fragile string matching
- document bild exit codes in README (0=ok, 1=fail, 2=nothing, 124=timeout)
Task-Id: t-589
diff --git a/Omni/Bild.hs b/Omni/Bild.hs
index 2f88ac3f..dd268b56 100755
--- a/Omni/Bild.hs
+++ b/Omni/Bild.hs
@@ -269,11 +269,13 @@ doBild opts = do
then do
analysis <- analyzeAll True namespaces
if Map.null analysis
- then Log.wipe >> Log.fail ["bild", "nothing to build"] >> Log.br >> Exit.exitWith (Exit.ExitFailure 1)
+ then Log.wipe >> Log.fail ["bild", "nothing to build"] >> Log.br >> Exit.exitWith (Exit.ExitFailure 2)
else putJSON analysis
else do
when (null allNamespaces) <| do
- Log.wipe >> Log.fail ["bild", "nothing to build"] >> Log.br >> Exit.exitWith (Exit.ExitFailure 1)
+ Log.wipe >> Log.fail ["bild", "nothing to build"] >> Log.br >> Exit.exitWith (Exit.ExitFailure 2)
+ when (null namespaces) <| do
+ Log.wipe >> Log.fail ["bild", "nothing buildable (all targets skipped)"] >> Log.br >> Exit.exitWith (Exit.ExitFailure 2)
nproc <- GHC.getNumProcessors
createHier root
let runWithManager action =
diff --git a/Omni/Bild/README.md b/Omni/Bild/README.md
index 3e67ce0f..9a30ef6c 100644
--- a/Omni/Bild/README.md
+++ b/Omni/Bild/README.md
@@ -9,6 +9,15 @@ bild --time 0 Omni/Cloud.nix # Build with no timeout
bild --plan Omni/Test.hs # Analyze build without building
```
+## Exit Codes
+
+| Code | Meaning |
+|------|---------|
+| 0 | Build succeeded (or all targets were already cached) |
+| 1 | Build or test failure |
+| 2 | Nothing to build (no targets found, or all targets are non-buildable extensions like `.sh`, `.md`) |
+| 124 | Timeout |
+
When the executable is built, the output will go to `_/bin`. Example:
```bash
diff --git a/Omni/Ide/DEV_REVIEW_RELEASE.md b/Omni/Ide/DEV_REVIEW_RELEASE.md
index 3fdd38fa..6e78bfe3 100644
--- a/Omni/Ide/DEV_REVIEW_RELEASE.md
+++ b/Omni/Ide/DEV_REVIEW_RELEASE.md
@@ -94,7 +94,8 @@ Cost accounting is recorded per run in task comments:
- `--max-task-cost` prevents additional automated runs once the task exceeds the limit.
Namespace verification notes:
-- Dev build gating treats `bild` "nothing to build" / known parse-only namespace errors as non-buildable and skips verification instead of blocking progress.
+- `bild` exits with code 2 when there is nothing to build (no targets or all targets are non-buildable extensions like `.sh`, `.md`).
+- Dev build gating treats exit code 2 as a skip rather than a failure.
Expected lifecycle:
diff --git a/Omni/Ide/Workflows/integrator.md b/Omni/Ide/Workflows/integrator.md
index 8f62329e..15c023d4 100644
--- a/Omni/Ide/Workflows/integrator.md
+++ b/Omni/Ide/Workflows/integrator.md
@@ -71,8 +71,7 @@ Run namespace-specific checks:
- `bild <namespace>`
- `bild --test <namespace>` where available
-If `bild` reports a non-buildable namespace condition (for example `nothing to build`
-or the known container parse error `parsing Int failed, expected Number, but encountered String`),
+If `bild` exits with code 2 (nothing to build / non-buildable namespace),
record verification as skipped/N/A instead of blocking integration.
If verification fails for other reasons:
diff --git a/Omni/Ide/dev-review-release.sh b/Omni/Ide/dev-review-release.sh
index 0ac8497d..f6ff5cbd 100755
--- a/Omni/Ide/dev-review-release.sh
+++ b/Omni/Ide/dev-review-release.sh
@@ -339,9 +339,10 @@ run_cost_cents() {
agentd status "$run_name" --json 2>/dev/null | jq -r '.cost_cents // 0' 2>/dev/null || echo "0"
}
-is_non_buildable_namespace_error() {
- local output="$1"
- grep -Eq "nothing to build|parsing Int failed, expected Number, but encountered String" <<<"$output"
+is_non_buildable_exit_code() {
+ local rc="$1"
+ # bild exits 2 when there is nothing to build (no targets or all targets skipped).
+ [[ "$rc" -eq 2 ]]
}
cost_limit_comment_exists() {
@@ -786,16 +787,16 @@ run_single_task() {
local build_passed="true"
if [[ -n "$task_namespace" ]]; then
log "Running build verification for namespace: $task_namespace"
- local build_output
+ local build_output build_rc=0
if build_output=$(cd "$workspace" && bild "$task_namespace" 2>&1); then
log "Build verification passed for $task_namespace"
else
- if is_non_buildable_namespace_error "$build_output"; then
- log "Namespace $task_namespace is non-buildable in this environment; skipping build verification"
- task comment "$tid" "Automation (dev) skipped build verification for non-buildable namespace $task_namespace (bild reported no build target)." --json >/dev/null || true
+ build_rc=$?
+ if is_non_buildable_exit_code "$build_rc"; then
+ log "Namespace $task_namespace is non-buildable (bild exit 2); skipping build verification"
else
build_passed="false"
- log "Build verification FAILED for $task_namespace"
+ log "Build verification FAILED for $task_namespace (bild exit $build_rc)"
task comment "$tid" "Automation (dev) build verification failed for $task_namespace. Output:
\`\`\`