ruvnet / ruvnet/agentic-flow

workers agents: trigger argument unvalidated (case typo silently downgrades pipeline, exit 0); confidence pinned at 60% via dead profile branch

Open
#211 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
812
Forks
175
Avg merge
2m
Merged PRs (30d)
3

Description

Summary

workers agents <trigger> has a genuinely good trigger→agent table — 12 triggers, all differentiated and domain-appropriate, with --json matching the text exactly. Two defects sit on top of it: the confidence/reasoning are structurally pinned, and the trigger argument is not validated at all, so a case typo silently downgrades the pipeline.

Measured on 2.1.2. (Absent on @alpha — see #208 §3.)


What works (so the fix doesn't disturb it)

trigger primary fallback best
ultralearn researcher, coder planner researcher
optimize performance-analyzer, coder researcher performance-analyzer
consolidate researcher researcher
predict performance-analyzer researcher performance-analyzer
audit security-analyst, tester reviewer security-analyst
map researcher coder researcher
preload researcher researcher
deepdive researcher, security-analyst coder researcher
document documenter, researcher coder documenter
refactor coder, reviewer researcher coder
benchmark performance-analyzer coder, tester performance-analyzer
testgaps tester coder tester

These are sensible and clearly hand-curated. No [object Object], no text/JSON divergence.


1. Confidence is pinned at 60% and the reasoning is always "No performance history"

Every one of the 12 triggers returns:

"selection": {
  "agent": "researcher",
  "confidence": 0.6,
  "reasoning": "No performance history - using default recommendation"
}

This is a downstream consequence of #210, not an independent bug. selectBestAgent (dist/workers/worker-agent-integration.js:271-274):

const profile = agentPerformanceProfiles.get(bestAgent);
const confidence = profile
    ? Math.min(0.95, 0.5 + (profile.executionCount * 0.01) + (profile.qualityScore * 0.4))
    : 0.6;

agentPerformanceProfiles can never be populated — its only writer, recordAgentPerformance, has zero call sites in dist/ (#210). So the profile branch is dead code, confidence is always 0.6, and "Best Selection" is always just the first entry of primary.

The documented output — Confidence: 94% with Reason: Best match for learning tasks based on historical success — is not reachable by any code path in the package. Fixing #210 fixes this too; until then the "Best Selection" block reads as a ranking decision when it is a list index.

2. The trigger argument is not validated

All of these return the generic researcher recommendation at exit 0:

$ agentic-flow workers agents TOTALLY-INVENTED-TRIGGER   # exit 0
$ agentic-flow workers agents ""                         # exit 0
$ agentic-flow workers agents ULTRALEARN                 # exit 0
$ agentic-flow workers agents "ultralearn "              # exit 0
$ agentic-flow workers agents ../etc/passwd              # exit 0

The consequence is a silent downgrade, not just a cosmetic one:

ultralearn  → file-discovery → pattern-discovery → vectorization → summarization
ULTRALEARN  → file-discovery → summarization
TOTALLY-INVENTED-TRIGGER → file-discovery → summarization

A case typo produces output byte-identical in shape to a real trigger, while quietly losing the 4-phase pipeline — and there is no signal distinguishing "unknown trigger" from "this trigger has a minimal pipeline". workers triggers already enumerates the 12 valid values, so validating against that list is cheap.

This is inconsistent with sibling commands in the same group, which handle unknown arguments correctly:

  • workers native nonsense-typeUnknown native worker type + exit 1
  • workers status worker-INVENTED-999Worker not found + exit 1
  • workers benchmark --type nonsenseUnknown benchmark type + exit 1

Minor, same cause: the unrecognised string is echoed verbatim into the memory pattern (../etc/passwd/{topic}/{phase}). These are namespace strings rather than filesystem paths, so this is an unvalidated echo rather than a traversal — but it is another place the bad input passes through unchecked.

3. The documented example matches on no field

field documented actual
Primary researcher, coder, analyst researcher, coder
Fallback reviewer, architect planner
Pipeline discovery → analysis → pattern-extraction → storage file-discovery → pattern-discovery → vectorization → summarization
Memory {trigger}/{topic}/{timestamp} ultralearn/{topic}/{phase}
Confidence 94% 60%
Reason Best match … based on historical success No performance history - using default recommendation

There is no analyst or architect agent in the capability table, and the memory pattern's last segment is {phase}, not {timestamp}.

Environment

agentic-flow 2.1.2 (global), Node 24, macOS 15.6, run in an empty scratch directory.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at dist/workers/worker-agent-integration.js:271-274 and inspect the workers agents argument handling, comparing it with workers native, status, and benchmark validation. Reproduce the listed invalid-trigger commands and verify that valid trigger output remains unchanged while invalid, empty, case-mismatched, and path-like values produce an error and exit 1; review #210 separately for the confidence behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.