Repository navigation
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #694 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 313 313
Lines 39555 39734 +179
==========================================
+ Hits 39555 39734 +179
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Author
|
Not sure if you are accepting external PRs or what the procedure is, but I'm using your lib in an arazzo tool I'm building and want to see if I can get these fixes for issues I ran into merged upstream. This should bring it closer in line with the full arazzo spec. I see there is already a PR for handling 1/0 properly so I can rebase and modify if that gets pushed. Thanks for the work you do on this library, love it. |
Shaun1
marked this pull request as draft
November 5, 2026 04:37
The Arazzo Criterion Object operators table lists && (and), || (or) and () (logical grouping) alongside the comparison operators, but simple conditions were split on the first comparison operator found, so only a single `left <op> right` comparison could be expressed. Tokenize simple conditions and evaluate them with a small recursive-descent parser. || binds looser than &&, which binds looser than comparisons. Runtime expressions are consumed as one operand up to the next whitespace, operator or parenthesis, so operator characters inside JSON pointer paths are not misread. Malformed conditions (unterminated strings, unbalanced parentheses, misplaced operators) are reported as errors. https://spec.openapis.org/arazzo/v1.0.1.html#operators Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
compareSimpleValues fell back to string comparison for non-numeric operands and rendered nil as "<nil>". That sorts after digits, so an explicit JSON null passed `$response.body#/count > 0`. Null has no ordering: >, <, >= and <= now return false when either side is null, == is true only when both sides are null, and != is its inverse. A null used as a bare operand is falsy, so the rest of the condition still decides the outcome. A present but non-boolean bare operand is still an error. https://spec.openapis.org/arazzo/v1.0.1.html#literals Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Runtime expressions such as $response.body#/id or $response.header.Location can legitimately have no value, e.g. on an HTTP 204. Previously any such miss aborted the step, even inside an || branch intended as a fallback. Missing request/response values (headers, query and path parameters, JSON pointer segments, absent bodies or headers) now resolve to null and follow the null comparison rules: ordering comparisons fail, a bare operand is falsy, and step/workflow outputs are set to null. Unknown steps, workflows, inputs, outputs, components and source descriptions remain errors, and output atomicity is preserved. https://spec.openapis.org/arazzo/v1.0.1.html#runtime-expressions Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
strconv.ParseBool accepts "0" and "1", and it ran before numeric parsing, so conditions like `$response.body#/count > 0` compared a number to false and never passed. Parse numbers first and only accept true/false (also True/TRUE, False/FALSE) as boolean literals, per the Arazzo Literals section. https://spec.openapis.org/arazzo/v1.0.1.html#literals Co-authored-by: Cursor <cursoragent@cursor.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Shaun1
force-pushed
the
arazzo-criteria
branch
from
November 5, 2026 05:05
b492e05 to
46f2680
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR brings
simpleCriterion Object evaluation closer to the Arazzo 1.0.1 specification. It makes four changes, one per commit:&&,||and parentheses now work insimpleconditions.nullinstead of failing the whole step. A reference to an unknown step, workflow, input or component is still an error.0and1are now read as numbers, not booleans.Motivation
1. Logical operators and grouping
The spec's Operators table lists
&&(and),||(or) and()(logical grouping) next to the comparison operators. Before this change,evaluateSimpleConditionStringsplit a condition on the first comparison operator it found, so only a singleleft <op> rightcomparison worked. A condition like this one, which is common in auth and MFA flows, could not be expressed:Simple conditions are now tokenized and parsed with a small recursive-descent parser.
||binds more loosely than&&, and both bind more loosely than comparisons. A runtime expression ($...) is read as one operand up to the next whitespace, operator or parenthesis, so a character like>inside a JSON pointer path is not treated as an operator.2. Null operand handling
Fixes an upstream bug: an explicit JSON null passed ordering comparisons such as > 0. Missing values now follow the same null rules.
Null has no ordering: >, <, >= and <= now return false when either side is
null, == is true only when both sides are null, and != is its inverse. A
null used as a bare operand is falsy, so the rest of the condition still
decides the outcome. A present but non-boolean bare operand is still an
error.
https://spec.openapis.org/arazzo/v1.0.1.html#literals
3. Missing response values on empty responses
Runtime expressions such as
$response.body#/idor$response.header.Locationcan legitimately have no value. A 204 has no body, and an optional header may be missing. Before this change, any such miss aborted the step, even inside an||branch the author meant as a fallback.Missing request and response values (headers, query and path parameters, JSON-pointer segments, and absent bodies or headers) now resolve to
null:null. If a whole&&/||branch fails only because a value was missing, that branch counts asfalse, so the rest of the condition still decides the result.outputs: the output is set tonullinstead of failing the step.This is deliberately narrow. Unknown steps, workflows, inputs, outputs, components and source descriptions are authoring mistakes, so they still raise errors. The existing atomicity guarantees are unchanged (
TestEngine_StepOutputsAreNotPartiallyPopulatedOnEvaluationFailure,TestEngine_WorkflowOutputsAreNotPartiallyPopulatedOnEvaluationFailure): any non-optional failure still publishes no partial outputs, and workflow outputs are still committed only after every output has been evaluated.4.
0and1are numbersThe spec's Literals section defines
trueandfalseas boolean literals and treats numbers separately. Operands were previously passed tostrconv.ParseBoolbefore any numeric parsing.ParseBoolaccepts"0"and"1", so a condition like:compared a number to
falseand never passed. Numbers are now parsed first, and onlytrue/false(plusTrue/TRUEandFalse/FALSE) are read as booleans. As a side effect,t,f,TandFare no longer booleans. The spec doesn't define those literals, so this is a fix rather than a regression.Out of scope
These spec operators and literals are still not supported in
simpleconditions and could be follow-ups:!(logical not)[](array index) and.(property dereference) as operatorsnullas a literalTests
TestEvaluateCriterion_SimpleCondition_BooleanOperators: nested&&/||/()conditions, including the 204-or-challenge example above.TestEvaluateCriterion_NumericLiteralZeroIsNotBoolean:totalCount > 0passes when the count is positive and fails when it is zero.TestEvaluateSimpleOperand_ZeroAndOneAreIntegers: operand parsing for0and1.go vet ./arazzo/andgo test ./arazzo/...on its own;go test ./...passes on the final commit.🤖 Generated with Claude Code