Skip to content

feat(workflows): add fullsend_ai_ref for self-consistent version pinning#1278

Merged
rh-hemartin merged 1 commit into
mainfrom
feat/version-pinning-workflows
Jun 4, 2026
Merged

feat(workflows): add fullsend_ai_ref for self-consistent version pinning#1278
rh-hemartin merged 1 commit into
mainfrom
feat/version-pinning-workflows

Conversation

@rh-hemartin

Copy link
Copy Markdown
Member

Summary

Closes #1075 (partially — the installer-side SHA pinning is a follow-up PR).

  • Adds a required fullsend_ai_ref input to reusable-dispatch and all five stage workflows (triage, code, review, fix, retro)
  • Each stage workflow now checks out fullsend-ai/fullsend at inputs.fullsend_ai_ref instead of the hardcoded v0 ref, then loads all actions and the agent binary from the local .defaults/ path
  • reusable-dispatch switches its stage uses: to relative ./.github/workflows/reusable-*.yml paths — a caller pinned to e.g. @v0.10.1 automatically resolves all nested workflows at that same tag
  • Scaffold callers and the per-repo shim template pass fullsend_ai_ref: v0 as a stable default for enrolled repos
  • Drops sparse-checkout (full clone required for relative action refs to resolve)
  • Adds docs/guides/dev/testing-workflows.md explaining how to point an installed repo at a dev branch for end-to-end testing

What's not covered (follow-up)

The installer (fullsend admin install) still scaffolds fullsend_ai_ref: v0 as a literal string. A follow-up PR will make the installer substitute the actual release SHA at install time, completing the SHA-pinning story from #1075.

Test plan

  • Push a test branch, update a dev repo's shim uses: and fullsend_ai_ref to that branch, trigger /fs-triage — confirm the stage workflow loads actions and the agent binary from the branch
  • Verify per-org thin callers pass fullsend_ai_ref through correctly
  • Confirm relative ./ stage workflow paths resolve when dispatch is called at a pinned tag

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented May 21, 2026

Copy link
Copy Markdown

Site preview

Preview: https://8f687e32-site.fullsend-ai.workers.dev

Commit: 716f73c9c083431fc71de04d4c546954f7bc99e2

@fullsend-ai-review

fullsend-ai-review Bot commented May 21, 2026

Copy link
Copy Markdown

Review

Findings

Medium

  • [protected-path] .github/workflows/reusable-code.yml, .github/workflows/reusable-dispatch.yml, .github/workflows/reusable-fix.yml, .github/workflows/reusable-retro.yml, .github/workflows/reusable-review.yml, .github/workflows/reusable-triage.yml — Six workflow files under .github/ are modified. The PR links to admin install should pin reusable workflows and actions to a commit SHA instead of v0 #1075 and provides clear rationale (replacing hardcoded @v0 refs with caller-controlled fullsend_ai_ref input and relative workflow paths for self-consistent version pinning). The changes are mechanically consistent across all six workflows. Human approval is always required for protected-path changes regardless of context.

Info

  • [re-review] The prior medium-severity correctness finding (fullsend_ai_ref declared required: true with no default, breaking existing callers) has been resolved: all six workflows now declare required: false with default: v0, preserving backward compatibility.

  • [docs-currency] docs/ADRs/0031-reusable-workflows-for-action-installed-distribution.md — Multiple references to fullsend-ai/fullsend@v0 and fullsend-ai/fullsend/.github/actions/*@v0 describe the pre-PR action resolution pattern. These are historical ADR records and do not require updates.

Previous run

Review

Findings

Medium

  • [correctness] .github/workflows/reusable-*.yml, .github/workflows/reusable-dispatch.ymlfullsend_ai_ref is declared required: true with no default value across all six reusable workflows and dispatch. Existing deployed per-org thin callers and per-repo shims do not pass this input. When the v0 tag is moved forward to include this change, every existing installation will fail at workflow dispatch time because the required input is missing.
    Remediation: Add default: "v0" and set required: false so existing callers continue to work without modification. Alternatively, document and coordinate a synchronized rollout that updates all enrolled repos before moving the tag.

  • [protected-path] .github/workflows/reusable-code.yml, .github/workflows/reusable-dispatch.yml, .github/workflows/reusable-fix.yml, .github/workflows/reusable-retro.yml, .github/workflows/reusable-review.yml, .github/workflows/reusable-triage.yml — Six workflow files under .github/ are modified. The PR links to admin install should pin reusable workflows and actions to a commit SHA instead of v0 #1075 and provides clear rationale (replacing hardcoded @v0 refs with caller-controlled fullsend_ai_ref and relative workflow paths). Human approval is required for protected-path changes regardless of context.

Low

  • [docs-currency] docs/architecture.md:605 — The layer mapping table still describes the agent runner as using the fullsend-ai/fullsend@v0 composite action. After this PR the composite action is loaded via ./.defaults/ from a local checkout. This line is now stale.
    Remediation: Update to reflect the new ./.defaults/ action path and the fullsend_ai_ref mechanism.

Info

  • [docs-currency] docs/ADRs/0033-per-repo-installation-mode.md:161 — The layering precedence comment still says "sparse-checked" for upstream defaults. This PR removes sparse-checkout in favor of a full checkout. ADRs are historical records, but ADR 0035 was updated in this same PR, so consistency suggests updating this reference as well.

  • [docs-currency] docs/ADRs/0031-reusable-workflows-for-action-installed-distribution.md:62,80,96 — Multiple references to fullsend-ai/fullsend@v0 and fullsend-ai/fullsend/.github/actions/*@v0 describe the pre-PR action resolution pattern. The new pattern uses ./.defaults/ local paths. These are historical ADR references and may be intentionally preserved, but flagging for awareness.

Previous run (2)

Review

Findings

Medium

  • [protected-path] .github/workflows/reusable-{code,dispatch,fix,retro,review,triage}.yml — Six reusable workflow files under .github/ are modified. The linked issue (admin install should pin reusable workflows and actions to a commit SHA instead of v0 #1075) and PR description provide clear rationale (version-pinning plumbing with fullsend_ai_ref input and relative action paths), and the changes are mechanically consistent across all six workflows. Human approval is always required for protected-path changes regardless of context.

Low

  • [docs-currency] docs/architecture.md:605 — The layer-mapping table still describes the agent runner as using fullsend-ai/fullsend@v0 composite action. Stage workflows now load the composite action from ./.defaults/ (the local checkout at fullsend_ai_ref). The table entry is stale.
    Remediation: Update the Agent runner row to reflect that the composite action is loaded from the local .defaults/ checkout rather than a remote @v0 ref.
Previous run (3)

Review

Findings

Medium

  • [protected-path] .github/workflows/reusable-{code,dispatch,fix,retro,review,triage}.yml — Six reusable workflow files under .github/ are modified. The linked issue (admin install should pin reusable workflows and actions to a commit SHA instead of v0 #1075) and PR description provide clear rationale (version-pinning plumbing with fullsend_ai_ref input and relative action paths), and the changes are mechanically consistent across all six workflows. Human approval is always required for protected-path changes regardless of context.

Low

  • [docs-currency] docs/architecture.md:605 — The layer-mapping table still describes the agent runner as using fullsend-ai/fullsend@v0 composite action. Stage workflows now load the composite action from ./.defaults/ (the local checkout at fullsend_ai_ref). The table entry is stale.
    Remediation: Update the Agent runner row to reflect that the composite action is loaded from the local .defaults/ checkout rather than a remote @v0 ref.
Previous run (4)

Review

Findings

Medium

Low

  • [docs-currency] docs/architecture.md:332 — References "sparse-checkout of fullsend-ai/fullsend@v0" for runtime layering. This PR removes sparse-checkout in favor of a full checkout at inputs.fullsend_ai_ref. The description is now inaccurate.
    Remediation: Update to reflect full checkout with configurable ref input.

  • [docs-currency] docs/ADRs/0035-layered-content-resolution.md:61 — States the Prepare workspace step "sparse-checkouts upstream defaults from fullsend-ai/fullsend@v0". Sparse-checkout is removed and the ref is now parameterized. Since this is an ADR (historical record), a note or addendum acknowledging the change is sufficient.
    Remediation: Add a note that sparse-checkout was replaced by full checkout with fullsend_ai_ref in PR feat(workflows): add fullsend_ai_ref for self-consistent version pinning #1278.

  • [docs-currency] docs/guides/admin/installation.md:236-238 — Describes the per-repo circular-reference concern with hardcoded @v0 refs. With this PR, stage workflows now use relative ./ paths and the ref is configurable via fullsend_ai_ref, which partially changes the reference chain described here.
    Remediation: Update the note to reflect that reusable-dispatch now uses relative paths for stage workflows and the checkout ref is parameterized.

  • [style] .github/workflows/reusable-dispatch.yml vs stage workflows — The fullsend_ai_ref input description is inconsistent: dispatch says "Reference to load the actions from, should match the version this workflow" while stage workflows say "Reference used to load this action, it is used to pull the repo on this ref to load the defaults". Minor but worth harmonizing.
    Remediation: Use a consistent description across all six workflows.

@fullsend-ai-review fullsend-ai-review Bot added the requires-manual-review Review requires human judgment label May 21, 2026
@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment and removed requires-manual-review Review requires human judgment labels May 21, 2026
@rh-hemartin

Copy link
Copy Markdown
Member Author

/fs-review

@ralphbean ralphbean 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.

A few things to sort out:

prioritize.yml / repo-maintenance.yml — these scaffold workflows (internal/scaffold/fullsend-repo/.github/workflows/) still use the old pattern: ref: v0, sparse-checkout, rm -rf .defaults, fullsend-ai/fullsend/.github/actions/*@v0. Worth bringing them into the new pattern for consistency.

docs/architecture.md:611 — the layer mapping table still says the agent runner uses fullsend-ai/fullsend@v0. Now that it's loaded from ./.defaults/, this line is stale.

Comment thread .github/workflows/reusable-dispatch.yml Outdated

@waynesun09 waynesun09 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.

Review Squad Report — 7-agent review (2x claude-coder, 2x claude-researcher, 2x gemini, 1x cursor)

What this PR does

This PR replaces hardcoded @v0 remote action references with local action resolution via ./.defaults/. The mechanism:

  1. Caller pins to a tag (e.g., @v0.10.1) via uses:
  2. Passes the same ref as fullsend_ai_ref input
  3. Stage workflows check out fullsend-ai/fullsend at that ref into .defaults/
  4. All composite actions and the agent binary load from ./.defaults/ (local filesystem)
  5. reusable-dispatch.yml uses relative ./ paths for stage workflow calls, which GitHub resolves at the same ref

Is this for local action resolution? Yes — the core change switches from remote action refs (fullsend-ai/fullsend/.github/actions/*@v0) to local action refs (uses: ./.defaults/.github/actions/*). This ensures all action code comes from the same checked-out ref rather than independently-resolved remote refs.

Will this break existing callers using v0?

Yes. fullsend_ai_ref is required: true with no default:. The moment v0 advances to include this change, every existing caller that hasn't been updated to pass fullsend_ai_ref will fail with "required input not provided." This affects all deployed per-org .fullsend stage workflows and per-repo shims.

Fix: Change to required: false with default: "v0" — one-line change per workflow, fully backward-compatible.

Findings summary

Severity Count Key findings
CRITICAL 1 required: true breaks all existing installations (6/7 agents)
HIGH 3 .defaults/ retention exposes full repo (6/7); ref coupling footgun (6/7); prioritize.yml not updated (3/7)
MEDIUM 4 Full clone perf (7/7); no input validation (4/7); stale doc refs (2/7)
LOW 3 Testing guide clarity; quote style churn; misleading input descriptions

Notable findings NOT in inline comments

  • HIGH — prioritize.yml, prioritize-scheduler.yml, and repo-maintenance.yml still use the old pattern (hardcoded @v0, sparse-checkout, rm -rf .defaults, remote action refs). Creates inconsistency where 5 stages are updated but prioritize is not. Either update in this PR or track as a follow-up issue.

False positives removed (3)

  • Relative ./ workflow paths break cross-repo calls — GitHub resolves relative workflow_call paths within the called workflow's repository at the same ref. The design is correct.
  • Sparse-checkout already includes composite action files — Actions are at .github/actions/ in the repo root, not under internal/scaffold/fullsend-repo/.
  • Shell injection via fullsend_ai_refworkflow_call inputs aren't user-controllable; actions/checkout sanitizes the ref parameter. Downgraded to MEDIUM input validation concern.

Comment thread .github/workflows/reusable-dispatch.yml Outdated
done
mkdir -p .github/scripts
cp "${SRC}/.github/scripts/setup-agent-env.sh" .github/scripts/setup-agent-env.sh
rm -rf .defaults

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.

HIGH — .defaults/ directory retained during agent execution, exposing full repo source

The rm -rf .defaults cleanup was removed (necessary for local action refs), but with sparse-checkout also removed, the entire fullsend-ai/fullsend repo — Go source, internal tooling, CI config, e2e tests, infrastructure code — now persists in the workspace during agent execution. Previously only internal/scaffold/fullsend-repo/ was present.

Suggestion: Add a cleanup step with if: always() after the agent run step:

- name: Cleanup upstream checkout
  if: always()
  run: rm -rf .defaults

GitHub Actions resolves uses: action paths at step execution time (not eagerly for the whole job), but the composite action at .defaults/ needs to exist when its step runs. The cleanup should go immediately after the "Run code agent" step. If that's not safe, at minimum prune non-essential directories before agent execution:

find .defaults -mindepth 1 -maxdepth 1 \
  ! -name 'action.yml' ! -name '.github' \
  -exec rm -rf {} +

Same pattern applies to all 5 stage workflows. Flagged by 6/7 agents.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Why should we delete the repository? It is publicly available.

Comment thread .github/workflows/reusable-code.yml
install_mode: per-repo
mint_url: ${{ vars.FULLSEND_MINT_URL }}
gcp_region: ${{ vars.FULLSEND_GCP_REGION }}
fullsend_ai_ref: v0

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.

HIGH — fullsend_ai_ref / uses: ref coupling is unenforced

These two values must stay in sync but are independent strings with no enforcement. A caller could update uses: ...@v0.10.1 but forget to update fullsend_ai_ref, causing split-brain: dispatch workflow code from one version, composite actions/binary from another.

Suggestion:

  1. Add an explicit comment here: # Must match the @ref in the uses: line above
  2. Consider a runtime validation step in the stage workflows comparing inputs.fullsend_ai_ref against the workflow ref (extractable from GITHUB_WORKFLOW_REF)
  3. The follow-up installer PR should generate both values from a single source to prevent drift

Flagged by 6/7 agents.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

  1. Ok
  2. As far as I could test GITHUB_WORKFLOW_REF is the original workflow ref, not the reusable one.
  3. It will when we change to static versions. Or we can add it and that it uses v0, but I would do it on another PR.

Comment thread docs/ADRs/0035-layered-content-resolution.md Outdated
@rh-hemartin

Copy link
Copy Markdown
Member Author

prioritize.yml / repo-maintenance.yml — these scaffold workflows (internal/scaffold/fullsend-repo/.github/workflows/) still use the old pattern: ref: v0, sparse-checkout, rm -rf .defaults, fullsend-ai/fullsend/.github/actions/*@v0. Worth bringing them into the new pattern for consistency.

These changes act at reusable level, since prioritize does not have a reusable workflow we can't use the pattern there. And that is a bigger change than I intend.

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment and removed requires-manual-review Review requires human judgment labels Jun 1, 2026
ifireball added a commit to ifireball/fullsend that referenced this pull request Jun 1, 2026
…ng (ADR 41)

Replace thin stage workflows with synchronous reusable workflow_call jobs in
dispatch.yml, add fullsend_ai_ref pinning (fullsend-ai#1278), set FULLSEND_AI_REF on org
install, and pin e2e CI to the PR branch ref.

Co-authored-by: Cursor <cursoragent@cursor.com>
@ifireball

Copy link
Copy Markdown
Member

prioritize.yml / repo-maintenance.yml — these scaffold workflows (internal/scaffold/fullsend-repo/.github/workflows/) still use the old pattern: ref: v0, sparse-checkout, rm -rf .defaults, fullsend-ai/fullsend/.github/actions/*@v0. Worth bringing them into the new pattern for consistency.

These changes act at reusable level, since prioritize does not have a reusable workflow we can't use the pattern there. And that is a bigger change than I intend.

@rh-hemartin will the changes proposed in #1611 (basically moving org mode to reusable) resolve the issue for prioritize?

@rh-hemartin

Copy link
Copy Markdown
Member Author

@rh-hemartin will the changes proposed in #1611 (basically moving org mode to reusable) resolve the issue for prioritize?

i don't think that would solve the issue with prioritize. However the issue with prioritize is just that I'm not changing it. We are free to change it whenever so it conforms to these changes. Then caller of prioritize.yaml (prioritize-schedule.yaml) would pass the fullsend_ai_ref as well. I'm choosing to not modify it here as it is not part of the reusable collection of workflows.

…n pinning

Add required `fullsend_ai_ref` input to reusable-dispatch and all stage
workflows (triage, code, review, fix, retro). Each stage workflow now
checks out the fullsend repo at `inputs.fullsend_ai_ref` instead of the
hardcoded `v0` ref, then references actions and the agent itself via
relative `./.defaults/` paths rather than `fullsend-ai/fullsend/...@v0`.

Dispatch similarly switches stage workflow `uses:` to relative
`./.github/workflows/reusable-*.yml` paths, so a caller pinned to e.g.
`@v0.10.1` resolves all nested workflows at that same tag automatically.
Renamed the dispatch workflow to "Dispatch (local)" to reflect this.

Drop sparse-checkout (full clone required for relative action refs) and
keep `.defaults/` in place after workspace prep so relative paths resolve.

Scaffold callers and the per-repo shim template pass `fullsend_ai_ref: v0`
as a stable default for enrolled repos.

Signed-off-by: Hector Martinez <hemartin@redhat.com>
@rh-hemartin rh-hemartin force-pushed the feat/version-pinning-workflows branch from d0a575c to 716f73c Compare June 4, 2026 14:11
@rh-hemartin rh-hemartin enabled auto-merge June 4, 2026 14:12
@rh-hemartin rh-hemartin added this pull request to the merge queue Jun 4, 2026
Merged via the queue into main with commit b2b54fb Jun 4, 2026
7 of 8 checks passed
@rh-hemartin rh-hemartin deleted the feat/version-pinning-workflows branch June 4, 2026 14:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

requires-manual-review Review requires human judgment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

admin install should pin reusable workflows and actions to a commit SHA instead of v0

4 participants