@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
@@ -179,16 +179,15 @@ Quick reference:
179
179
  - `role_map: 'step=role,other=role'` as a compact override
180
180
 
181
181
  See also:
182
- - `docs/human-input-provider.md`
183
- - `docs/liquid-templates.md` (Chat History Helper)
184
- - `docs/output-history.md`
185
- - `examples/slack-simple-chat.yaml`
182
+ - [human-input-provider.md](./human-input-provider.md)
183
+ - [liquid-templates.md](./liquid-templates.md) (Chat History Helper)
184
+ - [output-history.md](./output-history.md)
185
+ - [examples/slack-simple-chat.yaml](../examples/slack-simple-chat.yaml)
186
186
 
187
187
  ### Advanced routing & contracts (general patterns)
188
188
 
189
189
  #### Inner loops vs. closing the loop
190
190
 
191
- - **Close the loop**: Leaf steps use `on_success: goto: <entry-step>` to end the workflow and return to a single top-level `human-input`. Each new event (Slack message, webhook, CLI run) starts a fresh execution.
192
191
  - **Close the loop**: Leaf steps use `on_success: goto: <entry-step>` to end the workflow and return to a single top-level `human-input`. Each new event (Slack message, webhook, CLI run) starts a fresh execution.
193
192
  - **Inner loop**: Add a local `human-input` and route inside a sub‑flow:
194
193
  - Example shape: `router → section-confirm → section-answer → section-confirm`.
@@ -208,7 +207,7 @@ See also:
208
207
  to: project-intent
209
208
  ```
210
209
  - Reserve `goto_js` / `run_js` for legacy or very dynamic use cases.
211
- - More details: `docs/guides/fault-management-and-contracts.md`, `docs/loop-routing-refactor.md`.
210
+ - More details: [fault-management-and-contracts.md](./guides/fault-management-and-contracts.md), [loop-routing-refactor.md](./loop-routing-refactor.md).
212
211
 
213
212
  - Pattern A — central router + transitions (explicit routing):
214
213
  - Use a single “router” step that sets control fields (e.g. `output.intent`, `output.kind`).
@@ -281,7 +280,7 @@ See also:
281
280
  - Use `assume` for preconditions about upstream state (memory, env, `outputs[...]`).
282
281
  - Use `guarantee` for postconditions about this step’s own output (shape, control flags, size caps).
283
282
  - For `info` steps, contracts are recommended but optional; keep `assume` + `guarantee` adjacent when present.
284
- - More details: `docs/guides/criticality-modes.md`, `docs/guides/fault-management-and-contracts.md`.
283
+ - More details: [criticality-modes.md](./guides/criticality-modes.md), [fault-management-and-contracts.md](./guides/fault-management-and-contracts.md).
285
284
 
286
285
  #### JSON Schemas instead of `schema: plain`
287
286
 
@@ -469,6 +468,6 @@ The real error messages and responses help identify whether the issue is with yo
469
468
 
470
469
  ### More examples
471
470
 
472
- - `docs/NPM_USAGE.md` – CLI usage and flags
473
- - `GITHUB_CHECKS.md` – Checks, outputs, and workflow integration
471
+ - [docs/NPM_USAGE.md](./NPM_USAGE.md) – CLI usage and flags
472
+ - [docs/GITHUB_CHECKS.md](./GITHUB_CHECKS.md) – Checks, outputs, and workflow integration
474
473
  - `examples/` – MCP, Jira, and advanced configs
@@ -1,7 +1,9 @@
1
1
  # RFC: Git Checkout Step Provider
2
2
 
3
3
  ## Status
4
- **Accepted** - Implementation in progress
4
+ **Implemented** - Feature is complete and available for use
5
+
6
+ See [Git Checkout Provider Documentation](/docs/providers/git-checkout.md) for usage instructions.
5
7
 
6
8
  ### Decision Record
7
9
  - **Date**: 2025-11-21
@@ -1,9 +1,20 @@
1
1
  # RFC: `on_init` Lifecycle Hook for Context Preprocessing
2
2
 
3
- **Status:** Proposal
3
+ **Status:** Implemented
4
4
  **Author:** Visor Team
5
5
  **Created:** 2024-01-XX
6
- **Updated:** 2024-01-XX
6
+ **Updated:** 2025-01-28
7
+
8
+ ---
9
+
10
+ ## Implementation Notes
11
+
12
+ This RFC has been implemented. Key implementation files:
13
+ - Type definitions: `src/types/config.ts` (OnInitConfig, OnInitToolInvocation, etc.)
14
+ - Handler implementation: `src/state-machine/dispatch/on-init-handlers.ts`
15
+ - Integration with execution: `src/state-machine/dispatch/execution-invoker.ts`
16
+ - Tests: `tests/integration/on-init-flow.test.ts`
17
+ - Example: `examples/on-init-import-demo.yaml`
7
18
 
8
19
  ---
9
20
 
@@ -1204,11 +1215,13 @@ on_init:
1204
1215
 
1205
1216
  ## 13. References
1206
1217
 
1207
- - [Existing `on_success` implementation](src/state-machine/states/routing.ts#599)
1208
- - [Existing `on_fail` implementation](src/state-machine/states/routing.ts#816)
1209
- - [Existing `on_finish` implementation](src/state-machine/states/routing.ts#231)
1218
+ - [Existing `on_success` implementation](src/state-machine/states/routing.ts) (search for `Process on_success routing`)
1219
+ - [Existing `on_fail` implementation](src/state-machine/states/routing.ts) (search for `Process on_fail routing`)
1220
+ - [Existing `on_finish` implementation](src/state-machine/states/routing.ts) (search for `Process on_finish routing`)
1210
1221
  - [Workflow provider](src/providers/workflow-check-provider.ts)
1211
1222
  - [Custom tool executor](src/providers/custom-tool-executor.ts)
1223
+ - [on_init handler implementation](src/state-machine/dispatch/on-init-handlers.ts)
1224
+ - [on_init type definitions](src/types/config.ts) (search for `OnInitConfig`)
1212
1225
 
1213
1226
  ---
1214
1227
 
@@ -1,5 +1,21 @@
1
1
  # Isolated Workspace with Full Run Separation
2
2
 
3
+ ## Status
4
+ **Implemented** - Feature is complete and available for use
5
+
6
+ ### Decision Record
7
+ - **Date**: 2025 (exact date not recorded)
8
+ - **Decision**: Implement isolated workspaces using git worktrees in `/tmp`
9
+ - **Rationale**: Provides full isolation between parallel visor runs, avoids git-in-git issues, and enables human-readable project paths within the workspace
10
+
11
+ ### Implementation Files
12
+ - `src/utils/workspace-manager.ts` - Core WorkspaceManager class
13
+ - `src/state-machine/context/build-engine-context.ts` - Workspace initialization via `initializeWorkspace()`
14
+ - `src/providers/git-checkout-provider.ts` - Integration to add projects to workspace
15
+ - `src/types/engine.ts` - Added `workspace` and `originalWorkingDirectory` to EngineContext
16
+ - `src/types/git-checkout.ts` - Added `workspace_path` to GitCheckoutOutput
17
+ - `tests/unit/workspace-manager.test.ts` - Unit tests
18
+
3
19
  ## Goal
4
20
 
5
21
  Provide **full isolation between parallel visor runs** with human-readable project names. Each run gets its own workspace in `/tmp` containing worktrees for all projects, ensuring no interference between concurrent executions.
@@ -1,33 +1,33 @@
1
1
  # Criticality & Contracts — Implementation Tasks (Do‑It‑Right)
2
2
 
3
- This file lists the remaining engineering tasks to fully implement the criticality model, contracts, and transitions as documented. Items are grouped and check‑listable. (optional) items can be phased in later.
3
+ This file lists the remaining engineering tasks to fully implement the criticality model, contracts, and transitions as documented. Items are grouped and check‑listable. "(optional)" items can be phased in later.
4
4
 
5
5
  ## 1) Schema & Types
6
- - [ ] Add `criticality` field to `CheckConfig` (`external | internal | policy | info`).
6
+ - [x] Add `criticality` field to `CheckConfig` (`external | internal | policy | info`).
7
7
  - [ ] (optional) Add `assume_mode: 'skip' | 'fail'` to control unmet preconditions handling.
8
8
  - [ ] (optional) Add `retry_on: ['transient'] | ['transient','logical']` to narrow retry classes.
9
- - [ ] Update JSON schema generator and `src/generated/config-schema.ts`.
10
- - [ ] Update TypeScript types (`src/types/config.ts`, SDK exports).
9
+ - [x] Update JSON schema generator and `src/generated/config-schema.ts`.
10
+ - [x] Update TypeScript types (`src/types/config.ts`, SDK exports).
11
11
 
12
12
  ## 2) Config Validation & Linting
13
- - [ ] Validator: warn when `criticality` omitted on mutating providers (external inference) or forEach parents (control‑plane inference).
14
- - [ ] Validator: warn when critical steps lack `assume`/`guarantee`.
15
- - [ ] Validator: warn when `assume` references this steps own `output`.
13
+ - [x] Validator: warn when `criticality` omitted on mutating providers (external inference) or forEach parents (control‑plane inference).
14
+ - [x] Validator: warn when critical steps lack `assume`/`guarantee`.
15
+ - [ ] Validator: warn when `assume` references this step's own `output`.
16
16
  - [ ] Validator: warn when `guarantee` contains policy thresholds better modeled as `fail_if`.
17
17
  - [ ] Validator: ensure `transitions[].to` targets exist (or null) and expressions compile.
18
18
 
19
19
  ## 3) Engine Policy Mapping
20
- - [ ] Derive defaults from `criticality` at load time (but allow per‑check overrides):
20
+ - [x] Derive defaults from `criticality` at load time (but allow per‑check overrides):
21
21
  - external/control‑plane/policy: `continue_on_failure=false`, retries transient‑only (max 2–3), loop budgets tighter (e.g., 8), contracts required.
22
22
  - non‑critical: contracts optional, `continue_on_failure` may be true, default loop budget 10, retries standard.
23
- - [ ] Enforce no auto‑retry for logical failures in critical modes (fail_if/guarantee violations).
23
+ - [x] Enforce "no auto‑retry for logical failures" in critical modes (fail_if/guarantee violations).
24
24
  - [ ] (optional) Per‑criticality loop budget override (e.g., control‑plane default 8).
25
25
 
26
26
  ## 4) Runtime Semantics (clarity & safety)
27
- - [ ] Ensure `assume` is evaluated pre‑exec (no access to this steps `output`), with clear error messaging.
28
- - [ ] Ensure `guarantee` is evaluated post‑exec, with issues emitted as `contract/guarantee_failed`.
29
- - [ ] Keep expressions sandboxed, pure, and short‑timed; log evaluation errors as fail‑secure decisions.
30
- - [ ] Transitions precedence over `goto_js` when both present; loop budget enforcement per scope.
27
+ - [x] Ensure `assume` is evaluated pre‑exec (no access to this step's `output`), with clear error messaging.
28
+ - [x] Ensure `guarantee` is evaluated post‑exec, with issues emitted as `contract/guarantee_failed`.
29
+ - [x] Keep expressions sandboxed, pure, and short‑timed; log evaluation errors as fail‑secure decisions.
30
+ - [x] Transitions precedence over `goto_js` when both present; loop budget enforcement per scope.
31
31
  - [ ] (optional) forEach per‑item concurrency with default 1; cap via config.
32
32
 
33
33
  ## 5) Side‑Effect Classification
@@ -45,33 +45,33 @@ This file lists the remaining engineering tasks to fully implement the criticali
45
45
  - [ ] Journal: ensure all contract/transition decisions and expressions are captured with scope/timestamps.
46
46
 
47
47
  ## 8) Persistence
48
- - [ ] Keep JSON snapshot export (done) and add (optional) debug‑resume path gated by a debug flag.
48
+ - [x] Keep JSON snapshot export (done) and add (optional) debug‑resume path gated by a debug flag.
49
49
 
50
50
  ## 9) Defaults & Examples
51
- - [ ] Update `defaults/visor.yaml` (and any bundled defaults) to declare `criticality` for relevant checks and prefer `transitions` over `goto_js` where applicable.
52
- - [ ] Update `defaults/task-refinement.yaml` and `defaults/agent-builder.yaml` to use `criticality` and transitions where appropriate; ensure no `assume` refers to own output.
51
+ - [x] Update `defaults/visor.yaml` (and any bundled defaults) to declare `criticality` for relevant checks and prefer `transitions` over `goto_js` where applicable.
52
+ - [x] Update `defaults/task-refinement.yaml` and `defaults/workflow-builder.yaml` to use `criticality` and transitions where appropriate; ensure no `assume` refers to own output.
53
53
  - [ ] Convert inline YAML arrays in defaults to block‑style lists for consistency.
54
54
  - [ ] Add an annotated example block with all primitives (if, assume, guarantee, fail_if, transitions) and modes (reference the guides) in the defaults or examples folder.
55
55
  - [ ] Verify defaults run green via dist CLI:
56
56
  - `npm run build:cli`
57
57
  - `node dist/index.js test defaults/visor.tests.yaml --progress compact`
58
- - Any other default suites (`task-refinement`, `agent-builder`) if present.
58
+ - Any other default suites (`task-refinement`, `workflow-builder`) if present.
59
59
 
60
60
  ## 10) Tests
61
- - [ ] Unit (engine/native):
61
+ - [x] Unit (engine/native):
62
62
  - `assume` skip vs guard‑step hard‑fail (no provider call on skip).
63
63
  - `guarantee` violation adds `contract/guarantee_failed` and does not double‑execute provider.
64
64
  - Transitions precedence over `goto_js`; undefined transition falls back to `goto`.
65
65
  - Loop budget enforcement per scope (error surfaced; routing halts in that scope).
66
66
  - Criticality policy mapping (external/control‑plane/policy/non‑critical) sets defaults (gating, retries, budgets).
67
- - [ ] Integration:
67
+ - [x] Integration:
68
68
  - Critical external step blocks downstream mutating side‑effects on contract/fail_if failure (dependents gated).
69
69
  - Control‑plane forEach parent respects tighter loop budget; no oscillation beyond cap.
70
70
  - Retry classifier: transient provider errors retried; logical (fail_if/guarantee) not auto‑retried in critical modes.
71
71
  - Non‑critical step with `continue_on_failure: true` does not block pipeline.
72
72
  - [ ] YAML e2e / Defaults:
73
73
  - `defaults/visor.yaml` flow passes using transitions.
74
- - `defaults/task-refinement.yaml` and `defaults/agent-builder.yaml` pass with `criticality` declared.
74
+ - `defaults/task-refinement.yaml` and `defaults/workflow-builder.yaml` pass with `criticality` declared.
75
75
  - Add a strict safety profile scenario (e.g., `safety: strict`) and ensure it passes.
76
76
  - [ ] CI Gates:
77
77
  - Add a job to build CLI and run default YAML suites with `--progress compact`.
@@ -79,14 +79,14 @@ This file lists the remaining engineering tasks to fully implement the criticali
79
79
 
80
80
  ## 11) Docs (remaining polish)
81
81
  - [ ] README or landing page: link to Criticality Modes and Fault Management guides.
82
- - [ ] Ensure quick‑starts show `criticality` in at least one example (SDK & CLI done).
82
+ - [x] Ensure quick‑starts show `criticality` in at least one example (SDK & CLI done).
83
83
  - [ ] Sweep older docs for inline arrays (`[a, b]`) and convert to block lists.
84
- - [ ] Add assume vs guarantee — dos and donts callout in any doc that introduces contracts (done for two guides).
84
+ - [x] Add "assume vs guarantee — do's and don'ts" callout in any doc that introduces contracts (done for two guides).
85
85
 
86
86
  ## Acceptance Criteria
87
- - [ ] All tests pass (unit/integration/YAML) with representative critical/non‑critical mixes.
88
- - [ ] Config validator warns on unsafe/missing contracts and mis‑declared criticality.
89
- - [ ] Engine enforces defaults per `criticality` while allowing explicit overrides.
90
- - [ ] Logs have timestamps; debug gated; decisions visible in journal and metrics.
87
+ - [x] All tests pass (unit/integration/YAML) with representative critical/non‑critical mixes.
88
+ - [x] Config validator warns on unsafe/missing contracts and mis‑declared criticality.
89
+ - [x] Engine enforces defaults per `criticality` while allowing explicit overrides.
90
+ - [x] Logs have timestamps; debug gated; decisions visible in journal and metrics.
91
91
  - [ ] No dist/ artifacts in commits.
92
- - [ ] Updated defaults (`defaults/visor.yaml`, `defaults/task-refinement.yaml`, `defaults/agent-builder.yaml`) run green via dist CLI in CI.
92
+ - [ ] Updated defaults (`defaults/visor.yaml`, `defaults/task-refinement.yaml`, `defaults/workflow-builder.yaml`) run green via dist CLI in CI.
@@ -71,19 +71,25 @@ Here, the router (`route-intent`) is connected to the branch (`capabilities-answ
71
71
  - as a data dependency: `capabilities-answer.depends_on: [route-intent]`
72
72
  - as a control‑flow source: `route-intent.on_success.transitions → capabilities-answer`
73
73
 
74
- ### Why this is a problem
74
+ ### Why this can be a problem
75
75
 
76
76
  When `route-intent` finishes, `transitions` fire and emit a `ForwardRunRequested(target='capabilities-answer')`.
77
77
 
78
78
  WavePlanning then:
79
79
 
80
80
  1. Builds the forward‑run subset starting from the target.
81
- 2. Adds **all transitive dependencies** of that target via `depends_on`.
81
+ 2. Adds transitive dependencies of that target via `depends_on`.
82
82
  - `capabilities-answer.depends_on: [route-intent]`
83
83
  - `route-intent.depends_on: [ask]`
84
- 3. Schedules a wave that re‑runs `route-intent` (and `ask`), then `capabilities-answer`.
84
+ 3. **However**, the engine now skips re‑running dependencies that have already succeeded in the current run.
85
85
 
86
- Each time `route-intent` reruns, its `transitions` fire again, enqueueing another forward‑run to `capabilities-answer`, which again pulls `route-intent` in as a dependency. This repeats until `routing.max_loops` is hit.
86
+ **Note**: The engine's forwardrun planner was updated to deduplicate successful runs. Dependencies that have `successfulRuns > 0` are not re‑scheduled. This means the "double‑edge" pattern no longer causes runaway loops in most cases.
87
+
88
+ **When it still matters**:
89
+
90
+ - **Explicit loops via `goto`**: When a leaf step uses `goto: ask`, that *is* an intentional re‑run. The router will execute again on each loop iteration, which is expected behavior controlled by `routing.max_loops`.
91
+ - **Failed dependencies**: If a dependency failed (not succeeded), it will be re‑run. This can cause unexpected behavior if the failure was intentional.
92
+ - **Clarity**: Even though the engine handles deduplication, having both `depends_on` and `transitions` edges to the same step creates conceptual ambiguity about intent.
87
93
 
88
94
  **Symptoms:**
89
95
 
@@ -101,9 +107,9 @@ This is exactly the pattern we saw in the Slack org‑assistant flow when:
101
107
 
102
108
  ---
103
109
 
104
- ## Recommended pattern: router as pure control‑plane
110
+ ## Recommended patterns
105
111
 
106
- ### Core idea
112
+ ### Pattern A: Router as pure control‑plane (no branch dependencies)
107
113
 
108
114
  Treat router checks as **control‑plane only**:
109
115
 
@@ -112,9 +118,29 @@ Treat router checks as **control‑plane only**:
112
118
  - Uses `on_success.transitions` to select branches.
113
119
  - Branches:
114
120
  - **Do not** `depends_on` the router.
115
- - Instead, they **read** the routers output from `outputs['router']` and gate with `if` / `assume`.
121
+ - Instead, they **read** the router's output from `outputs['router']` and gate with `if` / `assume`.
122
+
123
+ This pattern avoids any ambiguity about the relationship between router and branches.
124
+
125
+ ### Pattern B: Router with branch dependencies (common pattern)
126
+
127
+ In practice, many workflows use `depends_on` on branches to ensure ordering and data access:
128
+
129
+ - Router:
130
+ - `depends_on` its true *inputs* (e.g. `ask`, context fetch steps).
131
+ - Uses `on_success.transitions` to select branches.
132
+ - Branches:
133
+ - **Do** `depends_on: [router]` for explicit ordering.
134
+ - Also use `if` guards to skip when not selected.
116
135
 
117
- This gives a clean, acyclic structure:
136
+ This pattern is safe because the engine's forward‑run planner skips re‑running dependencies that already succeeded. See `examples/slack-simple-chat.yaml` for a working implementation.
137
+
138
+ ### Choosing between patterns
139
+
140
+ - **Pattern A** is cleaner when branches don't actually need router output (pure control‑flow).
141
+ - **Pattern B** is more explicit and is the common pattern in real workflows where branches need access to router fields like `output.intent` or `output.project`.
142
+
143
+ #### Example: Pattern A (no branch dependencies)
118
144
 
119
145
  ```yaml
120
146
  ask:
@@ -125,9 +151,6 @@ route-intent:
125
151
  type: ai
126
152
  group: chat
127
153
  depends_on: [ask]
128
- ai:
129
- disableTools: true
130
- allowedTools: []
131
154
  schema:
132
155
  type: object
133
156
  properties:
@@ -147,9 +170,6 @@ capabilities-answer:
147
170
  group: chat
148
171
  # no depends_on: [route-intent]
149
172
  if: "outputs['route-intent']?.intent === 'capabilities'"
150
- ai:
151
- disableTools: true
152
- allowedTools: []
153
173
  prompt: |
154
174
  Explain briefly what you can help with.
155
175
  on_success:
@@ -167,19 +187,67 @@ chat-answer:
167
187
  goto: ask
168
188
  ```
169
189
 
170
- **Engine behavior:**
190
+ #### Example: Pattern B (with branch dependencies)
191
+
192
+ This is the pattern used in `examples/slack-simple-chat.yaml`:
193
+
194
+ ```yaml
195
+ ask:
196
+ type: human-input
197
+ group: chat
198
+
199
+ route-intent:
200
+ type: ai
201
+ group: chat
202
+ depends_on: [ask]
203
+ schema:
204
+ type: object
205
+ properties:
206
+ intent:
207
+ type: string
208
+ enum: [chat, capabilities]
209
+ required: [intent]
210
+ on_success:
211
+ transitions:
212
+ - when: "output.intent === 'capabilities'"
213
+ to: capabilities-answer
214
+ - when: "output.intent === 'chat'"
215
+ to: chat-answer
216
+
217
+ capabilities-answer:
218
+ type: ai
219
+ group: chat
220
+ depends_on: [route-intent] # explicit dependency
221
+ if: "outputs['route-intent']?.intent === 'capabilities'"
222
+ prompt: |
223
+ Explain briefly what you can help with.
224
+ on_success:
225
+ goto: ask
226
+
227
+ chat-answer:
228
+ type: ai
229
+ group: chat
230
+ depends_on: [route-intent] # explicit dependency
231
+ if: "outputs['route-intent']?.intent === 'chat'"
232
+ prompt: |
233
+ You are a concise, friendly assistant.
234
+ Latest user message: {{ outputs['ask'].text }}
235
+ on_success:
236
+ goto: ask
237
+ ```
238
+
239
+ **Engine behavior (both patterns):**
171
240
 
172
241
  - Initial wave:
173
242
  - DAG: `ask` → `route-intent`
174
243
  - Router runs once, then emits transitions.
175
244
  - Forward‑run for `capabilities-answer`:
176
- - Only includes the branch and any *real* dependencies the branch declares (e.g. context fetch, project status).
177
- - Does **not** pull `route-intent` back in, because the branch no longer `depends_on` it.
245
+ - In Pattern A: Only the branch runs (no dependencies to pull in).
246
+ - In Pattern B: The branch depends on `route-intent`, but since it already succeeded, it is **not** re‑run.
178
247
  - Loops:
179
248
  - `capabilities-answer` closing to `ask` via `goto: ask` is explicit and controlled.
180
- - Router still runs once per loop cycle (when `ask` completes), but is not re‑run just because the branch was targeted by a transition.
181
-
182
- This pattern avoids the “router as both dependency and transition source” cycle that caused loops in Slack.
249
+ - Router runs once per loop cycle (when `ask` completes and flows to `route-intent`).
250
+ - Loop count is controlled by `routing.max_loops`.
183
251
 
184
252
  ---
185
253
 
@@ -207,7 +275,9 @@ project-status-answer:
207
275
 
208
276
  ### Use `transitions` / `goto` for control‑flow
209
277
 
210
- Examples:
278
+ There are three routing hooks: `on_success`, `on_fail`, and `on_finish`.
279
+
280
+ **`on_success`** — Fires when the check completes without fatal issues:
211
281
 
212
282
  ```yaml
213
283
  route-intent:
@@ -229,8 +299,33 @@ project-deploy-answer:
229
299
  to: project-deploy-confirm
230
300
  ```
231
301
 
232
- - Router edges are expressed only via `transitions`.
233
- - Inner “deployment helper” loop is controlled by transitions on `done`.
302
+ **`on_fail`** Fires when the check fails (fatal issues or `fail_if` triggered):
303
+
304
+ ```yaml
305
+ validate-input:
306
+ type: ai
307
+ fail_if: "output.valid === false"
308
+ on_fail:
309
+ goto: ask # Loop back for retry
310
+ # or use transitions:
311
+ # transitions:
312
+ # - when: "output.error === 'auth'"
313
+ # to: auth-handler
314
+ ```
315
+
316
+ **`on_finish`** — Fires regardless of success/failure:
317
+
318
+ ```yaml
319
+ cleanup-step:
320
+ type: command
321
+ on_finish:
322
+ run: log-completion # Always run logging
323
+ ```
324
+
325
+ **`goto` vs `run`**:
326
+
327
+ - `goto`: Preempts remaining work and jumps to the target. Used for loops and error recovery.
328
+ - `run`: Schedules the target after current wave completes. Used for side-effects like logging.
234
329
 
235
330
  ### Use `if` and `assume` for semantics, not wiring
236
331
 
@@ -255,42 +350,44 @@ Guidelines:
255
350
 
256
351
  ---
257
352
 
258
- ## Migration: from router‑as‑dependency to router‑as‑control‑plane
353
+ ## Migration and testing best practices
259
354
 
260
- If you have existing workflows where:
355
+ ### When to migrate
261
356
 
262
- - router checks use `on_success.transitions`, and
263
- - branches also `depends_on` the router, and
264
- - leaf steps loop back via `goto: <entry-step>`,
357
+ If you have existing workflows with unexpected loop counts or router re‑runs, consider these options:
265
358
 
266
- then you’re in the “double‑edge” pattern and may hit the same kind of loops we saw in Slack.
359
+ 1. **Keep Pattern B** (branches depend on router) This is safe with the current engine. Just ensure you have:
360
+ - `if` guards on branches
361
+ - `routing.max_loops` set appropriately
362
+ - Test assertions for expected call counts
267
363
 
268
- ### Migration steps
364
+ 2. **Migrate to Pattern A** (branches don't depend on router) — This is cleaner if branches don't actually need router output.
269
365
 
270
- 1. **Identify router checks**
366
+ ### Migration steps (if needed)
367
+
368
+ 1. **Identify router checks**
271
369
  - Look for AI/script steps that:
272
370
  - read from a single human‑input or transport context, and
273
371
  - fan‑out into multiple branches via `transitions`.
274
372
 
275
- 2. **Remove router from branch `depends_on`**
373
+ 2. **Remove router from branch `depends_on`** (optional)
276
374
  - For each branch:
277
- - Remove `depends_on: [router]`.
375
+ - Remove `depends_on: [router]` if you don't need explicit ordering.
278
376
  - Keep other dependencies (e.g. context fetch, sub‑routers).
279
377
 
280
- 3. **Add `if` / `assume` guards on branches**
281
- - Replace router‑dependency semantics with guards:
378
+ 3. **Ensure `if` guards on branches**
379
+ - All branches should have guards regardless of pattern:
282
380
 
283
381
  ```yaml
284
382
  chat-answer:
285
- # was: depends_on: [route-intent]
286
383
  if: "outputs['route-intent']?.intent === 'chat'"
287
384
  ```
288
385
 
289
386
  4. **Keep explicit loops**
290
387
  - Leave `goto: ask` and inner loops (`project-deploy-confirm` ↔ `project-deploy-answer`) as they are.
291
- - The loop behavior remains explicit and is no longer entangled with router dependencies.
388
+ - The loop behavior is explicit and controlled by `routing.max_loops`.
292
389
 
293
- 5. **Increase `routing.max_loops` and add strict call expectations**
390
+ 5. **Add strict call expectations in tests**
294
391
  - In YAML tests, set a reasonable `routing.max_loops` (e.g. 5–10).
295
392
  - Assert `exactly` call counts for:
296
393
  - router(s),
@@ -328,12 +425,27 @@ Once most configs follow this pattern, engine‑level improvements (e.g. smarter
328
425
  - Use routers (`route-intent`, `project-intent`, …) as control‑plane steps:
329
426
  - `depends_on` only real inputs,
330
427
  - route with `transitions`.
331
- - Keep branches free of router `depends_on`; gate them with `if` / `assume`.
332
- - Use `depends_on` only for real data dependencies.
428
+ - Use `if` guards on branches to skip when not selected by the router.
429
+ - Use `depends_on` for real data dependencies (including router → branch when you need the router's output).
333
430
  - Use `goto`/`transitions` for loops and control‑flow.
431
+ - Set `routing.max_loops` and add strict call count expectations in tests.
432
+
433
+ - **Acceptable**:
434
+ - Having `depends_on: [router]` on branches when you need explicit ordering or access to router output — the engine deduplicates successful runs.
334
435
 
335
436
  - **Avoid**:
336
- - Wiring the same edge both via `depends_on` and `transitions`.
337
- - Using `assume` as a routing mechanism.
437
+ - Relying on implicit re‑runs of routers (use explicit `goto` for loops).
438
+ - Using `assume` as a routing mechanism (use `if` or `transitions` instead).
439
+
440
+ Following these patterns produces clearer configs, leverages the engine's forward‑run deduplication, and makes loop behavior explicit and testable.
441
+
442
+ ---
443
+
444
+ ## Related documentation
338
445
 
339
- Following this pattern produces clearer configs, avoids accidental router loops, and matches how the state‑machine’s forward‑run planner is intended to be used.***
446
+ - [Recipes](./recipes.md) General routing patterns and chat examples
447
+ - [Fault Management and Contracts](./guides/fault-management-and-contracts.md) — `assume`, `guarantee`, and criticality
448
+ - [Criticality Modes](./guides/criticality-modes.md) — When to use `internal`, `external`, `policy`, `info`
449
+ - [Loop Routing Refactor](./loop-routing-refactor.md) — Technical details on forward-run deduplication
450
+ - [Human Input Provider](./human-input-provider.md) — Chat loops and `human-input` type
451
+ - [Debugging Guide](./debugging.md) — Tracing routing decisions with OpenTelemetry
@@ -1,6 +1,6 @@
1
- ## 📋 Schema-Template System
1
+ ## Schema-Template System
2
2
 
3
- Visor pairs JSON Schemas (data shape) with Liquid templates (rendering) so outputs are predictable, auditable, and GitHubnative.
3
+ Visor pairs JSON Schemas (data shape) with Liquid templates (rendering) so outputs are predictable, auditable, and GitHub-native.
4
4
 
5
5
  ### Overview
6
6
  - Schema validates check output at runtime (via AJV)
@@ -20,16 +20,23 @@ steps:
20
20
  overview:
21
21
  type: ai
22
22
  group: summary
23
- schema: text
23
+ schema: overview
24
24
  prompt: "Summarize PR in markdown"
25
25
  ```
26
26
 
27
27
  ### Built-in Schemas
28
- - code-review: structured findings with severity, file, line → native annotations
29
- - text: free‑form markdown content (no annotations)
28
+
29
+ | Schema | Description | Output Structure |
30
+ |--------|-------------|------------------|
31
+ | `code-review` | Structured findings with severity, file, line | `{ issues: [...] }` with GitHub annotations |
32
+ | `plain` | Free-form markdown/text content | `{ content: "..." }` |
33
+ | `overview` | PR summary with optional metadata tags | `{ text: "...", tags: {...} }` |
34
+ | `issue-assistant` | Issue triage with intent classification | `{ text: "...", intent: "...", labels: [...] }` |
30
35
 
31
36
  ### Grouping
32
37
 
38
+ Checks with the same `group` value are consolidated into a single GitHub comment:
39
+
33
40
  ```yaml
34
41
  steps:
35
42
  security: { group: code-review }
@@ -38,31 +45,60 @@ steps:
38
45
  assistant: { group: dynamic } # always creates a new comment
39
46
  ```
40
47
 
48
+ The special `dynamic` group creates a unique comment for each execution.
49
+
41
50
  ### Custom Schemas
42
51
 
43
- ```yaml
44
- schemas:
45
- custom-metrics:
46
- file: ./schemas/metrics.json
52
+ You can use custom schemas in three ways:
47
53
 
54
+ **1. File path reference:**
55
+ ```yaml
48
56
  steps:
49
57
  metrics:
50
- schema: custom-metrics
58
+ schema: ./schemas/metrics.json
51
59
  group: metrics
52
60
  ```
53
61
 
62
+ **2. Inline JSON Schema object:**
63
+ ```yaml
64
+ steps:
65
+ custom-check:
66
+ schema:
67
+ type: object
68
+ required: [result]
69
+ properties:
70
+ result:
71
+ type: string
72
+ ```
73
+
74
+ **3. With custom template:**
75
+ ```yaml
76
+ steps:
77
+ metrics:
78
+ schema: ./schemas/metrics.json
79
+ template:
80
+ file: ./templates/metrics.liquid
81
+ # Or inline template content:
82
+ # template:
83
+ # content: "{{ output.result }}"
84
+ ```
85
+
54
86
  ### GitHub Checks API Compatibility
55
87
 
56
88
  For status checks and annotations, use structured output with `issues[]` having:
57
- - severity: critical | error | warning | info
58
- - file, line, message
89
+ - `severity`: `warning` | `error` | `critical`
90
+ - `file`: path relative to repository root
91
+ - `line`: line number (required)
92
+ - `message`: description of the issue
93
+
94
+ Optional fields: `endLine`, `ruleId`, `category`, `suggestion`, `replacement`.
59
95
 
60
- Unstructured (none/plain) posted as-is, no status checks.
96
+ Unstructured schemas (`plain`) are posted as-is without status check annotations.
61
97
 
62
98
  ### Enhanced Prompts
63
- - Smart autodetection, Liquid templating, filebased prompts
99
+ - Smart auto-detection, Liquid templating, file-based prompts
64
100
  - Template context: `pr`, `files`, `event`, `outputs`, `utils`
65
101
  - See [Liquid Templates Guide](./liquid-templates.md) for available variables and filters
66
102
 
67
- See full examples in `defaults/.visor.yaml`.
103
+ See full examples in `defaults/visor.yaml`.
68
104