Skip to content

feat(dispatch): route /fs-plan-tests to the qualityflow stage - #6284

Closed
guyoron1 wants to merge 1 commit into
fullsend-ai:mainfrom
guyoron1:feat/dispatch-plan-tests-stage
Closed

feat(dispatch): route /fs-plan-tests to the qualityflow stage#6284
guyoron1 wants to merge 1 commit into
fullsend-ai:mainfrom
guyoron1:feat/dispatch-plan-tests-stage

Conversation

@guyoron1

Copy link
Copy Markdown
Contributor

Problem

A custom agent registered via config.yaml agents[] cannot be triggered by comment in per-org mode.

Concretely, /fs-plan-tests on #6010 fired run 32015419992 and the dispatch job logged:

EVENT_NAME: issue_comment
COMMENT_BODY: /fs-plan-tests
COMMENT_AUTHOR_ASSOC: MEMBER
...
No stage matched — skipping dispatch

Two reasons it routes nowhere:

  1. The bash router here only knows the built-in commands; it never reads config.yaml agents[] (and cannot — routing runs before the config repo is checked out).
  2. The harness CEL path (reusable-dispatch.ymlharness-dispatch) runs fullsend dispatch --config-dir .fullsend against the caller repo. Per-org enrolled repos have no .fullsend/ directory, so CEL triggers never evaluate. QualityFlow's trigger is registered in Add QualityFlow custom agent with CEL trigger .fullsend#93 and is correct — nothing consumes it yet.

Change

This adds the case branch that this file documents as the way to add a stage:

  • /fs-plan-testsSTAGE=qualityflow, gated PR-only + write+ + non-Bot, mirroring the harness CEL trigger (has(change_proposal) && !is_fork)
  • qualityflowcoder role, which its harness declares (role: coder)
  • fork gate extended to qualityflow, since the agent commits generated tests to the PR branch (same exposure as fix), and a failed PR-context fetch is fatal rather than a warning
  • max-lines 610 → 625, the documented path for a justified increase

The companion stage workflow lives in .fullsend (org-local, like scribe.yml) and is discovered via its # fullsend-stage: qualityflow marker.

Interim by design: #2902 removes the bash routing this branch lives in, and this case goes with it.

Verification

Extracted the real "Determine stage" script from the workflow and ran it against a stubbed gh (permission API), asserting the routed stage:

case expected result
/fs-plan-tests on PR, write+ member qualityflow
/fs-plan-tests PROJ-123 (trailing arg) qualityflow
/fs-plan-tests on an issue (no PR) (none)
/fs-plan-tests from a Bot (none)
/fs-plan-tests from read-only user (none)
/fs-plan-tests from triage-only user (none)
/fs-review, /fs-code, /fs-triage unchanged
unknown /fs-bogus (none)

10/10, and the same 10 pass against the currently-deployed copy in .fullsend with the same patch applied. Happy to port these into the behaviour-test harness (#2891#2895) if you'd prefer them in-repo.

Custom agents registered via config.yaml agents[] cannot be triggered by
comment in per-org mode: the bash router only knows the built-in commands,
and the harness CEL path (harness-dispatch) reads .fullsend/config.yaml from
the caller repo, which per-org enrolled repos do not have. A /fs-plan-tests
comment therefore routes nowhere and the run exits with "No stage matched".

Adds the case branch this file documents as the way to add a stage, plus the
qualityflow -> coder role mapping (declared by its harness) and the existing
fork gate, since the agent commits generated tests to the PR branch.

Interim until harness CEL dispatch becomes primary (fullsend-ai#2902), which removes
the bash routing this branch lives in.

Signed-off-by: guy oron <goron@redhat.com>
@guyoron1
guyoron1 requested a review from a team as a code owner August 17, 2026 11:21
@github-actions

Copy link
Copy Markdown

E2E tests did not run

E2E tests run automatically for org/repo members and collaborators on pull requests.

For other contributors, a maintainer must add the ok-to-test label after the latest push.

See E2E testing guide for details.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Route /fs-plan-tests comments to the qualityflow dispatch stage

✨ Enhancement ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Route /fs-plan-tests issue comments on PRs to the qualityflow stage.
• Map qualityflow to coder role and enforce PR-context + fork safety gates.
• Increase workflow-size lint limit to allow the new routing branch.
Diagram

graph TD
  A(["Issue comment event"]) --> B["Determine stage (dispatch.yml)"] --> C{"/fs-plan-tests matched?"} -->|"yes"| D["STAGE=qualityflow"] --> E["Role mapped: coder"] --> F["Resolve PR head + fork gate"] --> G["Dispatch workflows (stage marker)"]
  C -->|"no"| H["Skip dispatch"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Rely solely on CEL/harness-based dispatch
  • ➕ Keeps routing data-driven from org-owned .fullsend/config.yaml
  • ➕ Avoids growing the bash case router over time
  • ➖ Doesn’t work in per-org mode until the harness path is made primary (router runs before config checkout)
  • ➖ Requires broader architectural change (tracked by feat(dispatch)!: make harness-dispatch primary and remove bash routing #2902) rather than a targeted fix
2. Checkout `.fullsend` configuration earlier in dispatch.yml
  • ➕ Would allow the router to consult config.yaml agents[] directly
  • ➕ Reduces need for hard-coded command branches
  • ➖ Adds complexity and runtime cost to the critical dispatch path
  • ➖ Expands attack surface (must be careful about what is checked out and trusted)

Recommendation: Given current constraints (routing happens before config checkout in per-org mode), adding an explicit /fs-plan-tests branch is the most reliable and least invasive fix. The added role mapping and fork/PR-context gates align the new stage with existing trust boundaries for mutating agents, while remaining an interim step until CEL dispatch becomes primary (#2902).

Files changed (1) +17 / -5

Other (1) +17 / -5
dispatch.ymlAdd /fs-plan-tests routing to qualityflow with coder-role + fork gating +17/-5

Add /fs-plan-tests routing to qualityflow with coder-role + fork gating

• Adds a new issue_comment slash-command route for '/fs-plan-tests' that dispatches to the 'qualityflow' stage only for authorized, non-bot users on PRs. Maps 'qualityflow' to the 'coder' role, and extends PR-head fetch fatality and fork-blocking rules to cover 'qualityflow'. Increases the workflow size lint limit to accommodate the new branch.

internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (2) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. /fs-plan-tests routing out-of-sync 📘 Rule violation ⚙ Maintainability
Description
internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml adds routing for /fs-plan-tests
to STAGE="qualityflow", but .github/workflows/reusable-dispatch.yml does not implement the same
routing (and related stage handling), violating the requirement to keep the per-org and per-repo
dispatch workflows in sync. This drift makes /fs-plan-tests behave differently across install
modes and can result in per-repo dispatch being skipped when STAGE remains empty.
Code

internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[R166-173]

+                /fs-plan-tests)
+                  # QualityFlow custom agent. Mirrors its harness CEL trigger
+                  # (change_proposal, non-fork); fork gate is in "Resolve PR
+                  # head" below. Interim until CEL dispatch is primary (#2902).
+                  if [[ "${COMMENT_USER_TYPE}" != "Bot" ]] && is_authorized \
+                    && [[ "${ISSUE_HAS_PR}" == "true" ]]; then
+                    STAGE="qualityflow"
+                  fi
Relevance

●●● Strong

Team has repeatedly required and accepted keeping scaffold and reusable dispatch routing/auth logic
in sync.

PR-#1688
PR-#2781
PR-#42

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The citations indicate the scaffold (per-org) dispatch workflow was updated with a new router branch
for /fs-plan-tests that sets STAGE="qualityflow", while the reusable (per-repo) dispatch
workflow’s Determine stage routing case list contains no corresponding /fs-plan-tests branch.
Because the reusable dispatcher explicitly exits early when STAGE is empty, a /fs-plan-tests
comment in per-repo mode will not match a stage and will be skipped; additionally, the reusable
workflow is documented as the per-repo equivalent of the per-org dispatcher, making this divergence
user-visible and unintended.

Rule 1062045: Keep jq payload, stage routing, and secret threading logic in dispatch workflows in sync
internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[166-173]
.github/workflows/reusable-dispatch.yml[185-214]
internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[166-174]
.github/workflows/reusable-dispatch.yml[1-4]
.github/workflows/reusable-dispatch.yml[185-231]
.github/workflows/reusable-dispatch.yml[315-318]
.github/workflows/reusable-dispatch.yml[450-453]
.github/workflows/reusable-dispatch.yml[508-520]
PR-#1688

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The per-org dispatcher scaffold (`internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml`) now routes the `/fs-plan-tests` slash command to `STAGE=qualityflow`, but the per-repo dispatcher (`.github/workflows/reusable-dispatch.yml`) does not include the same `/fs-plan-tests` routing and associated stage handling (role mapping and relevant gating). This creates stage-routing drift between the two dispatch workflows and causes per-repo installations to ignore `/fs-plan-tests` (logging that no stage matched and skipping dispatch).

## Issue Context
This repository maintains two dispatch workflows:
- Per-org dispatcher scaffold: `internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml`
- Per-repo dispatcher: `.github/workflows/reusable-dispatch.yml`

Compliance requires jq payload/stage routing/secret threading logic to remain in sync across these dispatch workflows unless an explicit inline comment documents an intentional divergence. When introducing a new built-in command/stage, both dispatchers should support the same slash-command surface; otherwise behavior drifts across install modes.

## Fix Focus Areas
- internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[166-173]
- .github/workflows/reusable-dispatch.yml[185-245]
- .github/workflows/reusable-dispatch.yml[440-454]
- .github/workflows/reusable-dispatch.yml[494-520]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

2. max-lines comment-only hunk 📘 Rule violation ⚙ Maintainability
Description
The # lint-workflow-size: max-lines=... comment was modified in a comment-only hunk with no
adjacent code change in that hunk. This violates the requirement to avoid comment-only edits outside
code changes for the issue.
Code

internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[2]

+# lint-workflow-size: max-lines=625
Relevance

● Weak

Team consistently rejects comment-only max-lines bumps as weakening the size-lint guardrail.

PR-#5578
PR-#5244
PR-#5274

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The PR changes only the max-lines comment in its own hunk, with no non-comment code changes
alongside it, which matches the rule’s failure criteria for comment-only hunks.

Rule 1062072: Do not add or modify comments outside code lines changed for the issue
internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[1-6]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A standalone comment-only change was made to the workflow size lint directive.

## Issue Context
Compliance requires comment edits to be coupled with related code changes in the same diff hunk (or otherwise be explicitly justified as an allowed comment-only sweep).

## Fix Focus Areas
- internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[1-6]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context
✅ Compliance rules (platform): 63 rules

Grey Divider

Tip of the day
💡 Did you know, you can route each action level your way: inline, summary, both, or drop

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment on lines +166 to +173
/fs-plan-tests)
# QualityFlow custom agent. Mirrors its harness CEL trigger
# (change_proposal, non-fork); fork gate is in "Resolve PR
# head" below. Interim until CEL dispatch is primary (#2902).
if [[ "${COMMENT_USER_TYPE}" != "Bot" ]] && is_authorized \
&& [[ "${ISSUE_HAS_PR}" == "true" ]]; then
STAGE="qualityflow"
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

1. /fs-plan-tests routing out-of-sync 📘 Rule violation ⚙ Maintainability

internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml adds routing for /fs-plan-tests
to STAGE="qualityflow", but .github/workflows/reusable-dispatch.yml does not implement the same
routing (and related stage handling), violating the requirement to keep the per-org and per-repo
dispatch workflows in sync. This drift makes /fs-plan-tests behave differently across install
modes and can result in per-repo dispatch being skipped when STAGE remains empty.
Agent Prompt
## Issue description
The per-org dispatcher scaffold (`internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml`) now routes the `/fs-plan-tests` slash command to `STAGE=qualityflow`, but the per-repo dispatcher (`.github/workflows/reusable-dispatch.yml`) does not include the same `/fs-plan-tests` routing and associated stage handling (role mapping and relevant gating). This creates stage-routing drift between the two dispatch workflows and causes per-repo installations to ignore `/fs-plan-tests` (logging that no stage matched and skipping dispatch).

## Issue Context
This repository maintains two dispatch workflows:
- Per-org dispatcher scaffold: `internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml`
- Per-repo dispatcher: `.github/workflows/reusable-dispatch.yml`

Compliance requires jq payload/stage routing/secret threading logic to remain in sync across these dispatch workflows unless an explicit inline comment documents an intentional divergence. When introducing a new built-in command/stage, both dispatchers should support the same slash-command surface; otherwise behavior drifts across install modes.

## Fix Focus Areas
- internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[166-173]
- .github/workflows/reusable-dispatch.yml[185-245]
- .github/workflows/reusable-dispatch.yml[440-454]
- .github/workflows/reusable-dispatch.yml[494-520]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@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 findings (review-only sweep; not requesting changes).

CRITICAL — PR breaks go test ./internal/scaffold/... (two pre-existing assertions now fail)
internal/scaffold/workflow_call_alignment_test.go:975 (file not touched by this diff, so it can't be anchored inline)

Reproduced locally at HEAD (a1724c5): go test ./internal/scaffold/... fails with --- FAIL: TestDispatchPRHeadResolution and --- FAIL: TestRoleCheckCaseBranches, both in the scaffold/dispatch.yml sub-case (the reusable-dispatch.yml sub-case still passes).

  1. TestDispatchPRHeadResolution's regex expects the old fix|review) guard text in the "Resolve PR head for issue_comment events" step; this PR changed it to ^(fix|review|qualityflow)$, so the regex no longer matches.
  2. TestRoleCheckCaseBranches asserts the literal substring code|fix) STAGE_ROLE="coder" exists in dispatch.yml (test line 975). This PR changed that line (dispatch.yml:437) to code|fix|qualityflow) STAGE_ROLE="coder", so the exact-substring match fails with does not contain "code|fix) STAGE_ROLE=\"coder\"".

The PR description's verification table only covers a manually-extracted routing script, not the repo's actual Go test suite, so this regression isn't caught there.

Suggestion: update workflow_call_alignment_test.go alongside the workflow change — relax TestDispatchPRHeadResolution's regex to tolerate the added |qualityflow alternative (e.g. (?s)fix\|review(\|qualityflow)?\).*exit 1), and update TestRoleCheckCaseBranches' expected substring to code|fix|qualityflow) STAGE_ROLE="coder". Re-run go test ./internal/scaffold/... before pushing — it currently fails deterministically on this branch.


MEDIUM — New /fs-plan-tests slash command and its auth requirement are undocumented
docs/ADRs/0054-require-authorization-on-all-agent-dispatch-paths.md:41 (file not touched by this diff, so it can't be anchored inline)

This ADR maintains an explicit table of every slash-command dispatch path and its authorization requirement (lines 41-42 list /fs-review and /fs-fix), presented as the canonical enumeration of gated paths, but has no row for the new /fs-plan-tests -> write-level is_authorized path this PR adds. Grepping docs/ for fs-plan-tests also turns up zero references anywhere else in docs/ (docs/agents/, docs/guides/, docs/glossary.md), unlike /fs-fix and /fs-review which are documented in multiple places. Since this ADR explicitly claims to enumerate all gated dispatch paths and this PR adds a new one with a real security-relevant auth requirement, the omission is a genuine gap, not merely stylistic.

Suggestion: add a row for /fs-plan-tests (Yes, is_authorized write) to the ADR-0054 authorization table, and add a brief docs/agents/ or glossary mention of the command, or explicitly note in the PR that documentation is deferred pending #2902 given the command's interim/bash-routing lifetime.

# QualityFlow custom agent. Mirrors its harness CEL trigger
# (change_proposal, non-fork); fork gate is in "Resolve PR
# head" below. Interim until CEL dispatch is primary (#2902).
if [[ "${COMMENT_USER_TYPE}" != "Bot" ]] && is_authorized \

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.

MEDIUM — /fs-plan-tests gate order runs the GitHub permission-API call before the cheap ISSUE_HAS_PR check

Because bash && short-circuits left-to-right, is_authorized (a gh api repos/.../collaborators/<user>/permission network call) runs for every non-bot /fs-plan-tests comment regardless of whether the comment is even on a PR, since the cheap ISSUE_HAS_PR check is evaluated last. The existing /fs-review and /fs-fix cases in this same file put ISSUE_HAS_PR as the outer/first condition specifically to skip the API call when it can't route anywhere, so this is a real deviation from the established pattern, adding avoidable GitHub API load on every plain-issue use of the command.

Suggestion: reorder to check ISSUE_HAS_PR first, matching /fs-review and /fs-fix:

if [[ "${ISSUE_HAS_PR}" == "true" ]]; then
  if [[ "${COMMENT_USER_TYPE}" != "Bot" ]] && is_authorized; then
    STAGE="qualityflow"
  fi
fi

STAGE="prioritize"
fi
;;
/fs-plan-tests)

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.

MEDIUM — No test coverage added for the new /fs-plan-tests routing or its gates

The diff only touches dispatch.yml and the lint-workflow-size max-lines directive; internal/scaffold/workflow_call_alignment_test.go gains no new test cases. The PR description substitutes an ad hoc, out-of-repo script run (a manual verification table) for actual in-repo coverage, and offers to port it into the behaviour-test harness later. As-is, nothing in the Go test suite asserts /fs-plan-tests routes to stage qualityflow, requires write-level (not triage) auth, requires ISSUE_HAS_PR, fails closed on PR-head fetch failure for the qualityflow stage, or is blocked on fork PRs by the extended regex.

Suggestion: add unit test cases mirroring existing /fs-fix/-review coverage in workflow_call_alignment_test.go: assert /fs-plan-tests requires write-level auth, requires ISSUE_HAS_PR == true, fails closed (exit 1) on PR-head fetch failure, and is blocked on fork PRs via the same regex as fix/qualityflow.

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

Requesting changes — this adds a new feature to the deprecated per-org path, and puts a third-party agent's command into the shared upstream scaffold. Neither should ship. The good news is the capability you need already exists on the per-repo path and needs no upstream change.

Which file this touches

Confirmed from the shim templates on main:

  • internal/scaffold/fullsend-repo/templates/shim-workflow-call.yaml:58__ORG__/.fullsend/.github/workflows/dispatch.yml@mainper-org, a deployed copy of the file this PR edits
  • internal/scaffold/fullsend-repo/templates/shim-per-repo.yaml:46__REUSABLE_DISPATCH__ with install_mode: per-repoper-repo, reusable-dispatch.yml, untouched here

So this change lands exclusively on the per-org dispatcher and does nothing for per-repo users. Run 32015419992 confirms the same routing: the shim forwards to fullsend-ai/.fullsend/.github/workflows/dispatch.yml@main, and that deployed copy has no harness-dispatch job, no fullsend dispatch, and no --config-dir at all — so the CEL path isn't evaluating against a missing .fullsend/ directory as the description says, it simply doesn't exist on that path. harness-dispatch lives only in reusable-dispatch.yml (per-repo).

Why this shouldn't land

1. New feature on the immediate-removal path. ADR 0044 (Accepted 2026-06-16) makes per-repo the sole supported install model. #2302 plus the 2026-08-06 decision (#5995) dropped the phased deprecation in favour of immediate removal. #6113 was filed precisely because agents keep generating org-mode content — "do not add org-mode-specific content to docs or code." Extending the org dispatcher is that, in the routing layer.

2. A third-party agent's command and role in the shared scaffold. /fs-plan-tests belongs to redhat-community-ai-tools/qualityflow-fullsend, and the change also hardcodes code|fix|qualityflow → coder into the generic router. A fullsend release shouldn't ship one team's fleet extension as a default — that's what agents[] registration exists to avoid.

3. Concrete defect for per-org orgs that don't have QualityFlow. Check agent is enabled only skips on an explicit enabled: false name match, and registered agents are source: URLs with no name key — so nothing matches and nothing skips. The coder role gate passes on any standard defaults.roles. Stage discovery then finds no # fullsend-stage: qualityflow marker and the job hits ::error::No workflows found for stage: $STAGEexit 1. Result: a failed dispatch run for any write+ user who types /fs-plan-tests on a PR in such an org — and it only reaches them after a manual sync-scaffold, since nothing auto-propagates this file (#6013).

The supported path already covers this

The QualityFlow harness documents the intended consumption model itself:

Consuming teams reference this via base: inheritance in their .fullsend repo

That's the same layering the code/fix agents use to pick up remote skills — base composition is implemented in internal/harness/compose.go (LoadWithBase), and the harness already carries its own skills:, policy, image, and role: coder. This belongs in the consuming repo's config, extending the default fleet from fullsend-ai/agents, not in the action release.

The trigger side needs nothing upstream either. Your CEL trigger is comment-shaped, not PR-shaped:

event.transition.kind == "comment_added"
  && event.transition.comment.command == "/fs-plan-tests"
  && has(event.state.change_proposal)
  && !event.state.change_proposal.is_fork

internal/dispatch already routes exactly this — see TestHarnessRouter_SlashCommandCustomAgent, which asserts /fs-custom-agent routes to a config-registered agent, alongside the unknown-agent case. A per-repo install that registers QualityFlow in its own .fullsend/config.yaml gets /fs-plan-tests working today. The trigger registered in fullsend-ai/.fullsend#93 is correct; the reason nothing consumes it is that fullsend-ai is still on per-org mode, where the CEL path doesn't exist.

Suggested path forward

  • Register QualityFlow in the consuming repo's own .fullsend/config.yaml via base: extend with its remote skills. Supported today, no upstream change.
  • For the fullsend-ai dogfood gap: the fix is migrating off per-org (#5815 repos migrate), not extending the dispatcher that #2302 deletes.
  • If you need it working before that migration lands: the org's .fullsend/dispatch.yml is an org-local copy and nothing auto-overwrites it (#6013) — the same repo where the QualityFlow stage workflow already lives. Carrying the case branch there unblocks you now without the command entering the upstream scaffold.

On the two points in the description: the "case branch is the documented way to add a stage" note is about built-in stages — org-specific custom agents are exactly the case agents[]/CEL registration was built for. And "interim, #2902 removes it" doesn't quite hold either, since #2902 rewrites reusable-dispatch.yml (per-repo), while this branch lives in the per-org copy that #2302 deletes on a separate track.

The verification table is genuinely thorough, and the diagnosis that nothing consumes the registered trigger is correct — it's the placement of the fix I'm objecting to, not the problem statement.

@waynesun09

Copy link
Copy Markdown
Member

Closing per the review above: per-org mode is deprecated (ADR 0044, #2302) and this change only lands on that path, while the custom-agent capability it's after is already supported per-repo via base: extend in the consuming repo's config. Happy to reopen if the discussion goes the other way.

@waynesun09 waynesun09 closed this Aug 17, 2026
@fullsend-ai-retro

fullsend-ai-retro Bot commented Aug 17, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 5:41 PM UTC · Completed 5:55 PM UTC

Commit: a1724c5 · View workflow run →

@fullsend-ai-retro

Copy link
Copy Markdown

Retro: PR #6284 — Route /fs-plan-tests to qualityflow stage

Outcome: Well-handled workflow. No proposals filed — all improvement opportunities are already tracked in existing issues.

What happened

External contributor guyoron1 (Red Hat) opened PR #6284 to add /fs-plan-tests slash-command routing to a qualityflow stage in the per-org dispatch workflow. The PR modified one file (internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml, +17/−5 lines).

No fullsend review agent ran — by design. The contributor has read-only permission on the repo, failing the triage-level gate for automated review dispatch on fork PRs. The qodo-code-review bot (a separate GitHub App) ran independently and caught a valid dispatch-drift finding.

CI caught two broken Go tests (TestDispatchPRHeadResolution, TestRoleCheckCaseBranches). Human reviewer waynesun09 independently verified those failures and provided a thorough two-pass review:

  1. First pass (COMMENTED): Broken tests (critical), gate ordering issue, missing test coverage.
  2. Second pass (CHANGES_REQUESTED): Architectural rejection — the PR extends a per-org dispatch path deprecated by ADR 0044 (Remove per-org install mode #2302) when the capability already exists via the supported per-repo agents[]/CEL registration path.

The PR was closed ~6 hours after opening with a clear, constructive rationale and actionable alternatives.

Assessment

Review quality: Excellent. The human review caught everything — test breakage, code quality issues, and the fundamental architectural concern. The qodo bot contributed one valid finding (dispatch drift between per-org and per-repo modes) that was ultimately superseded by the broader rejection.

Token cost concern: This retro itself is the main inefficiency. No fullsend agent interacted with this PR — no review, code, or fix agent ran. The retro was dispatched solely because the PR was closed, spending agent compute to analyze a human-only workflow.

Evidence supporting existing issues

@guyoron1

Copy link
Copy Markdown
Contributor Author

Thanks @waynesun09 — agreed on all counts, closing this.

I verified both blocking findings independently rather than taking them on faith:

The defect for orgs without QualityFlow is real. Every entry in fullsend-ai/.fullsend's agents[] is a bare source: URL with no name: key, so Check agent is enabled's select((.name | downcase) == "$STAGE") matches nothing, .enabled comes back empty, and the skip never fires. coder is in any standard defaults.roles, so the role gate passes too. Stage discovery then finds no marker and exits 1. That's a failed run for any write+ user who types /fs-plan-tests in such an org — a regression I'd have shipped to every per-org install.

The test breakage reproduces at the line you cited. internal/scaffold/workflow_call_alignment_test.go:975 asserts the literal `code|fix) STAGE_ROLE="coder"`, which this branch changed. Same for TestDispatchPRHeadResolution's fix|review) regex. My verification table covered an extracted routing script, not the Go suite — that's a gap in how I verified, and the reason I missed it.

I've also taken the ADR 0044 / #2302 point: extending the per-org dispatcher is adding to the path that's being deleted, and /fs-plan-tests is a third-party command that shouldn't ship in the shared scaffold as a default.

Following your suggested path — the case branch now lives only in the org-local copy in fullsend-ai/.fullsend#167, alongside the stage workflow it needs, so nothing enters the upstream scaffold and no other org is affected. I've corrected the #2902 framing there too (per-org goes away via #2302; #2902 rewrites the per-repo dispatcher). The durable fix is the per-repo migration (#5815), not this.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants