Skip to content

squad-triage.yml presents keyword matching as Lead agent analysis (substring matching + unconditional Lead fallback + routing.md read but unused)Β #2085

Description

@AmittaiShapira

Summary

templates/workflows/squad-triage.yml presents keyword-matching output as the Lead agent's analysis. The posted comment is titled:

### πŸ—οΈ Squad Triage β€” {lead.name} ({lead.role})
**Assigned to:** ...
**Reason:** Issue relates to frontend/UI work

No agent runs. Reason: is a hardcoded string selected by issueText.includes(...). A reader reasonably concludes the Lead read the issue and reasoned about it.

This matters beyond cosmetics: it makes a low-accuracy signal look like a high-accuracy one, which is exactly when a human stops double-checking.

Specific defects

  1. Unbounded substring matching. issueText.includes('ci') matches "specific", "decision", "precision". includes('ui') matches "build", "require", "guide". includes('api') matches "rapid".

  2. Unconditional Lead fallback. When nothing matches, the issue is assigned to the Lead with Reason: No specific domain match. There is no "unassigned" or "ambiguous" outcome, so the workflow always produces a confident-looking answer.

  3. routing.md is read but never used for routing. routingContent is loaded and then unreferenced; routing uses role keywords hardcoded in the workflow. Teams that carefully curate routing.md get no effect from it.

  4. Wrong assignments are self-sealing. A squad:* label suppresses later re-triage, so a bad label is worse than no label β€” it hides itself and cannot be automatically corrected.

This defect class was already fixed once, elsewhere

#1591 fixed "unbounded substring matching + unconditional Lead fallback" for ralph-triage.js. Both defects remain in the bundled squad-triage.yml. The fix appears not to have been applied across both triage paths.

Evidence and its limits

We replaced this workflow locally with word-boundary matching driven by a routing.md signals table, plus explicit ambiguous / unassigned outcomes instead of a Lead fallback.

Measured: our word-boundary implementation against 14 real issues from our repository, using our live team.md / routing.md. Roughly 4 of 14 routed correctly. One issue about PR tooling was confidently assigned to the crawler specialist because its body mentions "workday" once, in passing.

Not measured: stock squad-triage.yml itself. It uses looser substring matching and ignores routing.md, so we expect it to do no better, but we did not benchmark it and are not claiming a number for it.

Our conclusion was that keyword matching is the wrong instrument for this problem, not that it needed better keywords. We have disabled automatic assignment entirely and reduced our workflow to queueing (opened β†’ add squad), leaving triage to the Lead at session start.

Suggestions

Roughly in order of effort:

  1. Stop attributing keyword output to the Lead. Even keeping the current logic, retitle the comment so it does not read as agent analysis. This is a small change and independently worthwhile.
  2. Add word boundaries and an explicit no-match outcome instead of the Lead fallback.
  3. Actually consume routing.md, since it is already read.
  4. Consider LLM-based triage. actions/ai-inference with permissions: models: read runs on GITHUB_TOKEN with no additional secret, which fits Squad's existing GitHub-native posture. Reading an issue and matching it to a roster is a natural language task; this seems closer to what Squad's own doctrine describes when it says the Lead "reads the issue, analyzes it, and assigns the correct label."

Happy to contribute a PR for 1–3 if that would help.


Found while auditing our local fork of this workflow. Squad CLI 0.13.1.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions