From 9f3c18e9b17f0ae987964fe6e88e7b5ca6fa017e Mon Sep 17 00:00:00 2001 From: Wayne Sun Date: Tue, 5 May 2026 13:01:09 -0400 Subject: [PATCH 1/2] feat(run): add --no-post-script flag to skip post-script execution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow users to run agent inference without post-script side effects (posting PR comments, pushing branches, creating PRs). The agent runs normally inside the sandbox, but the post-script is skipped with a warning message. Named --no-post-script instead of --dry-run because the agent still runs full inference with real GCP costs — dry-run would be misleading. Signed-off-by: Wayne Sun --- internal/cli/run.go | 10 ++++++++-- internal/cli/run_test.go | 7 +++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/internal/cli/run.go b/internal/cli/run.go index afa6a2c86..3ff9b23e1 100644 --- a/internal/cli/run.go +++ b/internal/cli/run.go @@ -25,6 +25,7 @@ func newRunCmd() *cobra.Command { var targetRepo string var fullsendBinary string var envFiles []string + var noPostScript bool cmd := &cobra.Command{ Use: "run ", @@ -34,7 +35,7 @@ func newRunCmd() *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { agentName := args[0] printer := ui.New(os.Stdout) - return runAgent(agentName, fullsendDir, outputBase, targetRepo, fullsendBinary, envFiles, printer) + return runAgent(agentName, fullsendDir, outputBase, targetRepo, fullsendBinary, envFiles, noPostScript, printer) }, } @@ -43,13 +44,14 @@ func newRunCmd() *cobra.Command { cmd.Flags().StringVar(&targetRepo, "target-repo", "", "path to the target repository") cmd.Flags().StringVar(&fullsendBinary, "fullsend-binary", "", "path to a Linux fullsend binary to copy into the sandbox (default: current executable)") cmd.Flags().StringArrayVar(&envFiles, "env-file", nil, "load environment variables from a dotenv file (repeatable)") + cmd.Flags().BoolVar(&noPostScript, "no-post-script", false, "skip post-script execution (agent inference still runs)") _ = cmd.MarkFlagRequired("fullsend-dir") _ = cmd.MarkFlagRequired("target-repo") return cmd } -func runAgent(agentName, fullsendDir, outputBase, targetRepo, fullsendBinary string, envFiles []string, printer *ui.Printer) (runErr error) { +func runAgent(agentName, fullsendDir, outputBase, targetRepo, fullsendBinary string, envFiles []string, noPostScript bool, printer *ui.Printer) (runErr error) { printer.Banner() printer.Blank() printer.Header("Running agent: " + agentName) @@ -230,6 +232,10 @@ func runAgent(agentName, fullsendDir, outputBase, targetRepo, fullsendBinary str // any output checks it needs. if h.PostScript != "" { defer func() { + if noPostScript { + printer.StepWarn("Skipping post-script: --no-post-script") + return + } if h.ValidationLoop != nil && !validationPassed { printer.StepWarn("Skipping post-script: validation did not pass") return diff --git a/internal/cli/run_test.go b/internal/cli/run_test.go index bcfd9870f..27147bd2d 100644 --- a/internal/cli/run_test.go +++ b/internal/cli/run_test.go @@ -42,6 +42,13 @@ func TestRunCommand_RegisteredOnRoot(t *testing.T) { assert.True(t, found, "run command should be registered on root") } +func TestRunCommand_HasNoPostScriptFlag(t *testing.T) { + cmd := newRunCmd() + flag := cmd.Flags().Lookup("no-post-script") + require.NotNil(t, flag) + assert.Equal(t, "false", flag.DefValue) +} + func TestRunCommand_HasOutputDirFlag(t *testing.T) { cmd := newRunCmd() flag := cmd.Flags().Lookup("output-dir") From ec40bf0ae256f25c8f3c77aa1b3b76db5e2dab7d Mon Sep 17 00:00:00 2001 From: Wayne Sun Date: Tue, 5 May 2026 14:14:58 -0400 Subject: [PATCH 2/2] fix: address review feedback for --no-post-script flag - Log flag state in initial plan output so users see it immediately - Include post-script name in skip warning for easier debugging - Add defensive comment to composite action YAML warning against exposing --no-post-script as a workflow input in CI Signed-off-by: Wayne Sun --- internal/cli/run.go | 10 +++++++--- .../fullsend-repo/.github/actions/fullsend/action.yml | 4 ++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/internal/cli/run.go b/internal/cli/run.go index 3ff9b23e1..464e2e0b0 100644 --- a/internal/cli/run.go +++ b/internal/cli/run.go @@ -44,7 +44,7 @@ func newRunCmd() *cobra.Command { cmd.Flags().StringVar(&targetRepo, "target-repo", "", "path to the target repository") cmd.Flags().StringVar(&fullsendBinary, "fullsend-binary", "", "path to a Linux fullsend binary to copy into the sandbox (default: current executable)") cmd.Flags().StringArrayVar(&envFiles, "env-file", nil, "load environment variables from a dotenv file (repeatable)") - cmd.Flags().BoolVar(&noPostScript, "no-post-script", false, "skip post-script execution (agent inference still runs)") + cmd.Flags().BoolVar(&noPostScript, "no-post-script", false, "skip post-script execution (agent still runs full inference)") _ = cmd.MarkFlagRequired("fullsend-dir") _ = cmd.MarkFlagRequired("target-repo") @@ -145,7 +145,11 @@ func runAgent(agentName, fullsendDir, outputBase, targetRepo, fullsendBinary str printer.KeyValue("Pre-script", h.PreScript) } if h.PostScript != "" { - printer.KeyValue("Post-script", h.PostScript) + if noPostScript { + printer.KeyValue("Post-script", h.PostScript+" (SKIPPED: --no-post-script)") + } else { + printer.KeyValue("Post-script", h.PostScript) + } } if h.TimeoutMinutes > 0 { printer.KeyValue("Timeout", fmt.Sprintf("%d minutes", h.TimeoutMinutes)) @@ -233,7 +237,7 @@ func runAgent(agentName, fullsendDir, outputBase, targetRepo, fullsendBinary str if h.PostScript != "" { defer func() { if noPostScript { - printer.StepWarn("Skipping post-script: --no-post-script") + printer.StepWarn(fmt.Sprintf("Skipping post-script %s: --no-post-script", h.PostScript)) return } if h.ValidationLoop != nil && !validationPassed { diff --git a/internal/scaffold/fullsend-repo/.github/actions/fullsend/action.yml b/internal/scaffold/fullsend-repo/.github/actions/fullsend/action.yml index 8821fd4e3..b7fc9484c 100644 --- a/internal/scaffold/fullsend-repo/.github/actions/fullsend/action.yml +++ b/internal/scaffold/fullsend-repo/.github/actions/fullsend/action.yml @@ -113,6 +113,10 @@ runs: run: | set -euo pipefail mkdir -p "${GITHUB_WORKSPACE}/output" + # SECURITY: Never expose --no-post-script as a workflow input. + # Post-scripts enforce secret scanning, protected-path blocks, + # and review-downgrade controls. Skipping them in CI bypasses + # all post-push security gates. fullsend run "${AGENT}" \ --fullsend-dir "${GITHUB_WORKSPACE}" \ --output-dir "${GITHUB_WORKSPACE}/output" \