FN-6832: preserve default workflow routing
Preserve the default workflow unless users explicitly request workflow routing changes. - Update triage and fast-planning prompt guidance to stop inferring alternate workflows from task type or no-commit markers. - Refresh workflow docs and prompt tests to assert explicit-request-only workflow selection. - Add a patch changeset for the published CLI package. Files changed: .changeset/fn-6832-workflow-routing.md | 5 +++++ docs/workflow-steps.md | 5 ++++- packages/core/src/agent-prompts.ts | 20 +++++++++++++------- .../src/__tests__/triage-threshold-settings.test.ts | 7 +++++-- packages/engine/src/__tests__/triage.test.ts | 13 +++++-------- 5 files changed, 32 insertions(+), 18 deletions(-) Fusion-Task-Id: FN-6832 Fusion-Task-Lineage: 5a7ad103-2081-4c4c-ac32-fd5e4f6adfda
This commit is contained in:
5
.changeset/fn-6832-workflow-routing.md
Normal file
5
.changeset/fn-6832-workflow-routing.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@runfusion/fusion": patch
|
||||
---
|
||||
|
||||
Stop triage and planning prompts from auto-selecting alternate workflows based on task type; agents now preserve the project default workflow unless the user explicitly requests a specific workflow.
|
||||
@@ -12,6 +12,9 @@ Public docs need one concise workflow overview that names the shipped built-ins,
|
||||
|
||||
FNXC:Docs 2026-06-20-08:47:
|
||||
The built-in catalog now includes a business lead-generation workflow with custom columns, custom lead fields, and inline per-stage prompts, so the public inventory must show it beside coding workflows instead of implying all selectable built-ins are engineering-only.
|
||||
|
||||
FNXC:WorkflowRouting 2026-06-21-04:25:
|
||||
Triage and planning agents must preserve the project default workflow unless the user explicitly requests a different workflow. No-commit markers describe expected artifact behavior only; they no longer imply automatic Quick fix workflow selection.
|
||||
-->
|
||||
|
||||
Fusion workflows define the task lifecycle policy that moves work from an idea to delivery. The default coding path is **Plan/Triage → Execute → Workflow steps → Review → Merge**, but that path is now represented as a workflow selection rather than only as fixed engine behavior. A task with no explicit workflow resolves to `builtin:coding`; an explicit missing/corrupt custom workflow fails closed instead of silently falling back.
|
||||
@@ -24,7 +27,7 @@ Operators can select workflows in the dashboard wherever the task or board workf
|
||||
- `fn_workflow_select` — assign a workflow to the current or named task.
|
||||
- `workflow_id` on `fn_task_create` / delegation tools — create a task with a workflow already selected.
|
||||
|
||||
Decision-only or investigation tasks can also declare `noCommitsExpected` / `**No commits expected:** true`; the built-in triage policy prefers the Quick fix workflow for that no-commit lane.
|
||||
Decision-only or investigation tasks can also declare `noCommitsExpected` / `**No commits expected:** true`; that marker does not change workflow selection by itself. Tasks without an explicit workflow request stay on the project default (`builtin:coding`).
|
||||
|
||||
### Built-in workflow catalog
|
||||
|
||||
|
||||
@@ -405,8 +405,12 @@ If an executor later proves an ordinary implementation task is already satisfied
|
||||
## Project commands
|
||||
When the user prompt includes explicit test/build commands, use those exact commands in the generated spec.
|
||||
|
||||
<!--
|
||||
FNXC:WorkflowRouting 2026-06-20-22:08:
|
||||
Fast triage must keep tasks on the project default workflow unless the user explicitly asked for a specific workflow. The no-commits header remains a PROMPT.md marker only; it is not permission to select a lightweight workflow automatically.
|
||||
-->
|
||||
## Workflow Routing
|
||||
Call \`fn_workflow_list\` and use workflow descriptions as the routing signal. For investigation/audit/research, operational routing/coordination, or decision-only tasks that meet the no-commits criteria above, include \`**No commits expected:** true\` in the PROMPT.md header and prefer \`builtin:quick-fix\` or a custom investigation workflow; standard coding tasks can stay on the default \`builtin:coding\`. Use \`fn_workflow_select\` for the current task or pass \`workflow_id\` to \`fn_task_create\` for subtasks.
|
||||
Keep the project default workflow (\`builtin:coding\`) unless the user explicitly requested a specific workflow for this task or subtask. Do NOT call \`fn_workflow_select\` or pass \`workflow_id\` to \`fn_task_create\` just because a task looks like investigation, audit, research, coordination, decision-only work, or coding work. If the user explicitly asks for a workflow, call \`fn_workflow_list\` to discover valid IDs, then use \`fn_workflow_select\` for the current task or pass \`workflow_id\` to \`fn_task_create\` for the requested subtask. For investigation/audit/research, operational routing/coordination, or decision-only tasks that meet the no-commits criteria above, still include \`**No commits expected:** true\` in the PROMPT.md header when appropriate; that header marker does not change the workflow.
|
||||
|
||||
## Task Artifact Location for Forensic / Reconciliation Tasks
|
||||
|
||||
@@ -698,13 +702,15 @@ commands, use those EXACT commands in the testing/verification steps and anywher
|
||||
the spec references running tests or builds. Do NOT guess or infer commands from
|
||||
package.json when explicit commands are provided.
|
||||
|
||||
<!--
|
||||
FNXC:WorkflowRouting 2026-06-20-22:08:
|
||||
Standard triage must not infer workflow changes from task type. Agents preserve the project default unless the user names or explicitly requests a workflow; no-commit decisions use the header marker without automatic workflow selection.
|
||||
-->
|
||||
## Workflow Routing
|
||||
- Call \`fn_workflow_list\` to discover available workflows before selecting a routing path, and read each workflow description as the routing signal.
|
||||
- For investigation, audit, research, operational routing/coordination, or decision-only tasks that produce no code/config/file changes, set \`**No commits expected:** true\` in the PROMPT.md header when the no-commits criteria above are met, then select an appropriate lightweight workflow.
|
||||
- For decision-only tasks ({{triageNoCommitsDecisionVerbs}}), prefer \`{{triageDecisionOnlyWorkflowId}}\` or a custom investigation workflow when one is available.
|
||||
- For standard coding tasks, \`{{triageDefaultWorkflowId}}\` is the default and is usually appropriate.
|
||||
- Use \`fn_workflow_select\` to set the workflow on the current task, or pass \`workflow_id\` to \`fn_task_create\` when creating subtasks.
|
||||
- Match the task nature to the workflow description; descriptions are authoritative for routing decisions.
|
||||
- Keep the project default workflow (\`{{triageDefaultWorkflowId}}\`) unless the user explicitly requested a specific workflow for this task or subtask.
|
||||
- Do NOT call \`fn_workflow_select\` or pass \`workflow_id\` to \`fn_task_create\` just because a task looks like investigation, audit, research, operational routing/coordination, decision-only work, or standard coding work.
|
||||
- For decision-only tasks ({{triageNoCommitsDecisionVerbs}}) or other no-code tasks, set \`**No commits expected:** true\` in the PROMPT.md header when the no-commits criteria above are met; this is a header marker only and does not select \`{{triageDecisionOnlyWorkflowId}}\` or any custom investigation workflow by itself.
|
||||
- If the user explicitly asks for a workflow, call \`fn_workflow_list\` to discover valid IDs, then use \`fn_workflow_select\` to set the workflow on the current task or pass \`workflow_id\` to \`fn_task_create\` when creating a requested subtask.
|
||||
|
||||
## Spec Review
|
||||
|
||||
|
||||
@@ -43,8 +43,11 @@ describe("triage threshold workflow settings", () => {
|
||||
expect(rendered).toContain("at or above 30 items");
|
||||
expect(rendered).toContain("S (<2h), M (2-4h), L (4-8h). Split if XL (8h+)");
|
||||
expect(rendered).toContain("Decide, Evaluate, Verify, Confirm, Audit, Review whether, Investigate and report");
|
||||
expect(rendered).toContain("prefer `builtin:quick-fix`");
|
||||
expect(rendered).toContain("`builtin:coding` is the default");
|
||||
expect(rendered).toContain("Keep the project default workflow (`builtin:coding`)");
|
||||
expect(rendered).toContain("unless the user explicitly requested a specific workflow");
|
||||
expect(rendered).toContain("Do NOT call `fn_workflow_select` or pass `workflow_id`");
|
||||
expect(rendered).toContain("set `**No commits expected:** true` in the PROMPT.md header");
|
||||
expect(rendered).not.toContain("prefer `builtin:quick-fix`");
|
||||
expect(rendered).not.toContain("{{");
|
||||
});
|
||||
|
||||
|
||||
@@ -784,15 +784,12 @@ describe("fast-mode triage", () => {
|
||||
expect(FAST_PLANNING_PROMPT).not.toContain("Frontend UX Criteria");
|
||||
});
|
||||
|
||||
it("documents workflow routing in standard and fast prompts", () => {
|
||||
it("documents explicit-request-only workflow routing in standard and fast prompts", () => {
|
||||
const required = ["## Workflow Routing", "Keep the project default workflow", "unless the user explicitly requested a specific workflow", "Do NOT call `fn_workflow_select` or pass `workflow_id`", "If the user explicitly", "fn_workflow_list", "fn_workflow_select", "workflow_id", "**No commits expected:** true", "builtin:coding"];
|
||||
const forbidden = ["use workflow descriptions as the routing signal", "select an appropriate lightweight workflow", "prefer `builtin:quick-fix` or a custom investigation workflow", "Match the task nature to the workflow description", "descriptions are authoritative for routing decisions"];
|
||||
for (const prompt of [RENDERED_TRIAGE_POLICY_PROMPT, FAST_PLANNING_PROMPT]) {
|
||||
expect(prompt).toContain("## Workflow Routing");
|
||||
expect(prompt).toContain("fn_workflow_list");
|
||||
expect(prompt).toContain("fn_workflow_select");
|
||||
expect(prompt).toContain("workflow_id");
|
||||
expect(prompt).toContain("**No commits expected:** true");
|
||||
expect(prompt).toContain("builtin:quick-fix");
|
||||
expect(prompt).toContain("builtin:coding");
|
||||
for (const text of required) expect(prompt).toContain(text);
|
||||
for (const text of forbidden) expect(prompt).not.toContain(text);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user