From 31770610cde548e17d0cd6bef1ac05976044d269 Mon Sep 17 00:00:00 2001 From: fullsend-code <278716306+fullsend-ai-coder[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2026 15:10:22 +0000 Subject: [PATCH] fix(#349): use runner_env YAML key matching Go struct tags Harness YAML files used nested env.runner for runner environment variables, but Harness.RunnerEnv and ForgeConfig.RunnerEnv are tagged yaml:"runner_env" and expect a flat runner_env key. The YAML parser silently ignored the env.runner sections, leaving RunnerEnv nil after unmarshalling. This caused REVIEW_TOKEN (and other forge-specific runner env vars like PUSH_TOKEN, GH_TOKEN) to never reach post-scripts via the harness config. Post-scripts fell back to inheriting vars from os.Environ() via the GHA step env, which breaks when the workflow identity matches the PR author (GitHub rejects self-reviews with 422). Changes all harness YAML files (scaffold defaults and customized overrides) from nested env.runner to flat runner_env matching the Go struct tags. Also removes env.sandbox sections which were equally silently ignored (no SandboxEnv field exists in Harness or ForgeConfig). Fixes code.yaml test expectations to match actual runner_env keys. Closes #349 --- .fullsend/customized/harness/fix.yaml | 51 ++++++------------- .fullsend/customized/harness/prioritize.yaml | 19 +++---- .fullsend/customized/harness/retro.yaml | 20 +++----- .fullsend/customized/harness/review.yaml | 25 +++------ .fullsend/customized/harness/triage.yaml | 15 ++---- .../scaffold/fullsend-repo/harness/fix.yaml | 51 ++++++------------- .../fullsend-repo/harness/prioritize.yaml | 19 +++---- .../scaffold/fullsend-repo/harness/retro.yaml | 20 +++----- .../fullsend-repo/harness/review.yaml | 25 +++------ .../fullsend-repo/harness/triage.yaml | 15 ++---- internal/scaffold/scaffold_test.go | 2 +- 11 files changed, 81 insertions(+), 181 deletions(-) diff --git a/.fullsend/customized/harness/fix.yaml b/.fullsend/customized/harness/fix.yaml index f109385e8..300630ebe 100644 --- a/.fullsend/customized/harness/fix.yaml +++ b/.fullsend/customized/harness/fix.yaml @@ -43,24 +43,15 @@ skills: plugins: - plugins/ponytail -env: - runner: - TARGET_BRANCH: "${TARGET_BRANCH}" - TRIGGER_SOURCE: "${TRIGGER_SOURCE}" - HUMAN_INSTRUCTION: "${HUMAN_INSTRUCTION}" - FIX_ITERATION: "${FIX_ITERATION}" - REVIEW_BODY_FILE: "${REVIEW_BODY_FILE}" - PRE_AGENT_HEAD: "${PRE_AGENT_HEAD}" - FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/fix-result.schema.json - FULLSEND_OUTPUT_FILE: fix-result.json - sandbox: - MAX_RETRIES: "1" - TIMEOUT_SECONDS: "1500" - STRATEGY_ESCALATION_THRESHOLD: "3" - ITERATION_CAP: "5" - ITERATION_CAP_HUMAN: "10" - GOPATH: "/sandbox/go" - GOMODCACHE: "/sandbox/go/pkg/mod" +runner_env: + TARGET_BRANCH: "${TARGET_BRANCH}" + TRIGGER_SOURCE: "${TRIGGER_SOURCE}" + HUMAN_INSTRUCTION: "${HUMAN_INSTRUCTION}" + FIX_ITERATION: "${FIX_ITERATION}" + REVIEW_BODY_FILE: "${REVIEW_BODY_FILE}" + PRE_AGENT_HEAD: "${PRE_AGENT_HEAD}" + FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/fix-result.schema.json + FULLSEND_OUTPUT_FILE: fix-result.json timeout_minutes: 25 @@ -68,21 +59,9 @@ forge: github: pre_script: scripts/pre-fix.sh post_script: scripts/post-fix.sh - env: - runner: - PUSH_TOKEN: "${PUSH_TOKEN}" - PUSH_TOKEN_SOURCE: "${PUSH_TOKEN_SOURCE}" - REPO_FULL_NAME: "${REPO_FULL_NAME}" - PR_NUMBER: "${PR_NUMBER}" - REPO_DIR: "${GITHUB_WORKSPACE}/target-repo" - sandbox: - PR_NUMBER: "${PR_NUMBER}" - REPO_FULL_NAME: "${REPO_FULL_NAME}" - TRIGGER_SOURCE: "${TRIGGER_SOURCE}" - HUMAN_INSTRUCTION: "${HUMAN_INSTRUCTION}" - FIX_ITERATION: "${FIX_ITERATION}" - GH_TOKEN: "${GH_TOKEN}" - GIT_AUTHOR_NAME: "fullsend-fix" - GIT_AUTHOR_EMAIL: "${GIT_BOT_EMAIL}" - GIT_COMMITTER_NAME: "fullsend-fix" - GIT_COMMITTER_EMAIL: "${GIT_BOT_EMAIL}" + runner_env: + PUSH_TOKEN: "${PUSH_TOKEN}" + PUSH_TOKEN_SOURCE: "${PUSH_TOKEN_SOURCE}" + REPO_FULL_NAME: "${REPO_FULL_NAME}" + PR_NUMBER: "${PR_NUMBER}" + REPO_DIR: "${GITHUB_WORKSPACE}/target-repo" diff --git a/.fullsend/customized/harness/prioritize.yaml b/.fullsend/customized/harness/prioritize.yaml index 86bd61918..92ef00d4b 100644 --- a/.fullsend/customized/harness/prioritize.yaml +++ b/.fullsend/customized/harness/prioritize.yaml @@ -36,9 +36,8 @@ validation_loop: script: scripts/validate-output-schema.sh max_iterations: 2 -env: - runner: - FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/prioritize-result.schema.json +runner_env: + FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/prioritize-result.schema.json timeout_minutes: 10 @@ -46,12 +45,8 @@ forge: github: pre_script: scripts/pre-prioritize.sh post_script: scripts/post-prioritize.sh - env: - runner: - GITHUB_ISSUE_URL: ${GITHUB_ISSUE_URL} - GH_TOKEN: ${GH_TOKEN} - ORG: ${ORG} - PROJECT_NUMBER: ${PROJECT_NUMBER} - sandbox: - GITHUB_ISSUE_URL: "${GITHUB_ISSUE_URL}" - GH_TOKEN: "${GH_TOKEN}" + runner_env: + GITHUB_ISSUE_URL: ${GITHUB_ISSUE_URL} + GH_TOKEN: ${GH_TOKEN} + ORG: ${ORG} + PROJECT_NUMBER: ${PROJECT_NUMBER} diff --git a/.fullsend/customized/harness/retro.yaml b/.fullsend/customized/harness/retro.yaml index e01c630b7..5625b78e4 100644 --- a/.fullsend/customized/harness/retro.yaml +++ b/.fullsend/customized/harness/retro.yaml @@ -42,11 +42,8 @@ validation_loop: script: scripts/validate-output-schema.sh max_iterations: 2 -env: - runner: - FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/retro-result.schema.json - sandbox: - RETRO_COMMENT: "${RETRO_COMMENT}" +runner_env: + FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/retro-result.schema.json timeout_minutes: 30 @@ -54,12 +51,7 @@ forge: github: pre_script: scripts/pre-retro.sh post_script: scripts/post-retro.sh - env: - runner: - ORIGINATING_URL: "${ORIGINATING_URL}" - REPO_FULL_NAME: "${REPO_FULL_NAME}" - GH_TOKEN: "${GH_TOKEN}" - sandbox: - ORIGINATING_URL: "${ORIGINATING_URL}" - REPO_FULL_NAME: "${REPO_FULL_NAME}" - GH_TOKEN: "${GH_TOKEN}" + runner_env: + ORIGINATING_URL: "${ORIGINATING_URL}" + REPO_FULL_NAME: "${REPO_FULL_NAME}" + GH_TOKEN: "${GH_TOKEN}" diff --git a/.fullsend/customized/harness/review.yaml b/.fullsend/customized/harness/review.yaml index f05e16240..a6a6a65cd 100644 --- a/.fullsend/customized/harness/review.yaml +++ b/.fullsend/customized/harness/review.yaml @@ -45,13 +45,8 @@ validation_loop: script: scripts/validate-output-schema.sh max_iterations: 2 -env: - runner: - FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/review-result.schema.json - sandbox: - PRIOR_REVIEW_SHA: "${PRIOR_REVIEW_SHA}" - PRIOR_REVIEW_PROVENANCE: "${PRIOR_REVIEW_PROVENANCE}" - REVIEW_FINDING_SEVERITY_THRESHOLD: "${REVIEW_FINDING_SEVERITY_THRESHOLD}" +runner_env: + FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/review-result.schema.json timeout_minutes: 20 @@ -59,14 +54,8 @@ forge: github: pre_script: scripts/pre-review.sh post_script: scripts/post-review.sh - env: - runner: - REVIEW_TOKEN: "${REVIEW_TOKEN}" - REPO_FULL_NAME: "${REPO_FULL_NAME}" - PR_NUMBER: "${PR_NUMBER}" - GITHUB_PR_URL: "${GITHUB_PR_URL}" - sandbox: - GITHUB_PR_URL: "${GITHUB_PR_URL}" - GH_TOKEN: "${GH_TOKEN}" - PR_NUMBER: "${PR_NUMBER}" - REPO_FULL_NAME: "${REPO_FULL_NAME}" + runner_env: + REVIEW_TOKEN: "${REVIEW_TOKEN}" + REPO_FULL_NAME: "${REPO_FULL_NAME}" + PR_NUMBER: "${PR_NUMBER}" + GITHUB_PR_URL: "${GITHUB_PR_URL}" diff --git a/.fullsend/customized/harness/triage.yaml b/.fullsend/customized/harness/triage.yaml index 5c11c589e..88a73a5b9 100644 --- a/.fullsend/customized/harness/triage.yaml +++ b/.fullsend/customized/harness/triage.yaml @@ -38,9 +38,8 @@ validation_loop: script: scripts/validate-output-schema.sh max_iterations: 2 -env: - runner: - FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/triage-result.schema.json +runner_env: + FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/triage-result.schema.json timeout_minutes: 10 @@ -48,10 +47,6 @@ forge: github: pre_script: scripts/pre-triage.sh post_script: scripts/post-triage.sh - env: - runner: - GITHUB_ISSUE_URL: ${GITHUB_ISSUE_URL} - GH_TOKEN: ${GH_TOKEN} - sandbox: - GITHUB_ISSUE_URL: "${GITHUB_ISSUE_URL}" - GH_TOKEN: "${GH_TOKEN}" + runner_env: + GITHUB_ISSUE_URL: ${GITHUB_ISSUE_URL} + GH_TOKEN: ${GH_TOKEN} diff --git a/internal/scaffold/fullsend-repo/harness/fix.yaml b/internal/scaffold/fullsend-repo/harness/fix.yaml index e6ce2a339..0ec1165a1 100644 --- a/internal/scaffold/fullsend-repo/harness/fix.yaml +++ b/internal/scaffold/fullsend-repo/harness/fix.yaml @@ -55,24 +55,15 @@ plugins: skills: - skills/fix-review -env: - runner: - TARGET_BRANCH: "${TARGET_BRANCH}" - TRIGGER_SOURCE: "${TRIGGER_SOURCE}" - HUMAN_INSTRUCTION: "${HUMAN_INSTRUCTION}" - FIX_ITERATION: "${FIX_ITERATION}" - REVIEW_BODY_FILE: "${REVIEW_BODY_FILE}" - PRE_AGENT_HEAD: "${PRE_AGENT_HEAD}" - FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/fix-result.schema.json - FULLSEND_OUTPUT_FILE: fix-result.json - sandbox: - MAX_RETRIES: "1" - TIMEOUT_SECONDS: "1500" - STRATEGY_ESCALATION_THRESHOLD: "3" - ITERATION_CAP: "5" - ITERATION_CAP_HUMAN: "10" - GOPATH: "/sandbox/go" - GOMODCACHE: "/sandbox/go/pkg/mod" +runner_env: + TARGET_BRANCH: "${TARGET_BRANCH}" + TRIGGER_SOURCE: "${TRIGGER_SOURCE}" + HUMAN_INSTRUCTION: "${HUMAN_INSTRUCTION}" + FIX_ITERATION: "${FIX_ITERATION}" + REVIEW_BODY_FILE: "${REVIEW_BODY_FILE}" + PRE_AGENT_HEAD: "${PRE_AGENT_HEAD}" + FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/fix-result.schema.json + FULLSEND_OUTPUT_FILE: fix-result.json timeout_minutes: 25 @@ -80,21 +71,9 @@ forge: github: pre_script: scripts/pre-fix.sh post_script: scripts/post-fix.sh - env: - runner: - PUSH_TOKEN: "${PUSH_TOKEN}" - PUSH_TOKEN_SOURCE: "${PUSH_TOKEN_SOURCE}" - REPO_FULL_NAME: "${REPO_FULL_NAME}" - PR_NUMBER: "${PR_NUMBER}" - REPO_DIR: "${GITHUB_WORKSPACE}/target-repo" - sandbox: - PR_NUMBER: "${PR_NUMBER}" - REPO_FULL_NAME: "${REPO_FULL_NAME}" - TRIGGER_SOURCE: "${TRIGGER_SOURCE}" - HUMAN_INSTRUCTION: "${HUMAN_INSTRUCTION}" - FIX_ITERATION: "${FIX_ITERATION}" - GH_TOKEN: "${GH_TOKEN}" - GIT_AUTHOR_NAME: "fullsend-fix" - GIT_AUTHOR_EMAIL: "${GIT_BOT_EMAIL}" - GIT_COMMITTER_NAME: "fullsend-fix" - GIT_COMMITTER_EMAIL: "${GIT_BOT_EMAIL}" + runner_env: + PUSH_TOKEN: "${PUSH_TOKEN}" + PUSH_TOKEN_SOURCE: "${PUSH_TOKEN_SOURCE}" + REPO_FULL_NAME: "${REPO_FULL_NAME}" + PR_NUMBER: "${PR_NUMBER}" + REPO_DIR: "${GITHUB_WORKSPACE}/target-repo" diff --git a/internal/scaffold/fullsend-repo/harness/prioritize.yaml b/internal/scaffold/fullsend-repo/harness/prioritize.yaml index 07fe8ca86..83f2f4e97 100644 --- a/internal/scaffold/fullsend-repo/harness/prioritize.yaml +++ b/internal/scaffold/fullsend-repo/harness/prioritize.yaml @@ -36,9 +36,8 @@ validation_loop: script: scripts/validate-output-schema.sh max_iterations: 2 -env: - runner: - FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/prioritize-result.schema.json +runner_env: + FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/prioritize-result.schema.json timeout_minutes: 10 @@ -46,12 +45,8 @@ forge: github: pre_script: scripts/pre-prioritize.sh post_script: scripts/post-prioritize.sh - env: - runner: - GITHUB_ISSUE_URL: ${GITHUB_ISSUE_URL} - GH_TOKEN: ${GH_TOKEN} - ORG: ${ORG} - PROJECT_NUMBER: ${PROJECT_NUMBER} - sandbox: - GITHUB_ISSUE_URL: "${GITHUB_ISSUE_URL}" - GH_TOKEN: "${GH_TOKEN}" + runner_env: + GITHUB_ISSUE_URL: ${GITHUB_ISSUE_URL} + GH_TOKEN: ${GH_TOKEN} + ORG: ${ORG} + PROJECT_NUMBER: ${PROJECT_NUMBER} diff --git a/internal/scaffold/fullsend-repo/harness/retro.yaml b/internal/scaffold/fullsend-repo/harness/retro.yaml index b6d8ef805..60de256da 100644 --- a/internal/scaffold/fullsend-repo/harness/retro.yaml +++ b/internal/scaffold/fullsend-repo/harness/retro.yaml @@ -43,11 +43,8 @@ validation_loop: script: scripts/validate-output-schema.sh max_iterations: 2 -env: - runner: - FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/retro-result.schema.json - sandbox: - RETRO_COMMENT: "${RETRO_COMMENT}" +runner_env: + FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/retro-result.schema.json timeout_minutes: 30 @@ -55,12 +52,7 @@ forge: github: pre_script: scripts/pre-retro.sh post_script: scripts/post-retro.sh - env: - runner: - ORIGINATING_URL: "${ORIGINATING_URL}" - REPO_FULL_NAME: "${REPO_FULL_NAME}" - GH_TOKEN: "${GH_TOKEN}" - sandbox: - ORIGINATING_URL: "${ORIGINATING_URL}" - REPO_FULL_NAME: "${REPO_FULL_NAME}" - GH_TOKEN: "${GH_TOKEN}" + runner_env: + ORIGINATING_URL: "${ORIGINATING_URL}" + REPO_FULL_NAME: "${REPO_FULL_NAME}" + GH_TOKEN: "${GH_TOKEN}" diff --git a/internal/scaffold/fullsend-repo/harness/review.yaml b/internal/scaffold/fullsend-repo/harness/review.yaml index d14f7f5bb..27674ceec 100644 --- a/internal/scaffold/fullsend-repo/harness/review.yaml +++ b/internal/scaffold/fullsend-repo/harness/review.yaml @@ -45,13 +45,8 @@ validation_loop: script: scripts/validate-output-schema.sh max_iterations: 2 -env: - runner: - FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/review-result.schema.json - sandbox: - PRIOR_REVIEW_SHA: "${PRIOR_REVIEW_SHA}" - PRIOR_REVIEW_PROVENANCE: "${PRIOR_REVIEW_PROVENANCE}" - REVIEW_FINDING_SEVERITY_THRESHOLD: "${REVIEW_FINDING_SEVERITY_THRESHOLD}" +runner_env: + FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/review-result.schema.json timeout_minutes: 20 @@ -59,14 +54,8 @@ forge: github: pre_script: scripts/pre-review.sh post_script: scripts/post-review.sh - env: - runner: - REVIEW_TOKEN: "${REVIEW_TOKEN}" - REPO_FULL_NAME: "${REPO_FULL_NAME}" - PR_NUMBER: "${PR_NUMBER}" - GITHUB_PR_URL: "${GITHUB_PR_URL}" - sandbox: - GITHUB_PR_URL: "${GITHUB_PR_URL}" - GH_TOKEN: "${GH_TOKEN}" - PR_NUMBER: "${PR_NUMBER}" - REPO_FULL_NAME: "${REPO_FULL_NAME}" + runner_env: + REVIEW_TOKEN: "${REVIEW_TOKEN}" + REPO_FULL_NAME: "${REPO_FULL_NAME}" + PR_NUMBER: "${PR_NUMBER}" + GITHUB_PR_URL: "${GITHUB_PR_URL}" diff --git a/internal/scaffold/fullsend-repo/harness/triage.yaml b/internal/scaffold/fullsend-repo/harness/triage.yaml index 276445e74..4c4545ba1 100644 --- a/internal/scaffold/fullsend-repo/harness/triage.yaml +++ b/internal/scaffold/fullsend-repo/harness/triage.yaml @@ -39,9 +39,8 @@ validation_loop: script: scripts/validate-output-schema.sh max_iterations: 2 -env: - runner: - FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/triage-result.schema.json +runner_env: + FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/triage-result.schema.json timeout_minutes: 10 @@ -49,10 +48,6 @@ forge: github: pre_script: scripts/pre-triage.sh post_script: scripts/post-triage.sh - env: - runner: - GITHUB_ISSUE_URL: ${GITHUB_ISSUE_URL} - GH_TOKEN: ${GH_TOKEN} - sandbox: - GITHUB_ISSUE_URL: "${GITHUB_ISSUE_URL}" - GH_TOKEN: "${GH_TOKEN}" + runner_env: + GITHUB_ISSUE_URL: ${GITHUB_ISSUE_URL} + GH_TOKEN: ${GH_TOKEN} diff --git a/internal/scaffold/scaffold_test.go b/internal/scaffold/scaffold_test.go index 90e6cf599..02cd6f294 100644 --- a/internal/scaffold/scaffold_test.go +++ b/internal/scaffold/scaffold_test.go @@ -645,7 +645,7 @@ func TestHarnessForgeRunnerEnvMerge(t *testing.T) { }, { file: "code.yaml", - topLevelKeys: []string{"TARGET_BRANCH"}, + topLevelKeys: []string{"CODE_ALLOWED_TARGET_BRANCHES", "FULLSEND_OUTPUT_SCHEMA", "FULLSEND_OUTPUT_FILE"}, forgeGithubKeys: []string{"PUSH_TOKEN", "PUSH_TOKEN_SOURCE", "REPO_FULL_NAME", "ISSUE_NUMBER", "REPO_DIR"}, }, {