stageflow 0.25.0 → 0.27.0
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 +10 -3
- package/dist/a2a/contracts.d.ts +1 -0
- package/dist/a2a/contracts.js +1 -0
- package/dist/a2a/registry.d.ts +2 -0
- package/dist/a2a/registry.js +20 -1
- package/dist/a2a/server.d.ts +7 -0
- package/dist/a2a/server.js +5 -2
- package/dist/a2a/service.d.ts +1 -1
- package/dist/a2a/service.js +57 -8
- package/dist/a2a/store.d.ts +8 -5
- package/dist/a2a/store.js +24 -67
- package/dist/agent/activity.d.ts +3 -0
- package/dist/agent/bootProviderConfig.d.ts +21 -0
- package/dist/agent/bootProviderConfig.js +74 -0
- package/dist/agent/piAdapter.d.ts +9 -1
- package/dist/agent/piAdapter.js +58 -3
- package/dist/agent/piIsolatedMcp.d.ts +2 -0
- package/dist/agent/piIsolatedMcp.js +10 -2
- package/dist/agent/port.d.ts +6 -0
- package/dist/agent/streamLogRedact.d.ts +1 -1
- package/dist/agent/streamLogRedact.js +4 -11
- package/dist/cli/artifactCommand.js +9 -16
- package/dist/cli/backupCommand.d.ts +9 -0
- package/dist/cli/backupCommand.js +111 -0
- package/dist/cli/debugRunCommand.d.ts +10 -0
- package/dist/cli/debugRunCommand.js +109 -0
- package/dist/cli/doctorCommand.d.ts +32 -0
- package/dist/cli/doctorCommand.js +453 -0
- package/dist/cli/envelopeCommand.js +9 -2
- package/dist/cli/exportAllCommand.d.ts +55 -0
- package/dist/cli/exportAllCommand.js +218 -0
- package/dist/cli/exportRunCommand.js +23 -21
- package/dist/cli/hostClient.d.ts +21 -3
- package/dist/cli/hostClient.js +93 -12
- package/dist/cli/initTemplates.d.ts +1 -1
- package/dist/cli/initTemplates.js +8 -1
- package/dist/cli/resolveSafeOutPath.d.ts +2 -0
- package/dist/cli/resolveSafeOutPath.js +40 -0
- package/dist/cli/restoreCommand.d.ts +10 -0
- package/dist/cli/restoreCommand.js +90 -0
- package/dist/cli/runCommand.d.ts +3 -2
- package/dist/cli/runCommand.js +93 -11
- package/dist/cli/runOutput.d.ts +4 -0
- package/dist/cli/runOutput.js +33 -7
- package/dist/cli/runStageCommand.d.ts +1 -0
- package/dist/cli/runStageCommand.js +44 -25
- package/dist/cli/runsCommand.d.ts +1 -1
- package/dist/cli/runsCommand.js +162 -8
- package/dist/cli.js +171 -30
- package/dist/config/catalogRelativePath.d.ts +62 -0
- package/dist/config/catalogRelativePath.js +118 -0
- package/dist/config/configOrigin.d.ts +27 -0
- package/dist/config/configOrigin.js +59 -0
- package/dist/config/hostConfig.d.ts +55 -0
- package/dist/config/hostConfig.js +333 -0
- package/dist/config/listSkills.d.ts +26 -0
- package/dist/config/listSkills.js +190 -3
- package/dist/config/loadOutcome.d.ts +1 -1
- package/dist/config/loadPipeline.js +23 -2
- package/dist/config/loadStage.js +18 -0
- package/dist/config/loadTask.d.ts +2 -0
- package/dist/config/loadTask.js +57 -18
- package/dist/config/materializeStageModels.js +5 -1
- package/dist/config/mergePipelineIncludes.d.ts +3 -0
- package/dist/config/mergePipelineIncludes.js +19 -0
- package/dist/config/migrateYaml.js +6 -11
- package/dist/config/multiProjectCatalog.d.ts +30 -0
- package/dist/config/multiProjectCatalog.js +142 -0
- package/dist/config/normalizePipelineStageEntry.js +20 -1
- package/dist/config/pipelineStageKeys.js +2 -0
- package/dist/config/resolveCatalogRoots.d.ts +27 -0
- package/dist/config/resolveCatalogRoots.js +76 -0
- package/dist/config/resolveModel.d.ts +7 -1
- package/dist/config/resolveModel.js +11 -1
- package/dist/config/resolveStageMcpServers.d.ts +9 -1
- package/dist/config/resolveStageMcpServers.js +36 -9
- package/dist/config/secretFromEnvOrFile.d.ts +9 -0
- package/dist/config/secretFromEnvOrFile.js +34 -0
- package/dist/config/seededCatalog.d.ts +11 -0
- package/dist/config/seededCatalog.js +29 -0
- package/dist/config/toolRequires.d.ts +24 -0
- package/dist/config/toolRequires.js +115 -0
- package/dist/config/validateCatalog.d.ts +5 -1
- package/dist/config/validateCatalog.js +140 -1
- package/dist/diagnostics/checks.d.ts +39 -0
- package/dist/diagnostics/checks.js +135 -0
- package/dist/errors/codes.d.ts +14 -0
- package/dist/errors/codes.js +59 -0
- package/dist/git/cache.d.ts +14 -0
- package/dist/git/cache.js +150 -0
- package/dist/git/credentials.d.ts +9 -0
- package/dist/git/credentials.js +88 -0
- package/dist/git/errors.d.ts +20 -0
- package/dist/git/errors.js +94 -0
- package/dist/git/exec.d.ts +16 -0
- package/dist/git/exec.js +135 -0
- package/dist/git/operations.d.ts +29 -0
- package/dist/git/operations.js +153 -0
- package/dist/git/version.d.ts +1 -0
- package/dist/git/version.js +10 -0
- package/dist/logging/audit.d.ts +16 -0
- package/dist/logging/audit.js +19 -0
- package/dist/logging/commonWords.d.ts +2 -0
- package/dist/logging/commonWords.js +13 -0
- package/dist/logging/logger.d.ts +49 -0
- package/dist/logging/logger.js +193 -0
- package/dist/logging/namedSecrets.d.ts +6 -0
- package/dist/logging/namedSecrets.js +58 -0
- package/dist/logging/redact.d.ts +13 -0
- package/dist/logging/redact.js +88 -0
- package/dist/mcp/catalogTools.js +456 -80
- package/dist/mcp/checkoutTools.d.ts +52 -0
- package/dist/mcp/checkoutTools.js +332 -0
- package/dist/mcp/controlTools.js +179 -5
- package/dist/mcp/deps.d.ts +1 -0
- package/dist/mcp/getStartedTool.d.ts +3 -0
- package/dist/mcp/getStartedTool.js +62 -0
- package/dist/mcp/readArtifact.d.ts +11 -0
- package/dist/mcp/readArtifact.js +46 -30
- package/dist/mcp/server.js +1 -0
- package/dist/mcp/tools.js +4 -0
- package/dist/net/proxy.d.ts +14 -0
- package/dist/net/proxy.js +78 -0
- package/dist/package-meta.d.ts +2 -1
- package/dist/package-meta.js +2 -1
- package/dist/preflight/bash.d.ts +8 -0
- package/dist/preflight/bash.js +34 -0
- package/dist/preflight/claudeRoot.d.ts +11 -0
- package/dist/preflight/claudeRoot.js +23 -0
- package/dist/preflight/mcpCommands.d.ts +8 -0
- package/dist/preflight/mcpCommands.js +36 -0
- package/dist/preflight/pipelinePreflight.d.ts +40 -0
- package/dist/preflight/pipelinePreflight.js +192 -0
- package/dist/preflight/tls.d.ts +6 -0
- package/dist/preflight/tls.js +18 -0
- package/dist/preflight/toolchain.d.ts +45 -0
- package/dist/preflight/toolchain.js +219 -0
- package/dist/project/findProjectRoot.js +3 -4
- package/dist/project/globalHome.d.ts +7 -0
- package/dist/project/globalHome.js +63 -2
- package/dist/project/resolveProjectContext.js +2 -2
- package/dist/project/resolveStageflowContext.js +2 -2
- package/dist/projection/projectRun.d.ts +2 -1
- package/dist/projection/projectRun.js +1 -0
- package/dist/runstore/assertTmpdir.d.ts +1 -0
- package/dist/runstore/assertTmpdir.js +21 -0
- package/dist/runstore/backup.d.ts +52 -0
- package/dist/runstore/backup.js +292 -0
- package/dist/runstore/createStore.d.ts +18 -1
- package/dist/runstore/createStore.js +64 -5
- package/dist/runstore/debugBundle.d.ts +60 -0
- package/dist/runstore/debugBundle.js +143 -0
- package/dist/runstore/diskUsage.d.ts +50 -0
- package/dist/runstore/diskUsage.js +214 -0
- package/dist/runstore/exportRunPayload.d.ts +8 -0
- package/dist/runstore/exportRunPayload.js +23 -0
- package/dist/runstore/normalizeCatalogPath.d.ts +1 -0
- package/dist/runstore/normalizeCatalogPath.js +10 -0
- package/dist/runstore/paths.d.ts +5 -0
- package/dist/runstore/paths.js +145 -1
- package/dist/runstore/port.d.ts +111 -13
- package/dist/runstore/port.js +8 -1
- package/dist/runstore/restore.d.ts +81 -0
- package/dist/runstore/restore.js +355 -0
- package/dist/runstore/retention.d.ts +27 -0
- package/dist/runstore/retention.js +74 -0
- package/dist/runstore/runManifest.d.ts +146 -0
- package/dist/runstore/runManifest.js +288 -0
- package/dist/runstore/runProjection.d.ts +3 -1
- package/dist/runstore/runProjection.js +63 -1
- package/dist/runstore/sqlite/SqliteRunStore.d.ts +28 -3
- package/dist/runstore/sqlite/SqliteRunStore.js +352 -219
- package/dist/runstore/sqlite/applyStorePragmas.d.ts +39 -0
- package/dist/runstore/sqlite/applyStorePragmas.js +145 -0
- package/dist/runstore/sqlite/migrations/001-baseline.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/001-baseline.js +10 -0
- package/dist/runstore/sqlite/migrations/002-repository-binding.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/002-repository-binding.js +29 -0
- package/dist/runstore/sqlite/migrations/003-run-lifecycle.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/003-run-lifecycle.js +28 -0
- package/dist/runstore/sqlite/migrations/004-auto-resume-count.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/004-auto-resume-count.js +19 -0
- package/dist/runstore/sqlite/migrations/005-config-origins.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/005-config-origins.js +19 -0
- package/dist/runstore/sqlite/migrations/006-pipeline-body-and-caller.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/006-pipeline-body-and-caller.js +28 -0
- package/dist/runstore/sqlite/migrations/007-projects-registry.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/007-projects-registry.js +31 -0
- package/dist/runstore/sqlite/migrations/index.d.ts +21 -0
- package/dist/runstore/sqlite/migrations/index.js +72 -0
- package/dist/runstore/sqlite/schema.d.ts +20 -1
- package/dist/runstore/sqlite/schema.js +277 -1
- package/dist/runstore/sqlite/storeOpenError.d.ts +6 -0
- package/dist/runstore/sqlite/storeOpenError.js +11 -0
- package/dist/runstore/sqlite/storeSchemaError.d.ts +5 -0
- package/dist/runstore/sqlite/storeSchemaError.js +8 -0
- package/dist/runstore/stageExecution.js +3 -0
- package/dist/runstore/storeFilesystem.d.ts +32 -0
- package/dist/runstore/storeFilesystem.js +148 -0
- package/dist/runstore/trackProjection.js +2 -0
- package/dist/runstore/workspaceLayout.d.ts +13 -0
- package/dist/runstore/workspaceLayout.js +76 -0
- package/dist/runtime/completionCheckRunner.d.ts +3 -0
- package/dist/runtime/completionCheckRunner.js +45 -7
- package/dist/runtime/containerLimits.d.ts +16 -0
- package/dist/runtime/containerLimits.js +84 -0
- package/dist/runtime/credentialMaterialisation.d.ts +28 -0
- package/dist/runtime/credentialMaterialisation.js +128 -0
- package/dist/runtime/gitCheckoutCapability.js +7 -13
- package/dist/runtime/pipelineRunner.d.ts +36 -1
- package/dist/runtime/pipelineRunner.js +178 -17
- package/dist/runtime/pipelineScheduler.d.ts +15 -0
- package/dist/runtime/pipelineScheduler.js +135 -27
- package/dist/runtime/reloadRunCatalog.js +6 -1
- package/dist/runtime/repositoryMaterialize.d.ts +47 -0
- package/dist/runtime/repositoryMaterialize.js +235 -0
- package/dist/runtime/resumeTimedOut.d.ts +1 -1
- package/dist/runtime/resumeTimedOut.js +5 -2
- package/dist/runtime/runChangeBus.js +9 -0
- package/dist/runtime/runDeletion.d.ts +7 -0
- package/dist/runtime/runDeletion.js +37 -0
- package/dist/runtime/runManager.d.ts +158 -4
- package/dist/runtime/runManager.js +1596 -79
- package/dist/runtime/runRetentionSweep.d.ts +31 -0
- package/dist/runtime/runRetentionSweep.js +328 -0
- package/dist/runtime/runRetryCoordinator.d.ts +2 -0
- package/dist/runtime/runRetryCoordinator.js +19 -2
- package/dist/runtime/runSkills.d.ts +40 -0
- package/dist/runtime/runSkills.js +173 -0
- package/dist/runtime/stageAttemptBootstrap.d.ts +5 -1
- package/dist/runtime/stageAttemptBootstrap.js +195 -24
- package/dist/runtime/stageCacheEnv.d.ts +6 -0
- package/dist/runtime/stageCacheEnv.js +34 -0
- package/dist/runtime/stageConcurrency.d.ts +2 -1
- package/dist/runtime/stageConcurrency.js +4 -2
- package/dist/runtime/stageEnvironment.d.ts +38 -0
- package/dist/runtime/stageEnvironment.js +193 -0
- package/dist/runtime/stageProcessLauncher.d.ts +18 -0
- package/dist/runtime/stageProcessLauncher.js +194 -38
- package/dist/runtime/stageRecovery.d.ts +3 -1
- package/dist/runtime/stageRecovery.js +19 -4
- package/dist/runtime/stageRoots.d.ts +38 -1
- package/dist/runtime/stageRoots.js +118 -0
- package/dist/runtime/stageRunner.d.ts +1 -0
- package/dist/runtime/stageRunner.js +3 -1
- package/dist/runtime/stageSecretDecl.d.ts +9 -0
- package/dist/runtime/stageSecretDecl.js +102 -0
- package/dist/runtime/stageSecrets.d.ts +40 -0
- package/dist/runtime/stageSecrets.js +181 -0
- package/dist/runtime/stageWorker.d.ts +3 -2
- package/dist/runtime/stageWorker.js +58 -10
- package/dist/runtime/stageWorkerProtocol.d.ts +5 -0
- package/dist/runtime/stageWorkerProtocol.js +8 -0
- package/dist/runtime/startPayload.d.ts +32 -0
- package/dist/runtime/startPayload.js +59 -0
- package/dist/runtime/taskInput.js +14 -5
- package/dist/runtime/verifiedStageExecution.d.ts +1 -0
- package/dist/runtime/verifiedStageExecution.js +2 -1
- package/dist/runtime/workspaceBinding.d.ts +20 -0
- package/dist/runtime/workspaceBinding.js +60 -0
- package/dist/server/allowedHosts.d.ts +19 -0
- package/dist/server/allowedHosts.js +179 -0
- package/dist/server/bootstrap.d.ts +36 -2
- package/dist/server/bootstrap.js +209 -5
- package/dist/server/controlToken.d.ts +47 -0
- package/dist/server/controlToken.js +241 -0
- package/dist/server/createHttpHost.d.ts +11 -2
- package/dist/server/createHttpHost.js +103 -10
- package/dist/server/ensureGlobalService.d.ts +5 -1
- package/dist/server/ensureGlobalService.js +35 -1
- package/dist/server/healthSurfaces.d.ts +6 -0
- package/dist/server/healthSurfaces.js +98 -0
- package/dist/server/http.d.ts +12 -1
- package/dist/server/http.js +1085 -485
- package/dist/server/listenHost.d.ts +5 -0
- package/dist/server/listenHost.js +56 -0
- package/dist/server/mcpHost.d.ts +10 -1
- package/dist/server/mcpHost.js +36 -6
- package/dist/server/operatorResults.d.ts +2 -2
- package/dist/server/operatorResults.js +40 -29
- package/dist/server/requestAuthContext.d.ts +12 -0
- package/dist/server/requestAuthContext.js +21 -0
- package/dist/server/shutdown.d.ts +69 -0
- package/dist/server/shutdown.js +219 -0
- package/dist/types/pipeline.d.ts +7 -0
- package/dist/types/stage.d.ts +8 -0
- package/dist/types/task.d.ts +8 -0
- package/dist/ui/assets/index-B6hlSXXn.js +120 -0
- package/dist/ui/index.html +1 -1
- package/examples/README.md +98 -0
- package/examples/archify-on-pr/README.md +213 -0
- package/examples/archify-on-pr/archify-on-pr.pipeline.yaml +19 -0
- package/examples/archify-on-pr/archify-on-pr.task.yaml +19 -0
- package/examples/archify-on-pr/author-diagrams.yaml +106 -0
- package/examples/archify-on-pr/detect-changes.yaml +89 -0
- package/examples/ci-validate/README.md +35 -0
- package/examples/ci-validate/check.yaml +13 -0
- package/examples/ci-validate/ci-demo.pipeline.yaml +4 -0
- package/examples/ci-validate/validate.sh +5 -0
- package/examples/compliance-review-demo/README.md +125 -0
- package/examples/compliance-review-demo/compliance-review-demo.pipeline.yaml +29 -0
- package/examples/compliance-review-demo/connect-account.yaml +47 -0
- package/examples/compliance-review-demo/map-to-control.yaml +123 -0
- package/examples/compliance-review-demo/poll-bucket-config.yaml +103 -0
- package/examples/compliance-review-demo/publish-report.yaml +79 -0
- package/examples/compliance-review-demo/review-verdict.yaml +122 -0
- package/examples/compliance-review-demo/run-compliance-check.yaml +96 -0
- package/examples/compliance-review-demo/store-evidence.yaml +143 -0
- package/examples/conditional-fork/README.md +89 -0
- package/examples/conditional-fork/branch-a.yaml +13 -0
- package/examples/conditional-fork/branch-b.yaml +13 -0
- package/examples/conditional-fork/decide.yaml +35 -0
- package/examples/conditional-fork/fork-demo.pipeline.yaml +20 -0
- package/examples/conditional-fork/fork-demo.task.yaml +8 -0
- package/examples/context7-mcp/README.md +42 -0
- package/examples/context7-mcp/context7-mcp.pipeline.yaml +15 -0
- package/examples/context7-mcp/context7-mcp.task.yaml +4 -0
- package/examples/context7-mcp/fetch-docs.yaml +52 -0
- package/examples/context7-mcp/resolve-library.yaml +31 -0
- package/examples/context7-mcp/write-brief.yaml +52 -0
- package/examples/feature-loop/README.md +104 -0
- package/examples/feature-loop/address-feedback.yaml +148 -0
- package/examples/feature-loop/align.yaml +116 -0
- package/examples/feature-loop/decompose.yaml +86 -0
- package/examples/feature-loop/default-model-hierarchy.task.yaml +58 -0
- package/examples/feature-loop/feature-loop.pipeline.yaml +140 -0
- package/examples/feature-loop/feature-loop.task.yaml +25 -0
- package/examples/feature-loop/implement.yaml +128 -0
- package/examples/feature-loop/plan.yaml +111 -0
- package/examples/feature-loop/publish.yaml +167 -0
- package/examples/feature-loop/review.yaml +146 -0
- package/examples/feature-loop/verify.yaml +106 -0
- package/examples/feedback-loop/README.md +72 -0
- package/examples/feedback-loop/VERIFY.md +208 -0
- package/examples/feedback-loop/continue-only.task.yaml +4 -0
- package/examples/feedback-loop/exhaust-require-continue.task.yaml +6 -0
- package/examples/feedback-loop/exhaust-wait-human.task.yaml +11 -0
- package/examples/feedback-loop/feedback-loop-wait-human.pipeline.yaml +23 -0
- package/examples/feedback-loop/feedback-loop.pipeline.yaml +23 -0
- package/examples/feedback-loop/feedback-loop.task.yaml +4 -0
- package/examples/feedback-loop/implement.yaml +14 -0
- package/examples/feedback-loop/plan.yaml +14 -0
- package/examples/feedback-loop/review.yaml +15 -0
- package/examples/feedback-loop/send-back-once.task.yaml +6 -0
- package/examples/feedback-loop/submit.yaml +12 -0
- package/examples/generic-fan-in/README.md +151 -0
- package/examples/generic-fan-in/clarify.yaml +18 -0
- package/examples/generic-fan-in/generic-fan-in-accepted.pipeline.yaml +19 -0
- package/examples/generic-fan-in/generic-fan-in-accepted.task.yaml +8 -0
- package/examples/generic-fan-in/generic-fan-in.pipeline.yaml +18 -0
- package/examples/generic-fan-in/generic-fan-in.task.yaml +9 -0
- package/examples/generic-fan-in/research.yaml +45 -0
- package/examples/generic-fan-in/synthesize.yaml +66 -0
- package/examples/generic-fan-in/validation.yaml +45 -0
- package/examples/github-release/README.md +78 -0
- package/examples/github-release/draft-release-notes.yaml +64 -0
- package/examples/github-release/github-release.pipeline.yaml +11 -0
- package/examples/github-release/github-release.task.yaml +13 -0
- package/examples/github-release/publish-github-release.yaml +64 -0
- package/examples/hello-world/README.md +28 -0
- package/examples/hello-world/hello.pipeline.yaml +4 -0
- package/examples/hello-world/my-task.task.yaml +6 -0
- package/examples/hello-world/research.yaml +18 -0
- package/examples/mcp-hitl-tour/README.md +113 -0
- package/examples/mcp-hitl-tour/draft-angle.yaml +33 -0
- package/examples/mcp-hitl-tour/draft-short.yaml +32 -0
- package/examples/mcp-hitl-tour/emit-angles.yaml +45 -0
- package/examples/mcp-hitl-tour/gather.yaml +31 -0
- package/examples/mcp-hitl-tour/intake.yaml +62 -0
- package/examples/mcp-hitl-tour/mcp-hitl-tour-exhaust.task.yaml +13 -0
- package/examples/mcp-hitl-tour/mcp-hitl-tour.pipeline.yaml +54 -0
- package/examples/mcp-hitl-tour/mcp-hitl-tour.task.yaml +16 -0
- package/examples/mcp-hitl-tour/polish.yaml +33 -0
- package/examples/mcp-hitl-tour/review.yaml +17 -0
- package/examples/mcp-hitl-tour/ship.yaml +25 -0
- package/examples/oss-issue-contribution/README.md +218 -0
- package/examples/oss-issue-contribution/oss-address-review-feedback.yaml +117 -0
- package/examples/oss-issue-contribution/oss-approve-contribution.yaml +181 -0
- package/examples/oss-issue-contribution/oss-approve-plan.yaml +111 -0
- package/examples/oss-issue-contribution/oss-explain-fix.yaml +108 -0
- package/examples/oss-issue-contribution/oss-explain-issue.yaml +114 -0
- package/examples/oss-issue-contribution/oss-implement-source-fix.yaml +171 -0
- package/examples/oss-issue-contribution/oss-investigate-area.yaml +116 -0
- package/examples/oss-issue-contribution/oss-issue-contribution.pipeline.yaml +125 -0
- package/examples/oss-issue-contribution/oss-issue-intake.yaml +106 -0
- package/examples/oss-issue-contribution/oss-plan-investigation.yaml +112 -0
- package/examples/oss-issue-contribution/oss-plan-review.yaml +109 -0
- package/examples/oss-issue-contribution/oss-reproduce-issue.yaml +140 -0
- package/examples/oss-issue-contribution/oss-review-change.yaml +107 -0
- package/examples/oss-issue-contribution/oss-verify-fix.yaml +130 -0
- package/examples/oss-issue-contribution/oss-write-regression-test.yaml +135 -0
- package/examples/oss-issue-contribution/pi-7629.task.yaml +79 -0
- package/examples/oss-issue-contribution/pi-8919.task.yaml +75 -0
- package/examples/oss-issue-contribution/pydantic-ai-7971.task.yaml +53 -0
- package/examples/oss-quick-fix/README.md +65 -0
- package/examples/oss-quick-fix/implement-fix.yaml +84 -0
- package/examples/oss-quick-fix/oss-quick-fix.pipeline.yaml +35 -0
- package/examples/oss-quick-fix/oss-quick-fix.task.yaml +19 -0
- package/examples/oss-quick-fix/ship-fix.yaml +81 -0
- package/examples/oss-quick-fix/understand-issue.yaml +67 -0
- package/examples/oss-quick-fix/verify-fix.yaml +73 -0
- package/examples/plan-review/README.md +37 -0
- package/examples/plan-review/plan-review-followup.yaml +13 -0
- package/examples/plan-review/plan-review.pipeline.yaml +9 -0
- package/examples/plan-review/plan-review.task.yaml +9 -0
- package/examples/plan-review/plan-review.yaml +25 -0
- package/examples/playwright-mcp/README.md +39 -0
- package/examples/playwright-mcp/playwright-mcp.pipeline.yaml +5 -0
- package/examples/playwright-mcp/playwright-mcp.task.yaml +4 -0
- package/examples/playwright-mcp/screenshot.yaml +40 -0
- package/examples/retry-tour/README.md +75 -0
- package/examples/retry-tour/retry-tour.pipeline.yaml +122 -0
- package/examples/retry-tour/retry-tour.task.yaml +9 -0
- package/examples/route-if-tour/README.md +202 -0
- package/examples/route-if-tour/route-if-tour.pipeline.yaml +950 -0
- package/examples/route-if-tour/route-if-tour.task.yaml +4 -0
- package/examples/route-wiring-smoke-test/01-core-routing.pipeline.yaml +168 -0
- package/examples/route-wiring-smoke-test/02-on-gating.pipeline.yaml +44 -0
- package/examples/route-wiring-smoke-test/03-two-entry-points.pipeline.yaml +28 -0
- package/examples/route-wiring-smoke-test/04-entry-false-equivalent-to-omitted.pipeline.yaml +27 -0
- package/examples/route-wiring-smoke-test/05-fork-choice.pipeline.yaml +110 -0
- package/examples/route-wiring-smoke-test/06-fan-out-fan-in.pipeline.yaml +82 -0
- package/examples/route-wiring-smoke-test/07-loop-human-decision.pipeline.yaml +82 -0
- package/examples/route-wiring-smoke-test/08-skip-fallback-and-multi-on-gate.pipeline.yaml +77 -0
- package/examples/route-wiring-smoke-test/09-multi-loop-targets.pipeline.yaml +102 -0
- package/examples/route-wiring-smoke-test/10-uses-dialect-fork.pipeline.yaml +23 -0
- package/examples/route-wiring-smoke-test/11-sequential-io-handoff.pipeline.yaml +37 -0
- package/examples/route-wiring-smoke-test/12-complex-io-schemas.pipeline.yaml +138 -0
- package/examples/route-wiring-smoke-test/13-ref-io-handoff.pipeline.yaml +84 -0
- package/examples/route-wiring-smoke-test/14-if-eq-gating.pipeline.yaml +50 -0
- package/examples/route-wiring-smoke-test/15-if-all-gated.pipeline.yaml +37 -0
- package/examples/route-wiring-smoke-test/16-if-composition.pipeline.yaml +65 -0
- package/examples/route-wiring-smoke-test/17-if-join.pipeline.yaml +80 -0
- package/examples/route-wiring-smoke-test/README.md +377 -0
- package/examples/route-wiring-smoke-test/rejected/01-reject-legacy-needs.pipeline.yaml +26 -0
- package/examples/route-wiring-smoke-test/rejected/02-reject-legacy-fork.pipeline.yaml +25 -0
- package/examples/route-wiring-smoke-test/rejected/03-reject-legacy-feedback-loop.pipeline.yaml +30 -0
- package/examples/route-wiring-smoke-test/rejected/04-reject-missing-entry.pipeline.yaml +24 -0
- package/examples/route-wiring-smoke-test/rejected/05-reject-unreachable.pipeline.yaml +35 -0
- package/examples/route-wiring-smoke-test/rejected/06-reject-allow-none-without-route-select.pipeline.yaml +37 -0
- package/examples/route-wiring-smoke-test/rejected/07-reject-cycle.pipeline.yaml +27 -0
- package/examples/route-wiring-smoke-test/rejected/08-reject-loop-non-ancestor.pipeline.yaml +42 -0
- package/examples/route-wiring-smoke-test/rejected/09-reject-route-select-leaf.pipeline.yaml +26 -0
- package/examples/route-wiring-smoke-test/rejected/12-reject-loop-replay-unsafe.pipeline.yaml +55 -0
- package/examples/route-wiring-smoke-test/rejected/13-reject-multiple-loop-entries.pipeline.yaml +51 -0
- package/examples/route-wiring-smoke-test/rejected/14-reject-duplicate-stage-id.pipeline.yaml +35 -0
- package/examples/route-wiring-smoke-test/rejected/15-reject-unknown-route-target.pipeline.yaml +15 -0
- package/examples/route-wiring-smoke-test/rejected/16-reject-malformed-route-item.pipeline.yaml +15 -0
- package/examples/route-wiring-smoke-test/rejected/17-reject-io-incompatible.pipeline.yaml +33 -0
- package/examples/route-wiring-smoke-test/rejected/18-reject-nested-io.pipeline.yaml +51 -0
- package/examples/route-wiring-smoke-test/rejected/19-reject-array-item-io.pipeline.yaml +55 -0
- package/examples/route-wiring-smoke-test/rejected/20-reject-closed-io.pipeline.yaml +36 -0
- package/examples/route-wiring-smoke-test/rejected/21-reject-ref-io.pipeline.yaml +42 -0
- package/examples/route-wiring-smoke-test/rejected/22-reject-if-unknown-field.pipeline.yaml +33 -0
- package/examples/route-wiring-smoke-test/rejected/23-reject-if-optional-field.pipeline.yaml +32 -0
- package/examples/route-wiring-smoke-test/rejected/24-reject-if-empty-all.pipeline.yaml +31 -0
- package/examples/route-wiring-smoke-test/rejected/25-reject-if-gt-on-string.pipeline.yaml +33 -0
- package/examples/route-wiring-smoke-test/rejected/26-reject-if-optional-nested.pipeline.yaml +36 -0
- package/examples/route-wiring-smoke-test/rejected/27-reject-if-on-loop.pipeline.yaml +63 -0
- package/examples/route-wiring-smoke-test/rejected/29-reject-if-on-failed.pipeline.yaml +46 -0
- package/examples/route-wiring-smoke-test/smoke-test.task.yaml +4 -0
- package/examples/route-wiring-smoke-test/stages/branch-a.yaml +12 -0
- package/examples/route-wiring-smoke-test/stages/branch-b.yaml +12 -0
- package/examples/route-wiring-smoke-test/stages/decide.yaml +12 -0
- package/examples/route-wiring-smoke-test/stages/finish.yaml +12 -0
- package/examples/ship-feature/README.md +190 -0
- package/examples/ship-feature/feat-address-feedback.yaml +119 -0
- package/examples/ship-feature/feat-implement.yaml +180 -0
- package/examples/ship-feature/feat-plan.yaml +120 -0
- package/examples/ship-feature/feat-review.yaml +109 -0
- package/examples/ship-feature/feat-ship.yaml +203 -0
- package/examples/ship-feature/ship-feature.pipeline.yaml +44 -0
- package/examples/ship-feature/ship-feature.task.yaml +78 -0
- package/examples/stage-mcp/README.md +144 -0
- package/examples/stage-mcp/echo-mcp.mjs +20 -0
- package/examples/stage-mcp/stage-mcp-dead.pipeline.yaml +5 -0
- package/examples/stage-mcp/stage-mcp-dead.task.yaml +3 -0
- package/examples/stage-mcp/stage-mcp-missing-var.pipeline.yaml +5 -0
- package/examples/stage-mcp/stage-mcp-missing-var.task.yaml +3 -0
- package/examples/stage-mcp/stage-mcp.pipeline.yaml +5 -0
- package/examples/stage-mcp/stage-mcp.task.yaml +4 -0
- package/examples/stage-mcp/use-echo.yaml +20 -0
- package/examples/verify-tour/README.md +80 -0
- package/examples/verify-tour/verify-tour.pipeline.yaml +162 -0
- package/examples/verify-tour/verify-tour.task.yaml +11 -0
- package/package.json +5 -1
- package/skills/stageflow/SKILL.md +6 -6
- package/skills/stageflow/references/control-surface.md +11 -5
- package/skills/stageflow/scripts/detect-host.mjs +14 -1
- package/skills/stageflow/scripts/detect-host.test.mjs +29 -1
- package/skills/stageflow-author/SKILL.md +4 -3
- package/skills/stageflow-author/references/catalog-mapping.md +16 -0
- package/skills/stageflow-author/references/catalog-write-conventions.md +1 -1
- package/skills/stageflow-run/SKILL.md +20 -12
- package/skills/stageflow-run/references/mcp-call.md +9 -1
- package/skills/stageflow-run/references/task-and-pipeline-selection.md +16 -5
- package/skills/stageflow-run/scripts/mcp-call.mjs +46 -6
- package/skills/stageflow-run/scripts/mcp-call.test.mjs +64 -0
- package/skills/stageflow-session-capture/references/catalog-authoring.md +2 -0
- package/skills/stageflow-setup/SKILL.md +40 -8
- package/dist/ui/assets/index-Da5EHU6M.js +0 -119
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# compliance-review-demo
|
|
2
|
+
|
|
3
|
+
A demo of a Stageflow pipeline built for unattended, scheduled compliance
|
|
4
|
+
checking. A SOC2-style bucket public-access check is the working example —
|
|
5
|
+
the point is the *pattern*: connect, poll, check, map to a control, log
|
|
6
|
+
evidence, publish a report, safe to run on a cron schedule with nobody
|
|
7
|
+
watching. It runs against a real AWS S3 bucket, a real GCS bucket, or a
|
|
8
|
+
simulated fixture, whichever `poll-bucket-config` finds available.
|
|
9
|
+
|
|
10
|
+
Verified end to end against a real GCS bucket — see [Verified against real
|
|
11
|
+
infra](#verified-against-real-infra) below for the actual run data.
|
|
12
|
+
|
|
13
|
+
## What this demonstrates
|
|
14
|
+
|
|
15
|
+
- **Never blocks, still tells the difference.** `review-verdict.yaml` reads
|
|
16
|
+
the checked-in evidence log and compares this run's verdict to the last
|
|
17
|
+
one recorded for the same check. A first-time failure or a repeat result
|
|
18
|
+
gets `reviewer: "auto"`. A flip (FAIL → PASS or back) gets
|
|
19
|
+
`reviewer: "unreviewed-flip"` instead — same non-blocking success either
|
|
20
|
+
way, so nothing about a schedule or a CI runner can get this stage stuck
|
|
21
|
+
waiting on a person. The distinction lives in the evidence, not in a gate.
|
|
22
|
+
- **State that persists across runs.** `store-evidence.yaml` appends to a
|
|
23
|
+
checkout file (`data/evidence-log.json`, gitignored — see below) instead
|
|
24
|
+
of a per-attempt artifact, so `review-verdict` can compare "this run"
|
|
25
|
+
against "last run" days or weeks apart. `store-evidence.yaml` carries an
|
|
26
|
+
after-phase `verify` check (`type: checkout_changes`,
|
|
27
|
+
`path_fields: [changed_files]`) so the stage can't succeed without a real
|
|
28
|
+
edit to that file.
|
|
29
|
+
- **One report stage, swappable target.** `publish-report.yaml` writes a
|
|
30
|
+
markdown timeline as a stage artifact today. Point that same stage at a
|
|
31
|
+
Confluence or Notion API instead and nothing upstream of it changes —
|
|
32
|
+
the other six stages don't know or care where the report ends up.
|
|
33
|
+
|
|
34
|
+
Full design writeup (why this exists instead of just running Prowler in a
|
|
35
|
+
GitHub Action, or self-hosting an existing open-source tool like Comp AI):
|
|
36
|
+
see the project conversation this came from.
|
|
37
|
+
|
|
38
|
+
## Prerequisites
|
|
39
|
+
|
|
40
|
+
- Node.js ≥ 20, Stageflow installed (`npm i -g stageflow`)
|
|
41
|
+
- A configured provider (`sf providers status`; at least one row
|
|
42
|
+
`configured`)
|
|
43
|
+
- No cloud account needed — without a working `gcloud` or `aws` CLI on
|
|
44
|
+
PATH, `poll-bucket-config` simulates the check instead, clearly labeled
|
|
45
|
+
as simulated.
|
|
46
|
+
|
|
47
|
+
### Testing against a real bucket
|
|
48
|
+
|
|
49
|
+
`poll-bucket-config` tries `gcloud` first, then `aws`, then falls back to
|
|
50
|
+
simulated. To point it at a real bucket:
|
|
51
|
+
|
|
52
|
+
- **GCS**: have `gcloud` authenticated (`gcloud auth list` shows an active
|
|
53
|
+
account) and pass that bucket's bare name (no `gs://`) as `bucket` in the
|
|
54
|
+
task input. It reads `public_access_prevention` and
|
|
55
|
+
`uniform_bucket_level_access` from `gcloud storage buckets describe`, and
|
|
56
|
+
checks `gcloud storage buckets get-iam-policy` for any `allUsers` /
|
|
57
|
+
`allAuthenticatedUsers` binding. `scenario` is ignored in this path — the
|
|
58
|
+
bucket's real state decides the verdict, so to see a flip you need to
|
|
59
|
+
actually change the bucket's settings between runs (e.g. toggle uniform
|
|
60
|
+
bucket-level access), not just change `scenario`.
|
|
61
|
+
- **AWS S3**: have `aws` authenticated and pass the bucket name; it calls
|
|
62
|
+
`aws s3api get-public-access-block` directly, same field names.
|
|
63
|
+
|
|
64
|
+
The four fields it maps to (`block_public_acls`, `ignore_public_acls`,
|
|
65
|
+
`block_public_policy`, `restrict_public_buckets`) are cloud-agnostic — for
|
|
66
|
+
GCS they're a translation, not a literal setting name, and the stage writes
|
|
67
|
+
both the raw `gcloud` fields and the translated ones to its artifact so the
|
|
68
|
+
mapping is never hidden.
|
|
69
|
+
|
|
70
|
+
## Commands
|
|
71
|
+
|
|
72
|
+
From the **repository git root**:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
sf validate --pipeline examples/compliance-review-demo/compliance-review-demo.pipeline.yaml --strict
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Use the `stageflow-run` job to build a task with a payload like
|
|
79
|
+
`{ "bucket": "customer-uploads", "scenario": "fail" }`, or point `sf run`
|
|
80
|
+
at it directly:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
sf run \
|
|
84
|
+
--pipeline examples/compliance-review-demo/compliance-review-demo.pipeline.yaml \
|
|
85
|
+
--task <path> \
|
|
86
|
+
--json
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Never pauses, so it's safe to call from a non-interactive runner — a
|
|
90
|
+
nightly GitHub Action, a Cloud Scheduler → Cloud Run job, an EventBridge
|
|
91
|
+
Scheduler → Fargate task, or any cron.
|
|
92
|
+
|
|
93
|
+
## Verified against real infra
|
|
94
|
+
|
|
95
|
+
This pipeline has actually been run, twice, against a live GCS bucket, via
|
|
96
|
+
a Stageflow MCP host on a different checkout than the pipeline files
|
|
97
|
+
themselves (`task.checkout` pointed it at this worktree). Real, unrounded
|
|
98
|
+
per-stage cost from that first run:
|
|
99
|
+
|
|
100
|
+
| Stage | Cost (USD) |
|
|
101
|
+
|---|---|
|
|
102
|
+
| connect-account | $0.0213894 |
|
|
103
|
+
| poll-bucket-config | $0.0505455 |
|
|
104
|
+
| run-compliance-check | $0.0361527 |
|
|
105
|
+
| review-verdict | $0.0325805 |
|
|
106
|
+
| map-to-control | $0.0246600 |
|
|
107
|
+
| store-evidence | $0.0451638 |
|
|
108
|
+
| publish-report | $0.0480890 |
|
|
109
|
+
| **Total** | **$0.2585808** |
|
|
110
|
+
|
|
111
|
+
Run 1: bucket had `public_access_prevention: inherited`,
|
|
112
|
+
`uniform_bucket_level_access: false` → verdict `FAIL`, `reviewer: "auto"`
|
|
113
|
+
(first observation, nothing to flip against). The bucket was then actually
|
|
114
|
+
hardened (`gcloud storage buckets update --uniform-bucket-level-access`,
|
|
115
|
+
`--pap`) and reverted afterward. Run 2 against the hardened bucket: verdict
|
|
116
|
+
`PASS`, `reviewer: "unreviewed-flip"` — logged as a flip worth a human's
|
|
117
|
+
attention, without the run ever pausing to ask for one.
|
|
118
|
+
|
|
119
|
+
## Data directory is gitignored
|
|
120
|
+
|
|
121
|
+
`data/evidence-log.json` is runtime output written by `store-evidence`, not
|
|
122
|
+
source, and in practice ends up referencing whatever real bucket and
|
|
123
|
+
project someone tested against. It's gitignored on purpose — don't remove
|
|
124
|
+
that `.gitignore` to "fix" an empty `data/` directory after a fresh clone;
|
|
125
|
+
the file is created on first run.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
id: compliance-review-demo
|
|
2
|
+
stages:
|
|
3
|
+
- id: connect-account
|
|
4
|
+
uses: ./connect-account.yaml
|
|
5
|
+
entry: true
|
|
6
|
+
route:
|
|
7
|
+
- to: poll-bucket-config
|
|
8
|
+
- id: poll-bucket-config
|
|
9
|
+
uses: ./poll-bucket-config.yaml
|
|
10
|
+
route:
|
|
11
|
+
- to: run-compliance-check
|
|
12
|
+
- id: run-compliance-check
|
|
13
|
+
uses: ./run-compliance-check.yaml
|
|
14
|
+
route:
|
|
15
|
+
- to: review-verdict
|
|
16
|
+
- id: review-verdict
|
|
17
|
+
uses: ./review-verdict.yaml
|
|
18
|
+
route:
|
|
19
|
+
- to: map-to-control
|
|
20
|
+
- id: map-to-control
|
|
21
|
+
uses: ./map-to-control.yaml
|
|
22
|
+
route:
|
|
23
|
+
- to: store-evidence
|
|
24
|
+
- id: store-evidence
|
|
25
|
+
uses: ./store-evidence.yaml
|
|
26
|
+
route:
|
|
27
|
+
- to: publish-report
|
|
28
|
+
- id: publish-report
|
|
29
|
+
uses: ./publish-report.yaml
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
id: connect-account
|
|
2
|
+
system_prompt: |
|
|
3
|
+
This pipeline demonstrates Stageflow orchestrating a compliance check with
|
|
4
|
+
a human-in-the-loop review gate. A SOC2-style bucket public-access check is
|
|
5
|
+
the example — the point of this pipeline is the orchestration pattern, not
|
|
6
|
+
compliance coverage. It works against a real AWS S3 bucket, a real GCS
|
|
7
|
+
bucket, or a simulated fixture — whichever the next stage finds available.
|
|
8
|
+
|
|
9
|
+
State the scope for this run: read-only access to bucket configuration
|
|
10
|
+
only (no write or delete permissions), and the target bucket. Read
|
|
11
|
+
optional "bucket" and "scenario" fields from the task's input object.
|
|
12
|
+
Default bucket to "customer-uploads" and scenario to "fail" when absent.
|
|
13
|
+
scenario must end up "fail" or "fixed" — if the task gave something else,
|
|
14
|
+
use "fail". scenario is only used as a fallback if no real cloud CLI is
|
|
15
|
+
available; it's ignored entirely when polling a real bucket.
|
|
16
|
+
|
|
17
|
+
This stage does not call AWS or GCP itself — it only records the scope
|
|
18
|
+
and scenario the next stage will use.
|
|
19
|
+
|
|
20
|
+
Write a short artifact via write_stage_artifact naming the bucket, check,
|
|
21
|
+
and scenario.
|
|
22
|
+
|
|
23
|
+
summary and payload are handed to the next stage verbatim. State outcomes
|
|
24
|
+
and artifact pointers only. Do not repeat this stage's prohibitions in
|
|
25
|
+
summary — downstream will obey them literally.
|
|
26
|
+
|
|
27
|
+
When finished, call emit_stage_envelope exactly once with status, summary,
|
|
28
|
+
artifacts, and a payload matching io.output.schema: bucket, check_id
|
|
29
|
+
("bucket-public-access-block"), and scenario. Your last tool call in this
|
|
30
|
+
attempt must be emit_stage_envelope. An empty final message is a stage
|
|
31
|
+
failure.
|
|
32
|
+
model: anthropic/claude-sonnet-4-5
|
|
33
|
+
io:
|
|
34
|
+
input:
|
|
35
|
+
schema:
|
|
36
|
+
type: object
|
|
37
|
+
output:
|
|
38
|
+
schema:
|
|
39
|
+
type: object
|
|
40
|
+
required: [bucket, check_id, scenario]
|
|
41
|
+
properties:
|
|
42
|
+
bucket:
|
|
43
|
+
type: string
|
|
44
|
+
check_id:
|
|
45
|
+
type: string
|
|
46
|
+
scenario:
|
|
47
|
+
type: string
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
id: map-to-control
|
|
2
|
+
system_prompt: |
|
|
3
|
+
Read verdict, check_id, resource, reviewed, auto_approved, and reviewer
|
|
4
|
+
from the prior stage's payload.
|
|
5
|
+
|
|
6
|
+
Map check_id "bucket-public-access-block" to SOC2 control
|
|
7
|
+
"CC6.1 — logical access is restricted", regardless of which cloud the
|
|
8
|
+
bucket lives in. This demo hardcodes one mapping; a real build would look
|
|
9
|
+
this up from a maintained check-to-control table (Prowler ships one for
|
|
10
|
+
its AWS checks; a GCP-equivalent would need its own).
|
|
11
|
+
|
|
12
|
+
summary and payload are handed to the next stage verbatim. State outcomes
|
|
13
|
+
and artifact pointers only. Do not repeat this stage's prohibitions in
|
|
14
|
+
summary — downstream will obey them literally.
|
|
15
|
+
|
|
16
|
+
When finished, call emit_stage_envelope exactly once with status, summary,
|
|
17
|
+
artifacts, and a payload matching io.output.schema: everything carried
|
|
18
|
+
forward from the prior stage, plus control_id = "CC6.1". Your last tool
|
|
19
|
+
call in this attempt must be emit_stage_envelope. An empty final message
|
|
20
|
+
is a stage failure.
|
|
21
|
+
model: anthropic/claude-sonnet-4-5
|
|
22
|
+
io:
|
|
23
|
+
input:
|
|
24
|
+
schema:
|
|
25
|
+
type: object
|
|
26
|
+
required:
|
|
27
|
+
- bucket
|
|
28
|
+
- check_id
|
|
29
|
+
- scenario
|
|
30
|
+
- source
|
|
31
|
+
- block_public_acls
|
|
32
|
+
- ignore_public_acls
|
|
33
|
+
- block_public_policy
|
|
34
|
+
- restrict_public_buckets
|
|
35
|
+
- verdict
|
|
36
|
+
- resource
|
|
37
|
+
- failed_fields
|
|
38
|
+
- reviewed
|
|
39
|
+
- auto_approved
|
|
40
|
+
- reviewer
|
|
41
|
+
properties:
|
|
42
|
+
bucket:
|
|
43
|
+
type: string
|
|
44
|
+
check_id:
|
|
45
|
+
type: string
|
|
46
|
+
scenario:
|
|
47
|
+
type: string
|
|
48
|
+
source:
|
|
49
|
+
type: string
|
|
50
|
+
block_public_acls:
|
|
51
|
+
type: boolean
|
|
52
|
+
ignore_public_acls:
|
|
53
|
+
type: boolean
|
|
54
|
+
block_public_policy:
|
|
55
|
+
type: boolean
|
|
56
|
+
restrict_public_buckets:
|
|
57
|
+
type: boolean
|
|
58
|
+
verdict:
|
|
59
|
+
type: string
|
|
60
|
+
resource:
|
|
61
|
+
type: string
|
|
62
|
+
failed_fields:
|
|
63
|
+
type: array
|
|
64
|
+
items:
|
|
65
|
+
type: string
|
|
66
|
+
reviewed:
|
|
67
|
+
type: boolean
|
|
68
|
+
auto_approved:
|
|
69
|
+
type: boolean
|
|
70
|
+
reviewer:
|
|
71
|
+
type: string
|
|
72
|
+
output:
|
|
73
|
+
schema:
|
|
74
|
+
type: object
|
|
75
|
+
required:
|
|
76
|
+
- bucket
|
|
77
|
+
- check_id
|
|
78
|
+
- scenario
|
|
79
|
+
- source
|
|
80
|
+
- block_public_acls
|
|
81
|
+
- ignore_public_acls
|
|
82
|
+
- block_public_policy
|
|
83
|
+
- restrict_public_buckets
|
|
84
|
+
- verdict
|
|
85
|
+
- resource
|
|
86
|
+
- failed_fields
|
|
87
|
+
- reviewed
|
|
88
|
+
- auto_approved
|
|
89
|
+
- reviewer
|
|
90
|
+
- control_id
|
|
91
|
+
properties:
|
|
92
|
+
bucket:
|
|
93
|
+
type: string
|
|
94
|
+
check_id:
|
|
95
|
+
type: string
|
|
96
|
+
scenario:
|
|
97
|
+
type: string
|
|
98
|
+
source:
|
|
99
|
+
type: string
|
|
100
|
+
block_public_acls:
|
|
101
|
+
type: boolean
|
|
102
|
+
ignore_public_acls:
|
|
103
|
+
type: boolean
|
|
104
|
+
block_public_policy:
|
|
105
|
+
type: boolean
|
|
106
|
+
restrict_public_buckets:
|
|
107
|
+
type: boolean
|
|
108
|
+
verdict:
|
|
109
|
+
type: string
|
|
110
|
+
resource:
|
|
111
|
+
type: string
|
|
112
|
+
failed_fields:
|
|
113
|
+
type: array
|
|
114
|
+
items:
|
|
115
|
+
type: string
|
|
116
|
+
reviewed:
|
|
117
|
+
type: boolean
|
|
118
|
+
auto_approved:
|
|
119
|
+
type: boolean
|
|
120
|
+
reviewer:
|
|
121
|
+
type: string
|
|
122
|
+
control_id:
|
|
123
|
+
type: string
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
id: poll-bucket-config
|
|
2
|
+
system_prompt: |
|
|
3
|
+
Read bucket, check_id, and scenario from the prior stage's payload.
|
|
4
|
+
bucket is the bare bucket name, no gs:// or s3:// prefix — add the right
|
|
5
|
+
prefix yourself for whichever CLI you end up using.
|
|
6
|
+
|
|
7
|
+
The four output fields (block_public_acls, ignore_public_acls,
|
|
8
|
+
block_public_policy, restrict_public_buckets) are cloud-agnostic — they
|
|
9
|
+
mean "is public access meaningfully blocked", not literally AWS S3
|
|
10
|
+
setting names. Try real polls in this order, first one that works wins:
|
|
11
|
+
|
|
12
|
+
1. GCP: if `gcloud` is on PATH and `gcloud auth list
|
|
13
|
+
--filter=status:ACTIVE --format="value(account)"` returns a account,
|
|
14
|
+
poll the real bucket:
|
|
15
|
+
gcloud storage buckets describe gs://<bucket> --format=json
|
|
16
|
+
gcloud storage buckets get-iam-policy gs://<bucket> --format=json
|
|
17
|
+
Read these exact fields from the describe output:
|
|
18
|
+
public_access_prevention ("enforced" or "inherited")
|
|
19
|
+
uniform_bucket_level_access (boolean)
|
|
20
|
+
From the IAM policy output, check every binding's members list for
|
|
21
|
+
"allUsers" or "allAuthenticatedUsers" — call this has_public_iam_binding.
|
|
22
|
+
Map to the four fields:
|
|
23
|
+
block_public_acls = uniform_bucket_level_access
|
|
24
|
+
ignore_public_acls = uniform_bucket_level_access
|
|
25
|
+
block_public_policy = (public_access_prevention == "enforced")
|
|
26
|
+
restrict_public_buckets = NOT has_public_iam_binding
|
|
27
|
+
Set source = "real-gcp". Ignore scenario in this case.
|
|
28
|
+
|
|
29
|
+
2. AWS: else if `aws` CLI is on PATH and `aws sts get-caller-identity`
|
|
30
|
+
succeeds, run `aws s3api get-public-access-block --bucket <bucket>`
|
|
31
|
+
and use that real response directly (the field names already match).
|
|
32
|
+
Set source = "real-aws". Ignore scenario in this case.
|
|
33
|
+
|
|
34
|
+
3. Simulated: otherwise — no working cloud CLI — produce a SIMULATED
|
|
35
|
+
response and set source = "simulated". Never present simulated data
|
|
36
|
+
as real; label it "simulated" wherever it's written down. Use
|
|
37
|
+
scenario to pick the fixture:
|
|
38
|
+
|
|
39
|
+
scenario "fail":
|
|
40
|
+
{ block_public_acls: true, ignore_public_acls: true,
|
|
41
|
+
block_public_policy: false, restrict_public_buckets: true }
|
|
42
|
+
|
|
43
|
+
scenario "fixed":
|
|
44
|
+
{ block_public_acls: true, ignore_public_acls: true,
|
|
45
|
+
block_public_policy: true, restrict_public_buckets: true }
|
|
46
|
+
|
|
47
|
+
Write the raw response via write_stage_artifact. For a real GCP poll,
|
|
48
|
+
include both the raw gcloud fields (public_access_prevention,
|
|
49
|
+
uniform_bucket_level_access, has_public_iam_binding) and the four mapped
|
|
50
|
+
booleans, so the translation is visible, not hidden. Clearly mark the
|
|
51
|
+
artifact "simulated", "real-aws", or "real-gcp".
|
|
52
|
+
|
|
53
|
+
summary and payload are handed to the next stage verbatim. State outcomes
|
|
54
|
+
and artifact pointers only. Do not repeat this stage's prohibitions in
|
|
55
|
+
summary — downstream will obey them literally.
|
|
56
|
+
|
|
57
|
+
When finished, call emit_stage_envelope exactly once with status, summary,
|
|
58
|
+
artifacts, and a payload matching io.output.schema: bucket, check_id,
|
|
59
|
+
scenario carried forward, plus source and the four boolean fields. Your
|
|
60
|
+
last tool call in this attempt must be emit_stage_envelope. An empty
|
|
61
|
+
final message is a stage failure.
|
|
62
|
+
model: anthropic/claude-sonnet-4-5
|
|
63
|
+
io:
|
|
64
|
+
input:
|
|
65
|
+
schema:
|
|
66
|
+
type: object
|
|
67
|
+
required: [bucket, check_id, scenario]
|
|
68
|
+
properties:
|
|
69
|
+
bucket:
|
|
70
|
+
type: string
|
|
71
|
+
check_id:
|
|
72
|
+
type: string
|
|
73
|
+
scenario:
|
|
74
|
+
type: string
|
|
75
|
+
output:
|
|
76
|
+
schema:
|
|
77
|
+
type: object
|
|
78
|
+
required:
|
|
79
|
+
- bucket
|
|
80
|
+
- check_id
|
|
81
|
+
- scenario
|
|
82
|
+
- source
|
|
83
|
+
- block_public_acls
|
|
84
|
+
- ignore_public_acls
|
|
85
|
+
- block_public_policy
|
|
86
|
+
- restrict_public_buckets
|
|
87
|
+
properties:
|
|
88
|
+
bucket:
|
|
89
|
+
type: string
|
|
90
|
+
check_id:
|
|
91
|
+
type: string
|
|
92
|
+
scenario:
|
|
93
|
+
type: string
|
|
94
|
+
source:
|
|
95
|
+
type: string
|
|
96
|
+
block_public_acls:
|
|
97
|
+
type: boolean
|
|
98
|
+
ignore_public_acls:
|
|
99
|
+
type: boolean
|
|
100
|
+
block_public_policy:
|
|
101
|
+
type: boolean
|
|
102
|
+
restrict_public_buckets:
|
|
103
|
+
type: boolean
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
id: publish-report
|
|
2
|
+
system_prompt: |
|
|
3
|
+
Read the evidence log at
|
|
4
|
+
examples/compliance-review-demo/data/evidence-log.json (checkout-relative,
|
|
5
|
+
use the Read tool) and the current run's payload.
|
|
6
|
+
|
|
7
|
+
Write a short markdown report via write_stage_artifact (for example
|
|
8
|
+
report.md) showing the timeline for this check_id + resource: every
|
|
9
|
+
recorded verdict with its timestamp, and — for any row with
|
|
10
|
+
reviewed = true — the reviewer. Make the human-in-the-loop review visible:
|
|
11
|
+
call out explicitly which rows were auto-approved (no flip) versus which
|
|
12
|
+
required a person's confirmation (a flip), since that distinction is the
|
|
13
|
+
whole point of this pipeline.
|
|
14
|
+
|
|
15
|
+
When finished, call emit_stage_envelope exactly once with status, summary,
|
|
16
|
+
and artifacts pointing at the report. Your last tool call in this attempt
|
|
17
|
+
must be emit_stage_envelope. An empty final message is a stage failure.
|
|
18
|
+
model: anthropic/claude-sonnet-4-5
|
|
19
|
+
io:
|
|
20
|
+
input:
|
|
21
|
+
schema:
|
|
22
|
+
type: object
|
|
23
|
+
required:
|
|
24
|
+
- bucket
|
|
25
|
+
- check_id
|
|
26
|
+
- scenario
|
|
27
|
+
- source
|
|
28
|
+
- block_public_acls
|
|
29
|
+
- ignore_public_acls
|
|
30
|
+
- block_public_policy
|
|
31
|
+
- restrict_public_buckets
|
|
32
|
+
- verdict
|
|
33
|
+
- resource
|
|
34
|
+
- failed_fields
|
|
35
|
+
- reviewed
|
|
36
|
+
- auto_approved
|
|
37
|
+
- reviewer
|
|
38
|
+
- control_id
|
|
39
|
+
- changed_files
|
|
40
|
+
properties:
|
|
41
|
+
bucket:
|
|
42
|
+
type: string
|
|
43
|
+
check_id:
|
|
44
|
+
type: string
|
|
45
|
+
scenario:
|
|
46
|
+
type: string
|
|
47
|
+
source:
|
|
48
|
+
type: string
|
|
49
|
+
block_public_acls:
|
|
50
|
+
type: boolean
|
|
51
|
+
ignore_public_acls:
|
|
52
|
+
type: boolean
|
|
53
|
+
block_public_policy:
|
|
54
|
+
type: boolean
|
|
55
|
+
restrict_public_buckets:
|
|
56
|
+
type: boolean
|
|
57
|
+
verdict:
|
|
58
|
+
type: string
|
|
59
|
+
resource:
|
|
60
|
+
type: string
|
|
61
|
+
failed_fields:
|
|
62
|
+
type: array
|
|
63
|
+
items:
|
|
64
|
+
type: string
|
|
65
|
+
reviewed:
|
|
66
|
+
type: boolean
|
|
67
|
+
auto_approved:
|
|
68
|
+
type: boolean
|
|
69
|
+
reviewer:
|
|
70
|
+
type: string
|
|
71
|
+
control_id:
|
|
72
|
+
type: string
|
|
73
|
+
changed_files:
|
|
74
|
+
type: array
|
|
75
|
+
items:
|
|
76
|
+
type: string
|
|
77
|
+
output:
|
|
78
|
+
schema:
|
|
79
|
+
type: object
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
id: review-verdict
|
|
2
|
+
system_prompt: |
|
|
3
|
+
This stage never pauses for a human — it has to be safe to run unattended
|
|
4
|
+
on a schedule (cron, a nightly GitHub Action, Cloud Scheduler). It still
|
|
5
|
+
tells the difference between "nothing changed" and "this just flipped,"
|
|
6
|
+
it just never blocks on that difference.
|
|
7
|
+
|
|
8
|
+
1. Read examples/compliance-review-demo/data/evidence-log.json if it
|
|
9
|
+
exists (checkout-relative path, use the Read tool). Find the most
|
|
10
|
+
recent entry for this run's check_id + resource, if any.
|
|
11
|
+
2. No prior entry, or the prior entry's verdict matches this run's
|
|
12
|
+
verdict: set reviewer = "auto".
|
|
13
|
+
3. Prior entry exists and its verdict differs from this run's verdict (a
|
|
14
|
+
flip): set reviewer = "unreviewed-flip" and write a short artifact via
|
|
15
|
+
write_stage_artifact noting the flip (prior verdict, new verdict, the
|
|
16
|
+
raw field values from the prior stage's payload), so a person can spot
|
|
17
|
+
it later in the evidence log or the published report — without the
|
|
18
|
+
run ever waiting on them.
|
|
19
|
+
4. In both cases set reviewed = false and auto_approved = true. Never
|
|
20
|
+
call ask_operator — this stage has no gate_kinds. Always emit an
|
|
21
|
+
advancing success status; a flip is information, not a failure.
|
|
22
|
+
|
|
23
|
+
summary and payload are handed to the next stage verbatim. State outcomes
|
|
24
|
+
and artifact pointers only. Do not repeat this stage's prohibitions in
|
|
25
|
+
summary — downstream will obey them literally.
|
|
26
|
+
|
|
27
|
+
When finished, call emit_stage_envelope exactly once with status, summary,
|
|
28
|
+
artifacts, and a payload matching io.output.schema: everything carried
|
|
29
|
+
forward from the prior stage, plus reviewed, auto_approved, and reviewer
|
|
30
|
+
as described above. Your last tool call in this attempt must be
|
|
31
|
+
emit_stage_envelope. An empty final message is a stage failure.
|
|
32
|
+
model: anthropic/claude-sonnet-4-5
|
|
33
|
+
io:
|
|
34
|
+
input:
|
|
35
|
+
schema:
|
|
36
|
+
type: object
|
|
37
|
+
required:
|
|
38
|
+
- bucket
|
|
39
|
+
- check_id
|
|
40
|
+
- scenario
|
|
41
|
+
- source
|
|
42
|
+
- block_public_acls
|
|
43
|
+
- ignore_public_acls
|
|
44
|
+
- block_public_policy
|
|
45
|
+
- restrict_public_buckets
|
|
46
|
+
- verdict
|
|
47
|
+
- resource
|
|
48
|
+
- failed_fields
|
|
49
|
+
properties:
|
|
50
|
+
bucket:
|
|
51
|
+
type: string
|
|
52
|
+
check_id:
|
|
53
|
+
type: string
|
|
54
|
+
scenario:
|
|
55
|
+
type: string
|
|
56
|
+
source:
|
|
57
|
+
type: string
|
|
58
|
+
block_public_acls:
|
|
59
|
+
type: boolean
|
|
60
|
+
ignore_public_acls:
|
|
61
|
+
type: boolean
|
|
62
|
+
block_public_policy:
|
|
63
|
+
type: boolean
|
|
64
|
+
restrict_public_buckets:
|
|
65
|
+
type: boolean
|
|
66
|
+
verdict:
|
|
67
|
+
type: string
|
|
68
|
+
resource:
|
|
69
|
+
type: string
|
|
70
|
+
failed_fields:
|
|
71
|
+
type: array
|
|
72
|
+
items:
|
|
73
|
+
type: string
|
|
74
|
+
output:
|
|
75
|
+
schema:
|
|
76
|
+
type: object
|
|
77
|
+
required:
|
|
78
|
+
- bucket
|
|
79
|
+
- check_id
|
|
80
|
+
- scenario
|
|
81
|
+
- source
|
|
82
|
+
- block_public_acls
|
|
83
|
+
- ignore_public_acls
|
|
84
|
+
- block_public_policy
|
|
85
|
+
- restrict_public_buckets
|
|
86
|
+
- verdict
|
|
87
|
+
- resource
|
|
88
|
+
- failed_fields
|
|
89
|
+
- reviewed
|
|
90
|
+
- auto_approved
|
|
91
|
+
- reviewer
|
|
92
|
+
properties:
|
|
93
|
+
bucket:
|
|
94
|
+
type: string
|
|
95
|
+
check_id:
|
|
96
|
+
type: string
|
|
97
|
+
scenario:
|
|
98
|
+
type: string
|
|
99
|
+
source:
|
|
100
|
+
type: string
|
|
101
|
+
block_public_acls:
|
|
102
|
+
type: boolean
|
|
103
|
+
ignore_public_acls:
|
|
104
|
+
type: boolean
|
|
105
|
+
block_public_policy:
|
|
106
|
+
type: boolean
|
|
107
|
+
restrict_public_buckets:
|
|
108
|
+
type: boolean
|
|
109
|
+
verdict:
|
|
110
|
+
type: string
|
|
111
|
+
resource:
|
|
112
|
+
type: string
|
|
113
|
+
failed_fields:
|
|
114
|
+
type: array
|
|
115
|
+
items:
|
|
116
|
+
type: string
|
|
117
|
+
reviewed:
|
|
118
|
+
type: boolean
|
|
119
|
+
auto_approved:
|
|
120
|
+
type: boolean
|
|
121
|
+
reviewer:
|
|
122
|
+
type: string
|