Make compass shell report a script abort in its exit status

Table of Contents

This page is a capture in the inbox bucket of the product backlog — a pre-sprint idea, not yet pulled into a sprint as a story.

1. What

A scripted shell run must report its own failure. Today it does not:

./compass.sh shell -l projects/ores.shell/scripts/library/pricing_model_product_parameters/pricing_model_product_parameters-put-many.ores
# prints: ✗ Invalid value for pricing_model_product_id: __none__
#         ✗ Script aborted at line 6: ...
echo $?
# 0

The shell already knows. script_commands.cpp calls fail(out), which keeps the failure flag set so an enclosing load aborts too, and the tests assert on command_feedback::failed(). Nothing carries that flag to the process exit status: host::execute returns whatever run_host_sync returns, and that is EXIT_SUCCESS unless early_exit asks for something else.

The fix is to let a failed scripted run reach the exit status — the flag exists, and compass shell already forwards the child's status.

2. Why

Found on 2026-09-26 during the ores.analytics clean pass. The library keeps one script per command so that a failure cannot hide the commands after it, and V04 ran all 40 of them. The exit code carried nothing, so each verdict had to be read by eye, and a wrapper that trusted the code would have reported success on the aborted script. The same gap stops the library from being a CI gate at all: a job that ran the scripts would be green whether they passed or aborted.

Two related facts, so the fix is not attempted the wrong way:

  • load --continue-on-error does not help. The inner abort still propagates and stops the enclosing script, which is why the sweep runs one script per invocation rather than one file that loads 40.
  • compass shell already propagates the child's exit code; it is the child that never sets it. Fixing the child fixes every caller at once.

3. References

  • projects/ores.shell/application/src/app/commands/script_commands.cpp — the load command, its fail(out) call and result.aborted.
  • projects/ores.shell/application/src/app/host.cpp — host::execute returns run_host_sync's value.
  • projects/ores.service/include/ores.service/service/host_runner_sync_impl.hpp — EXIT_SUCCESS unless early_exit intervenes.
  • How do I test the shell? — the recipe that has to tell readers to read the output instead of the exit code because of this.

4. See also

Emacs 29.3 (Org mode 9.6.15)