Skip to content

feat(#6226): gate WIF secrets in per-repo shim by credential mode - #6241

Closed
fullsend-ai-coder[bot] wants to merge 1 commit into
mainfrom
agent/6226-scaffold-wif-gating
Closed

feat(#6226): gate WIF secrets in per-repo shim by credential mode#6241
fullsend-ai-coder[bot] wants to merge 1 commit into
mainfrom
agent/6226-scaffold-wif-gating

Conversation

@fullsend-ai-coder

@fullsend-ai-coder fullsend-ai-coder Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Gate WIF secrets (FULLSEND_GCP_WIF_PROVIDER, FULLSEND_GCP_PROJECT_ID) in the per-repo shim workflow template by credential mode — OIDC repos no longer get confusing WIF secret references in their generated .github/workflows/fullsend.yaml
  • Add CredentialMode to scaffold RenderOptions and thread it through CollectPerRepoInstallFiles, BuildScaffoldFiles, and FetchRemoteScaffold
  • Make FULLSEND_GCP_PROJECT_ID optional (required: false) in reusable-dispatch.yml so OIDC-mode shims don't fail validation
  • Document credential modes (wif/oidc/token) in the mint administration guide

Changes

  • internal/scaffold/render.go: Add CredentialMode field to RenderOptions; add stripWIFSecrets() that removes WIF secret lines when credential mode is oidc
  • internal/scaffold/installfiles.go: Add credentialMode parameter to CollectPerRepoInstallFiles
  • internal/repos/install.go: Resolve credential mode via resolveCredentialMode() in BuildScaffoldFiles before passing to scaffold layer
  • internal/repos/remote_scaffold.go: Thread credentialMode through FetchRemoteScaffold and fetchRemoteGitHubScaffold
  • internal/repos/batch_install.go: Pass resolved credential mode to FetchRemoteScaffold
  • internal/cli/github.go: Pass empty credential mode (backward compat for org-mode setup)
  • .github/workflows/reusable-dispatch.yml: Change FULLSEND_GCP_PROJECT_ID to required: false
  • docs/guides/infrastructure/mint-administration.md: Add "Credential modes" section

Testing

  • TestRenderPerRepoShimWIFMode — verifies WIF secrets present when credential mode is wif
  • TestRenderPerRepoShimOIDCMode — verifies WIF secrets stripped and OTEL secrets preserved when credential mode is oidc
  • TestRenderPerRepoShimDefaultCredMode — verifies empty credential mode defaults to including WIF secrets
  • TestCollectPerRepoInstallFiles_OIDCMode and TestCollectPerRepoInstallFiles_WIFMode — end-to-end tests through install file collection
  • TestFetchRemoteScaffold_GitHubOIDCMode — remote scaffold path strips WIF secrets in OIDC mode
  • All existing scaffold and repos tests pass

Out of scope

Upgrade SHA-pinning behavior change moved to a separate issue.


Closes #6226

@fullsend-ai-coder
fullsend-ai-coder Bot requested a review from a team as a code owner August 14, 2026 21:50
@fullsend-ai-coder fullsend-ai-coder Bot added the ready-for-review Agent PR ready for human review label Aug 14, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 14, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 9:52 PM UTC · Completed 10:11 PM UTC

Commit: e3ac5c2 · View workflow run →

@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown

Site preview

Preview: https://ce4501f2-site.fullsend-ai.workers.dev

Commit: 8ac981b8404e2b91a93ae7ea403049cd133001b2

@codecov

codecov Bot commented Aug 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 14, 2026

Copy link
Copy Markdown

Review

Findings

Medium

Low

  • [secret requirement relaxation] .github/workflows/reusable-dispatch.yml:66FULLSEND_GCP_PROJECT_ID changed from required: true to required: false. Combined with FULLSEND_GCP_WIF_PROVIDER already being required: false, the reusable workflow now accepts calls with no GCP credentials. This is fail-closed in practice (setup-gcp still rejects empty values), but a YAML comment explaining why these secrets are optional and which modes require them would aid future maintainers.

  • [stale-doc] docs/guides/infrastructure/infrastructure-reference.md:240 — The "Per-Repo Mode Secrets/Variables > GitHub" section lists FULLSEND_GCP_PROJECT_ID and FULLSEND_GCP_WIF_PROVIDER as unconditional "Target repo secrets." With credential-mode-aware shim generation, OIDC-mode repos do not have these secrets.
    Remediation: Add a WIF-mode qualifier (e.g., "Target repo secrets (WIF mode only):").

  • [intent-alignment] internal/scaffold/render.gostripWIFSecrets uses exact indentation-sensitive string matching (6-space prefix). Template indentation changes would silently break stripping. Mitigated by existing tests.

  • [API-shape-consistency] internal/scaffold/installfiles.go:49CollectPerRepoInstallFiles takes 4 positional parameters (bool + 3 strings), while its sibling CollectInstallFiles uses a CollectInstallFilesOptions struct. The new credentialMode parameter deepens this divergence.

  • [growing-positional-parameter-list] internal/repos/remote_scaffold.go:34FetchRemoteScaffold now accepts 7 parameters including 4 consecutive strings, which is error-prone at call sites.

  • [magic-string-vs-constant] internal/scaffold/render.go:120stripWIFSecrets compares against the string literal "oidc" rather than a named constant. The CredModeOIDC constant in the repos package cannot be imported due to circular dependency; consider a package-local constant.

  • [stale-doc] docs/guides/dev/cli-internals.md:256 — Phase 6 diagram states "Both modes write the same credential set" and unconditionally lists FULLSEND_GCP_PROJECT_ID and FULLSEND_GCP_WIF_PROVIDER. With credential-mode gating, OIDC-mode installs omit these secrets.

  • [stale-doc] docs/guides/getting-started/operations.md:26 — The GitHub operations table lists FULLSEND_GCP_PROJECT_ID and FULLSEND_GCP_WIF_PROVIDER as unconditional "Repo secret" entries without noting they are WIF-mode only. The GitLab section on the same page already annotates its equivalent entries with a mode qualifier.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run

Review

Findings

High

  • [API contract violation] .github/workflows/reusable-dispatch.yml — The setup-gcp composite action is called unconditionally in every stage job (triage, code, review, fix, retro, prioritize, harness-run) and its action.yml declares gcp_wif_provider as required: true. For OIDC-mode repos, the generated shim omits FULLSEND_GCP_WIF_PROVIDER (via stripWIFSecrets), so the secret will be empty at runtime, causing the google-github-actions/auth step to fail. OIDC-mode repos cannot successfully dispatch any agent stage. Issue repos: scaffold template WIF gating and mint-administration docs for credential modes #6226 item 2 ("setup-gcp action: skip when credential mode is oidc") is not addressed by this PR, which claims to close repos: scaffold template WIF gating and mint-administration docs for credential modes #6226.
    Remediation: Make the setup-gcp step conditional on the presence of WIF secrets (e.g., if: secrets.FULLSEND_GCP_WIF_PROVIDER != ''), or make the gcp_wif_provider input optional in setup-gcp/action.yml and add a conditional skip inside the composite action.

Medium

  • [scope-creep] internal/repos/upgrade.go:220 — The upgrade logic changes alter SHA pinning semantics in a way not authorized by issue repos: scaffold template WIF gating and mint-administration docs for credential modes #6226. Previously, all floating refs (tags, branches) were resolved to commit SHAs during upgrades, writing the pinned format (@<sha> # <ref>). Now SHA resolution is only performed for repos already SHA-pinned; tag-only or branch-pinned repos keep the string ref as-is. This spans ~60 lines of logic rewrite in upgrade.go, ~184 lines of test changes in upgrade_test.go, and documentation changes in repo-management.md. Issue repos: scaffold template WIF gating and mint-administration docs for credential modes #6226 scopes work to scaffold template WIF gating and mint-administration documentation.
    Remediation: Extract the upgrade.go, upgrade_test.go, and repo-management.md changes into a separate PR with its own issue that documents the rationale for changing SHA pinning behavior.

  • [breaking-change-risk] internal/repos/upgrade.go:293 — The upgrade behavior change may constitute a breaking change per COMMITS.md criteria: previously, running repos install on a tag-pinned repo (e.g., @v2.1.0 with target v2.3.0) would produce @<sha> # v2.3.0 (SHA-pinned output). Now the same operation produces @v2.3.0 (tag-only output). Users who depend on SHA pinning being applied universally during upgrades will see different workflow file contents. If this change is retained, the PR title needs the ! suffix and a BREAKING CHANGE trailer per COMMITS.md.
    Remediation: Evaluate whether this meets the breaking change threshold. If retained (in this PR or a separate one), mark the PR title with ! and add a BREAKING CHANGE trailer.

  • [stale-doc] docs/guides/infrastructure/infrastructure-reference.md:240 — The "Per-Repo Mode Secrets/Variables > GitHub" section lists FULLSEND_GCP_PROJECT_ID and FULLSEND_GCP_WIF_PROVIDER as unconditional "Target repo secrets" for all GitHub per-repo installations. With credential-mode-aware shim generation, OIDC-mode repos do not have these secrets in the generated workflow.
    Remediation: Add a WIF-mode qualifier (e.g., "Target repo secrets (WIF mode only):"), similar to the GitLab section's pattern.

  • [protected-path] .github/workflows/reusable-dispatch.yml — This PR modifies files under the .github/ protected path. The change is authorized by issue repos: scaffold template WIF gating and mint-administration docs for credential modes #6226 item 3 (change FULLSEND_GCP_PROJECT_ID to required: false). Human approval is required for all protected-path changes regardless of context.

Low

  • [intent-alignment] internal/scaffold/render.go:62stripWIFSecrets uses exact string matching against indentation-specific patterns (" FULLSEND_GCP_WIF_PROVIDER: ..."). Template indentation changes would silently break stripping (mitigated by existing tests).

  • [API-shape-consistency] internal/scaffold/installfiles.go:49CollectPerRepoInstallFiles takes 4 positional parameters (bool + 3 strings), while its sibling CollectInstallFiles uses a CollectInstallFilesOptions struct. The new credentialMode parameter deepens this divergence.

  • [growing-positional-parameter-list] internal/repos/remote_scaffold.go:37FetchRemoteScaffold now accepts 7 parameters including 4 consecutive strings, which is error-prone at call sites.

  • [magic-string-vs-constant] internal/scaffold/render.go:120stripWIFSecrets compares against the string literal "oidc" rather than a named constant. The CredModeOIDC constant in the repos package cannot be imported due to circular dependency; consider a package-local constant.

  • [stale-doc] docs/guides/dev/cli-internals.md:256 — Phase 6 diagram states "Both modes write the same credential set" and unconditionally lists FULLSEND_GCP_PROJECT_ID and FULLSEND_GCP_WIF_PROVIDER. With credential-mode gating, OIDC-mode installs omit these secrets.

  • [stale-doc] docs/guides/getting-started/operations.md:26 — The GitHub operations table lists FULLSEND_GCP_PROJECT_ID and FULLSEND_GCP_WIF_PROVIDER as unconditional "Repo secret" entries without noting they are WIF-mode only. The GitLab section on the same page already annotates its equivalent entries with a mode qualifier.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run (2)

Review

Findings

High

  • [API contract violation] .github/workflows/reusable-dispatch.yml — The setup-gcp composite action is called unconditionally in every stage job and its action.yml declares gcp_wif_provider as required: true. For OIDC-mode repos — where the generated shim omits FULLSEND_GCP_WIF_PROVIDER — the secret will be empty at runtime, causing the google-github-actions/auth step to fail. OIDC-mode repos cannot successfully dispatch any agent stage. This is issue repos: scaffold template WIF gating and mint-administration docs for credential modes #6226 item 2, which the PR claims to close but does not address.
    Remediation: Make the setup-gcp step conditional on the presence of WIF secrets (e.g., if: secrets.FULLSEND_GCP_WIF_PROVIDER != ''), or pass credential mode as a workflow input and skip setup-gcp when mode is oidc.

Medium

  • [scope-creep] internal/repos/upgrade.go:220 — The upgrade logic changes alter SHA pinning semantics: previously, all floating refs were resolved to SHAs during upgrades; now SHA pinning is only preserved for repos that are already SHA-pinned. This is a significant behavioral change not authorized by issue repos: scaffold template WIF gating and mint-administration docs for credential modes #6226, which scopes work to scaffold template WIF gating and mint-administration documentation.
    Remediation: Split the upgrade.go SHA-pinning changes (and corresponding test rewrites in upgrade_test.go and documentation update in repo-management.md) into a separate PR linked to a dedicated issue.

  • [stale-doc] docs/guides/infrastructure/infrastructure-reference.md:240 — The "Per-Repo Mode Secrets/Variables > GitHub" section lists FULLSEND_GCP_PROJECT_ID and FULLSEND_GCP_WIF_PROVIDER as unconditional "Target repo secrets" for all GitHub per-repo installations. With credential-mode-aware shim generation, OIDC-mode repos do not have these secrets.
    Remediation: Add a WIF-mode qualifier, e.g., "Target repo secrets (WIF mode only):", similar to the GitLab section's pattern.

  • [protected-path] .github/workflows/reusable-dispatch.yml — This PR modifies files under the .github/ protected path. The change is authorized by issue repos: scaffold template WIF gating and mint-administration docs for credential modes #6226 (item 3: change FULLSEND_GCP_PROJECT_ID to required: false). Human approval is required for all protected-path changes regardless of context.

Low

  • [dry-run inconsistency] internal/repos/upgrade.go:222 — DryRun for SHA-pinned repos at the target version produces a false positive: replaceShimRef(content, targetRef, "", ...) replaces @<sha> # v2.3.0 with @v2.3.0 (changed=true), but non-DryRun resolves the tag back to the same SHA and correctly skips.

  • [API-shape-consistency] internal/scaffold/installfiles.go:49CollectPerRepoInstallFiles takes 4 positional parameters (bool + 3 strings), while its sibling CollectInstallFiles uses an options struct.

  • [growing-positional-parameter-list] internal/repos/remote_scaffold.go:37FetchRemoteScaffold now accepts 7 parameters including forge-specific ones (credentialMode for GitHub, runnerTags for GitLab).

  • [magic-string-vs-constant] internal/scaffold/render.go:120stripWIFSecrets compares against the string literal "oidc" rather than a named constant. The CredModeOIDC constant in the repos package cannot be imported due to circular dependency; consider a package-local constant.

  • [intent-alignment] internal/scaffold/render.go:124stripWIFSecrets uses exact string matching against indentation-specific patterns. Template indentation changes would silently break stripping (mitigated by existing tests).

  • [upgrade behavior change] internal/repos/upgrade.go:235 — Floating refs are no longer resolved to SHAs for non-SHA-pinned repos, reducing automatic supply-chain pinning on upgrade.


Labels: PR modifies scaffold/install code, dispatch workflow, and documentation


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run (3)

Review

Findings

High

  • [API contract violation] internal/scaffold/render.go:126stripWIFSecrets removes the FULLSEND_GCP_PROJECT_ID secret line from the per-repo shim when credential mode is oidc. However, reusable-dispatch.yml declares this secret as required: true (line 65-66). When a repo is installed with credential_mode: oidc, the generated fullsend.yaml will call reusable-dispatch.yml without passing FULLSEND_GCP_PROJECT_ID, causing GitHub Actions to reject the workflow call with a validation error.
    Remediation: Either (1) change FULLSEND_GCP_PROJECT_ID to required: false in .github/workflows/reusable-dispatch.yml (item 3 from issue repos: scaffold template WIF gating and mint-administration docs for credential modes #6226), or (2) only strip FULLSEND_GCP_WIF_PROVIDER in OIDC mode while keeping FULLSEND_GCP_PROJECT_ID.

Medium

  • [parameter-threading-inconsistency] internal/repos/install.go:316BuildScaffoldFiles passes the raw cfg.CredentialMode to CollectPerRepoInstallFiles, but Install() resolves credential mode via resolveCredentialMode() earlier. When CredentialMode is empty (common default for GitHub repos without --inference-project), resolveCredentialMode returns "oidc", but BuildScaffoldFiles passes "" to the scaffold layer, so stripWIFSecrets is a no-op. The scaffold output is inconsistent with the resolved credential mode.
    Remediation: Pass the resolved credential mode to BuildScaffoldFiles.

  • [scope-gap] .github/workflows/reusable-dispatch.yml:66 — Issue repos: scaffold template WIF gating and mint-administration docs for credential modes #6226 lists three scaffold items: (1) conditionally pass WIF secrets, (2) skip setup-gcp when oidc, (3) change FULLSEND_GCP_PROJECT_ID from required: true. This PR implements only item 1 and says "Closes repos: scaffold template WIF gating and mint-administration docs for credential modes #6226". Item 3 directly causes the high-severity API contract violation above.
    Remediation: Implement item 3 in this PR to fix the contract violation, or change "Closes repos: scaffold template WIF gating and mint-administration docs for credential modes #6226" to a partial reference and file a follow-up.

  • [technical-documentation-accuracy] docs/guides/infrastructure/mint-administration.md:78 — The new documentation states "The CLI flag --credential-mode on repos install overrides both the manifest default and per-repo settings." No --credential-mode flag exists on repos install.
    Remediation: Remove the paragraph or implement the flag.

Low

  • [API-shape-consistency] internal/scaffold/installfiles.go:49CollectPerRepoInstallFiles now takes 4 positional parameters (bool + 3 strings), while its sibling CollectInstallFiles uses an options struct. Consider refactoring for consistency.

  • [fail-open-default] internal/scaffold/render.go:120stripWIFSecrets only strips when CredentialMode is exactly "oidc". Any other value (including empty string) leaves WIF secret references. Practical risk mitigated by upstream validation.

  • [intent-alignment] internal/scaffold/render.go:119stripWIFSecrets uses exact string matching against indentation-specific patterns. If template indentation changes, stripping silently stops working. Consistent with existing codebase patterns.

  • [growing-positional-parameter-list] internal/repos/remote_scaffold.go:37FetchRemoteScaffold now accepts 7 parameters including 4 consecutive strings, making call sites error-prone.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR

fullsend-ai-review[bot]

This comment was marked as outdated.

@ggallen
ggallen force-pushed the agent/6226-scaffold-wif-gating branch from e3ac5c2 to e188658 Compare August 14, 2026 22:52
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 14, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 10:54 PM UTC · Completed 11:14 PM UTC

Commit: e188658 · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added component/install CLI install and app setup component/dispatch Workflow dispatch and triggers go Pull requests that update go code labels Aug 14, 2026
@ggallen
ggallen force-pushed the agent/6226-scaffold-wif-gating branch from e188658 to b300bb1 Compare August 15, 2026 00:40
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 15, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 12:42 AM UTC · Completed 1:22 AM UTC

Commit: b300bb1 · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

Signed-off-by: Greg Allen <gallen@redhat.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Greg Allen <gallen@redhat.com>
@ggallen
ggallen force-pushed the agent/6226-scaffold-wif-gating branch from b300bb1 to 8ac981b Compare August 15, 2026 01:38
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 15, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 1:39 AM UTC · Completed 2:00 AM UTC

Commit: 8ac981b · View workflow run →

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the review comment for full details.


Note: The following inline comments could not be posted on the diff (GitHub returned 422) and are included here instead:

  • .github/workflows/reusable-dispatch.yml (file-level): Line 626 · [medium] API contract violation

The setup-gcp composite action is called unconditionally in every stage job, and its action.yml declares gcp_wif_provider as required: true. For OIDC-mode repos, stripWIFSecrets removes FULLSEND_GCP_WIF_PROVIDER from the generated shim, so the secret reaches reusable-dispatch.yml as an empty string. google-github-actions/auth will fail with an empty workload_identity_provider, aborting the stage job. This is a known-deferred item (issue #6226 item 2) and is fail-closed, but the PR claims Closes #6226 while this item remains unaddressed.

Suggested fix: Either add an if condition to each setup-gcp step (e.g., if: secrets.FULLSEND_GCP_WIF_PROVIDER != ''), or change Closes #6226 to a partial reference and file a follow-up for the setup-gcp conditional.

  • .github/workflows/reusable-dispatch.yml:66: [medium] protected-path

This PR modifies a file under the .github/ protected path. The change is authorized by issue #6226 item 3 (change FULLSEND_GCP_PROJECT_ID to required: false). Human approval is required for all protected-path changes regardless of context.

  • .github/workflows/reusable-dispatch.yml:66: [low] secret-requirement-relaxation

FULLSEND_GCP_PROJECT_ID changed from required: true to required: false. Combined with FULLSEND_GCP_WIF_PROVIDER already being required: false, the reusable workflow now accepts calls with no GCP credentials. This is fail-closed in practice (setup-gcp still rejects empty values), but a YAML comment explaining why these secrets are optional would aid future maintainers.

  • internal/scaffold/installfiles.go:49: [low] API-shape-consistency

CollectPerRepoInstallFiles takes 4 positional parameters (bool + 3 strings), while its sibling CollectInstallFiles uses a CollectInstallFilesOptions struct. The new credentialMode parameter deepens this divergence.

  • internal/repos/remote_scaffold.go:34: [low] growing-positional-parameter-list

FetchRemoteScaffold now accepts 7 parameters including 4 consecutive strings, which is error-prone at call sites.

  • internal/scaffold/render.go:120: [low] magic-string-vs-constant

stripWIFSecrets compares against the string literal oidc rather than a named constant. The CredModeOIDC constant in the repos package cannot be imported due to circular dependency; consider a package-local constant.

@ifireball ifireball left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tihis PR is wrong and should not be merged,

FULLSEND_GCP_WIF_PROVIDER, FULLSEND_GCP_PROJECT_ID are required for WIF authentication for GCP Vertex inference and has nothing to do with the mint.

The confusion must be a result of the move to the public mint that no longer requires enrolment at the mint level, but that change does not imply or require any changes at the inference infrastructure and the credetials used for it.

@ggallen

ggallen commented Aug 16, 2026

Copy link
Copy Markdown
Member

Closing: the credential mode model this builds on is being removed in #6257. Stripping WIF secrets from the shim would break inference — see #6257 for the full analysis.

@ggallen ggallen closed this Aug 16, 2026
@fullsend-ai-retro

fullsend-ai-retro Bot commented Aug 16, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 12:25 PM UTC · Completed 12:36 PM UTC

Commit: 8ac981b · View workflow run →

@fullsend-ai-retro

Copy link
Copy Markdown

Retro: PR #6241 — gate WIF secrets in per-repo shim by credential mode

Outcome: PR closed without merging. The entire credential-mode approach was architecturally unsound — WIF secrets are required for GCP Vertex inference regardless of mint mode, so stripping them from the shim would break inference.

Timeline

  1. Issue #6226 created by ggallen (2026-08-14) — scaffold template WIF gating follow-up to repos commands: add credential mode model (wif/oidc/token) for public mint compatibility #6222.
  2. Triage agent ran 3× (2026-08-14 13:53–14:31) — correctly identified the issue as blocked on PR feat(#6222): add credential mode model (wif/oidc/token) to repos commands #6224 and warned that .github/workflows/ and .github/actions/ files require manual intervention due to missing workflows permission.
  3. Code agent run 1 (31839938708, 2026-08-14 20:52–21:19) — FAILED. The agent read and acknowledged the triage warnings about .github/ permission constraints, then proceeded to modify .github/workflows/reusable-dispatch.yml anyway. Push was rejected by GitHub (refusing to allow a GitHub App to create or update workflow ... without workflows permission).
  4. Human re-dispatch (2026-08-14 21:34) — ggallen provided explicit constraints: "DO NOT modify any files under .github/."
  5. Code agent run 2 (31843055047, 2026-08-14 21:35–21:51) — SUCCEEDED. PR #6241 created.
  6. Review agent ran 4× (2026-08-14 21:51 – 2026-08-15 01:38) — found 12+ valid implementation-level findings including API contract violations, parameter-threading bugs, scope creep, and incomplete scope. All operated at the code level; none questioned the feature premise.
  7. Human reviewer ifireball (2026-08-16 05:45) — CHANGES_REQUESTED with the fundamental objection: WIF secrets are for GCP Vertex inference, not the mint. Stripping them would break repos.
  8. PR closed by ggallen (2026-08-16 12:23) — credential mode model being removed in fix: remove credential mode model, separate mint mode from inference requirements #6257.

Key Findings

1. Review agent altitude gap — design-level premise missed across 4 rounds

The review agent performed well at implementation review: it found real bugs (API contract violation between stripWIFSecrets and reusable-dispatch.yml requiring FULLSEND_GCP_PROJECT_ID), a parameter-threading inconsistency, documentation inaccuracies, and scope creep. The code agent acted on these findings, fixing 3 and reverting 1.

However, across all 4 review rounds, the agent never questioned the fundamental premise — that OIDC-mode repos don't need WIF secrets. It accepted the PR's assumption at face value and reviewed only whether the implementation was internally consistent with that assumption. Notably, the agent's stale-documentation findings (recommending docs say WIF secrets are "WIF mode only") would have introduced factual errors if acted upon, because the agent had internalized the flawed premise.

The human reviewer (ifireball) identified the design flaw in a single sentence. This evidence corroborates existing open issues:

2. Code agent ignored triage permission warnings

The code agent's run logs show it explicitly acknowledged the triage warning about .github/workflows/ requiring manual intervention — then modified those files anyway, causing a push rejection. The root cause is a semantic gap in the code agent definition (agents/code.md): it says the agent "may propose changes to any path, including .github/" with the caveat that human review is needed, but doesn't distinguish between "needs human review approval" and "push will be rejected by GitHub." The agent treated the triage warning as advisory rather than a hard constraint, consistent with its zero-trust stance toward triage output.

This evidence corroborates existing open issues:

  • fullsend-ai/fullsend#3627 — code agent should treat .github/workflows/ as unpushable when coder token lacks workflows permission
  • fullsend-ai/agents#774 — post-triage footer should suppress /fs-code when triage flags requires_workflow_changes

3. Review agent did not incorporate scope reductions from human instructions

In later review rounds, the review agent continued flagging "incomplete scope" (item 2 of #6226 — conditionally skip setup-gcp) as a medium finding, even though the human had explicitly scoped this out as requiring workflow file modification that the coder app cannot perform. The agent re-reviewed without incorporating this context.

This evidence corroborates fullsend-ai/agents#447 — review agent should incorporate outstanding human reviews when re-reviewing.

Autonomy Assessment

The review agent's implementation-level findings were consistently valid and actionable — 12 of 13 findings were real issues. The code agent acted on most of them. This demonstrates strong value at the code-review altitude.

However, the missed design-level flaw — which rendered all implementation work moot — means increased autonomy is not warranted for PRs involving infrastructure credential configuration or architecture-level changes. The agent cannot substitute for human domain judgment on whether a feature's premise is correct. For straightforward implementation PRs within well-understood subsystems, the agent's review quality supports its current autonomy level.

Waste Impact

Total wasted effort: 2 code agent runs, 4 review agent runs, multiple human iteration cycles, all producing a PR that was discarded entirely. The most impactful improvements would be (a) the review agent questioning feature premises (existing issues #5385, #1535, #543) and (b) the code agent respecting permission boundaries (existing issues #3627, #774).

Proposals

All candidate improvements are covered by existing open issues (referenced above). No new proposals filed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/dispatch Workflow dispatch and triggers component/install CLI install and app setup go Pull requests that update go code ready-for-review Agent PR ready for human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

repos: scaffold template WIF gating and mint-administration docs for credential modes

2 participants