@probelabs/visor 0.1.124 → 0.1.126

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/dist/config.d.ts.map +1 -1
  2. package/dist/docs/DEPLOYMENT.md +117 -11
  3. package/dist/docs/GITHUB_CHECKS.md +18 -4
  4. package/dist/docs/NPM_USAGE.md +112 -39
  5. package/dist/docs/action-reference.md +63 -9
  6. package/dist/docs/advanced-ai.md +58 -51
  7. package/dist/docs/ai-configuration.md +99 -11
  8. package/dist/docs/ai-custom-tools-usage.md +70 -33
  9. package/dist/docs/ai-custom-tools.md +50 -27
  10. package/dist/docs/architecture.md +1232 -0
  11. package/dist/docs/bot-transports-rfc.md +13 -3
  12. package/dist/docs/ci-cli-mode.md +116 -8
  13. package/dist/docs/claude-code.md +111 -41
  14. package/dist/docs/command-provider.md +37 -15
  15. package/dist/docs/commands.md +252 -6
  16. package/dist/docs/configuration.md +138 -4
  17. package/dist/docs/contributing.md +737 -0
  18. package/dist/docs/custom-tools.md +39 -8
  19. package/dist/docs/dashboards/README.md +33 -19
  20. package/dist/docs/debug-visualizer-progress.md +14 -13
  21. package/dist/docs/debug-visualizer-rfc.md +14 -13
  22. package/dist/docs/debug-visualizer.md +30 -5
  23. package/dist/docs/debugging.md +73 -8
  24. package/dist/docs/default-output-schema.md +24 -20
  25. package/dist/docs/dependencies.md +75 -21
  26. package/dist/docs/dev-playbook.md +85 -9
  27. package/dist/docs/engine-pause-resume-rfc.md +11 -11
  28. package/dist/docs/engine-state-machine-plan.md +10 -3
  29. package/dist/docs/event-driven-github-integration-rfc.md +20 -11
  30. package/dist/docs/event-triggers.md +95 -6
  31. package/dist/docs/execution-statistics-rfc.md +16 -4
  32. package/dist/docs/fact-validator-gap-analysis.md +12 -1
  33. package/dist/docs/fact-validator-implementation-plan.md +19 -11
  34. package/dist/docs/fail-if.md +116 -11
  35. package/dist/docs/failure-conditions-implementation.md +40 -6
  36. package/dist/docs/failure-conditions-schema.md +243 -87
  37. package/dist/docs/failure-routing-rfc.md +43 -18
  38. package/dist/docs/failure-routing.md +80 -23
  39. package/dist/docs/faq.md +836 -0
  40. package/dist/docs/foreach-dependency-propagation.md +32 -15
  41. package/dist/docs/github-ops.md +6 -5
  42. package/dist/docs/glossary.md +322 -0
  43. package/dist/docs/goto-forward-run-plan.md +23 -10
  44. package/dist/docs/guides/criticality-modes.md +15 -13
  45. package/dist/docs/guides/fault-management-and-contracts.md +8 -5
  46. package/dist/docs/guides/workflow-style-guide.md +17 -8
  47. package/dist/docs/http.md +102 -3
  48. package/dist/docs/human-input-provider.md +20 -36
  49. package/dist/docs/index.md +206 -0
  50. package/dist/docs/lifecycle-hooks.md +322 -2
  51. package/dist/docs/limits.md +20 -5
  52. package/dist/docs/liquid-templates.md +86 -14
  53. package/dist/docs/loop-routing-refactor.md +4 -2
  54. package/dist/docs/mcp-provider.md +53 -19
  55. package/dist/docs/mcp.md +27 -1
  56. package/dist/docs/memory.md +7 -2
  57. package/dist/docs/migration.md +596 -0
  58. package/dist/docs/observability.md +227 -6
  59. package/dist/docs/output-formats.md +388 -9
  60. package/dist/docs/output-history.md +36 -6
  61. package/dist/docs/performance.md +510 -4
  62. package/dist/docs/pluggable.md +95 -4
  63. package/dist/docs/proposals/snapshot-scope-execution.md +6 -5
  64. package/dist/docs/providers/git-checkout.md +16 -14
  65. package/dist/docs/providers/noop.md +696 -0
  66. package/dist/docs/recipes.md +8 -9
  67. package/dist/docs/rfc/git-checkout-step.md +3 -1
  68. package/dist/docs/rfc/on_init-hook.md +18 -5
  69. package/dist/docs/rfc/workspace-isolation.md +16 -0
  70. package/dist/docs/roadmap/criticality-implementation-tasks.md +27 -27
  71. package/dist/docs/router-patterns.md +155 -43
  72. package/dist/docs/schema-templates.md +51 -15
  73. package/dist/docs/script.md +162 -13
  74. package/dist/docs/sdk.md +46 -12
  75. package/dist/docs/security.md +464 -5
  76. package/dist/docs/slack-integration.md +481 -0
  77. package/dist/docs/tag-filtering.md +60 -20
  78. package/dist/docs/telemetry-setup.md +157 -46
  79. package/dist/docs/test-framework-rfc.md +37 -36
  80. package/dist/docs/testing/assertions.md +92 -4
  81. package/dist/docs/testing/ci.md +56 -7
  82. package/dist/docs/testing/cli.md +57 -15
  83. package/dist/docs/testing/cookbook.md +53 -20
  84. package/dist/docs/testing/dsl-reference.md +110 -9
  85. package/dist/docs/testing/fixtures-and-mocks.md +28 -3
  86. package/dist/docs/testing/flows.md +59 -4
  87. package/dist/docs/testing/getting-started.md +14 -13
  88. package/dist/docs/testing/troubleshooting.md +39 -2
  89. package/dist/docs/timeouts.md +174 -18
  90. package/dist/docs/troubleshooting.md +176 -6
  91. package/dist/docs/workflow-creation-guide.md +101 -3
  92. package/dist/docs/workflows.md +138 -41
  93. package/dist/examples/README.md +169 -4
  94. package/dist/examples/ai-custom-tools-simple.yaml +2 -3
  95. package/dist/examples/cron-webhook-config.yaml +15 -0
  96. package/dist/examples/forEach-example.yaml +6 -0
  97. package/dist/examples/git-checkout-basic.yaml +4 -0
  98. package/dist/examples/git-checkout-compare.yaml +6 -0
  99. package/dist/examples/git-checkout-cross-repo.yaml +7 -0
  100. package/dist/examples/http-integration-config.yaml +30 -0
  101. package/dist/examples/https-server-config.yaml +15 -0
  102. package/dist/examples/mcp-provider-example.yaml +10 -10
  103. package/dist/examples/transform-example.yaml +3 -0
  104. package/dist/examples/webhook-pipeline-config.yaml +18 -0
  105. package/dist/examples/workflows/workflow-composition-example.yaml +4 -0
  106. package/dist/frontends/slack-frontend.d.ts +2 -0
  107. package/dist/frontends/slack-frontend.d.ts.map +1 -1
  108. package/dist/generated/config-schema.d.ts +11 -7
  109. package/dist/generated/config-schema.d.ts.map +1 -1
  110. package/dist/generated/config-schema.json +11 -7
  111. package/dist/index.js +3127 -974
  112. package/dist/output/traces/{run-2026-01-28T16-15-24-569Z.ndjson → run-2026-01-31T16-37-22-321Z.ndjson} +84 -84
  113. package/dist/output/traces/{run-2026-01-28T16-16-09-757Z.ndjson → run-2026-01-31T16-38-06-031Z.ndjson} +1013 -1013
  114. package/dist/providers/ai-check-provider.d.ts +9 -2
  115. package/dist/providers/ai-check-provider.d.ts.map +1 -1
  116. package/dist/providers/command-check-provider.d.ts.map +1 -1
  117. package/dist/providers/mcp-custom-sse-server.d.ts +17 -1
  118. package/dist/providers/mcp-custom-sse-server.d.ts.map +1 -1
  119. package/dist/providers/workflow-check-provider.d.ts.map +1 -1
  120. package/dist/providers/workflow-tool-executor.d.ts +68 -0
  121. package/dist/providers/workflow-tool-executor.d.ts.map +1 -0
  122. package/dist/sdk/{check-provider-registry-AQ3JETBG.mjs → check-provider-registry-3KI5RKXT.mjs} +6 -5
  123. package/dist/sdk/check-provider-registry-IYILYY35.mjs +28 -0
  124. package/dist/sdk/chunk-2CPMMNIX.mjs +1459 -0
  125. package/dist/sdk/chunk-2CPMMNIX.mjs.map +1 -0
  126. package/dist/sdk/chunk-5LI6T4O3.mjs +3600 -0
  127. package/dist/sdk/chunk-5LI6T4O3.mjs.map +1 -0
  128. package/dist/sdk/{chunk-YLQ4UN62.mjs → chunk-A4PGHURG.mjs} +6838 -6257
  129. package/dist/sdk/chunk-A4PGHURG.mjs.map +1 -0
  130. package/dist/sdk/chunk-EXFGO4FX.mjs +147 -0
  131. package/dist/sdk/chunk-EXFGO4FX.mjs.map +1 -0
  132. package/dist/sdk/chunk-PJ7K5UFC.mjs +17732 -0
  133. package/dist/sdk/chunk-PJ7K5UFC.mjs.map +1 -0
  134. package/dist/sdk/{chunk-BHZ4CKUS.mjs → chunk-PXFIALUH.mjs} +77 -8
  135. package/dist/sdk/chunk-PXFIALUH.mjs.map +1 -0
  136. package/dist/sdk/{chunk-PVITVJ6J.mjs → chunk-RTKJXNZS.mjs} +32 -9
  137. package/dist/sdk/chunk-RTKJXNZS.mjs.map +1 -0
  138. package/dist/sdk/chunk-VW2GBXQT.mjs +606 -0
  139. package/dist/sdk/chunk-VW2GBXQT.mjs.map +1 -0
  140. package/dist/sdk/{config-RQQPMLRD.mjs → config-5AUYQFHE.mjs} +2 -2
  141. package/dist/sdk/config-6CUVEH7H.mjs +16 -0
  142. package/dist/sdk/config-6CUVEH7H.mjs.map +1 -0
  143. package/dist/sdk/{github-frontend-6Q4BISZX.mjs → github-frontend-BZ4N3BFZ.mjs} +7 -3
  144. package/dist/sdk/github-frontend-BZ4N3BFZ.mjs.map +1 -0
  145. package/dist/sdk/host-4MT3EW2I.mjs +52 -0
  146. package/dist/sdk/{host-P5NQICP7.mjs → host-NYWXLIFC.mjs} +2 -2
  147. package/dist/sdk/host-NYWXLIFC.mjs.map +1 -0
  148. package/dist/sdk/{routing-DEY2AIXM.mjs → routing-6R42GXUO.mjs} +2 -2
  149. package/dist/sdk/routing-6R42GXUO.mjs.map +1 -0
  150. package/dist/sdk/routing-7FXPULTO.mjs +24 -0
  151. package/dist/sdk/routing-7FXPULTO.mjs.map +1 -0
  152. package/dist/sdk/sdk.d.mts +3 -1
  153. package/dist/sdk/sdk.d.ts +3 -1
  154. package/dist/sdk/sdk.js +12163 -11204
  155. package/dist/sdk/sdk.js.map +1 -1
  156. package/dist/sdk/sdk.mjs +14 -10
  157. package/dist/sdk/sdk.mjs.map +1 -1
  158. package/dist/sdk/slack-frontend-JUT3TYVC.mjs +821 -0
  159. package/dist/sdk/slack-frontend-JUT3TYVC.mjs.map +1 -0
  160. package/dist/sdk/workflow-check-provider-H3CUOLUD.mjs +28 -0
  161. package/dist/sdk/workflow-check-provider-H3CUOLUD.mjs.map +1 -0
  162. package/dist/sdk/workflow-check-provider-YUNNF4KC.mjs +28 -0
  163. package/dist/sdk/workflow-check-provider-YUNNF4KC.mjs.map +1 -0
  164. package/dist/sdk/workflow-registry-KFWSDSLM.mjs +12 -0
  165. package/dist/sdk/workflow-registry-KFWSDSLM.mjs.map +1 -0
  166. package/dist/slack/socket-runner.d.ts +2 -0
  167. package/dist/slack/socket-runner.d.ts.map +1 -1
  168. package/dist/state-machine/context/workflow-inputs.d.ts +20 -0
  169. package/dist/state-machine/context/workflow-inputs.d.ts.map +1 -0
  170. package/dist/state-machine/dispatch/execution-invoker.d.ts.map +1 -1
  171. package/dist/state-machine/dispatch/foreach-processor.d.ts.map +1 -1
  172. package/dist/state-machine/dispatch/stats-manager.d.ts.map +1 -1
  173. package/dist/state-machine/states/level-dispatch.d.ts.map +1 -1
  174. package/dist/state-machine/states/routing.d.ts +2 -1
  175. package/dist/state-machine/states/routing.d.ts.map +1 -1
  176. package/dist/traces/{run-2026-01-28T16-15-24-569Z.ndjson → run-2026-01-31T16-37-22-321Z.ndjson} +84 -84
  177. package/dist/traces/{run-2026-01-28T16-16-09-757Z.ndjson → run-2026-01-31T16-38-06-031Z.ndjson} +1013 -1013
  178. package/dist/types/config.d.ts +3 -1
  179. package/dist/types/config.d.ts.map +1 -1
  180. package/dist/utils/human-id.d.ts +12 -0
  181. package/dist/utils/human-id.d.ts.map +1 -0
  182. package/dist/utils/worktree-manager.d.ts +3 -0
  183. package/dist/utils/worktree-manager.d.ts.map +1 -1
  184. package/dist/workflow-executor.d.ts.map +1 -1
  185. package/dist/workflow-registry.d.ts +1 -0
  186. package/dist/workflow-registry.d.ts.map +1 -1
  187. package/package.json +2 -2
  188. package/dist/sdk/chunk-BHZ4CKUS.mjs.map +0 -1
  189. package/dist/sdk/chunk-PVITVJ6J.mjs.map +0 -1
  190. package/dist/sdk/chunk-YLQ4UN62.mjs.map +0 -1
  191. package/dist/sdk/github-frontend-6Q4BISZX.mjs.map +0 -1
  192. /package/dist/sdk/{check-provider-registry-AQ3JETBG.mjs.map → check-provider-registry-3KI5RKXT.mjs.map} +0 -0
  193. /package/dist/sdk/{config-RQQPMLRD.mjs.map → check-provider-registry-IYILYY35.mjs.map} +0 -0
  194. /package/dist/sdk/{routing-DEY2AIXM.mjs.map → config-5AUYQFHE.mjs.map} +0 -0
  195. /package/dist/sdk/{host-P5NQICP7.mjs.map → host-4MT3EW2I.mjs.map} +0 -0
@@ -24,25 +24,109 @@ fail_if: outputs["fetch-tickets"].error
24
24
 
25
25
  Inside the expression you can use:
26
26
 
27
+ ### Primary context variables
28
+
27
29
  - `output`: the current check's structured output.
28
30
  - Includes `issues` and any other fields produced by the provider.
29
- - For custom schemas, all toplevel JSON fields are preserved and exposed here.
31
+ - For custom schemas, all top-level JSON fields are preserved and exposed here.
30
32
  - For command output that is JSON, fields are available directly; for plain text, treat `output` as a string.
31
33
  - `outputs`: a map of dependency outputs keyed by check name. Each value is that check's `output` if present; otherwise the whole check result.
32
34
 
33
- **Helper functions:**
34
- - String: `contains(haystack, needle)`, `startsWith(s,prefix)`, `endsWith(s,suffix)`, `length(x)`
35
- - Control: `always()`, `success()`, `failure()`
36
- - Author permissions: `hasMinPermission(level)`, `isOwner()`, `isMember()`, `isCollaborator()`, `isContributor()`, `isFirstTimer()` - See [Author Permissions](./author-permissions.md)
37
- - Issue/file matching helpers (see source FailureConditionEvaluator for the full list)
35
+ ### Additional context variables
36
+
37
+ - `memory`: accessor for the memory store (see [Memory](./memory.md))
38
+ - `memory.get(key, namespace?)` - Get a value
39
+ - `memory.has(key, namespace?)` - Check if key exists
40
+ - `memory.list(namespace?)` - List keys
41
+ - `memory.getAll(namespace?)` - Get all key-value pairs
42
+ - `inputs`: workflow inputs (for workflows)
43
+ - `env`: environment variables
44
+ - `debug`: debug information (if available)
45
+ - `debug.errors` - Array of error messages
46
+ - `debug.processingTime` - Processing time in milliseconds
47
+ - `debug.provider` - AI provider used
48
+ - `debug.model` - AI model used
49
+
50
+ ### Context for `if` conditions
51
+
52
+ When used in `if` conditions (not `fail_if`), additional context is available:
53
+
54
+ - `branch`: current branch name
55
+ - `baseBranch`: target branch (default: `main`)
56
+ - `filesChanged`: array of changed file paths
57
+ - `filesCount`: number of changed files
58
+ - `event`: GitHub event context with `event_name`, `action`, `repository`, etc.
59
+ - `checkName`, `schema`, `group`: check metadata
60
+
61
+ ### Legacy context (backward compatibility)
62
+
63
+ - `issues`: shorthand for `output.issues`
64
+ - `criticalIssues`, `errorIssues`, `warningIssues`, `infoIssues`, `totalIssues`: count of issues by severity
65
+ - `metadata`: object containing `checkName`, `schema`, `group`, issue counts, `hasChanges`, `branch`, `event`
66
+
67
+ ## Helper functions
68
+
69
+ ### String helpers
70
+ - `contains(haystack, needle)` - Case-insensitive substring check
71
+ - `startsWith(s, prefix)` - Case-insensitive prefix check
72
+ - `endsWith(s, suffix)` - Case-insensitive suffix check
73
+ - `length(x)` - Length of string, array, or object keys
74
+
75
+ ### Control helpers
76
+ - `always()` - Always returns `true`
77
+ - `success()` - Returns `true`
78
+ - `failure()` - Returns `false`
79
+
80
+ ### Debugging
81
+ - `log(...args)` - Print debug output prefixed with emoji. See [Debugging Guide](./debugging.md)
82
+
83
+ ### Issue/file matching helpers
84
+ - `hasIssue(issues, field, value)` - Check if any issue has a field matching value
85
+ - `countIssues(issues, field, value)` - Count issues matching field/value
86
+ - `hasFileMatching(issues, pattern)` - Check if any issue affects a file matching pattern
87
+ - `hasIssueWith(issues, field, value)` - Alias for `hasIssue`
88
+ - `hasFileWith(issues, pattern)` - Alias for `hasFileMatching`
89
+
90
+ ### Author permission helpers
91
+ - `hasMinPermission(level)` - Check if author has at least the specified permission level
92
+ - `isOwner()` - Check if author is repository owner
93
+ - `isMember()` - Check if author is organization member
94
+ - `isCollaborator()` - Check if author is collaborator
95
+ - `isContributor()` - Check if author has contributed before
96
+ - `isFirstTimer()` - Check if author is a first-time contributor
97
+
98
+ See [Author Permissions](./author-permissions.md) for detailed usage.
38
99
 
39
- Truthiness rules follow JavaScript: non‑empty strings are truthy, `""` and `null`/`undefined` are falsy, `0` is falsy.
100
+ ## Truthiness
101
+
102
+ Truthiness rules follow JavaScript: non-empty strings are truthy, `""` and `null`/`undefined` are falsy, `0` is falsy.
103
+
104
+ ## Complex failure conditions
105
+
106
+ For more control, use the complex form with additional options:
107
+
108
+ ```yaml
109
+ failure_conditions:
110
+ no_critical_issues:
111
+ condition: "criticalIssues > 0"
112
+ message: "Critical security issues found"
113
+ severity: error # error, warning, or info
114
+ halt_execution: true # Stop all execution immediately
115
+ ```
116
+
117
+ Options:
118
+ - `condition`: The expression to evaluate (required)
119
+ - `message`: Human-readable message when condition triggers (optional)
120
+ - `severity`: Issue severity level - `error`, `warning`, or `info` (default: `error`)
121
+ - `halt_execution`: If `true`, stops all workflow execution immediately (default: `false`)
40
122
 
41
123
  ## What happens when a condition is met
42
124
 
43
- - The engine adds an error‑severity issue to the check with ruleId `<checkName>_fail_if` (or `global_fail_if` for the global rule).
125
+ - The engine adds an issue to the check with ruleId `<checkName>_fail_if` (or `global_fail_if` for the global rule).
126
+ - Issue severity is `error` by default (configurable with complex form).
44
127
  - Direct dependents of that check are skipped with reason `dependency_failed`.
45
- - Skipped checks do not execute their providers; they appear as in the details table.
128
+ - Skipped checks do not execute their providers; they appear as skipped in the details table.
129
+ - If `halt_execution: true`, the entire workflow stops immediately.
46
130
 
47
131
  Only direct dependencies gate execution. Transitive checks are gated through the chain (i.e., if A fails B, and C depends on B, C will also be skipped once B is skipped).
48
132
 
@@ -88,8 +172,29 @@ fail_if: output.some(x => x.status === 'fail')
88
172
 
89
173
  Per‑item fail logic is not evaluated via `fail_if`; use `if:` to skip item work or emit issues inside the per‑item action.
90
174
 
175
+ ## Multi-line expressions
176
+
177
+ You can write multi-line expressions with debug statements:
178
+
179
+ ```yaml
180
+ fail_if: |
181
+ log("Checking output:", output);
182
+ log("Issue count:", output.issues?.length);
183
+ output.issues?.some(i => i.severity === 'critical')
184
+ ```
185
+
186
+ The last expression determines the boolean result. Lines are joined using the comma operator.
187
+
91
188
  ## Notes
92
189
 
93
- - Fail conditions are evaluated during dependencyaware execution as part of the engine (not only in providers), ensuring dependents are reliably skipped even if a provider path didnt attach issues.
94
- - Issue ruleIds are consistent: `<checkName>_fail_if` for percheck and `global_fail_if` for global.
190
+ - Fail conditions are evaluated during dependency-aware execution as part of the engine (not only in providers), ensuring dependents are reliably skipped even if a provider path didn't attach issues.
191
+ - Issue ruleIds are consistent: `<checkName>_fail_if` for per-check and `global_fail_if` for global.
192
+ - Expressions support optional chaining (`?.`) and nullish coalescing (`??`) for safe property access.
193
+ - If expression evaluation fails, the condition is treated as `false` (fail-safe behavior).
194
+
195
+ ## Related documentation
95
196
 
197
+ - [Author Permissions](./author-permissions.md) - Permission helper functions
198
+ - [Debugging Guide](./debugging.md) - Using `log()` and other debugging techniques
199
+ - [Memory](./memory.md) - Memory store access in expressions
200
+ - [Configuration](./configuration.md) - Full configuration reference
@@ -1,5 +1,17 @@
1
1
  # Enhanced Failure Condition System for Visor
2
2
 
3
+ > **Status: Partially Outdated**
4
+ >
5
+ > This document was written during initial implementation and some details are now outdated.
6
+ > For current usage, see:
7
+ > - [fail-if.md](./fail-if.md) - Primary documentation for failure conditions (recommended)
8
+ > - [failure-conditions-schema.md](./failure-conditions-schema.md) - Configuration schema reference
9
+ >
10
+ > Key differences from current implementation:
11
+ > - Integration is now via `StateMachineExecutionEngine` (not `CheckExecutionEngine`)
12
+ > - The simpler `fail_if` syntax is now the recommended approach
13
+ > - Additional helper functions exist (see fail-if.md for complete list)
14
+
3
15
  This document provides a complete overview of the enhanced failure condition configuration system implemented for the Visor code review tool.
4
16
 
5
17
  ## Overview
@@ -18,9 +30,9 @@ The enhanced failure condition system allows users to define flexible, powerful
18
30
  - TypeScript interfaces for failure conditions
19
31
  - Context object definition for expression evaluation
20
32
 
21
- 3. **CheckExecutionEngine Integration** (`src/check-execution-engine.ts`)
22
- - Integration with existing check execution pipeline
23
- - Automated evaluation after check completion
33
+ 3. **StateMachineExecutionEngine Integration** (`src/state-machine-execution-engine.ts`)
34
+ - Integration with the state machine execution pipeline
35
+ - Automated evaluation after check completion via `evaluateFailureConditions()` method
24
36
 
25
37
  ## Configuration Schema
26
38
 
@@ -85,11 +97,20 @@ The context object available to all JavaScript expressions (evaluated in a secur
85
97
 
86
98
  ## Available Helper Functions
87
99
 
100
+ > **Note**: This list is incomplete. See [fail-if.md](./fail-if.md#helper-functions) for the complete and current list of helper functions.
101
+
88
102
  ### Issue Analysis
89
103
  - `hasIssueWith(issues, field, value)` - Check if any issue has field matching value
90
104
  - `countIssues(issues, field, value)` - Count issues with field matching value
91
105
  - `hasFileWith(issues, text)` - Check if any issue file path contains text
92
106
 
107
+ ### Additional helpers (not listed here)
108
+ - String helpers: `contains()`, `startsWith()`, `endsWith()`, `length()`
109
+ - Control helpers: `always()`, `success()`, `failure()`
110
+ - Debug helper: `log()` for debugging expressions
111
+ - Permission helpers: `hasMinPermission()`, `isOwner()`, `isMember()`, etc.
112
+ - Memory accessor: `memory.get()`, `memory.has()`, `memory.list()`, `memory.getAll()`
113
+
93
114
  ## Example Use Cases
94
115
 
95
116
  ### Basic Quality Gates
@@ -157,13 +178,15 @@ failure_conditions:
157
178
 
158
179
  ## Integration Points
159
180
 
160
- ### CheckExecutionEngine
181
+ ### StateMachineExecutionEngine
161
182
  ```typescript
162
183
  // Evaluate conditions after check completion
163
184
  const results = await engine.evaluateFailureConditions(
164
185
  checkName,
165
186
  reviewSummary,
166
- config
187
+ config,
188
+ previousOutputs,
189
+ authorAssociation
167
190
  );
168
191
 
169
192
  // Check if execution should halt
@@ -172,6 +195,8 @@ if (FailureConditionEvaluator.shouldHaltExecution(results)) {
172
195
  }
173
196
  ```
174
197
 
198
+ > **Note**: The integration was originally in `CheckExecutionEngine` but has been migrated to `StateMachineExecutionEngine` as part of the engine refactor.
199
+
175
200
  ### GitHub Action Integration
176
201
  Failure conditions can be used to:
177
202
  - Set action exit codes
@@ -268,4 +293,13 @@ steps:
268
293
 
269
294
  The enhanced failure condition system provides a flexible, powerful foundation for implementing custom quality gates and policies in Visor. By leveraging JavaScript expressions (evaluated in a secure sandbox) with comprehensive context access, teams can create sophisticated review workflows that adapt to their specific needs and standards.
270
295
 
271
- The system maintains full backward compatibility while opening new possibilities for automated code quality enforcement and intelligent review assistance.
296
+ The system maintains full backward compatibility while opening new possibilities for automated code quality enforcement and intelligent review assistance.
297
+
298
+ ## Related Documentation
299
+
300
+ - [fail-if.md](./fail-if.md) - **Primary documentation** for failure conditions (recommended starting point)
301
+ - [failure-conditions-schema.md](./failure-conditions-schema.md) - Configuration schema reference
302
+ - [author-permissions.md](./author-permissions.md) - Permission helper functions
303
+ - [debugging.md](./debugging.md) - Using `log()` and debugging techniques
304
+ - [memory.md](./memory.md) - Memory store access in expressions
305
+ - [configuration.md](./configuration.md) - Full configuration reference
@@ -1,42 +1,63 @@
1
- # Enhanced Failure Condition Configuration Schema
1
+ # Failure Condition Configuration Schema
2
2
 
3
- This document describes the enhanced failure condition configuration system for Visor that supports JavaScript expressions (evaluated in a secure sandbox) for flexible and powerful failure evaluation.
3
+ This document describes the failure condition configuration system for Visor that supports JavaScript expressions (evaluated in a secure sandbox) for flexible and powerful failure evaluation.
4
4
 
5
- ## YAML Configuration Schema
5
+ > **Note:** The simple `fail_if` syntax is now preferred over the legacy `failure_conditions` object syntax. See [Fail If](./fail-if.md) for the recommended approach.
6
6
 
7
- ### Global Failure Conditions
7
+ ## Quick Start: Using `fail_if` (Recommended)
8
+
9
+ The simplest way to define failure conditions:
8
10
 
9
11
  ```yaml
10
12
  version: "1.0"
11
13
 
12
- # Global failure conditions apply to all checks
13
- failure_conditions:
14
- # Simple JavaScript expression for basic failure conditions
15
- critical_threshold: "metadata.criticalIssues > 0"
14
+ # Global fail_if applies to all steps unless overridden
15
+ fail_if: "output.error || criticalIssues > 0"
16
16
 
17
- # Complex conditions with multiple criteria
18
- security_gate: "metadata.checkName == 'security' && metadata.criticalIssues > 0"
17
+ steps:
18
+ security:
19
+ type: ai
20
+ prompt: "Analyze for security vulnerabilities..."
21
+ schema: code-review
22
+ on:
23
+ - pr_opened
24
+ - pr_updated
25
+ # Step-specific fail_if overrides global
26
+ fail_if: "criticalIssues > 0 || errorIssues >= 3"
19
27
 
20
- # Schema-based conditions
21
- code_review_quality: "metadata.schema == 'code-review' && metadata.totalIssues > 10"
28
+ performance:
29
+ type: ai
30
+ prompt: "Analyze performance implications..."
31
+ schema: code-review
32
+ on:
33
+ - pr_opened
34
+ - pr_updated
35
+ # Complex condition with helper functions
36
+ fail_if: "hasIssue(issues, 'category', 'performance') && errorIssues > 1"
37
+ ```
38
+
39
+ ## Legacy: Complex Failure Conditions
22
40
 
23
- # Combined conditions with logical operators
24
- deployment_blocker: "metadata.criticalIssues > 0 || (metadata.errorIssues > 5 && metadata.checkName == 'security')"
41
+ For more control, use the complex `failure_conditions` object syntax (deprecated but still supported):
25
42
 
26
- # Alternative object syntax for more complex conditions
43
+ ```yaml
44
+ version: "1.0"
45
+
46
+ # Object syntax for complex conditions with additional options
27
47
  failure_conditions:
28
48
  critical_security_issues:
29
- condition: "metadata.criticalIssues > 0 && metadata.checkName == 'security'"
49
+ condition: "criticalIssues > 0"
30
50
  message: "Critical security issues detected - deployment blocked"
31
51
  severity: "error"
52
+ halt_execution: true # Stop all execution immediately
32
53
 
33
54
  performance_degradation:
34
- condition: "metadata.checkName == 'performance' && metadata.errorIssues >= 3"
55
+ condition: "hasIssue(issues, 'category', 'performance') && errorIssues >= 3"
35
56
  message: "Performance issues detected that may impact production"
36
57
  severity: "warning"
37
58
 
38
59
  insufficient_coverage:
39
- condition: "metadata.schema == 'code-review' && metadata.totalIssues > 15"
60
+ condition: "totalIssues > 15"
40
61
  message: "Too many code quality issues - consider additional review"
41
62
  severity: "info"
42
63
 
@@ -49,69 +70,160 @@ steps:
49
70
  on:
50
71
  - pr_opened
51
72
  - pr_updated
52
-
53
- # Check-specific failure conditions override global ones
54
- failure_conditions:
55
- block_on_any_critical: "metadata.criticalIssues > 0"
56
- warn_on_multiple_errors: "metadata.errorIssues >= 2"
57
-
58
- performance:
59
- type: ai
60
- prompt: "Analyze performance implications..."
61
- group: review
62
- schema: code-review
63
- on:
64
- - pr_opened
65
- - pr_updated
66
-
67
- # Inherits global failure conditions unless overridden
73
+ # Step-specific failure conditions override global ones with same name
68
74
  failure_conditions:
69
- performance_regression: "metadata.errorIssues > 1 && issues.some(i => i.category == 'performance')"
75
+ block_on_any_critical: "criticalIssues > 0"
76
+ warn_on_multiple_errors: "errorIssues >= 2"
70
77
  ```
71
78
 
72
79
  ### Advanced JavaScript Expression Examples
73
80
 
74
81
  ```yaml
75
- failure_conditions:
76
- # Issue analysis with helper functions
77
- sql_injection_check: "hasFileWith(issues, 'sql') && hasIssueWith(issues, 'severity', 'critical')"
82
+ steps:
83
+ security-check:
84
+ type: ai
85
+ prompt: "Analyze for security issues..."
86
+ # Issue analysis with helper functions
87
+ fail_if: "hasFileWith(issues, 'sql') && hasIssue(issues, 'severity', 'critical')"
78
88
 
79
- # Multiple file types analysis
80
- critical_files_affected: "hasFileWith(issues, '.ts') || hasFileWith(issues, '.js') && hasIssueWith(issues, 'severity', 'critical')"
89
+ critical-files:
90
+ type: ai
91
+ prompt: "Review critical files..."
92
+ # Multiple file types analysis
93
+ fail_if: "(hasFileWith(issues, '.ts') || hasFileWith(issues, '.js')) && hasIssue(issues, 'severity', 'critical')"
81
94
 
82
- # Complex metadata-based conditions
83
- large_change_with_issues: "metadata.totalIssues > 5 && debug && debug.processingTime > 30000"
95
+ performance-check:
96
+ type: ai
97
+ prompt: "Analyze performance..."
98
+ # Time-based conditions (if debug info is available)
99
+ fail_if: "debug && debug.processingTime > 60000 && errorIssues > 0"
84
100
 
85
- # Schema and group combinations
86
- review_blocking_issues: "metadata.schema == 'code-review' && metadata.group == 'review' && metadata.criticalIssues > 0"
101
+ auth-check:
102
+ type: ai
103
+ prompt: "Check authentication code..."
104
+ # File-specific security checks with counting
105
+ fail_if: "hasFileWith(issues, 'auth') && countIssues(issues, 'severity', 'critical') > 0"
87
106
 
88
- # Time-based conditions (if debug info is available)
89
- slow_analysis_with_errors: "debug && debug.processingTime > 60000 && metadata.errorIssues > 0"
107
+ security-count:
108
+ type: ai
109
+ prompt: "Security analysis..."
110
+ # Count-based conditions
111
+ fail_if: "countIssues(issues, 'category', 'security') >= 3"
112
+ ```
90
113
 
91
- # File-specific security checks
92
- sensitive_file_changes: "hasFileWith(issues, 'auth') || hasFileWith(issues, 'password') || hasFileWith(issues, 'secret')"
114
+ ## Available Context Variables
115
+
116
+ ### Primary Context
117
+
118
+ | Variable | Description |
119
+ |----------|-------------|
120
+ | `output` | Current step's structured output (includes `issues` and provider-specific fields) |
121
+ | `outputs` | Map of dependency outputs keyed by step name |
122
+ | `memory` | Memory store accessor (see [Memory](./memory.md)) |
123
+ | `inputs` | Workflow inputs (for workflows) |
124
+ | `env` | Environment variables |
125
+ | `debug` | Debug information (`errors`, `processingTime`, `provider`, `model`) |
126
+
127
+ ### Legacy Context (Backward Compatibility)
128
+
129
+ | Variable | Description |
130
+ |----------|-------------|
131
+ | `issues` | Shorthand for `output.issues` |
132
+ | `criticalIssues` | Count of critical severity issues |
133
+ | `errorIssues` | Count of error severity issues |
134
+ | `warningIssues` | Count of warning severity issues |
135
+ | `infoIssues` | Count of info severity issues |
136
+ | `totalIssues` | Total issue count |
137
+ | `metadata` | Object with `checkName`, `schema`, `group`, issue counts, etc. |
138
+
139
+ ### Additional Context for `if` Conditions
140
+
141
+ | Variable | Description |
142
+ |----------|-------------|
143
+ | `branch` | Current branch name |
144
+ | `baseBranch` | Target branch (default: `main`) |
145
+ | `filesChanged` | Array of changed file paths |
146
+ | `filesCount` | Number of changed files |
147
+ | `event` | GitHub event context (`event_name`, `action`, `repository`, etc.) |
148
+ | `checkName` | Current check name |
149
+ | `schema` | Check schema |
150
+ | `group` | Check group |
151
+
152
+ ## Available Helper Functions
153
+
154
+ ### String Helpers
155
+
156
+ | Function | Description |
157
+ |----------|-------------|
158
+ | `contains(haystack, needle)` | Case-insensitive substring check |
159
+ | `startsWith(s, prefix)` | Case-insensitive prefix check |
160
+ | `endsWith(s, suffix)` | Case-insensitive suffix check |
161
+ | `length(x)` | Length of string, array, or object keys |
162
+
163
+ ### Control Helpers
164
+
165
+ | Function | Description |
166
+ |----------|-------------|
167
+ | `always()` | Always returns `true` |
168
+ | `success()` | Returns `true` |
169
+ | `failure()` | Returns `false` |
170
+
171
+ ### Issue/File Matching Helpers
172
+
173
+ | Function | Description |
174
+ |----------|-------------|
175
+ | `hasIssue(issues, field, value)` | Check if any issue has a field matching value |
176
+ | `countIssues(issues, field, value)` | Count issues matching field/value |
177
+ | `hasFileMatching(issues, pattern)` | Check if any issue affects a file matching pattern |
178
+ | `hasIssueWith(issues, field, value)` | Alias for `hasIssue` |
179
+ | `hasFileWith(issues, pattern)` | Alias for `hasFileMatching` |
180
+
181
+ ### Permission Helpers
182
+
183
+ | Function | Description |
184
+ |----------|-------------|
185
+ | `hasMinPermission(level)` | Check if author has at least the specified permission level |
186
+ | `isOwner()` | Check if author is repository owner |
187
+ | `isMember()` | Check if author is organization member |
188
+ | `isCollaborator()` | Check if author is collaborator |
189
+ | `isContributor()` | Check if author has contributed before |
190
+ | `isFirstTimer()` | Check if author is a first-time contributor |
191
+
192
+ ### Debugging
193
+
194
+ | Function | Description |
195
+ |----------|-------------|
196
+ | `log(...args)` | Print debug output prefixed with emoji (see [Debugging Guide](./debugging.md)) |
93
197
 
94
- # Count-based conditions
95
- multiple_security_issues: "countIssues(issues, 'category', 'security') >= 3"
198
+ ## Configuration Priority and Inheritance
96
199
 
97
- # Combined conditions
98
- critical_auth_issues: "hasFileWith(issues, 'auth') && countIssues(issues, 'severity', 'critical') > 0"
99
- ```
200
+ 1. **Step-specific conditions** override global conditions with the same name
201
+ 2. **Global conditions** apply to all steps unless specifically overridden
202
+ 3. **Multiple conditions** are evaluated independently - any true condition triggers a failure
100
203
 
101
- ## Configuration Priority and Inheritance
204
+ ## Interaction with Criticality
205
+
206
+ Failure conditions (`fail_if`) and design-by-contract (`assume`, `guarantee`) work together with criticality:
207
+
208
+ - **Critical steps** (external/control-plane/policy):
209
+ - Require meaningful `assume` and `guarantee`.
210
+ - `continue_on_failure: false` by default; dependents skip when this step fails.
211
+ - Retries only for transient provider faults; no auto-retry for logical failures (`fail_if`/`guarantee`).
212
+ - **Non-critical steps**:
213
+ - Contracts recommended; may allow `continue_on_failure: true`.
214
+ - Same retry bounds; tolerant gating.
102
215
 
103
- 1. **Check-specific conditions** override global conditions with the same name
104
- 2. **Global conditions** apply to all checks unless specifically overridden
105
- 3. **Built-in conditions** (if any) have the lowest priority
106
- 4. **Multiple conditions** are evaluated independently - any true condition triggers a failure
216
+ See [Fault Management and Contracts](./guides/fault-management-and-contracts.md) for the full policy checklist and examples.
107
217
 
108
218
  ## Backward Compatibility
109
219
 
110
- The enhanced system maintains full backward compatibility:
220
+ The system maintains full backward compatibility with both `fail_if` and `failure_conditions`:
111
221
 
112
222
  ```yaml
113
- # Legacy format (still supported)
223
+ # Simple fail_if (recommended)
114
224
  version: "1.0"
225
+ fail_if: "criticalIssues > 0"
226
+
115
227
  steps:
116
228
  security:
117
229
  type: ai
@@ -119,11 +231,15 @@ steps:
119
231
  on:
120
232
  - pr_opened
121
233
  - pr_updated
234
+ fail_if: "errorIssues >= 1"
122
235
 
123
- # Enhanced format with failure conditions
236
+ # Legacy failure_conditions (still supported)
124
237
  version: "1.0"
125
238
  failure_conditions:
126
- default_critical: "metadata.criticalIssues > 0"
239
+ default_critical:
240
+ condition: "criticalIssues > 0"
241
+ message: "Critical issues found"
242
+ severity: error
127
243
 
128
244
  steps:
129
245
  security:
@@ -132,42 +248,82 @@ steps:
132
248
  on:
133
249
  - pr_opened
134
250
  - pr_updated
251
+ failure_conditions:
252
+ security_specific: "errorIssues >= 1"
253
+ ```
135
254
 
136
- ## Interaction with Criticality
255
+ ## Migration Guide
137
256
 
138
- Failure conditions (`fail_if`) and design‑by‑contract (`assume`, `guarantee`) work together with criticality:
257
+ ### Migrating from `failure_conditions` to `fail_if`
139
258
 
140
- - Critical steps (external/control‑plane/policy):
141
- - Require meaningful `assume` and `guarantee`.
142
- - `continue_on_failure: false` by default; dependents skip when this step fails.
143
- - Retries only for transient provider faults; no auto‑retry for logical failures (`fail_if`/`guarantee`).
144
- - Non‑critical steps:
145
- - Contracts recommended; may allow `continue_on_failure: true`.
146
- - Same retry bounds; tolerant gating.
259
+ If you have existing `failure_conditions` configurations, migrate them to `fail_if`:
147
260
 
148
- See docs/guides/fault-management-and-contracts.md for the full policy checklist and examples.
149
- failure_conditions:
150
- security_specific: "metadata.errorIssues >= 1"
261
+ **Before (legacy):**
262
+ ```yaml
263
+ failure_conditions:
264
+ critical_blocker:
265
+ condition: "metadata.criticalIssues > 0"
266
+ message: "Critical issues found"
267
+ severity: error
268
+ quality_gate:
269
+ condition: "metadata.totalIssues > 10"
270
+ severity: warning
151
271
  ```
152
272
 
153
- ## Migration Guide
273
+ **After (recommended):**
274
+ ```yaml
275
+ # Simple condition - just use fail_if
276
+ fail_if: "criticalIssues > 0 || totalIssues > 10"
277
+ ```
154
278
 
155
- ### Step 1: Add Global Conditions
279
+ If you need the `halt_execution` feature, keep using the complex form:
156
280
  ```yaml
157
- # Add to existing configuration
158
281
  failure_conditions:
159
- critical_blocker: "metadata.criticalIssues > 0"
160
- quality_gate: "metadata.totalIssues > 10"
282
+ critical_blocker:
283
+ condition: "criticalIssues > 0"
284
+ message: "Critical issues found"
285
+ severity: error
286
+ halt_execution: true
287
+ ```
288
+
289
+ ### Step-by-Step Migration
290
+
291
+ 1. Replace `metadata.criticalIssues` with `criticalIssues` (legacy variables still work)
292
+ 2. Replace `hasIssueWith` with `hasIssue` (both work, but `hasIssue` is clearer)
293
+ 3. Use `fail_if` string instead of `failure_conditions` object when possible
294
+ 4. Test with `--debug` flag to verify expressions evaluate correctly
295
+
296
+ ### Testing Your Conditions
297
+
298
+ Use debug mode to test conditions and refine expressions:
299
+
300
+ ```bash
301
+ visor --config your-config.yaml --debug
161
302
  ```
162
303
 
163
- ### Step 2: Add Check-Specific Conditions
304
+ You can also use the `log()` helper in expressions:
164
305
  ```yaml
165
- steps:
166
- security:
167
- # existing configuration...
168
- failure_conditions:
169
- security_gate: "metadata.errorIssues >= 1"
306
+ fail_if: |
307
+ log("Issues:", issues);
308
+ log("Critical count:", criticalIssues);
309
+ criticalIssues > 0
170
310
  ```
171
311
 
172
- ### Step 3: Test and Refine
173
- Use debug mode to test conditions and refine expressions based on actual results.
312
+ ## Complex Failure Condition Options
313
+
314
+ When using the object syntax, these options are available:
315
+
316
+ | Option | Type | Default | Description |
317
+ |--------|------|---------|-------------|
318
+ | `condition` | string | required | JavaScript expression to evaluate |
319
+ | `message` | string | - | Human-readable message when condition triggers |
320
+ | `severity` | string | `"error"` | Severity level: `error`, `warning`, or `info` |
321
+ | `halt_execution` | boolean | `false` | If `true`, stops all workflow execution immediately |
322
+
323
+ ## Related Documentation
324
+
325
+ - [Fail If](./fail-if.md) - Recommended simple syntax for failure conditions
326
+ - [Author Permissions](./author-permissions.md) - Permission helper functions
327
+ - [Debugging Guide](./debugging.md) - Using `log()` and debugging techniques
328
+ - [Memory](./memory.md) - Memory store access in expressions
329
+ - [Fault Management and Contracts](./guides/fault-management-and-contracts.md) - Criticality and contracts