@probelabs/visor 0.1.106 → 0.1.111
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.
- package/README.md +71 -2
- package/action.yml +1 -1
- package/defaults/code-refiner.yaml +114 -0
- package/defaults/{.visor.yaml → code-review.yaml} +35 -226
- package/defaults/override.yaml +52 -0
- package/defaults/task-refinement.yaml +624 -0
- package/defaults/visor.tests.yaml +685 -0
- package/defaults/visor.yaml +483 -0
- package/dist/action-cli-bridge.d.ts +11 -82
- package/dist/action-cli-bridge.d.ts.map +1 -1
- package/dist/ai-review-service.d.ts +28 -9
- package/dist/ai-review-service.d.ts.map +1 -1
- package/dist/check-execution-engine.d.ts +19 -331
- package/dist/check-execution-engine.d.ts.map +1 -1
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/config.d.ts +16 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/cron-scheduler.d.ts +3 -3
- package/dist/cron-scheduler.d.ts.map +1 -1
- package/dist/debug-visualizer/ws-server.d.ts +7 -1
- package/dist/debug-visualizer/ws-server.d.ts.map +1 -1
- package/dist/defaults/code-refiner.yaml +114 -0
- package/dist/defaults/{.visor.yaml → code-review.yaml} +35 -226
- package/dist/defaults/override.yaml +52 -0
- package/dist/defaults/task-refinement.yaml +624 -0
- package/dist/defaults/visor.tests.yaml +685 -0
- package/dist/defaults/visor.yaml +483 -0
- package/dist/docs/DEPLOYMENT.md +118 -0
- package/dist/docs/GITHUB_CHECKS.md +280 -0
- package/dist/docs/NPM_USAGE.md +208 -0
- package/dist/docs/action-reference.md +19 -0
- package/dist/docs/advanced-ai.md +237 -0
- package/dist/docs/ai-configuration.md +535 -0
- package/dist/docs/ai-custom-tools-usage.md +261 -0
- package/dist/docs/ai-custom-tools.md +392 -0
- package/dist/docs/author-permissions.md +610 -0
- package/dist/docs/bot-transports-rfc.md +23 -0
- package/dist/docs/ci-cli-mode.md +34 -0
- package/dist/docs/claude-code.md +74 -0
- package/dist/docs/command-provider.md +559 -0
- package/dist/docs/commands.md +8 -0
- package/dist/docs/configuration.md +324 -0
- package/dist/docs/custom-tools.md +424 -0
- package/dist/docs/dashboards/README.md +23 -0
- package/dist/docs/dashboards/grafana-visor-diagrams.json +20 -0
- package/dist/docs/dashboards/grafana-visor-overview.json +33 -0
- package/dist/docs/debug-visualizer-progress.md +572 -0
- package/dist/docs/debug-visualizer-rfc.md +691 -0
- package/dist/docs/debug-visualizer.md +114 -0
- package/dist/docs/debugging.md +636 -0
- package/dist/docs/default-output-schema.md +28 -0
- package/dist/docs/dependencies.md +369 -0
- package/dist/docs/dev-playbook.md +9 -0
- package/dist/docs/engine-pause-resume-rfc.md +192 -0
- package/dist/docs/engine-state-machine-plan.md +333 -0
- package/dist/docs/event-driven-github-integration-rfc.md +743 -0
- package/dist/docs/event-triggers.md +292 -0
- package/dist/docs/execution-statistics-rfc.md +290 -0
- package/dist/docs/fact-validator-gap-analysis.md +178 -0
- package/dist/docs/fact-validator-implementation-plan.md +1235 -0
- package/dist/docs/fail-if.md +95 -0
- package/dist/docs/failure-conditions-implementation.md +271 -0
- package/dist/docs/failure-conditions-schema.md +173 -0
- package/dist/docs/failure-routing-rfc.md +193 -0
- package/dist/docs/failure-routing.md +507 -0
- package/dist/docs/foreach-dependency-propagation.md +473 -0
- package/dist/docs/github-ops.md +89 -0
- package/dist/docs/goto-forward-run-plan.md +113 -0
- package/dist/docs/guides/criticality-modes.md +332 -0
- package/dist/docs/guides/fault-management-and-contracts.md +738 -0
- package/dist/docs/guides/workflow-style-guide.md +224 -0
- package/dist/docs/http.md +299 -0
- package/dist/docs/human-input-provider.md +372 -0
- package/dist/docs/lifecycle-hooks.md +253 -0
- package/dist/docs/limits.md +64 -0
- package/dist/docs/liquid-templates.md +490 -0
- package/dist/docs/loop-routing-refactor.md +89 -0
- package/dist/docs/mcp-provider.md +557 -0
- package/dist/docs/mcp.md +124 -0
- package/dist/docs/memory.md +903 -0
- package/dist/docs/observability.md +12 -0
- package/dist/docs/output-formats.md +20 -0
- package/dist/docs/output-formatting.md +29 -0
- package/dist/docs/output-history.md +383 -0
- package/dist/docs/performance.md +6 -0
- package/dist/docs/pluggable.md +124 -0
- package/dist/docs/proposals/snapshot-scope-execution.md +236 -0
- package/dist/docs/providers/git-checkout.md +589 -0
- package/dist/docs/recipes.md +474 -0
- package/dist/docs/rfc/git-checkout-step.md +601 -0
- package/dist/docs/rfc/on_init-hook.md +1294 -0
- package/dist/docs/rfc/workspace-isolation.md +216 -0
- package/dist/docs/roadmap/criticality-implementation-tasks.md +92 -0
- package/dist/docs/router-patterns.md +339 -0
- package/dist/docs/schema-next-pr.md +10 -0
- package/dist/docs/schema-templates.md +68 -0
- package/dist/docs/script.md +34 -0
- package/dist/docs/sdk.md +222 -0
- package/dist/docs/security.md +7 -0
- package/dist/docs/suppressions.md +89 -0
- package/dist/docs/tag-filtering.md +258 -0
- package/dist/docs/telemetry-setup.md +119 -0
- package/dist/docs/telemetry-tracing-rfc.md +275 -0
- package/dist/docs/test-framework-rfc.md +680 -0
- package/dist/docs/testing/assertions.md +85 -0
- package/dist/docs/testing/ci.md +44 -0
- package/dist/docs/testing/cli.md +41 -0
- package/dist/docs/testing/cookbook.md +172 -0
- package/dist/docs/testing/dsl-reference.md +199 -0
- package/dist/docs/testing/fixtures-and-mocks.md +91 -0
- package/dist/docs/testing/flows.md +92 -0
- package/dist/docs/testing/getting-started.md +93 -0
- package/dist/docs/testing/troubleshooting.md +55 -0
- package/dist/docs/timeouts.md +50 -0
- package/dist/docs/troubleshooting.md +7 -0
- package/dist/docs/visor-sdk-rfc.md +186 -0
- package/dist/docs/workflows.md +569 -0
- package/dist/engine/on-finish/orchestrator.d.ts +19 -0
- package/dist/engine/on-finish/orchestrator.d.ts.map +1 -0
- package/dist/engine/on-finish/utils.d.ts +44 -0
- package/dist/engine/on-finish/utils.d.ts.map +1 -0
- package/dist/event-bus/event-bus.d.ts +13 -0
- package/dist/event-bus/event-bus.d.ts.map +1 -0
- package/dist/event-bus/types.d.ts +71 -0
- package/dist/event-bus/types.d.ts.map +1 -0
- package/dist/examples/.claude/agents/code-reviewer.md +69 -0
- package/dist/examples/.mcp.json +34 -0
- package/dist/examples/CALCULATOR-SDK.md +364 -0
- package/dist/examples/README.md +384 -0
- package/dist/examples/ai-custom-tools-example.yaml +206 -0
- package/dist/examples/ai-custom-tools-simple.yaml +76 -0
- package/dist/examples/ai-retry-fallback-config.yaml +180 -0
- package/dist/examples/ai-with-bash.yaml +126 -0
- package/dist/examples/ai-with-mcp.yaml +82 -0
- package/dist/examples/basic-human-input.yaml +15 -0
- package/dist/examples/bedrock-config.yaml +77 -0
- package/dist/examples/calculator-config.yaml +133 -0
- package/dist/examples/calculator-json-output-guide.md +311 -0
- package/dist/examples/calculator-sdk-automated.ts +340 -0
- package/dist/examples/calculator-sdk-example.ts +275 -0
- package/dist/examples/calculator-sdk-json.ts +331 -0
- package/dist/examples/calculator-sdk-real.ts +374 -0
- package/dist/examples/calculator-sdk-test.ts +148 -0
- package/dist/examples/claude-code-config.yaml +191 -0
- package/dist/examples/cron-webhook-config.yaml +215 -0
- package/dist/examples/custom-template.liquid +57 -0
- package/dist/examples/custom-tools-example.yaml +281 -0
- package/dist/examples/enhanced-config.yaml +165 -0
- package/dist/examples/environments/visor.base.yaml +92 -0
- package/dist/examples/environments/visor.dev.yaml +33 -0
- package/dist/examples/environments/visor.prod.yaml +95 -0
- package/dist/examples/environments/visor.staging.yaml +46 -0
- package/dist/examples/fact-validator.yaml +361 -0
- package/dist/examples/fail-if-simple.yaml +90 -0
- package/dist/examples/failure-conditions-advanced.yaml +136 -0
- package/dist/examples/failure-conditions-basic.yaml +48 -0
- package/dist/examples/failure-conditions-github-style.yaml +119 -0
- package/dist/examples/failure-conditions-migration.yaml +74 -0
- package/dist/examples/for-loop-example.yaml +176 -0
- package/dist/examples/forEach-example.yaml +120 -0
- package/dist/examples/git-checkout-basic.yaml +32 -0
- package/dist/examples/git-checkout-compare.yaml +59 -0
- package/dist/examples/git-checkout-cross-repo.yaml +76 -0
- package/dist/examples/github-workflow-with-tags.yml +163 -0
- package/dist/examples/http-integration-config.yaml +240 -0
- package/dist/examples/https-server-config.yaml +209 -0
- package/dist/examples/human-input-example.yaml +63 -0
- package/dist/examples/if-conditions.yaml +173 -0
- package/dist/examples/jira-simple-example.yaml +56 -0
- package/dist/examples/jira-single-issue-workflow.yaml +166 -0
- package/dist/examples/jira-workflow-mcp.yaml +182 -0
- package/dist/examples/mcp/analyzer.py +119 -0
- package/dist/examples/mcp-provider-example.yaml +301 -0
- package/dist/examples/memory-counter.yaml +99 -0
- package/dist/examples/memory-error-collection.yaml +104 -0
- package/dist/examples/memory-exec-js.yaml +247 -0
- package/dist/examples/memory-namespace-isolation.yaml +184 -0
- package/dist/examples/memory-retry-counter.yaml +65 -0
- package/dist/examples/memory-state-machine.yaml +170 -0
- package/dist/examples/on-init-import-demo.yaml +179 -0
- package/dist/examples/outputs-raw-basic.yaml +26 -0
- package/dist/examples/project-with-tools.yaml +174 -0
- package/dist/examples/prompts/architecture-analysis.liquid +116 -0
- package/dist/examples/prompts/security-comprehensive.liquid +107 -0
- package/dist/examples/quick-start-tags.yaml +53 -0
- package/dist/examples/reusable-tools.yaml +92 -0
- package/dist/examples/reusable-workflows.yaml +88 -0
- package/dist/examples/routing-basic.yaml +35 -0
- package/dist/examples/routing-dynamic-js.yaml +46 -0
- package/dist/examples/routing-foreach.yaml +34 -0
- package/dist/examples/routing-goto-event.yaml +34 -0
- package/dist/examples/routing-on-success.yaml +25 -0
- package/dist/examples/run-calculator-demo.sh +71 -0
- package/dist/examples/sdk-basic.mjs +10 -0
- package/dist/examples/sdk-cjs.cjs +10 -0
- package/dist/examples/sdk-comprehensive.mjs +175 -0
- package/dist/examples/sdk-manual-config.mjs +65 -0
- package/dist/examples/sdk-typescript.js +81 -0
- package/dist/examples/sdk-typescript.ts +92 -0
- package/dist/examples/session-reuse-config.yaml +151 -0
- package/dist/examples/session-reuse-self.yaml +81 -0
- package/dist/examples/slack-simple-chat.yaml +775 -0
- package/dist/examples/templates/security-report.liquid +137 -0
- package/dist/examples/tools-library.yaml +281 -0
- package/dist/examples/transform-example.yaml +199 -0
- package/dist/examples/visor-with-tags.yaml +198 -0
- package/dist/examples/webhook-pipeline-config.yaml +218 -0
- package/dist/examples/workflows/calculator-workflow.yaml +163 -0
- package/dist/examples/workflows/code-quality.yaml +222 -0
- package/dist/examples/workflows/quick-pr-check.yaml +90 -0
- package/dist/examples/workflows/workflow-composition-example.yaml +130 -0
- package/dist/failure-condition-evaluator.d.ts +3 -0
- package/dist/failure-condition-evaluator.d.ts.map +1 -1
- package/dist/frontends/github-frontend.d.ts +58 -0
- package/dist/frontends/github-frontend.d.ts.map +1 -0
- package/dist/frontends/host.d.ts +47 -0
- package/dist/frontends/host.d.ts.map +1 -0
- package/dist/frontends/ndjson-sink.d.ts +12 -0
- package/dist/frontends/ndjson-sink.d.ts.map +1 -0
- package/dist/frontends/slack-frontend.d.ts +58 -0
- package/dist/frontends/slack-frontend.d.ts.map +1 -0
- package/dist/generated/config-schema.d.ts +967 -57
- package/dist/generated/config-schema.d.ts.map +1 -1
- package/dist/generated/config-schema.json +1033 -56
- package/dist/github-check-service.d.ts +4 -6
- package/dist/github-check-service.d.ts.map +1 -1
- package/dist/github-comments.d.ts +2 -4
- package/dist/github-comments.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +134327 -99004
- package/dist/liquid-extensions.d.ts.map +1 -1
- package/dist/logger.d.ts +2 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/memory-store.d.ts +6 -0
- package/dist/memory-store.d.ts.map +1 -1
- package/dist/output/assistant-json/template.liquid +0 -0
- package/dist/output/traces/run-2026-01-20T19-22-58-043Z.ndjson +138 -0
- package/dist/output/traces/run-2026-01-20T19-23-52-175Z.ndjson +1067 -0
- package/dist/output-formatters.d.ts +1 -1
- package/dist/output-formatters.d.ts.map +1 -1
- package/dist/providers/ai-check-provider.d.ts +12 -0
- package/dist/providers/ai-check-provider.d.ts.map +1 -1
- package/dist/providers/check-provider-registry.d.ts +6 -0
- package/dist/providers/check-provider-registry.d.ts.map +1 -1
- package/dist/providers/check-provider.interface.d.ts +43 -1
- package/dist/providers/check-provider.interface.d.ts.map +1 -1
- package/dist/providers/claude-code-check-provider.d.ts.map +1 -1
- package/dist/providers/command-check-provider.d.ts +1 -1
- package/dist/providers/command-check-provider.d.ts.map +1 -1
- package/dist/providers/custom-tool-executor.d.ts +61 -0
- package/dist/providers/custom-tool-executor.d.ts.map +1 -0
- package/dist/providers/git-checkout-provider.d.ts +25 -0
- package/dist/providers/git-checkout-provider.d.ts.map +1 -0
- package/dist/providers/github-ops-provider.d.ts.map +1 -1
- package/dist/providers/http-client-provider.d.ts +4 -4
- package/dist/providers/http-client-provider.d.ts.map +1 -1
- package/dist/providers/human-input-check-provider.d.ts +5 -0
- package/dist/providers/human-input-check-provider.d.ts.map +1 -1
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/log-check-provider.d.ts +2 -5
- package/dist/providers/log-check-provider.d.ts.map +1 -1
- package/dist/providers/mcp-check-provider.d.ts +10 -4
- package/dist/providers/mcp-check-provider.d.ts.map +1 -1
- package/dist/providers/mcp-custom-sse-server.d.ts +66 -0
- package/dist/providers/mcp-custom-sse-server.d.ts.map +1 -0
- package/dist/providers/memory-check-provider.d.ts +2 -8
- package/dist/providers/memory-check-provider.d.ts.map +1 -1
- package/dist/providers/script-check-provider.d.ts +25 -0
- package/dist/providers/script-check-provider.d.ts.map +1 -0
- package/dist/providers/workflow-check-provider.d.ts +56 -0
- package/dist/providers/workflow-check-provider.d.ts.map +1 -0
- package/dist/reviewer.d.ts +2 -1
- package/dist/reviewer.d.ts.map +1 -1
- package/dist/sdk/check-provider-registry-534KL5HT.mjs +27 -0
- package/dist/sdk/chunk-23L3QRYX.mjs +16872 -0
- package/dist/sdk/chunk-23L3QRYX.mjs.map +1 -0
- package/dist/sdk/{chunk-TUTOLSFV.mjs → chunk-3OMWVM6J.mjs} +11 -1
- package/dist/sdk/chunk-3OMWVM6J.mjs.map +1 -0
- package/dist/sdk/chunk-7UK3NIIT.mjs +482 -0
- package/dist/sdk/chunk-7UK3NIIT.mjs.map +1 -0
- package/dist/sdk/chunk-AGIZJ4UZ.mjs +173 -0
- package/dist/sdk/chunk-AGIZJ4UZ.mjs.map +1 -0
- package/dist/sdk/chunk-AIVFBIS4.mjs +1371 -0
- package/dist/sdk/chunk-AIVFBIS4.mjs.map +1 -0
- package/dist/sdk/chunk-AK6BVWIT.mjs +426 -0
- package/dist/sdk/chunk-AK6BVWIT.mjs.map +1 -0
- package/dist/sdk/chunk-AUT26LHW.mjs +139 -0
- package/dist/sdk/chunk-AUT26LHW.mjs.map +1 -0
- package/dist/sdk/chunk-BOVFH3LI.mjs +232 -0
- package/dist/sdk/chunk-BOVFH3LI.mjs.map +1 -0
- package/dist/sdk/chunk-CNX7V5JK.mjs +89 -0
- package/dist/sdk/chunk-CNX7V5JK.mjs.map +1 -0
- package/dist/sdk/chunk-HTOKWMPO.mjs +157 -0
- package/dist/sdk/chunk-HTOKWMPO.mjs.map +1 -0
- package/dist/sdk/chunk-NAW3DB3I.mjs +197 -0
- package/dist/sdk/chunk-NAW3DB3I.mjs.map +1 -0
- package/dist/sdk/chunk-O5EZDNYL.mjs +274 -0
- package/dist/sdk/chunk-O5EZDNYL.mjs.map +1 -0
- package/dist/sdk/chunk-QR7MOMJH.mjs +558 -0
- package/dist/sdk/chunk-QR7MOMJH.mjs.map +1 -0
- package/dist/sdk/chunk-QY2XYPEV.mjs +3556 -0
- package/dist/sdk/chunk-QY2XYPEV.mjs.map +1 -0
- package/dist/sdk/chunk-S2RUE2RG.mjs +145 -0
- package/dist/sdk/chunk-S2RUE2RG.mjs.map +1 -0
- package/dist/sdk/chunk-SIWNBRTK.mjs +800 -0
- package/dist/sdk/chunk-SIWNBRTK.mjs.map +1 -0
- package/dist/sdk/chunk-YSN4G6CI.mjs +146 -0
- package/dist/sdk/chunk-YSN4G6CI.mjs.map +1 -0
- package/dist/sdk/chunk-ZYAUYXSW.mjs +206 -0
- package/dist/sdk/chunk-ZYAUYXSW.mjs.map +1 -0
- package/dist/sdk/command-executor-TYUV6HUS.mjs +14 -0
- package/dist/sdk/config-YNC2EOOT.mjs +16 -0
- package/dist/sdk/config-merger-PX3WIT57.mjs +10 -0
- package/dist/sdk/event-bus-5BEVPQ6T.mjs +35 -0
- package/dist/sdk/event-bus-5BEVPQ6T.mjs.map +1 -0
- package/dist/sdk/failure-condition-evaluator-YGTF2GHG.mjs +17 -0
- package/dist/sdk/git-repository-analyzer-HJC4MYW4.mjs +458 -0
- package/dist/sdk/git-repository-analyzer-HJC4MYW4.mjs.map +1 -0
- package/dist/sdk/github-frontend-SIAEOCON.mjs +1420 -0
- package/dist/sdk/github-frontend-SIAEOCON.mjs.map +1 -0
- package/dist/sdk/host-DXUYTNMU.mjs +52 -0
- package/dist/sdk/host-DXUYTNMU.mjs.map +1 -0
- package/dist/sdk/{liquid-extensions-KVL4MKRH.mjs → liquid-extensions-PKWCKK7E.mjs} +8 -2
- package/dist/sdk/memory-store-XGBB7LX7.mjs +12 -0
- package/dist/sdk/memory-store-XGBB7LX7.mjs.map +1 -0
- package/dist/sdk/metrics-7PP3EJUH.mjs +29 -0
- package/dist/sdk/metrics-7PP3EJUH.mjs.map +1 -0
- package/dist/sdk/ndjson-sink-B4V4NTAQ.mjs +44 -0
- package/dist/sdk/ndjson-sink-B4V4NTAQ.mjs.map +1 -0
- package/dist/sdk/prompt-state-YRJY6QAL.mjs +16 -0
- package/dist/sdk/prompt-state-YRJY6QAL.mjs.map +1 -0
- package/dist/sdk/renderer-schema-LPKN5UJS.mjs +51 -0
- package/dist/sdk/renderer-schema-LPKN5UJS.mjs.map +1 -0
- package/dist/sdk/routing-6N45MJ4F.mjs +24 -0
- package/dist/sdk/routing-6N45MJ4F.mjs.map +1 -0
- package/dist/sdk/sdk.d.mts +541 -22
- package/dist/sdk/sdk.d.ts +541 -22
- package/dist/sdk/sdk.js +27963 -16505
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +1116 -2169
- package/dist/sdk/sdk.mjs.map +1 -1
- package/dist/sdk/session-registry-4E6YRQ77.mjs +10 -0
- package/dist/sdk/session-registry-4E6YRQ77.mjs.map +1 -0
- package/dist/sdk/slack-frontend-BVKW3GD5.mjs +735 -0
- package/dist/sdk/slack-frontend-BVKW3GD5.mjs.map +1 -0
- package/dist/sdk/trace-helpers-VP6QYVBX.mjs +23 -0
- package/dist/sdk/trace-helpers-VP6QYVBX.mjs.map +1 -0
- package/dist/sdk/{tracer-init-WC75N5NW.mjs → tracer-init-GSLPPLCD.mjs} +2 -2
- package/dist/sdk/tracer-init-GSLPPLCD.mjs.map +1 -0
- package/dist/sdk/workflow-registry-R6KSACFR.mjs +12 -0
- package/dist/sdk/workflow-registry-R6KSACFR.mjs.map +1 -0
- package/dist/sdk.d.ts.map +1 -1
- package/dist/slack/adapter.d.ts +36 -0
- package/dist/slack/adapter.d.ts.map +1 -0
- package/dist/slack/cache-prewarmer.d.ts +31 -0
- package/dist/slack/cache-prewarmer.d.ts.map +1 -0
- package/dist/slack/client.d.ts +77 -0
- package/dist/slack/client.d.ts.map +1 -0
- package/dist/slack/markdown.d.ts +45 -0
- package/dist/slack/markdown.d.ts.map +1 -0
- package/dist/slack/prompt-state.d.ts +33 -0
- package/dist/slack/prompt-state.d.ts.map +1 -0
- package/dist/slack/rate-limiter.d.ts +56 -0
- package/dist/slack/rate-limiter.d.ts.map +1 -0
- package/dist/slack/signature.d.ts +2 -0
- package/dist/slack/signature.d.ts.map +1 -0
- package/dist/slack/socket-runner.d.ts +42 -0
- package/dist/slack/socket-runner.d.ts.map +1 -0
- package/dist/slack/thread-cache.d.ts +51 -0
- package/dist/slack/thread-cache.d.ts.map +1 -0
- package/dist/snapshot-store.d.ts +59 -0
- package/dist/snapshot-store.d.ts.map +1 -0
- package/dist/state-machine/context/build-engine-context.d.ts +17 -0
- package/dist/state-machine/context/build-engine-context.d.ts.map +1 -0
- package/dist/state-machine/dispatch/dependency-gating.d.ts +12 -0
- package/dist/state-machine/dispatch/dependency-gating.d.ts.map +1 -0
- package/dist/state-machine/dispatch/execution-invoker.d.ts +14 -0
- package/dist/state-machine/dispatch/execution-invoker.d.ts.map +1 -0
- package/dist/state-machine/dispatch/foreach-processor.d.ts +8 -0
- package/dist/state-machine/dispatch/foreach-processor.d.ts.map +1 -0
- package/dist/state-machine/dispatch/history-snapshot.d.ts +8 -0
- package/dist/state-machine/dispatch/history-snapshot.d.ts.map +1 -0
- package/dist/state-machine/dispatch/on-init-handlers.d.ts +43 -0
- package/dist/state-machine/dispatch/on-init-handlers.d.ts.map +1 -0
- package/dist/state-machine/dispatch/renderer-schema.d.ts +8 -0
- package/dist/state-machine/dispatch/renderer-schema.d.ts.map +1 -0
- package/dist/state-machine/dispatch/stats-manager.d.ts +15 -0
- package/dist/state-machine/dispatch/stats-manager.d.ts.map +1 -0
- package/dist/state-machine/dispatch/template-renderer.d.ts +7 -0
- package/dist/state-machine/dispatch/template-renderer.d.ts.map +1 -0
- package/dist/state-machine/execution/summary.d.ts +8 -0
- package/dist/state-machine/execution/summary.d.ts.map +1 -0
- package/dist/state-machine/runner.d.ts +79 -0
- package/dist/state-machine/runner.d.ts.map +1 -0
- package/dist/state-machine/states/check-running.d.ts +14 -0
- package/dist/state-machine/states/check-running.d.ts.map +1 -0
- package/dist/state-machine/states/completed.d.ts +12 -0
- package/dist/state-machine/states/completed.d.ts.map +1 -0
- package/dist/state-machine/states/error.d.ts +11 -0
- package/dist/state-machine/states/error.d.ts.map +1 -0
- package/dist/state-machine/states/init.d.ts +11 -0
- package/dist/state-machine/states/init.d.ts.map +1 -0
- package/dist/state-machine/states/level-dispatch.d.ts +17 -0
- package/dist/state-machine/states/level-dispatch.d.ts.map +1 -0
- package/dist/state-machine/states/plan-ready.d.ts +12 -0
- package/dist/state-machine/states/plan-ready.d.ts.map +1 -0
- package/dist/state-machine/states/routing.d.ts +52 -0
- package/dist/state-machine/states/routing.d.ts.map +1 -0
- package/dist/state-machine/states/wave-planning.d.ts +14 -0
- package/dist/state-machine/states/wave-planning.d.ts.map +1 -0
- package/dist/state-machine/workflow-projection.d.ts +47 -0
- package/dist/state-machine/workflow-projection.d.ts.map +1 -0
- package/dist/state-machine-execution-engine.d.ts +159 -0
- package/dist/state-machine-execution-engine.d.ts.map +1 -0
- package/dist/telemetry/opentelemetry.d.ts.map +1 -1
- package/dist/telemetry/state-capture.d.ts +5 -0
- package/dist/telemetry/state-capture.d.ts.map +1 -1
- package/dist/test-runner/assertions.d.ts +59 -0
- package/dist/test-runner/assertions.d.ts.map +1 -0
- package/dist/test-runner/core/environment.d.ts +8 -0
- package/dist/test-runner/core/environment.d.ts.map +1 -0
- package/dist/test-runner/core/fixture.d.ts +3 -0
- package/dist/test-runner/core/fixture.d.ts.map +1 -0
- package/dist/test-runner/core/flow-stage.d.ts +32 -0
- package/dist/test-runner/core/flow-stage.d.ts.map +1 -0
- package/dist/test-runner/core/mocks.d.ts +8 -0
- package/dist/test-runner/core/mocks.d.ts.map +1 -0
- package/dist/test-runner/core/test-execution-wrapper.d.ts +18 -0
- package/dist/test-runner/core/test-execution-wrapper.d.ts.map +1 -0
- package/dist/test-runner/evaluators.d.ts +45 -0
- package/dist/test-runner/evaluators.d.ts.map +1 -0
- package/dist/test-runner/fixture-loader.d.ts +30 -0
- package/dist/test-runner/fixture-loader.d.ts.map +1 -0
- package/dist/test-runner/index.d.ts +127 -0
- package/dist/test-runner/index.d.ts.map +1 -0
- package/dist/test-runner/recorders/github-recorder.d.ts +23 -0
- package/dist/test-runner/recorders/github-recorder.d.ts.map +1 -0
- package/dist/test-runner/recorders/global-recorder.d.ts +4 -0
- package/dist/test-runner/recorders/global-recorder.d.ts.map +1 -0
- package/dist/test-runner/recorders/slack-recorder.d.ts +17 -0
- package/dist/test-runner/recorders/slack-recorder.d.ts.map +1 -0
- package/dist/test-runner/utils/selectors.d.ts +2 -0
- package/dist/test-runner/utils/selectors.d.ts.map +1 -0
- package/dist/test-runner/validator.d.ts +8 -0
- package/dist/test-runner/validator.d.ts.map +1 -0
- package/dist/traces/run-2026-01-20T19-22-58-043Z.ndjson +138 -0
- package/dist/traces/run-2026-01-20T19-23-52-175Z.ndjson +1067 -0
- package/dist/types/bot.d.ts +109 -0
- package/dist/types/bot.d.ts.map +1 -0
- package/dist/types/cli.d.ts +8 -1
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/config.d.ts +459 -9
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/engine.d.ts +177 -0
- package/dist/types/engine.d.ts.map +1 -0
- package/dist/types/execution.d.ts +73 -0
- package/dist/types/execution.d.ts.map +1 -0
- package/dist/types/git-checkout.d.ts +76 -0
- package/dist/types/git-checkout.d.ts.map +1 -0
- package/dist/types/github.d.ts +51 -0
- package/dist/types/github.d.ts.map +1 -0
- package/dist/types/workflow.d.ts +237 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/dist/utils/command-executor.d.ts +43 -0
- package/dist/utils/command-executor.d.ts.map +1 -0
- package/dist/utils/comment-metadata.d.ts +21 -0
- package/dist/utils/comment-metadata.d.ts.map +1 -0
- package/dist/utils/config-loader.d.ts.map +1 -1
- package/dist/utils/config-merger.d.ts.map +1 -1
- package/dist/utils/env-exposure.d.ts +3 -0
- package/dist/utils/env-exposure.d.ts.map +1 -0
- package/dist/utils/file-exclusion.d.ts.map +1 -1
- package/dist/utils/interactive-prompt.d.ts +1 -1
- package/dist/utils/interactive-prompt.d.ts.map +1 -1
- package/dist/utils/json-text-extractor.d.ts +17 -0
- package/dist/utils/json-text-extractor.d.ts.map +1 -0
- package/dist/utils/sandbox.d.ts +10 -0
- package/dist/utils/sandbox.d.ts.map +1 -1
- package/dist/utils/script-memory-ops.d.ts +21 -0
- package/dist/utils/script-memory-ops.d.ts.map +1 -0
- package/dist/utils/template-context.d.ts +8 -0
- package/dist/utils/template-context.d.ts.map +1 -0
- package/dist/utils/tracer-init.d.ts.map +1 -1
- package/dist/utils/workspace-manager.d.ts +118 -0
- package/dist/utils/workspace-manager.d.ts.map +1 -0
- package/dist/utils/worktree-cleanup.d.ts +33 -0
- package/dist/utils/worktree-cleanup.d.ts.map +1 -0
- package/dist/utils/worktree-manager.d.ts +153 -0
- package/dist/utils/worktree-manager.d.ts.map +1 -0
- package/dist/webhook-server.d.ts +3 -3
- package/dist/webhook-server.d.ts.map +1 -1
- package/dist/workflow-executor.d.ts +81 -0
- package/dist/workflow-executor.d.ts.map +1 -0
- package/dist/workflow-registry.d.ts +79 -0
- package/dist/workflow-registry.d.ts.map +1 -0
- package/package.json +12 -5
- package/dist/output/traces/run-2025-10-22T18-22-56-873Z.ndjson +0 -218
- package/dist/sdk/check-execution-engine-2YYKUUSH.mjs +0 -11
- package/dist/sdk/check-execution-engine-6QJXYYON.mjs +0 -11
- package/dist/sdk/check-execution-engine-PJZ4ZOKG.mjs +0 -11
- package/dist/sdk/chunk-33QVZ2D4.mjs +0 -316
- package/dist/sdk/chunk-33QVZ2D4.mjs.map +0 -1
- package/dist/sdk/chunk-B5QBV2QJ.mjs +0 -752
- package/dist/sdk/chunk-B5QBV2QJ.mjs.map +0 -1
- package/dist/sdk/chunk-BVFNRCHT.mjs +0 -14129
- package/dist/sdk/chunk-BVFNRCHT.mjs.map +0 -1
- package/dist/sdk/chunk-KWZW23FG.mjs +0 -14129
- package/dist/sdk/chunk-KWZW23FG.mjs.map +0 -1
- package/dist/sdk/chunk-O4RP4BRH.mjs +0 -14092
- package/dist/sdk/chunk-O4RP4BRH.mjs.map +0 -1
- package/dist/sdk/chunk-TUTOLSFV.mjs.map +0 -1
- package/dist/sdk/chunk-U5D2LY66.mjs +0 -245
- package/dist/sdk/chunk-U5D2LY66.mjs.map +0 -1
- package/dist/sdk/chunk-U7X54EMV.mjs +0 -331
- package/dist/sdk/chunk-U7X54EMV.mjs.map +0 -1
- package/dist/sdk/config-merger-TWUBWFC2.mjs +0 -8
- package/dist/sdk/mermaid-telemetry-SN6A2TKW.mjs +0 -61
- package/dist/sdk/mermaid-telemetry-SN6A2TKW.mjs.map +0 -1
- package/dist/sdk/mermaid-telemetry-YCTIG76M.mjs +0 -61
- package/dist/sdk/mermaid-telemetry-YCTIG76M.mjs.map +0 -1
- package/dist/traces/run-2025-10-22T18-22-56-873Z.ndjson +0 -218
- /package/dist/sdk/{check-execution-engine-2YYKUUSH.mjs.map → check-provider-registry-534KL5HT.mjs.map} +0 -0
- /package/dist/sdk/{check-execution-engine-6QJXYYON.mjs.map → command-executor-TYUV6HUS.mjs.map} +0 -0
- /package/dist/sdk/{check-execution-engine-PJZ4ZOKG.mjs.map → config-YNC2EOOT.mjs.map} +0 -0
- /package/dist/sdk/{config-merger-TWUBWFC2.mjs.map → config-merger-PX3WIT57.mjs.map} +0 -0
- /package/dist/sdk/{liquid-extensions-KVL4MKRH.mjs.map → failure-condition-evaluator-YGTF2GHG.mjs.map} +0 -0
- /package/dist/sdk/{tracer-init-WC75N5NW.mjs.map → liquid-extensions-PKWCKK7E.mjs.map} +0 -0
|
@@ -0,0 +1,738 @@
|
|
|
1
|
+
# Visor Engine: Fault Management, Contracts, and Transitions (NASA‑style)
|
|
2
|
+
|
|
3
|
+
This guide consolidates the expected behavior for conditional gating, design‑by‑contract, routing, and retries in the state‑machine engine. It follows safety‑critical software principles (detect → isolate → recover → report) while remaining practical for CI/PR automation.
|
|
4
|
+
|
|
5
|
+
> Assume vs. Guarantee — Do’s and Don’ts
|
|
6
|
+
>
|
|
7
|
+
> Do
|
|
8
|
+
> - Use `assume` for pre‑execution prerequisites that do not depend on this step’s output (env, memory, upstream results).
|
|
9
|
+
> - Keep expressions pure (no time/random/network); short and deterministic.
|
|
10
|
+
> - Use `guarantee` to assert properties of this step’s produced output (shape, size caps, idempotency markers, control signals).
|
|
11
|
+
> - For critical steps, pair both: `assume` (preflight) + `guarantee` (post‑exec safety lock).
|
|
12
|
+
>
|
|
13
|
+
> Don’t
|
|
14
|
+
> - Don’t reference `output` of the same step in `assume` (it runs before execution).
|
|
15
|
+
> - Don’t put policy thresholds into `guarantee`—use `fail_if` for policy/quality gates.
|
|
16
|
+
> - Don’t rely on side‑effects or external clocks in expressions.
|
|
17
|
+
|
|
18
|
+
## Core Principles
|
|
19
|
+
- Deterministic evaluations: expressions are pure (no side‑effects, time/network), evaluated in a sandbox.
|
|
20
|
+
- Fail‑secure defaults: evaluation errors pick the safest behavior (skip or fail closed), and are logged.
|
|
21
|
+
- Bounded retries: never unbounded loops; per‑scope caps and loop budgets.
|
|
22
|
+
- Isolation: failures do not cascade unless explicitly permitted.
|
|
23
|
+
- Auditability: every decision is journaled with cause, scope, and timestamps; JSON snapshots are exportable.
|
|
24
|
+
|
|
25
|
+
## Criticality Model (What It Is, How To Declare It, What It Does)
|
|
26
|
+
|
|
27
|
+
Criticality classifies a step by the operational risk it carries. The engine uses it to pick safe defaults for contracts, gating, retries, loop budgets, and side‑effects. `continue_on_failure` only controls dependency gating; it does not define criticality.
|
|
28
|
+
|
|
29
|
+
Declare criticality on each check:
|
|
30
|
+
```yaml
|
|
31
|
+
checks:
|
|
32
|
+
post-comment:
|
|
33
|
+
type: github
|
|
34
|
+
criticality: external # external | internal | policy | info
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Meanings:
|
|
38
|
+
- external
|
|
39
|
+
- Step mutates an external system (GitHub ops, HTTP methods ≠ GET/HEAD, file writes).
|
|
40
|
+
- Defaults: contracts required; `continue_on_failure: false`; retries only for transient faults; tighter loop budgets; suppress downstream mutating actions when contracts or `fail_if` fail; idempotency or compensation expected.
|
|
41
|
+
- internal
|
|
42
|
+
- Step drives routing or fan‑out (forEach parents; on_* with goto/run; memory used by guards).
|
|
43
|
+
- Defaults: contracts required for route integrity; `continue_on_failure: false`; tighter loop budgets (recommended 8); retries only transient; treat loops/recirculation conservatively.
|
|
44
|
+
- policy
|
|
45
|
+
- Step enforces permissions/compliance gates (permission checks, org policy, human‑in‑the‑loop approvals).
|
|
46
|
+
- Defaults: contracts required; `continue_on_failure: false`; logical violations are failures (no auto‑retry), downstream mutating actions blocked until remediated.
|
|
47
|
+
- info
|
|
48
|
+
- Read‑only or low‑risk compute.
|
|
49
|
+
- Defaults: contracts recommended (not required); may allow `continue_on_failure: true`; standard loop budgets and retry bounds.
|
|
50
|
+
|
|
51
|
+
Precedence & inference:
|
|
52
|
+
- Explicit `criticality` on a check takes precedence over tags or heuristics.
|
|
53
|
+
- If `criticality` is omitted, the engine may infer:
|
|
54
|
+
- mutating providers → external; forEach parents or on_* goto/run → control‑plane; strong policy gates → policy; otherwise non‑critical.
|
|
55
|
+
|
|
56
|
+
Overriding defaults:
|
|
57
|
+
- You can override any default (e.g., set `continue_on_failure: true` or adjust budgets) per check. Criticality sets sensible baselines; it does not lock you in.
|
|
58
|
+
|
|
59
|
+
## Behavior Matrix by Construct and Criticality
|
|
60
|
+
|
|
61
|
+
Below is the exact behavior for each construct depending on criticality. “Skip” means provider is not executed and it does not count as a run.
|
|
62
|
+
|
|
63
|
+
- if (plan‑time)
|
|
64
|
+
- Non‑critical: false/error → skip; dependents may run if OR‑deps satisfy or they are unrelated.
|
|
65
|
+
- Critical: same skip; because `continue_on_failure: false` is default, downstream mutators must depend on this step and will skip.
|
|
66
|
+
|
|
67
|
+
- assume (pre‑exec)
|
|
68
|
+
- Non‑critical: false/error → skip (skipReason=assume); no retry.
|
|
69
|
+
- Critical: false/error → skip and block downstream side‑effects via dependency gating. If you need an explicit failure (not a skip), add a guard step (see Example C below) or (optional) `assume_mode: 'fail'` when available.
|
|
70
|
+
|
|
71
|
+
- guarantee (post‑exec)
|
|
72
|
+
- Non‑critical: violation → add `contract/guarantee_failed` issue; mark failure; route `on_fail`; no auto‑retry unless remediation exists.
|
|
73
|
+
- Critical: violation → mark failure; suppress downstream mutating actions (dependents should depend_on this step). Route `on_fail` to remediation; retries only for transient exec faults, not logical ones.
|
|
74
|
+
|
|
75
|
+
- fail_if (post‑exec)
|
|
76
|
+
- Non‑critical: true → failure; bounded retry only for transient faults; otherwise remediation.
|
|
77
|
+
- Critical: true → failure; do not auto‑retry logical failures; block side‑effects; route remediation with tight caps.
|
|
78
|
+
|
|
79
|
+
- transitions / goto
|
|
80
|
+
- Both: prefer declarative `transitions` first; respect per‑scope loop budgets (default 10; critical recommended 8). Exceeding budget adds `routing/loop_budget_exceeded` and halts routing in that scope.
|
|
81
|
+
|
|
82
|
+
Numeric defaults (recommended)
|
|
83
|
+
- Retries: max 3 (non‑critical), max 2 (critical), exponential backoff with jitter (e.g., 1s, 2s, 4s ±10%).
|
|
84
|
+
- Loop budgets: 10 (non‑critical), 8 (critical/control‑plane branches).
|
|
85
|
+
|
|
86
|
+
## Constructs and Expected Behavior
|
|
87
|
+
|
|
88
|
+
### Quick reference: differences at a glance
|
|
89
|
+
|
|
90
|
+
- Purpose
|
|
91
|
+
- `if`: Scheduling gate — decides whether the step should be scheduled in this run.
|
|
92
|
+
- `assume`: Preconditions — must hold immediately before executing the provider.
|
|
93
|
+
- `guarantee`: Postconditions — must hold for the result the provider produced.
|
|
94
|
+
- `fail_if`: Failure detector — declares which results count as failures.
|
|
95
|
+
|
|
96
|
+
- When it runs
|
|
97
|
+
- `if`: before scheduling (earliest).
|
|
98
|
+
- `assume`: after scheduling, right before calling the provider.
|
|
99
|
+
- `guarantee`: immediately after provider returns.
|
|
100
|
+
- `fail_if`: immediately after provider returns (can co‑exist with `guarantee`).
|
|
101
|
+
|
|
102
|
+
- Inputs visible to the expression
|
|
103
|
+
- `if`: event, env, filesChanged meta, previous check outputs (current wave), memory (read‑only helpers).
|
|
104
|
+
- `assume`: same as `if`, plus fully resolved dependency results for this scope.
|
|
105
|
+
- `guarantee`/`fail_if`: same as `assume`, plus the step’s own output/result.
|
|
106
|
+
|
|
107
|
+
- Effect on execution
|
|
108
|
+
- `if` false (or error): step is skipped and never scheduled.
|
|
109
|
+
- `assume` false (or error): step is skipped right before execution; provider is not called.
|
|
110
|
+
- `guarantee` violation: step has executed; violation adds issues; routes `on_fail`.
|
|
111
|
+
- `fail_if` true: step has executed; marks failure; routes `on_fail`.
|
|
112
|
+
|
|
113
|
+
- Stats/journal
|
|
114
|
+
- `if`/`assume` skip: recorded as a skip; does not count as a run; journal contains an empty result entry.
|
|
115
|
+
- `guarantee`/`fail_if`: counted run; issues recorded; journal contains the full result.
|
|
116
|
+
|
|
117
|
+
- Routing & dependents
|
|
118
|
+
- Skips (`if`/`assume`) propagate gating to dependents unless OR‑deps satisfy or `continue_on_failure` applies on an alternate path.
|
|
119
|
+
- Failures (`guarantee`/`fail_if`) route via `on_fail` with bounded retries/remediation.
|
|
120
|
+
|
|
121
|
+
When to choose which
|
|
122
|
+
- Use `if` when you can decide at plan time whether a step should even be considered (tags, events, coarse repo conditions).
|
|
123
|
+
- Use `assume` when prerequisites depend on dynamic dependencies or environment right before execution (e.g., tools bootstrapped by a `prepare` step).
|
|
124
|
+
- Use `guarantee` when the provider must produce outputs that satisfy invariants (shape, counts, idempotency confirmations).
|
|
125
|
+
- Use `fail_if` when policy/thresholds on the produced results define failure (test counts, lints, security finding thresholds).
|
|
126
|
+
|
|
127
|
+
### 1) `if` (pre‑run gate)
|
|
128
|
+
- Purpose: schedule a step only when conditions are met (event, env, prior outputs).
|
|
129
|
+
- Behavior:
|
|
130
|
+
- `if` true → run.
|
|
131
|
+
- `if` false or evaluation error → skip with reason `if_condition` (does not count as a run); dependents skip unless alternate OR‑deps satisfy.
|
|
132
|
+
- Example:
|
|
133
|
+
```yaml
|
|
134
|
+
checks:
|
|
135
|
+
lint:
|
|
136
|
+
type: command
|
|
137
|
+
on:
|
|
138
|
+
- pr_opened
|
|
139
|
+
- pr_updated
|
|
140
|
+
if: "filesCount > 0 && env.CI === 'true'"
|
|
141
|
+
exec: npx eslint .
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 2) `assume` (preconditions, design‑by‑contract)
|
|
145
|
+
- Purpose: non‑negotiable prerequisites before a step executes.
|
|
146
|
+
- Behavior:
|
|
147
|
+
- Any `assume` expression false → skip with reason `assume`. In critical branches, this blocks dependent mutating steps via dependency gating.
|
|
148
|
+
- No automatic retry unless a defined remediation can satisfy the precondition.
|
|
149
|
+
|
|
150
|
+
Important: `assume` runs before the provider; do not reference this step’s own `output` inside `assume`. Use dependency results (e.g., `outputs['dep']`) or environment/memory. Assertions about this step’s produced data belong in `guarantee`.
|
|
151
|
+
- Example with remediation:
|
|
152
|
+
```yaml
|
|
153
|
+
checks:
|
|
154
|
+
prepare-env:
|
|
155
|
+
type: command
|
|
156
|
+
exec: node scripts/bootstrap.js
|
|
157
|
+
analyze:
|
|
158
|
+
type: command
|
|
159
|
+
depends_on:
|
|
160
|
+
- prepare-env
|
|
161
|
+
assume:
|
|
162
|
+
- "env.TOOLING_READY === 'true'"
|
|
163
|
+
- "Array.isArray(outputs_history['prepare-env']) ? true : true"
|
|
164
|
+
exec: node scripts/analyze.js
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 3) `guarantee` (postconditions, design‑by‑contract)
|
|
168
|
+
- Purpose: invariants that must hold after a step completes.
|
|
169
|
+
- Behavior:
|
|
170
|
+
- Violations add issues with ruleId `contract/guarantee_failed`, mark failure, and route via `on_fail`.
|
|
171
|
+
- In critical branches, violation blocks downstream mutating actions (dependents should be gated on this step) and is not auto‑retried as a logical failure.
|
|
172
|
+
- Example:
|
|
173
|
+
```yaml
|
|
174
|
+
checks:
|
|
175
|
+
summarize:
|
|
176
|
+
type: command
|
|
177
|
+
exec: "node -e \"console.log('{\\"items\\":[1,2,3]}')\""
|
|
178
|
+
guarantee:
|
|
179
|
+
- "output && Array.isArray(output.items)"
|
|
180
|
+
- "output.items.length > 0"
|
|
181
|
+
on_fail:
|
|
182
|
+
run:
|
|
183
|
+
- recompute
|
|
184
|
+
recompute:
|
|
185
|
+
type: command
|
|
186
|
+
exec: node scripts/recompute.js
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### 4) `fail_if` (post‑run failure detector)
|
|
190
|
+
- Purpose: codifies “this result means failure.”
|
|
191
|
+
- Behavior:
|
|
192
|
+
- If true → mark step failed, append `<check>_fail_if` issue, and route `on_fail`.
|
|
193
|
+
- Evaluation errors → log, treat as not triggered (prefer separate system issue).
|
|
194
|
+
- Example with bounded retry/backoff:
|
|
195
|
+
```yaml
|
|
196
|
+
checks:
|
|
197
|
+
tests:
|
|
198
|
+
type: command
|
|
199
|
+
exec: npm test -- --runInBand
|
|
200
|
+
fail_if: "output.summary.failed > 0"
|
|
201
|
+
on_fail:
|
|
202
|
+
retry: { max: 2, backoff: { mode: exponential, delay_ms: 1000 } }
|
|
203
|
+
run:
|
|
204
|
+
- collect-logs
|
|
205
|
+
collect-logs:
|
|
206
|
+
type: command
|
|
207
|
+
exec: node scripts/collect-logs.js
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Declarative Transitions (on_success / on_fail / on_finish)
|
|
211
|
+
Use transitions for clear, testable routing without inline JS logic. If none match, the engine falls back to `goto_js/goto`.
|
|
212
|
+
|
|
213
|
+
Helpers available inside `when`: `outputs`, `outputs_history`, `output`, `event`, `memory`, plus `any/all/none/count`.
|
|
214
|
+
|
|
215
|
+
### Example — Fact Validation Loopback
|
|
216
|
+
```yaml
|
|
217
|
+
checks:
|
|
218
|
+
extract-facts:
|
|
219
|
+
type: ai
|
|
220
|
+
forEach: true
|
|
221
|
+
on_finish:
|
|
222
|
+
transitions:
|
|
223
|
+
- when: "any(outputs_history['validate-fact'], v => v && v.is_valid === false) && event.name === 'issue_opened'"
|
|
224
|
+
to: issue-assistant
|
|
225
|
+
- when: "any(outputs_history['validate-fact'], v => v && v.is_valid === false) && event.name === 'issue_comment'"
|
|
226
|
+
to: comment-assistant
|
|
227
|
+
|
|
228
|
+
validate-fact:
|
|
229
|
+
type: ai
|
|
230
|
+
depends_on:
|
|
231
|
+
- extract-facts
|
|
232
|
+
|
|
233
|
+
issue-assistant:
|
|
234
|
+
type: ai
|
|
235
|
+
on_success:
|
|
236
|
+
transitions:
|
|
237
|
+
- when: "event.name === 'issue_comment' && output?.intent === 'comment_retrigger'"
|
|
238
|
+
to: overview
|
|
239
|
+
goto_event: pr_updated
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## Critical vs Non‑Critical Steps
|
|
243
|
+
|
|
244
|
+
A step is critical when it meets any of:
|
|
245
|
+
- External side effects (mutating: GitHub ops, HTTP methods ≠ GET/HEAD, file writes).
|
|
246
|
+
- Control‑plane impact (forEach parents, on_* that drive goto/run, memory used by conditions).
|
|
247
|
+
- Safety/policy gates (permission checks, strong `fail_if`/`guarantee`).
|
|
248
|
+
- Irreversible/noisy effects (user‑visible posts, ticket creation).
|
|
249
|
+
|
|
250
|
+
Pragmatic marking today:
|
|
251
|
+
- Use `tags: [critical]` (and optionally `internal`, `external`).
|
|
252
|
+
- Heuristics: treat mutating providers as critical by default.
|
|
253
|
+
|
|
254
|
+
Policy matrix (default)
|
|
255
|
+
- Non‑critical: `assume` skip (no retry); `guarantee` → issues + on_fail; `fail_if` → failure; retries only for transient faults.
|
|
256
|
+
- Critical: `assume` violation blocks dependents; `guarantee` violations prevent downstream side‑effects; `fail_if` retried only if transient; tighter loop budgets.
|
|
257
|
+
|
|
258
|
+
## Criticality vs. `continue_on_failure`
|
|
259
|
+
|
|
260
|
+
`continue_on_failure` is a dependency‑gating knob: it decides whether dependents may run after this step fails. It does not fully define criticality. A NASA‑style notion of criticality also governs contracts, retries, loop budgets, side‑effect controls, and escalation paths.
|
|
261
|
+
|
|
262
|
+
Recommended practice:
|
|
263
|
+
|
|
264
|
+
- Use `continue_on_failure` to control gating per edge, but classify steps explicitly as critical or not.
|
|
265
|
+
- Express criticality today via tags, and (optionally) promote to a dedicated field later.
|
|
266
|
+
|
|
267
|
+
### Expressing criticality (current config)
|
|
268
|
+
|
|
269
|
+
- Using tags (immediately usable):
|
|
270
|
+
```yaml
|
|
271
|
+
checks:
|
|
272
|
+
post-comment:
|
|
273
|
+
type: github
|
|
274
|
+
tags:
|
|
275
|
+
- critical
|
|
276
|
+
- external
|
|
277
|
+
on:
|
|
278
|
+
- pr_opened
|
|
279
|
+
op: comment.create
|
|
280
|
+
assume:
|
|
281
|
+
- "env.ALLOW_POST === 'true'"
|
|
282
|
+
guarantee:
|
|
283
|
+
- "typeof output.id === 'number'"
|
|
284
|
+
continue_on_failure: false
|
|
285
|
+
on_fail:
|
|
286
|
+
retry: { max: 2, backoff: { mode: exponential, delay_ms: 1500 } }
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
- Using a proposed field (future‑proof, clearer intent):
|
|
290
|
+
```yaml
|
|
291
|
+
checks:
|
|
292
|
+
label:
|
|
293
|
+
type: github
|
|
294
|
+
criticality: external # or: internal | policy | info
|
|
295
|
+
on:
|
|
296
|
+
- pr_opened
|
|
297
|
+
op: labels.add
|
|
298
|
+
values:
|
|
299
|
+
- "reviewed"
|
|
300
|
+
assume: "isMember()"
|
|
301
|
+
guarantee: "Array.isArray(output.added) && output.added.includes('reviewed')"
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Engine policy derived from criticality (summary):
|
|
305
|
+
|
|
306
|
+
- Critical (external/control‑plane/policy):
|
|
307
|
+
- require meaningful `assume` and `guarantee`.
|
|
308
|
+
- `continue_on_failure: false` by default.
|
|
309
|
+
- retries only for transient faults, with tight caps and backoff.
|
|
310
|
+
- lower routing loop budgets for branches this step drives.
|
|
311
|
+
- suppress downstream mutating side‑effects when guarantees fail.
|
|
312
|
+
- Non‑critical:
|
|
313
|
+
- `assume`/`guarantee` recommended but not mandatory.
|
|
314
|
+
- may set `continue_on_failure: true` to keep non‑critical branches running.
|
|
315
|
+
|
|
316
|
+
### Concrete examples
|
|
317
|
+
|
|
318
|
+
1) Non‑critical compute that may fail without stopping the pipeline:
|
|
319
|
+
```yaml
|
|
320
|
+
checks:
|
|
321
|
+
summarize:
|
|
322
|
+
type: ai
|
|
323
|
+
tags:
|
|
324
|
+
- info
|
|
325
|
+
on:
|
|
326
|
+
- pr_opened
|
|
327
|
+
- pr_updated
|
|
328
|
+
continue_on_failure: true
|
|
329
|
+
fail_if: "(output.errors || []).length > 0"
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
2) External (critical) — posting a PR comment with strict contracts and bounded retries:
|
|
333
|
+
```yaml
|
|
334
|
+
checks:
|
|
335
|
+
post-comment:
|
|
336
|
+
type: github
|
|
337
|
+
tags:
|
|
338
|
+
- critical
|
|
339
|
+
- external
|
|
340
|
+
on:
|
|
341
|
+
- pr_opened
|
|
342
|
+
op: comment.create
|
|
343
|
+
assume:
|
|
344
|
+
- "isMember()"
|
|
345
|
+
- "env.DRY_RUN !== 'true'"
|
|
346
|
+
guarantee:
|
|
347
|
+
- "output && typeof output.id === 'number'"
|
|
348
|
+
continue_on_failure: false
|
|
349
|
+
on_fail:
|
|
350
|
+
retry: { max: 2, backoff: { mode: exponential, delay_ms: 1200 } }
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
3) Control‑plane (critical) — forEach parent that drives routing with a tighter loop budget:
|
|
354
|
+
```yaml
|
|
355
|
+
routing:
|
|
356
|
+
max_loops: 8 # lower than default for safety on control‑plane flows
|
|
357
|
+
|
|
358
|
+
checks:
|
|
359
|
+
extract-items:
|
|
360
|
+
type: command
|
|
361
|
+
tags:
|
|
362
|
+
- critical
|
|
363
|
+
- internal
|
|
364
|
+
exec: "node -e \"console.log('[\\"a\\",\\"b\\",\\"c\\"]')\""
|
|
365
|
+
forEach: true
|
|
366
|
+
on_finish:
|
|
367
|
+
transitions:
|
|
368
|
+
- when: "any(outputs_history['validate'], x => x && x.ok === false)"
|
|
369
|
+
to: remediate
|
|
370
|
+
|
|
371
|
+
validate:
|
|
372
|
+
type: command
|
|
373
|
+
depends_on:
|
|
374
|
+
- extract-items
|
|
375
|
+
fanout: map
|
|
376
|
+
exec: node scripts/validate.js
|
|
377
|
+
|
|
378
|
+
remediate:
|
|
379
|
+
type: command
|
|
380
|
+
exec: node scripts/fix.js
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## Retries, Loop Budgets, and ForEach
|
|
384
|
+
- Retries: bounded (e.g., max 3), exponential backoff with jitter; per‑scope attempt counters stored in memory.
|
|
385
|
+
- Routing loop budget: `routing.max_loops` (default 10) per scope; exceeding emits `routing/loop_budget_exceeded` and halts routing for that scope.
|
|
386
|
+
- ForEach fan‑out:
|
|
387
|
+
- Per‑item retries are independent; partial success allowed; failed items are isolated.
|
|
388
|
+
- Aggregates reflect per‑item outcomes; reduce/map fan‑out is controlled via `fanout: 'reduce' | 'map'` on dependents.
|
|
389
|
+
|
|
390
|
+
### Example — ForEach With Per‑Item Retries
|
|
391
|
+
```yaml
|
|
392
|
+
checks:
|
|
393
|
+
list:
|
|
394
|
+
type: command
|
|
395
|
+
exec: "node -e \"console.log('[\\"a\\",\\"b\\"]')\""
|
|
396
|
+
forEach: true
|
|
397
|
+
|
|
398
|
+
process:
|
|
399
|
+
type: command
|
|
400
|
+
depends_on: [list]
|
|
401
|
+
fanout: map
|
|
402
|
+
exec: node scripts/process-item.js
|
|
403
|
+
fail_if: "output.__failed === true"
|
|
404
|
+
on_fail:
|
|
405
|
+
retry: { max: 1, backoff: { mode: fixed, delay_ms: 500 } }
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
## Observability and Snapshots
|
|
409
|
+
- Every decision is committed to the journal (check id, scope, event, output, issues, timing).
|
|
410
|
+
- Export last run snapshot to JSON for post‑mortem or replay scaffolding:
|
|
411
|
+
```ts
|
|
412
|
+
const engine = new StateMachineExecutionEngine();
|
|
413
|
+
const result = await engine.executeChecks({ checks: ['build'], config });
|
|
414
|
+
await engine.saveSnapshotToFile('run-snapshot.json');
|
|
415
|
+
// const snap = await engine.loadSnapshotFromFile('run-snapshot.json');
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
## Safety Defaults Recap
|
|
419
|
+
- `if`: error → skip (if_condition).
|
|
420
|
+
- `assume`: violation → skip (or block dependents if critical).
|
|
421
|
+
- `guarantee`: violation → add `contract/guarantee_failed` issue; route on_fail.
|
|
422
|
+
- `fail_if`: true → failure; retries only for transient classifications.
|
|
423
|
+
- Loop budgets and retry caps prevent unbounded execution.
|
|
424
|
+
|
|
425
|
+
---
|
|
426
|
+
|
|
427
|
+
For additional examples, see:
|
|
428
|
+
- defaults/visor.yaml (fact validation transitions)
|
|
429
|
+
- tests/unit/routing-transitions-and-contracts.test.ts (transitions, assume/guarantee)
|
|
430
|
+
- docs/engine-state-machine-plan.md (state machine overview)
|
|
431
|
+
|
|
432
|
+
## End-to-End Policy (Do-It-Right Checklist)
|
|
433
|
+
|
|
434
|
+
This section summarizes the full, NASA‑style approach we recommend. Items marked (optional) are enhancements you can phase in.
|
|
435
|
+
|
|
436
|
+
### Config / Schema
|
|
437
|
+
- Criticality (proposed field; tags remain a fallback)
|
|
438
|
+
- `criticality: external | internal | policy | info`
|
|
439
|
+
- or minimal boolean `critical: true|false` if you prefer simplicity.
|
|
440
|
+
- Contracts (implemented)
|
|
441
|
+
- `assume:` preconditions (list of expressions)
|
|
442
|
+
- `guarantee:` postconditions (list of expressions)
|
|
443
|
+
- (optional) `assume_mode: 'skip' | 'fail'` — if set to `fail`, unmet assume marks failure and routes `on_fail`.
|
|
444
|
+
- Transitions (implemented)
|
|
445
|
+
- `on_success|on_fail|on_finish.transitions: [{ when, to, goto_event? }]` with `goto_js` fallback.
|
|
446
|
+
- Retries
|
|
447
|
+
- (proposed) `retry_on: ['transient'] | ['transient','logical']` (default: transient only).
|
|
448
|
+
- Safety profiles (optional)
|
|
449
|
+
- `safety: strict | standard` (global defaults for budgets/retries on critical branches).
|
|
450
|
+
|
|
451
|
+
### Engine Policy (derived from criticality)
|
|
452
|
+
- External / Control‑plane / Policy (critical)
|
|
453
|
+
- Require meaningful `assume` and `guarantee`.
|
|
454
|
+
- Default `continue_on_failure: false`.
|
|
455
|
+
- Retries: bounded (max 2–3), transient faults only; no auto‑retry for logical violations.
|
|
456
|
+
- Lower per‑scope loop budget (e.g., 8 instead of 10).
|
|
457
|
+
- Suppress downstream mutating actions if guarantees/fail_if violate; remediate or escalate.
|
|
458
|
+
- Non‑critical
|
|
459
|
+
- Contracts recommended but not required.
|
|
460
|
+
- `continue_on_failure: true` allowed where safe.
|
|
461
|
+
- Default loop budget (10), normal retry bounds.
|
|
462
|
+
|
|
463
|
+
### Runtime Semantics
|
|
464
|
+
- Evaluation order
|
|
465
|
+
1) `if` (plan‑time scheduling) → 2) `assume` (pre‑exec) → 3) provider → 4) `guarantee` + `fail_if` (post‑exec) → 5) transitions/goto.
|
|
466
|
+
- Determinism & safety
|
|
467
|
+
- Expressions run in a secure sandbox; no I/O/time randomness; short timeouts.
|
|
468
|
+
- ForEach isolation
|
|
469
|
+
- `fanout: map` executes per‑item; failures isolate; reduce aggregates once.
|
|
470
|
+
- (optional) per‑item concurrency with default 1.
|
|
471
|
+
|
|
472
|
+
### Side‑Effect Control
|
|
473
|
+
- Detect mutating providers (GitHub ops except read‑only, HTTP methods ≠ GET/HEAD, file writes).
|
|
474
|
+
- For critical steps: require idempotency or compensating actions; block side‑effects when contracts fail.
|
|
475
|
+
|
|
476
|
+
### Observability / Telemetry
|
|
477
|
+
- Journal each decision (check, scope, expression, inputs, result, timestamps).
|
|
478
|
+
- Emit structured fault events: `fault.detected`, `fault.isolated`, `fault.recovery.*`.
|
|
479
|
+
- Metrics: retries, fault counts by class, loop budget hits.
|
|
480
|
+
|
|
481
|
+
### Persistence / Resume (debug‑first)
|
|
482
|
+
- Export last run as JSON (implemented): `saveSnapshotToFile()`.
|
|
483
|
+
- (future) Debug‑only resume that reconstructs state from snapshot.
|
|
484
|
+
|
|
485
|
+
### Validation / Guardrails
|
|
486
|
+
- Warn if a critical step lacks `assume` or `guarantee`.
|
|
487
|
+
- Warn if mutating provider lacks criticality classification.
|
|
488
|
+
- Warn if `transitions` exist with tight loops disabled in `strict` safety profile.
|
|
489
|
+
- CLI `--safe-mode` to disable mutating providers for dry‑runs.
|
|
490
|
+
|
|
491
|
+
### Verification (Tests & Acceptance Criteria)
|
|
492
|
+
- Unit
|
|
493
|
+
- `assume` skip vs guard‑step hard‑fail.
|
|
494
|
+
- `guarantee` violations add issues; no extra provider calls.
|
|
495
|
+
- Transitions precedence over `goto_js`; loop budget enforcement.
|
|
496
|
+
- Integration
|
|
497
|
+
- Critical external step blocks downstream side‑effects on contract failure.
|
|
498
|
+
- Control‑plane forEach parent with tight budget; verifies no loops past limit.
|
|
499
|
+
- Retry policy honors transient vs logical classification.
|
|
500
|
+
- YAML e2e
|
|
501
|
+
- Updated defaults remain green; include a strict safety profile scenario.
|
|
502
|
+
|
|
503
|
+
### Acceptance Criteria (done when)
|
|
504
|
+
- All tests (unit/integration/YAML) green with critical/non‑critical mixes.
|
|
505
|
+
- Docs updated (this guide + engine plan); examples use block‑style YAML.
|
|
506
|
+
- Logger outputs timestamps; debug is gated.
|
|
507
|
+
- No dist/ committed; config validators warn on unsafe critical steps.
|
|
508
|
+
|
|
509
|
+
## Additional Examples
|
|
510
|
+
|
|
511
|
+
### Critical External Step
|
|
512
|
+
```yaml
|
|
513
|
+
checks:
|
|
514
|
+
post-comment:
|
|
515
|
+
type: github
|
|
516
|
+
criticality: external
|
|
517
|
+
on:
|
|
518
|
+
- pr_opened
|
|
519
|
+
op: comment.create
|
|
520
|
+
assume:
|
|
521
|
+
- "isMember()"
|
|
522
|
+
- "env.DRY_RUN !== 'true'"
|
|
523
|
+
guarantee:
|
|
524
|
+
- "output && typeof output.id === 'number'"
|
|
525
|
+
continue_on_failure: false
|
|
526
|
+
on_fail:
|
|
527
|
+
retry: { max: 2, backoff: { mode: exponential, delay_ms: 1200 } }
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
### Control‑Plane ForEach With Transitions
|
|
531
|
+
```yaml
|
|
532
|
+
routing:
|
|
533
|
+
max_loops: 8
|
|
534
|
+
|
|
535
|
+
checks:
|
|
536
|
+
extract-items:
|
|
537
|
+
type: command
|
|
538
|
+
criticality: internal
|
|
539
|
+
exec: "node -e \"console.log('[\\"a\\",\\"b\\"]')\""
|
|
540
|
+
forEach: true
|
|
541
|
+
on_finish:
|
|
542
|
+
transitions:
|
|
543
|
+
- when: "any(outputs_history['validate'], v => v && v.ok === false)"
|
|
544
|
+
to: remediate
|
|
545
|
+
|
|
546
|
+
validate:
|
|
547
|
+
type: command
|
|
548
|
+
depends_on:
|
|
549
|
+
- extract-items
|
|
550
|
+
fanout: map
|
|
551
|
+
exec: node scripts/validate.js
|
|
552
|
+
|
|
553
|
+
remediate:
|
|
554
|
+
type: command
|
|
555
|
+
exec: node scripts/fix.js
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
## Side‑by‑side examples: the same intent with different constructs
|
|
559
|
+
|
|
560
|
+
### Example A — Skip entirely when the repo has no changes
|
|
561
|
+
Using `if` (best: planning‑time decision):
|
|
562
|
+
```yaml
|
|
563
|
+
checks:
|
|
564
|
+
summarize:
|
|
565
|
+
type: ai
|
|
566
|
+
on:
|
|
567
|
+
- pr_opened
|
|
568
|
+
- pr_updated
|
|
569
|
+
if: "filesCount > 0"
|
|
570
|
+
exec: node scripts/summarize.js
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
Using `assume` (works but later in the lifecycle):
|
|
574
|
+
```yaml
|
|
575
|
+
checks:
|
|
576
|
+
summarize:
|
|
577
|
+
type: ai
|
|
578
|
+
on:
|
|
579
|
+
- pr_opened
|
|
580
|
+
- pr_updated
|
|
581
|
+
assume:
|
|
582
|
+
- "filesCount > 0"
|
|
583
|
+
exec: node scripts/summarize.js
|
|
584
|
+
```
|
|
585
|
+
Both skip the step; `if` prunes earlier, `assume` skips right before calling the provider.
|
|
586
|
+
|
|
587
|
+
### Example B — Ensure outputs obey invariants
|
|
588
|
+
Using `guarantee` (contract):
|
|
589
|
+
```yaml
|
|
590
|
+
checks:
|
|
591
|
+
collect:
|
|
592
|
+
type: command
|
|
593
|
+
exec: "node collect.js" # produces { items: [...] }
|
|
594
|
+
guarantee:
|
|
595
|
+
- "output && Array.isArray(output.items)"
|
|
596
|
+
- "output.items.length > 0"
|
|
597
|
+
on_fail:
|
|
598
|
+
run:
|
|
599
|
+
- recompute
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
Using `fail_if` (policy):
|
|
603
|
+
```yaml
|
|
604
|
+
checks:
|
|
605
|
+
collect:
|
|
606
|
+
type: command
|
|
607
|
+
exec: "node collect.js"
|
|
608
|
+
fail_if: "!(output && Array.isArray(output.items) && output.items.length > 0)"
|
|
609
|
+
on_fail:
|
|
610
|
+
run:
|
|
611
|
+
- recompute
|
|
612
|
+
```
|
|
613
|
+
Both mark the run as failed and route `on_fail`; use `guarantee` for design‑by‑contract semantics, `fail_if` for policy rules.
|
|
614
|
+
|
|
615
|
+
### Example C — “Hard‑fail” on unmet preconditions (guard step pattern)
|
|
616
|
+
If you need an explicit failure instead of a skip for an unmet `assume`, use a guard:
|
|
617
|
+
```yaml
|
|
618
|
+
checks:
|
|
619
|
+
prechecks:
|
|
620
|
+
type: command
|
|
621
|
+
exec: node scripts/check-tools.js # exit 1 when tools missing
|
|
622
|
+
fail_if: "output.exitCode !== 0"
|
|
623
|
+
analyze:
|
|
624
|
+
type: command
|
|
625
|
+
depends_on:
|
|
626
|
+
- prechecks
|
|
627
|
+
exec: node scripts/analyze.js
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
## Comprehensive Example — All Primitives Working Together
|
|
631
|
+
|
|
632
|
+
This end‑to‑end example shows `criticality`, `if`, `assume`, `guarantee`, `fail_if`, and declarative `transitions` in one flow. It includes fan‑out (control‑plane), a policy gate, and an external step with contracts.
|
|
633
|
+
|
|
634
|
+
```yaml
|
|
635
|
+
version: "1.0"
|
|
636
|
+
|
|
637
|
+
routing:
|
|
638
|
+
# Tighter budget recommended for control‑plane loops
|
|
639
|
+
max_loops: 8
|
|
640
|
+
|
|
641
|
+
checks:
|
|
642
|
+
# 1) Control‑plane fan‑out producer
|
|
643
|
+
extract-facts:
|
|
644
|
+
type: command
|
|
645
|
+
criticality: internal
|
|
646
|
+
on:
|
|
647
|
+
- issue_opened
|
|
648
|
+
- issue_comment
|
|
649
|
+
exec: "node -e \"console.log('[{""id"":1,""claim"":""A""},{""id"":2,""claim"":""B""}]')\""
|
|
650
|
+
forEach: true
|
|
651
|
+
# Postconditions: enforce shape and cap fan‑out size
|
|
652
|
+
guarantee:
|
|
653
|
+
- "Array.isArray(output)"
|
|
654
|
+
- "output.every(x => typeof x.id === 'number' && typeof x.claim === 'string')"
|
|
655
|
+
- "output.length <= 50"
|
|
656
|
+
# Route back for remediation when any validation failed
|
|
657
|
+
on_finish:
|
|
658
|
+
transitions:
|
|
659
|
+
- when: "any(outputs_history['validate-fact'], v => v && v.is_valid === false) && event.name === 'issue_opened'"
|
|
660
|
+
to: issue-assistant
|
|
661
|
+
- when: "any(outputs_history['validate-fact'], v => v && v.is_valid === false) && event.name === 'issue_comment'"
|
|
662
|
+
to: comment-assistant
|
|
663
|
+
|
|
664
|
+
# 2) Map fan‑out validator
|
|
665
|
+
validate-fact:
|
|
666
|
+
type: command
|
|
667
|
+
depends_on:
|
|
668
|
+
- extract-facts
|
|
669
|
+
fanout: map
|
|
670
|
+
exec: node scripts/validate-fact.js # -> { is_valid: boolean, errors?: number }
|
|
671
|
+
# declare policy failure
|
|
672
|
+
fail_if: "output && output.is_valid === false"
|
|
673
|
+
on_fail:
|
|
674
|
+
# Only retry transient provider errors (e.g., script crashed), not logical invalids
|
|
675
|
+
retry: { max: 1, backoff: { mode: exponential, delay_ms: 1000 } }
|
|
676
|
+
|
|
677
|
+
# 3) Control‑plane aggregator that computes overall validity
|
|
678
|
+
aggregate:
|
|
679
|
+
type: command
|
|
680
|
+
criticality: internal
|
|
681
|
+
depends_on:
|
|
682
|
+
- validate-fact
|
|
683
|
+
exec: node scripts/aggregate-validity.js # -> { all_valid: boolean }
|
|
684
|
+
guarantee:
|
|
685
|
+
- "output && typeof output.all_valid === 'boolean'"
|
|
686
|
+
on_success:
|
|
687
|
+
transitions:
|
|
688
|
+
- when: "output.all_valid === true"
|
|
689
|
+
to: permission-check
|
|
690
|
+
|
|
691
|
+
# 4) Policy gate (no external side‑effect but gates external actions)
|
|
692
|
+
permission-check:
|
|
693
|
+
type: command
|
|
694
|
+
criticality: policy
|
|
695
|
+
exec: node scripts/check-permissions.js # -> { allowed: boolean }
|
|
696
|
+
guarantee:
|
|
697
|
+
- "typeof output.allowed === 'boolean'"
|
|
698
|
+
|
|
699
|
+
# 5) External action — only runs when policy passes (belt and suspenders)
|
|
700
|
+
post-comment:
|
|
701
|
+
type: github
|
|
702
|
+
criticality: external
|
|
703
|
+
depends_on:
|
|
704
|
+
- permission-check
|
|
705
|
+
on:
|
|
706
|
+
- issue_opened
|
|
707
|
+
# Coarse plan‑time gate (cheap & early)
|
|
708
|
+
if: "outputs['permission-check'] && outputs['permission-check'].allowed === true"
|
|
709
|
+
# Final execution preflight to avoid side‑effects if context shifted
|
|
710
|
+
assume:
|
|
711
|
+
- "outputs['permission-check'] && outputs['permission-check'].allowed === true"
|
|
712
|
+
- "env.DRY_RUN !== 'true'"
|
|
713
|
+
op: comment.create
|
|
714
|
+
guarantee:
|
|
715
|
+
- "output && typeof output.id === 'number'"
|
|
716
|
+
continue_on_failure: false
|
|
717
|
+
|
|
718
|
+
# 6) Non‑critical compute — allowed to fail softly
|
|
719
|
+
summarize:
|
|
720
|
+
type: ai
|
|
721
|
+
criticality: info
|
|
722
|
+
on:
|
|
723
|
+
- issue_opened
|
|
724
|
+
continue_on_failure: true
|
|
725
|
+
fail_if: "(output.errors || []).length > 0"
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
Highlights
|
|
729
|
+
- control‑plane steps (extract-facts, aggregate) carry `assume`/`guarantee` and drive transitions under a tight loop budget.
|
|
730
|
+
- validate-fact uses `fail_if` for policy failure and a bounded retry only for transient provider errors.
|
|
731
|
+
- permission-check (policy) gates external actions without itself mutating external systems.
|
|
732
|
+
- post-comment (external) uses both `if` (early prune) and `assume` (preflight) plus a `guarantee` after posting.
|
|
733
|
+
- summarize shows a non‑critical step with soft failure handling via `continue_on_failure: true`.
|
|
734
|
+
```
|
|
735
|
+
- JSON Schema validation (unified `schema`)
|
|
736
|
+
- `schema: <string>` selects layout/renderer (no validation).
|
|
737
|
+
- `schema: <object>` is a JSON Schema; the engine validates `output` for any provider (ai/command/script/http). Violations create `contract/schema_validation_failed` and follow criticality rules.
|
|
738
|
+
- `output_schema` is deprecated; keep it only for backward compatibility.
|