workers agents: trigger argument unvalidated (case typo silently downgrades pipeline, exit 0); confidence pinned at 60% via dead profile branch
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-type→Unknown native worker type+ exit 1workers status worker-INVENTED-999→Worker not found+ exit 1workers benchmark --type nonsense→Unknown 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
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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