Failure scenario
Use a JSON/YAML producer that serializes the flag as a string:
name: deploy
steps:
- id: change
tool: shell
params: {command: "exit 1"}
continue_on_failure: "false"
- id: dependent
tool: shell
depends_on: [change]
params: {command: "perform-follow-up"}
The loader converts the value with Python bool(), where every nonempty string—including "false", "no", and "0"—is true. The failing step therefore permits its dependent to run, the opposite of the submitted policy. Combined with the aggregate behavior already filed separately, this can also make the plan report success.
Site
src/odin/plan_loader.py:52-60 uses bool(s.get("continue_on_failure", False)) instead of requiring a JSON/YAML boolean.
Expected result
Require a real boolean and reject strings/numbers with a field-specific validation error. Do not use language truthiness to parse execution-policy fields.
Failure scenario
Use a JSON/YAML producer that serializes the flag as a string:
The loader converts the value with Python
bool(), where every nonempty string—including"false","no", and"0"—is true. The failing step therefore permits its dependent to run, the opposite of the submitted policy. Combined with the aggregate behavior already filed separately, this can also make the plan report success.Site
src/odin/plan_loader.py:52-60usesbool(s.get("continue_on_failure", False))instead of requiring a JSON/YAML boolean.Expected result
Require a real boolean and reject strings/numbers with a field-specific validation error. Do not use language truthiness to parse execution-policy fields.