feat(sdk): flows build gates on flows check green (#318) - #360
Conversation
Refuses bundles that would fail preflight — no bad digests can escape a build machine. Adds `--json` support emitting the same CheckReport shape `flows check --json` emits. The refusal path never leaves partial artifacts; a previous successful bundle directory is not touched. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Session-Id: efeda5df-9b7c-48d4-b2ce-957f5bef0a82
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ea74cd7. Configure here.
| const diagnostics = result.diagnostics.filter( | ||
| (d) => !(d.severity === 'refusal' && d.kind === 'probe_failed'), | ||
| ); | ||
| const ok = !diagnostics.some((d) => d.severity === 'refusal'); |
There was a problem hiding this comment.
Named gates refuse under deferred probes
Medium Severity
The build gate drops only probe_failed refusals from deferred probes, but probeNamedGate fail-closes a thrown command probe as gate_command_missing. Any named-gate flow therefore fails checkBuildableFlow even when flows check is green, because the deferred probe always throws.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit ea74cd7. Configure here.
maintainability lens — FAILLooking at the diff with a maintainability lens. Blockers
ConcernsPreflight is now invoked twice with the same deferred-probes config — once in
Regex breadth in check.ts:159. The invariant "no partial artifacts on refusal" is enforced by ordering, not structure (build.ts:55-64 comment block). A future refactor that reorders Notes
REVIEW_FAILED |
history lens — FAILBlocker — H1, criterion 3: the commit overstates However, The relevant captured source inspection was: git show ea74cd78:packages/sdk/src/cli/build.ts | nl -ba | sed -n '30,110p'Excerpt: Either route TypeScript refusals through the report emitter or explicitly narrow the commit/PR claims to upfront YAML preflight refusals and document the remaining JSON behavior as a follow-up. Concerns: Notes: The deferred probes in REVIEW_FAILED |
structure lens — MISSING |
|
🎯 review-swarm: FAILED (M:fail H:fail S:missing) Lens transcripts posted as sibling comments above. |


Closes #318. Follow-up to slice A.
What
flows build <flow>runs the same preflight pipelineflows checkuses (with deferredcli/command/executorprobes, since the build host is not the deployment target). Any refusal-severity diagnostic exits2withREFUSED [kind] messageon stderr and no artifact directory is created. A previousdist/flows/<name>@sha256:<hex>/from an earlier successful build is not touched.How
checkBuildableFlow(path)inpackages/sdk/src/cli/check.ts— runs the shared preflight pipeline with build-mode deferred probes, filters outprobe_failedrefusals (probes are deferred to run time), returns aCheckReportin the exact shapeflows check --jsonemits.parseBuildArgsaccepts--json. On refusal in--jsonmode,runBuildprints one JSON object matchingflows check --json's shape on stdout, then exits2.buildFlow's inline preflight (which already refuses on the same threshold) — invokingcheckTypeScriptFlowat build time would need@relayflows/surfaceresolvable from the flow's directory, not a build-time invariant.Test evidence
New
packages/sdk/tests/build-gate.test.ts(3 cases per issue #318):flows build bad.flow.yaml(unresolvable named-agent CLI) → exit 2, stderrcli_unresolved,dist/flows/never created.flows build --json bad.flow.yaml→ exit 2, one CheckReport JSON on stdout,ok: false, refusal indiagnostics, no artifacts.flows build good.yaml(deterministic-only) → exit 0, full bundlebuildable@sha256:<hex>/withspec.canonical.json,preflight.json,manifest.json,identity.json, captured assets.Full
tests/bundle.test.tsregression: 21/21 pass.Note
Medium Risk
Changes when builds succeed or fail and what artifacts CI produces; behavior is intentional but affects the critical build path.
Overview
flows buildnow runs a preflight gate (same pipeline asflows check) before any bundling. Build-provable refusals exit 2, printREFUSED [kind]on stderr, and never create an output directory or partial bundle; prior successful bundle dirs are left untouched.The gate is
checkBuildableFlow: it uses deferredcli/command/executorprobes (host environment is not the deploy target) and dropsprobe_failedrefusals so only spec-level problems block the build. TypeScript flows skip this upfront check and still rely onbuildFlow’s inline preflight.--jsonon build emits a singleCheckReporton stdout on refusal, matchingflows check --json. Integration tests cover refusal with no artifacts, JSON output, and a successful deterministic build regression.Reviewed by Cursor Bugbot for commit ea74cd7. Bugbot is set up for automated code reviews on this repo. Configure here.