FN-7247: document current workflow behavior
Refresh workflow documentation to match the latest runtime, dashboard, and agent tool behavior. - Add a current workflow behavior inventory covering built-ins, fail-closed runtime semantics, optional gates, settings, tools, routing, and create forwarding. - Clarify dashboard All workflows aggregation, workflow badges, and workflow-aware task creation behavior. - Expand editor, agent, CLI, and settings docs for governed workflow authoring, values, trait inspection, and selection boundaries. - Add docs drift tests requiring workflow docs index coverage and current behavior markers. Files changed: docs/agents.md | 5 +- docs/cli-reference.md | 11 ++- docs/dashboard-guide.md | 10 ++- docs/settings-reference.md | 5 ++ docs/workflow-editor.md | 15 +++- docs/workflow-steps.md | 48 ++++++++--- .../cli/src/__tests__/docs-readme-index.test.ts | 4 + .../src/__tests__/workflow-docs-current.test.ts | 95 ++++++++++++++++++++++ 8 files changed, 172 insertions(+), 21 deletions(-) Fusion-Task-Id: FN-7247 Fusion-Task-Lineage: 72bf0c89-80a3-440c-b6aa-1aea315279f5 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
@@ -7,6 +7,9 @@ Fusion uses multiple agent roles for planning, execution, review, and merge work
|
||||
<!--
|
||||
FNXC:WorkflowRouting 2026-06-22-12:00:
|
||||
Agent-facing docs must preserve the workflow movement boundary: agents can assign workflows when the user explicitly asked or when creating a task, while executors cannot reroute the task under execution on their own initiative.
|
||||
|
||||
FNXC:WorkflowRouting 2026-06-30-09:20:
|
||||
Permanent agents and the published extension now have governed workflow authoring, settings, trait-inspection, and selection tools; docs must describe the broad tool surface while preserving the narrow routing permission boundary.
|
||||
-->
|
||||
|
||||
## CLI session actions
|
||||
@@ -34,7 +37,7 @@ fn chat <agent-id> [message…] [--once] [--non-interactive] [--poll-ms <n>]
|
||||
- Dashboard chat and planning sessions with a scoped task store expose `fn_task_document_write` and `fn_task_document_read`; because neither lane has an ambient task, both tools require an explicit `task_id`.
|
||||
- Agent workflow-routing tools follow an intent boundary: agents may select or change a task workflow only when the user explicitly requested that workflow or when the agent created the task. Executors must not call `fn_workflow_select` to reroute the task they are executing unless the task instructions or a user steering comment explicitly asks for the workflow change. Lanes without an ambient task, including dashboard chat/planning and published/pi extension calls outside a task, must pass an explicit `task_id`; task-bound executor paths may default to the current task.
|
||||
- Executor, heartbeat, and dashboard chat sessions expose artifact registry tools so agents can publish and inspect multi-type deliverables without relying on the dashboard gallery. Planning sessions intentionally exclude artifact tools until they can thread the existing `MessageStore` dependency.
|
||||
- Permanent/custom heartbeat agents and the published/pi extension receive the broad coordination and work-discovery tool surface instead of a narrowly curated subset: read-only task discovery (`fn_task_list`, `fn_task_show`, `fn_task_search`) for work discovery and duplicate avoidance, workflow discovery and authoring (`fn_workflow_list`, `fn_workflow_get`, `fn_workflow_create`, `fn_workflow_update`, `fn_workflow_delete`, `fn_workflow_settings`, `fn_trait_list`), governed research (`fn_research_run`, `fn_research_list`, `fn_research_get`, `fn_research_cancel`), structured clarification (`fn_ask_question`), artifact, memory, messaging, goal, evaluation, identity, and delegation tools. Task-scoped heartbeat sessions also expose current-task workflow selection and promotion (`fn_workflow_select`, `fn_task_promote`); no-task heartbeats omit those because they have no ambient task, while no-task extension/chat/planning lanes expose `fn_workflow_select` but require explicit `task_id`. Prompt-injectable lanes strip workflow approval-bypass flags during `fn_workflow_create`/`fn_workflow_update`; executor-owner paths are the only authoring path that may preserve those flags. Executor-only worktree/workspace tools such as `fn_run_verification` and `fn_acquire_repo_worktree` remain out of the ambient heartbeat lane until that lane owns the required worktree/workspace context. The task read tools are store-backed, text-only, and action-gate-recognized as read-only; dangerous actions are controlled at invocation time by each agent's `AgentPermissionPolicy` through the action gate (allow / require approval / block), not by withholding governed tools from the session.
|
||||
- Permanent/custom heartbeat agents and the published/pi extension receive the broad coordination and work-discovery tool surface instead of a narrowly curated subset: read-only task discovery (`fn_task_list`, `fn_task_show`, `fn_task_search`) for work discovery and duplicate avoidance, workflow discovery and authoring (`fn_workflow_list`, `fn_workflow_get`, `fn_workflow_create`, `fn_workflow_update`, `fn_workflow_delete`, `fn_workflow_settings`, `fn_trait_list`), governed research (`fn_research_run`, `fn_research_list`, `fn_research_get`, `fn_research_cancel`), structured clarification (`fn_ask_question`), artifact, memory, messaging, goal, evaluation, identity, and delegation tools. Task-scoped heartbeat sessions also expose current-task workflow selection and promotion (`fn_workflow_select`, `fn_task_promote`); no-task heartbeats omit those because they have no ambient task, while no-task extension/chat/planning lanes expose `fn_workflow_select` but require explicit `task_id`. Workflow creation, updates, settings writes, deletion, and selection remain permission-gated task/agent mutations even when the tools are exposed in the lane. Prompt-injectable lanes strip workflow approval-bypass flags during `fn_workflow_create`/`fn_workflow_update`; executor-owner paths are the only authoring path that may preserve those flags. Executor-only worktree/workspace tools such as `fn_run_verification` and `fn_acquire_repo_worktree` remain out of the ambient heartbeat lane until that lane owns the required worktree/workspace context. The task read tools are store-backed, text-only, and action-gate-recognized as read-only; dangerous actions are controlled at invocation time by each agent's `AgentPermissionPolicy` through the action gate (allow / require approval / block), not by withholding governed tools from the session.
|
||||
- `agent.taskId` is an active-execution linkage, not durable ownership. It may legitimately point at a `todo`/`triage` task only while the agent has live run or executor-active proof; task-move sync and self-healing clear stale parked, terminal, or unresolved links otherwise. `fn_list_agents` and `fn_agent_show` therefore include column context in the human-readable `Current Task` line, such as `(triage)`, `(in-progress)`, `(not active — done)`, or `(unresolved)`, so coordinators can distinguish transient planning ownership from drift.
|
||||
|
||||
### Artifact registry tools
|
||||
|
||||
@@ -7,6 +7,9 @@ Fusion’s command-line interface is exposed through the `fn` command.
|
||||
<!--
|
||||
FNXC:AgentTools 2026-06-29-22:31:
|
||||
The published CLI/pi extension must document its agent-facing workflow authoring surface so operators know agents can inspect, create, update, configure, and delete custom workflows without using the dashboard editor.
|
||||
|
||||
FNXC:AgentTools 2026-06-30-09:25:
|
||||
The extension docs must list workflow selection and task-creation forwarding alongside CRUD/settings tools so operators do not assume only discovery and selection exist or that agents may reroute arbitrary tasks.
|
||||
-->
|
||||
|
||||
## Published agent extension workflow tools
|
||||
@@ -14,12 +17,14 @@ The published CLI/pi extension must document its agent-facing workflow authoring
|
||||
The published `@runfusion/fusion` CLI bundle also exposes the pi extension tool surface used by external agents. Alongside task and coordination helpers, agents can now author and manage workflow definitions:
|
||||
|
||||
- `fn_workflow_list` / `fn_workflow_get` — discover built-in and custom workflows and inspect a workflow's IR before editing.
|
||||
- `fn_workflow_create` / `fn_workflow_update` — create or revise custom workflow definitions through Fusion's central workflow validator.
|
||||
- `fn_workflow_settings` — read and write typed per-project values for a workflow's declared settings.
|
||||
- `fn_workflow_create` / `fn_workflow_update` — create or revise custom workflow definitions through Fusion's central workflow validator. Built-in definitions are read-only, and broader-than-default column permission bindings require explicit policy-escalation confirmation.
|
||||
- `fn_workflow_settings` — read and write typed per-project values for a workflow's declared settings. `get` returns stored and engine-effective values; `set` validates atomically and treats `null` as deleting a stored override.
|
||||
- `fn_workflow_delete` — delete custom workflows; built-in workflows remain protected.
|
||||
- `fn_trait_list` — list the column trait vocabulary used when authoring workflow columns.
|
||||
- `fn_workflow_select` — assign a workflow to the current task in task-bound lanes or to an explicit `task_id` when the lane has no ambient task. Published/pi extension calls, dashboard chat/planning, and no-task heartbeat lanes must pass `task_id`; executor paths may omit it only for the task currently under execution.
|
||||
- `workflow_id` on task creation/delegation tools — create or delegate a task onto a real workflow id from the start.
|
||||
|
||||
Agents should still use `fn_workflow_select` only when assigning a workflow to an explicit task context or to a task they created.
|
||||
Agents should still use `fn_workflow_select` only when the user explicitly requested that workflow or when assigning a workflow to a task they created; they must not reroute arbitrary existing tasks just because another workflow appears more suitable. Prompt-injectable lanes strip workflow approval-bypass flags during `fn_workflow_create` / `fn_workflow_update`; executor-owner paths are the only authoring path that may preserve those flags.
|
||||
|
||||
## Global Usage
|
||||
|
||||
|
||||
@@ -132,7 +132,9 @@ Features:
|
||||
- The quick-entry GitHub icon is a per-task tracking override: leave it untouched to use the project default, turn it on to opt the next task into tracking when the default is off, or turn it off to opt the next task out when the default is on.
|
||||
- PR/issue badges with live updates
|
||||
- GitHub provenance marker on task cards imported from GitHub (`sourceType: github_import`), shown in the footer with other external-source metadata
|
||||
- Task card header meta badges group priority, fast mode, agent-created provenance, and elapsed/created-time chips into one wrapping row; agent labels prefer `sourceMetadata.agentName` over raw agent IDs
|
||||
- Task card header meta badges group priority, fast mode, agent-created provenance, workflow name, and elapsed/created-time chips into one wrapping row; agent labels prefer `sourceMetadata.agentName` over raw agent IDs
|
||||
- Task detail surfaces show the selected/effective workflow name near the task's workflow controls so individual cards remain understandable when Board is in **All workflows** or another aggregate/mixed context.
|
||||
<!-- FNXC:WorkflowBadges 2026-06-30-09:10: Task cards and task detail need workflow-name badges wherever mixed-workflow board contexts can hide the selected lane, especially the Board-only All workflows aggregate. -->
|
||||
<!-- FNXC:BoardDoneSorting 2026-06-29-00:00: The Done board column exposes a local descending sort selector so operators can review either latest completions or highest task IDs without changing other lifecycle columns. -->
|
||||
<!-- FNXC:BoardDoneSorting 2026-06-29-20:28: Document both Done sort modes as descending-only and Done-column-only so legacy Done and workflow complete-lane operators understand the selector does not change other lifecycle columns. -->
|
||||
- Column ordering semantics: `todo` mirrors scheduler pickup order (priority descending, then oldest `createdAt`, then task ID); `triage`, `in-progress`, `in-review`, and `archived` remain priority-first with task-ID tie-breaks; `done` defaults to most recent completion first (`columnMovedAt`, then `updatedAt`, then `createdAt` fallback) and can be switched from the Done column header to descending task ID. In workflow mode, non-archived columns marked with the `complete` flag use the same Done ordering even when their column ID or label is customized.
|
||||
@@ -142,7 +144,7 @@ Features:
|
||||
<!-- FNXC:WorkflowSelection 2026-06-29-18:37: The Board-only All workflows option renders an aggregate column set across workflows while keeping workflow-specific creates, edits, and durable selection scoped to real workflow ids. -->
|
||||
<!-- FNXC:WorkflowSelection 2026-06-29-23:58: All workflows quick-create must use a real workflow intake/default column rather than a synthesized lifecycle column, so custom-default boards do not create tasks into invalid or disappearing columns. -->
|
||||
<!-- FNXC:WorkflowSelection 2026-06-29-23:59: Workflow counts and All workflows grouping resolve each task's effective workflow before evaluating column visibility, so a shared column id hidden in one workflow does not leak that workflow's hidden tasks into another workflow's visible aggregate lane. -->
|
||||
- Board and List workflow switchers use a themed dropdown instead of a native select. The closed trigger shows the workflow name and chevron only; compact Todo / In Progress / Done counts derived from workflow column flags (excluding archived and board-hidden columns) refresh each time the dropdown opens and appear while the dropdown is expanded, including on each workflow option. Built-in lanes with synthesized trait-less lifecycle columns fall back to canonical column ids (`todo`, `in-progress`, `done`, and `archived`) for those counts. Board also shows **All workflows** before real workflows as a dashboard-only aggregate view with combined counts and a deterministic union of visible workflow columns; shared column ids use the default workflow label/flags when available, otherwise the first workflow definition that declares the column. That option is not editable and is not saved as the durable selected workflow, and its quick-create affordance appears only on the chosen real workflow intake/default column so task creation still sends a real workflow id and column. Each real workflow option row also exposes an inline edit action, and a persistent **New workflow** footer stays visible below the scrollable option list. The open listbox grows from the longest workflow name plus its count/edit decorations while remaining viewport-bounded; the closed trigger stays narrow and ellipsized. Those inline count badges intentionally use the same board column color tokens as cards: `--todo`, `--in-progress`, and `--done`.
|
||||
- Board and List workflow switchers use a themed dropdown instead of a native select. The closed trigger shows the workflow name and chevron only; compact Todo / In Progress / Done counts derived from workflow column flags (excluding archived and board-hidden columns) refresh each time the dropdown opens and appear while the dropdown is expanded, including on each workflow option. Built-in lanes with synthesized trait-less lifecycle columns fall back to canonical column ids (`todo`, `in-progress`, `done`, and `archived`) for those counts. Board also shows **All workflows** before real workflows as a dashboard-only aggregate view with combined counts and a deterministic union of visible workflow columns; shared column ids use the default workflow label/flags when available, otherwise the first workflow definition that declares the column. Hidden columns stay workflow-scoped in the aggregate: a task whose effective workflow hides a shared column is omitted from that aggregate column even if another workflow exposes the same column id. That option is not editable and is not saved as the durable selected workflow, and its quick-create affordance appears only on the chosen real workflow intake/default column so task creation still sends a real workflow id and column. Each real workflow option row also exposes an inline edit action, and a persistent **New workflow** footer stays visible below the scrollable option list. The open listbox grows from the longest workflow name plus its count/edit decorations while remaining viewport-bounded; the closed trigger stays narrow and ellipsized. Those inline count badges intentionally use the same board column color tokens as cards: `--todo`, `--in-progress`, and `--done`.
|
||||
- When workflow columns are enabled, Board and List hydrate the last successful workflow-lane payload from a per-project session cache; cold loads show a neutral skeleton until settings and workflow metadata are known, avoiding a legacy single-lane flash. The selected workflow is remembered per project in durable browser storage and restored when returning to Board/List after task refreshes, route changes, or respecification flows; if that saved workflow is later deleted, Fusion falls back to a valid default/first workflow so tasks remain visible.
|
||||
|
||||

|
||||
@@ -323,7 +325,9 @@ Planning is a desktop/tablet left-sidebar main-content destination after **Comma
|
||||
|
||||
These values are sent with the Planning Mode create-task request as `branchSelection`, so created tasks persist branch/base-branch settings consistently with other branch-aware task creation flows.
|
||||
|
||||
When inline quick-create, Planning Mode, or Subtask Breakdown is opened from a workflow-filtered board/list lane, the create request also carries that active workflow selection. Quick-created tasks appear on the selected workflow lane immediately while board-workflows metadata refreshes, and planning saves, planning breakdown saves, and subtask-breakdown saves create their tasks directly on the selected workflow lane instead of briefly landing on the default board.
|
||||
<!-- FNXC:WorkflowCreateForwarding 2026-06-30-09:12: Dashboard create flows must forward the active real workflow id so planning/quick-create tasks do not briefly land on the default workflow or persist the synthetic All workflows aggregate. -->
|
||||
|
||||
When inline quick-create, Planning Mode, or Subtask Breakdown is opened from a workflow-filtered board/list lane, the create request also carries that active workflow selection. Quick-created tasks appear on the selected workflow lane immediately while board-workflows metadata refreshes, and planning saves, planning breakdown saves, and subtask-breakdown saves create their tasks directly on the selected workflow lane instead of briefly landing on the default board. When Board is showing **All workflows**, quick-create uses the real workflow intake/default column that owns the affordance; it never submits the synthetic aggregate as a workflow id.
|
||||
|
||||
The **New Task** dialog's workflow selector also defaults to the current or last selected Board/List workflow lane for the current project. If no valid lane has been selected, or the remembered lane was deleted, the selector falls back to the project default workflow and task creation omits an explicit `workflowId`.
|
||||
|
||||
|
||||
@@ -227,6 +227,11 @@ When the dashboard footer reports that a newer `@runfusion/fusion` version is av
|
||||
|
||||
## Workflow Settings
|
||||
|
||||
<!--
|
||||
FNXC:WorkflowSettings 2026-06-30-09:15:
|
||||
Settings docs should keep workflow value resolution and prompt ownership separate: settings values are typed per-workflow/project data, while built-in prompt overrides are node text overlays edited through the workflow editor.
|
||||
-->
|
||||
|
||||
Some knobs that used to live in this Settings reference as project settings are now
|
||||
**workflow settings**: they are declared by a workflow and their values are stored
|
||||
**per `(workflow, project)`**, not as ambient project settings. A workflow models
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
<!--
|
||||
FNXC:WorkflowEditorDocs 2026-06-16-12:00:
|
||||
Fusion needs one canonical user-facing guide for the dashboard WorkflowNodeEditor so operators can discover every shipped entry point, understand the visual Workflow IR authoring model, and distinguish read-only built-ins from editable custom workflows without piecing the behavior together from settings and workflow-step references.
|
||||
|
||||
FNXC:WorkflowEditorDocs 2026-06-29-16:18:
|
||||
The editor guide must describe the current authored surface as one contract shared by dashboard and agent tools: graph nodes, columns/traits, fields, settings definitions/values, AI design, import/export, mobile destinations, and built-in prompt overrides without implying built-in topology edits are allowed.
|
||||
-->
|
||||
|
||||
The workflow editor is Fusion's visual workflow authoring surface in the dashboard. It uses the `@xyflow/react` canvas to view built-in lifecycle workflows and create or edit custom workflow definitions backed by Fusion's [Workflow IR](./workflow-steps.md#workflow-ir-v1). The graph you see is the same policy model the runtime uses for task lifecycle routing: nodes describe work or control-flow boundaries, edges describe how execution moves between them, and side panels declare workflow-specific columns, task fields, and typed workflow settings.
|
||||
@@ -25,7 +28,7 @@ These entry points do not create different workflow formats. Desktop and mobile
|
||||
|
||||
## Canvas anatomy
|
||||
|
||||
The editor is a modal with a workflow picker, toolbar actions, a React Flow graph, and inspectors:
|
||||
The editor is a modal with a workflow picker, toolbar actions, a React Flow graph, and inspectors. Built-in workflows use the same viewer and Values surfaces as custom workflows, but their topology stays read-only except for project-scoped prompt overrides on prompt/gate nodes:
|
||||
|
||||
- **Workflow list / picker:** choose a built-in or custom workflow. Built-ins are labeled and remain read-only; custom workflows are editable.
|
||||
- **Graph canvas:** the central React Flow surface where nodes and edges are displayed. Drag nodes to rearrange them, connect handles to create edges, and select a node or edge to inspect it.
|
||||
@@ -35,6 +38,7 @@ The editor is a modal with a workflow picker, toolbar actions, a React Flow grap
|
||||
- **Templates section:** insert reusable graph fragments, built-in workflow-step templates, and plugin-contributed workflow-step templates when available.
|
||||
- **Inspectors and side panels:** selecting a node opens its configuration inspector; selecting an edge opens the edge inspector. Separate panels manage Columns, Fields, and Settings.
|
||||
- **Validation and status banners:** save-time validation errors, import warnings, branch/interpreter notices, and read-only built-in hints appear inline instead of relying only on toasts.
|
||||
- **Prompt override controls:** when a built-in prompt or gate node is selected, the inspector allows only prompt text overrides and reset-to-default; node kind, edges, columns, traits, field declarations, and setting declarations remain locked.
|
||||
|
||||
## Node palette
|
||||
|
||||
@@ -167,7 +171,7 @@ Fusion ships built-in workflows as read-only references:
|
||||
|
||||
- `builtin:coding` — the default Stepwise-based coding lifecycle: plan steps, execute them one at a time, then run the optional final Code Review gate and merge.
|
||||
- `builtin:legacy-coding` — the original monolithic coding lifecycle for tasks that should not use graph-owned step execution.
|
||||
- `builtin:quick-fix` — a short path for trivial or no-commit/decision work.
|
||||
- `builtin:quick-fix` — a short explicitly selected path for trivial or decision work; no-commit markers do not select it automatically.
|
||||
- `builtin:review-heavy` — a standard execute/review/merge path with an additional gated security review.
|
||||
- `builtin:marketing` — a marketing content pipeline with brief, draft, editorial review, and publish stages.
|
||||
- `builtin:compound-engineering` — a plugin-gated Compound Engineering pipeline: `/ce-plan` writes the CE plan doc, optional `ce-doc-review` can pressure-test plans (markdown gets autofix/Open Questions write-back; HTML uses DOM-safe helper mutations, including canonical checklist repair, only when safety is proven and otherwise report-only with no write), `/ce-work` implements, `/ce-code-review` gates merge, and autoMerge-off projects route through the CE PR/feedback skills before Fusion's manual merge seam.
|
||||
@@ -177,7 +181,12 @@ Fusion ships built-in workflows as read-only references:
|
||||
|
||||
Built-ins can be viewed, exported, and used as templates, but their graph, columns, field declarations, and setting declarations are not editable. Their per-project setting **values** are editable from the Settings panel's Values tab. Selectable built-ins all use a capacity-released queue column (`todo` or a workflow-specific backlog) that dispatches to the active WIP column through the standard hold/release sweep.
|
||||
|
||||
To customize behavior, create a workflow from **Blank** or copy a built-in/custom workflow with **Duplicate to customize**. Tasks select a workflow by workflow id. Agents and automation can discover workflows with `fn_workflow_list`, assign one to an existing task with `fn_workflow_select`, or pass `workflow_id` when creating tasks through `fn_task_create` / delegation tools.
|
||||
<!--
|
||||
FNXC:WorkflowEditorDocs 2026-06-30-09:05:
|
||||
The editor guide should summarize agent workflow tooling without implying the tool surface is limited to list/select; workflow authoring and settings values are also first-class governed agent tools.
|
||||
-->
|
||||
|
||||
To customize behavior, create a workflow from **Blank** or copy a built-in/custom workflow with **Duplicate to customize**. Tasks select a workflow by workflow id. Agents and automation have parity with the editor's governed save paths: they can inspect definitions with `fn_workflow_list` / `fn_workflow_get`, inspect column traits with `fn_trait_list`, author custom definitions with `fn_workflow_create` / `fn_workflow_update` / `fn_workflow_delete`, tune per-project values with `fn_workflow_settings`, assign one to an existing task with `fn_workflow_select`, or pass `workflow_id` when creating tasks through `fn_task_create` / delegation tools. Tool writes run the same validation as dashboard saves/imports, including malformed-IR rejection and policy-escalation confirmation for broader column-agent bindings. The routing boundary still applies: agents select workflows only for explicit user requests or tasks they created.
|
||||
|
||||
## Mobile editor
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ FNXC:WorkflowRuntime 2026-06-28-08:10:
|
||||
Selectable built-in workflows must share the canonical dispatch traits: their held work enters through a capacity-released `todo`/backlog column and moves to the first WIP execution column via the hold/release sweep, so non-default built-ins do not need a separate dispatcher.
|
||||
-->
|
||||
|
||||
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.
|
||||
Fusion workflows define the task lifecycle policy that moves work from an idea to delivery. The default coding path is **Plan/Triage → Execute → graph-native optional gates → 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.
|
||||
|
||||
### Selecting workflows
|
||||
|
||||
@@ -49,7 +49,7 @@ Decision-only or investigation tasks can also declare `noCommitsExpected` / `**N
|
||||
|---|---|---|
|
||||
| Coding | `builtin:coding` | Default Stepwise-based coding lifecycle: plan steps, execute them one at a time, then run the optional final Code Review gate and merge. |
|
||||
| Legacy coding | `builtin:legacy-coding` | Original monolithic coding lifecycle for tasks that should not use graph-owned step execution. |
|
||||
| Quick fix | `builtin:quick-fix` | Short path for trivial or no-commit/decision work; omits the standard review stage. |
|
||||
| Quick fix | `builtin:quick-fix` | Short explicitly selected path for trivial or decision work; omits the standard review stage. No-commit markers do not route tasks here automatically. |
|
||||
| Review-heavy | `builtin:review-heavy` | Standard execute/review/merge path with an additional gated security review. |
|
||||
| Marketing | `builtin:marketing` | Content pipeline with custom Ideation, Backlog, Drafting, Editorial review, Published, and Archived columns plus structured marketing brief/draft/editorial prompts; drafts are persisted as task documents for review while the workflow reuses standard lifecycle traits and merge primitives. |
|
||||
| Compound engineering | `builtin:compound-engineering` | Plugin-gated CE workflow that invokes `/ce-plan`, optional advisory `ce-doc-review` (markdown autofix; HTML DOM-safe mutation with report-only fallback), `/ce-work`, merge-blocking `/ce-code-review`, CE PR/feedback skills, Fusion merge, and learnings capture. |
|
||||
@@ -60,6 +60,29 @@ Decision-only or investigation tasks can also declare `noCommitsExpected` / `**N
|
||||
|
||||
Every selectable built-in workflow uses a capacity-released hold column (`todo` or a workflow-specific backlog) for queued work and a WIP execution column for active work, so the hold/release sweep performs the normal `todo`/backlog → in-progress dispatch across the catalog.
|
||||
|
||||
### Current workflow behavior inventory
|
||||
|
||||
<!--
|
||||
FNXC:WorkflowDocs 2026-06-30-09:00:
|
||||
Workflow documentation needs a compact current-behavior inventory so future edits keep the canonical homes aligned instead of duplicating or reviving deleted workflow-step CRUD concepts.
|
||||
-->
|
||||
|
||||
Use this inventory as the documentation map for current workflow behavior:
|
||||
|
||||
| Topic | Current behavior | Canonical home |
|
||||
|---|---|---|
|
||||
| Built-in catalog and ids | The selectable built-ins are `builtin:coding`, `builtin:legacy-coding`, `builtin:quick-fix`, `builtin:review-heavy`, `builtin:marketing`, `builtin:compound-engineering`, `builtin:stepwise-coding`, `builtin:design`, and `builtin:lead-generation`; `builtin:pr-workflow` is a reusable fragment, not a task-selectable workflow. | This page, [Built-in workflow catalog](#built-in-workflow-catalog); authoring summary in [Workflow Editor](./workflow-editor.md#built-in-vs-custom-workflows). |
|
||||
| Runtime and fail-closed behavior | The graph runtime owns lifecycle routing. Unselected/default tasks resolve to `builtin:coding`; missing explicit custom selections fail closed as workflow-resolution failures, and corrupt or invalid resolved IR fails closed as `invalid-ir` instead of returning a legacy fallback. | This page, [Workflow graph integrity validation](#workflow-graph-integrity-validation) and [Workflow Graph Executor](#workflow-graph-executor). |
|
||||
| Workflow IR validation | Save/import/AI design/tool writes and runtime materialization all use the central IR validator for node/edge integrity, column/field/setting uniqueness, optional-group references, and plugin extension keys. | This page, [Workflow graph integrity validation](#workflow-graph-integrity-validation); visual authoring in [Workflow Editor](./workflow-editor.md). |
|
||||
| Optional groups and default-on gates | Quality gates are graph `optional-group` nodes keyed by node id in `enabledWorkflowSteps`; the runtime/display effective set is persisted ids plus `defaultOn` groups, so default-on gates still run and appear for in-progress tasks when a persisted selection array is empty. Edit-mode controls continue to show the persisted selection so operators can see exactly what the task stored. There is no workflow-step table, Settings manager, or CRUD form. | This page, [Workflow-declared optional steps](#workflow-declared-optional-steps-optional-group-nodes), [Default-On Behavior for New Tasks](#default-on-behavior-for-new-tasks), and [Authoring a Custom Quality Gate](#authoring-a-custom-quality-gate). |
|
||||
| Explicit empty step dependencies | A heading annotation `(depends:)` or JSON step `"depends": []` means the step has no prerequisites; an absent dependency annotation/key still inherits the legacy previous-step dependency. | This page, [Parallel mode & the `(depends:)` annotation](#parallel-mode--the-depends-annotation). |
|
||||
| Workflow settings values | Setting declarations live in workflow IR; values persist per `(workflowId, projectId)` and resolve as `stored value ?? declaration default`, with invalid/orphaned values dropped from effective settings. | [Settings Reference → Workflow Settings](./settings-reference.md#workflow-settings); editor UX in [Workflow Editor](./workflow-editor.md#settings-panel-definitions-and-values). |
|
||||
| Built-in prompt overrides | Built-in topology stays read-only, but prompt/gate node text can be overridden per `(workflowId, nodeId, projectId)` and reset to shipped defaults. | This page, [Overriding built-in workflow prompts](#overriding-built-in-workflow-prompts); dashboard UX in [Dashboard Guide](./dashboard-guide.md#workflow-selection-and-editor). |
|
||||
| Agent workflow tools | Agents can list/get/create/update/delete workflows, inspect traits, read/write workflow settings, select workflows for explicit task contexts, and pass `workflow_id` when creating/delegating tasks. Prompt-injectable lanes strip approval-bypass flags on workflow writes. | [Agents](./agents.md#interactive-cli-chat) and [CLI Reference](./cli-reference.md#published-agent-extension-workflow-tools). |
|
||||
| Routing boundary | Agents may select/change a workflow only for explicit user requests or tasks they created; no-commit markers do not imply Quick fix or any other workflow. | This page, [Selecting workflows](#selecting-workflows); [Agents](./agents.md#interactive-cli-chat). |
|
||||
| Dashboard board/list/graph selection | Board/List/Header/Graph share durable per-project workflow selection; stale saved ids fall back to a valid workflow. Board adds a dashboard-only **All workflows** aggregate and task workflow-name badges; Graph uses **All workflows** for the full active graph. | [Dashboard Guide → Board View](./dashboard-guide.md#board-view), [Graph View](./dashboard-guide.md#graph-view), and [Workflow Selection and Editor](./dashboard-guide.md#workflow-selection-and-editor). |
|
||||
| Create/planning forwarding | Inline quick-create, Planning Mode, Subtask Breakdown, and the New Task dialog forward the active real workflow id when creating tasks; **All workflows** quick-create chooses a real workflow intake/default column instead of saving a synthetic aggregate id. | [Dashboard Guide → Planning Mode](./dashboard-guide.md#planning-mode). |
|
||||
|
||||
### Skill-backed workflow steps
|
||||
|
||||
<!--
|
||||
@@ -181,7 +204,7 @@ The workflow runtime is the authoritative execution path for task lifecycle work
|
||||
|
||||
The engine remains the substrate for scheduler dispatch, routing claims, persistence, concurrency limits, process supervision, storage, and audit plumbing. Lifecycle policy belongs in built-in or custom workflows.
|
||||
|
||||
The default built-in catalog entry `builtin:coding` is backed by a Stepwise-derived graph with two default-on, toggleable review gates: `plan-review` before execution and `code-review` at the end of implementation. It is the resolver/runtime fallback for tasks with no workflow selection or an explicit default selection. Missing/corrupt explicit custom selections fail closed as workflow-resolution failures instead of silently running the default. The built-in IR parses planned steps, executes them sequentially without per-step review, then routes optional quality gates into the merge region:
|
||||
The default built-in catalog entry `builtin:coding` is backed by a Stepwise-derived graph with two default-on, toggleable review gates: `plan-review` before execution and `code-review` at the end of implementation. It is the resolver/runtime fallback for tasks with no workflow selection or an explicit default selection. Missing explicit custom selections fail closed as workflow-resolution failures, and corrupt or invalid resolved IR fails with `invalid-ir` instead of silently running the default or a legacy workflow. The built-in IR parses planned steps, executes them sequentially without per-step review, then routes optional quality gates into the merge region:
|
||||
|
||||
- `triage` → `plan` → `plan-review` (default-on optional plan review) → `parse-steps` → `foreach(step-execute)` → `browser-verification` (optional) → `code-review` (default-on optional final review) → `merge-gate` / branch-group integration / `merge-attempt` / retry or manual hold → `end`
|
||||
|
||||
@@ -335,23 +358,26 @@ Workflows declare typed task fields via IR `fields: [{ id, name, type, required?
|
||||
|
||||
<!--
|
||||
FNXC:WorkflowOptionalGroup 2026-06-26-15:00:
|
||||
FN-7039 retired the declaration-based optional-steps model (`WorkflowOptionalStep` / the `optionalSteps` IR field). Optional quality gates are now first-class graph `optional-group` NODES; per-task enablement reuses `enabledWorkflowSteps` keyed by the group NODE ID (not a template id). Docs must describe the node model, not the deleted declaration facet.
|
||||
FN-7039 retired the declaration-based optional-steps model (`WorkflowOptionalStep` / the `optionalSteps` IR field). Optional quality gates are now first-class graph `optional-group` NODES; per-task persisted selections reuse `enabledWorkflowSteps` keyed by the group NODE ID (not a template id). Docs must describe the node model, not the deleted declaration facet.
|
||||
|
||||
FNXC:WorkflowOptionalGroup 2026-06-29-16:10:
|
||||
Default-on optional groups are effective for execution and in-progress display even when a task has an empty persisted selection array. Keep edit-mode language separate because editors show the stored ids, not the default-augmented runtime set.
|
||||
-->
|
||||
|
||||
Optional quality gates are authored directly in the workflow graph as `optional-group` **nodes**. An `optional-group` node is a container (mirroring `foreach`/`loop`) whose `template` subgraph the executor runs **once** when the group is enabled for the task, and passes through (skips) when disabled. There is no iteration and no rework budget — a single pass — and rework edges inside the template are rejected by `validateOptionalGroup`.
|
||||
|
||||
Node config (`WorkflowOptionalGroupConfig`): `{ name?, defaultOn?, maxRevisions?: number | "unbounded", phase?: "pre-merge" | "post-merge", template: { nodes, edges } }`.
|
||||
|
||||
- `defaultOn` seeds the per-task enable set at task creation; operators can still toggle it.
|
||||
- `defaultOn` contributes to the runtime/display effective enable set for the task; operators can still toggle persisted selections when creating or editing tasks.
|
||||
- `maxRevisions` optionally overrides the workflow/project `maxPostReviewFixes` budget for this one optional group's pre-merge fix → re-review loop. Use a non-negative integer for a bounded number of automatic fix passes, `0` to disable automatic fixes for that step, or `"unbounded"` to keep cycling until the step returns `APPROVE` / `APPROVE_WITH_NOTES`. When omitted, the step keeps the global `maxPostReviewFixes` behavior.
|
||||
- `phase` defaults to `"pre-merge"` (the prior, only behavior). `"post-merge"` marks a group the executor runs after a successful merge (see [Execution Phases](#execution-phases)).
|
||||
- Enable state lives on the per-task `enabledWorkflowSteps` array, keyed by the **group node id** (for example `browser-verification`, `code-review`). The graph executor runs an optional-group node only when its id is present in `enabledWorkflowSteps`.
|
||||
- Persisted enable state lives on the per-task `enabledWorkflowSteps` array, keyed by the **group node id** (for example `browser-verification`, `code-review`). For execution and in-progress display, Fusion treats a group as enabled when its id is present in `enabledWorkflowSteps` **or** the workflow node has `defaultOn: true`; this preserves default-on gates even for tasks whose persisted array is empty. Edit-mode controls remain based on the persisted array so an operator can distinguish stored selections from workflow defaults.
|
||||
|
||||
Built-in optional gates ship as inlined IR builders, not as a template catalog:
|
||||
|
||||
- `builtin:coding` carries the `browser-verification` optional-group node (`builtin-browser-verification-group.ts`), default-off, so browser verification runs only for tasks whose `enabledWorkflowSteps` includes `browser-verification`.
|
||||
- `builtin:coding` and `builtin:stepwise-coding` carry the `plan-review` optional-group node (`builtin-plan-review-group.ts`), default-on, before `parse-steps` so the plan can be reviewed before execution begins.
|
||||
- The `code-review` optional-group node (`builtin-code-review-group.ts`) is the inlined code-review gate. On default `builtin:coding`, this is the only final review surface before merge; disabling it lets the graph continue from implementation/verification to the merge gate. On `builtin:stepwise-coding`, it remains a post-foreach optional final review gate before the workflow's final review seam.
|
||||
- `builtin:coding` and `builtin:stepwise-coding` carry the `plan-review` optional-group node (`builtin-plan-review-group.ts`), default-on, before `parse-steps` so the plan can be reviewed before execution begins even when a task has not persisted explicit optional-step ids.
|
||||
- The `code-review` optional-group node (`builtin-code-review-group.ts`) is the inlined default-on code-review gate. On default `builtin:coding`, this is the only final review surface before merge; it is effective by default even when no explicit optional-step ids are stored. On `builtin:stepwise-coding`, it remains a post-foreach optional final review gate before the workflow's final review seam.
|
||||
- A workflow (for example compound-engineering) can add a **post-merge** optional-group node via the generic `postMergeOptionalGroupNode(...)` builder (`builtin-post-merge-group.ts`) — e.g. a `document` step that runs after merge.
|
||||
|
||||
Create-time optional-step controls appear in the quick-add action row and the **New Task** dialog inline quick buttons for the active workflow. They resolve the workflow's optional-group nodes (plus plugin-contributed palette templates, see [Plugin-Contributed Steps](#plugin-contributed-steps)) into toggleable rows. Workflows with no optional groups render no trigger, and the selected node ids are submitted through `enabledWorkflowSteps` when the task is created. Unknown or removed ids are skipped during resolution so stale selections never render blank controls or break workflow loading.
|
||||
@@ -462,7 +488,7 @@ There is no longer a Settings → Workflow Steps manager or step CRUD form. To a
|
||||
|
||||
- Set the node's `name`, `defaultOn`, and `phase` (`pre-merge` / `post-merge`).
|
||||
- Author the gate inside the node's `template` subgraph as `prompt`/`script`/`gate` nodes (single pass, no rework edges).
|
||||
- Tasks enable the gate by its node id via `enabledWorkflowSteps` (seeded from `defaultOn` and toggled at task creation).
|
||||
- Tasks persist operator-selected gate ids via `enabledWorkflowSteps`; runtime/display also includes gates whose nodes declare `defaultOn: true`, while edit controls show only the persisted selection.
|
||||
|
||||
Plugin palette templates (above) can be dropped in as a starting point instead of authoring a node from scratch.
|
||||
|
||||
@@ -479,7 +505,7 @@ If both are set, node execution uses that model; otherwise it falls back to defa
|
||||
|
||||
`optional-group` nodes support `defaultOn`.
|
||||
|
||||
When `defaultOn: true`, the gate is preselected automatically for newly created tasks (users can still deselect it).
|
||||
When `defaultOn: true`, the gate is effectively enabled for execution and in-progress display even if the task's persisted `enabledWorkflowSteps` array is empty. Creation and edit controls still use the persisted selection as their source of truth, so operators can distinguish an explicit stored toggle from a workflow-authored default.
|
||||
|
||||
## Workflow Step Revision Loop
|
||||
|
||||
@@ -727,7 +753,7 @@ Workflow graph execution is the task lifecycle runtime. `TaskExecutor` pins `wor
|
||||
|
||||
Default node dispatch:
|
||||
- `prompt` / `script` nodes with `config.seam` dispatch through workflow runtime primitives (`planning`, `execute`, `review`, `merge`, `schedule`, `step-execute`). The legacy `workflow-step` seam/primitive was removed in FN-7039 — quality gates are graph nodes now, and an IR node still declaring `config.seam: "workflow-step"` fails loudly rather than silently skipping.
|
||||
- `optional-group` nodes run their template subgraph once when enabled for the task (per `enabledWorkflowSteps`) and pass through when disabled; the executor records the outcome onto `task.workflowStepResults`
|
||||
- `optional-group` nodes run their template subgraph once when enabled for the task (per `enabledWorkflowSteps` plus workflow-authored `defaultOn`) and pass through when disabled; the executor records the outcome onto `task.workflowStepResults`
|
||||
- `step-review`, `parse-steps`, `code`, `notify`, and PR nodes use their dedicated primitive/dependency adapters
|
||||
- `gate` nodes evaluate context-key expectations or run configured executable checks
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ const docsReadmePath = resolve(workspaceRoot, "docs", "README.md");
|
||||
|
||||
const requiredDocs = [
|
||||
"docs/dev-server-modules.md",
|
||||
"docs/workflow-steps.md",
|
||||
"docs/workflow-editor.md",
|
||||
"docs/plugins/external-proof-point-runbook.md",
|
||||
"docs/research/pi-autoresearch-analysis.md",
|
||||
@@ -18,6 +19,9 @@ const requiredDocs = [
|
||||
FNXC:DocsIndex 2026-06-15-01:35:
|
||||
FN-6479 keeps CLI Printing Press design and research entries indexed only as Audit Reports, not duplicated in Plugins.
|
||||
This test guards the documentation-index dedup invariant while requiredDocs guards committed upstream artifacts that must remain discoverable.
|
||||
|
||||
FNXC:WorkflowDocs 2026-06-30-09:45:
|
||||
Workflow authors need both the runtime Workflow Steps guide and the visual Workflow Editor guide discoverable from the docs index, so the drift guard treats both as required index entries.
|
||||
*/
|
||||
|
||||
describe("docs README index", () => {
|
||||
|
||||
95
packages/cli/src/__tests__/workflow-docs-current.test.ts
Normal file
95
packages/cli/src/__tests__/workflow-docs-current.test.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
const workspaceRoot = resolve(import.meta.dirname, "../../../..");
|
||||
const doc = (relativePath: string) => readFileSync(resolve(workspaceRoot, relativePath), "utf8");
|
||||
|
||||
const workflowSteps = () => doc("docs/workflow-steps.md");
|
||||
const workflowEditor = () => doc("docs/workflow-editor.md");
|
||||
const dashboardGuide = () => doc("docs/dashboard-guide.md");
|
||||
const agents = () => doc("docs/agents.md");
|
||||
const cliReference = () => doc("docs/cli-reference.md");
|
||||
|
||||
/*
|
||||
FNXC:WorkflowDocs 2026-06-30-09:30:
|
||||
Workflow docs drift easily when implementation tasks add agent tools or board affordances. Keep this guard targeted to the public docs surfaces that define the current workflow behavior inventory.
|
||||
*/
|
||||
|
||||
describe("workflow documentation current behavior", () => {
|
||||
it("documents the current built-in workflow catalog and fail-closed runtime contract", () => {
|
||||
const content = workflowSteps();
|
||||
for (const id of [
|
||||
"builtin:coding",
|
||||
"builtin:legacy-coding",
|
||||
"builtin:quick-fix",
|
||||
"builtin:review-heavy",
|
||||
"builtin:marketing",
|
||||
"builtin:compound-engineering",
|
||||
"builtin:stepwise-coding",
|
||||
"builtin:design",
|
||||
"builtin:pr-workflow",
|
||||
"builtin:lead-generation",
|
||||
]) {
|
||||
expect(content).toContain(id);
|
||||
}
|
||||
expect(content).toContain("fails closed");
|
||||
expect(content).toContain("invalid-ir");
|
||||
expect(content).toContain("instead of silently falling back");
|
||||
expect(content).toContain("An explicit empty list");
|
||||
expect(content).toContain('`json-steps` `"depends": []`');
|
||||
expect(content).toContain("An absent annotation/key is different");
|
||||
expect(content).toContain("default-on gates still run and appear for in-progress tasks when a persisted selection array is empty");
|
||||
expect(content).toContain("edit controls show only the persisted selection");
|
||||
});
|
||||
|
||||
it("keeps workflow tool docs broader than list/select only", () => {
|
||||
const combined = [workflowSteps(), workflowEditor(), agents(), cliReference()].join("\n");
|
||||
for (const tool of [
|
||||
"fn_workflow_list",
|
||||
"fn_workflow_get",
|
||||
"fn_workflow_create",
|
||||
"fn_workflow_update",
|
||||
"fn_workflow_delete",
|
||||
"fn_workflow_settings",
|
||||
"fn_trait_list",
|
||||
"fn_workflow_select",
|
||||
"workflow_id",
|
||||
]) {
|
||||
expect(combined).toContain(tool);
|
||||
}
|
||||
expect(combined).toContain("explicitly requested");
|
||||
expect(combined).toContain("tasks they created");
|
||||
});
|
||||
|
||||
it("documents aggregate board selection, workflow badges, and create forwarding", () => {
|
||||
const content = dashboardGuide();
|
||||
expect(content).toContain("All workflows");
|
||||
expect(content).toContain("workflow name");
|
||||
expect(content).toContain("synthetic aggregate");
|
||||
expect(content).toContain("active workflow selection");
|
||||
expect(content).toContain("Hidden columns stay workflow-scoped in the aggregate");
|
||||
expect(content).toContain("it never submits the synthetic aggregate as a workflow id");
|
||||
});
|
||||
|
||||
it("documents current workflow settings ownership and extension task-id semantics", () => {
|
||||
const settings = doc("docs/settings-reference.md");
|
||||
expect(settings).toContain("Settings → Project Models → Default workflow model lanes");
|
||||
expect(settings).toContain("workflow editor Values tab");
|
||||
expect(settings).toContain("Built-in prompt overrides");
|
||||
expect(settings).toContain("not writable through");
|
||||
|
||||
const cli = cliReference();
|
||||
expect(cli).toContain("must pass `task_id`");
|
||||
expect(cli).toContain("treats `null` as deleting a stored override");
|
||||
expect(cli).toContain("broader-than-default column permission bindings require explicit policy-escalation confirmation");
|
||||
});
|
||||
|
||||
it("keeps removed workflow-step CRUD surfaces documented only as removed", () => {
|
||||
const content = workflowSteps();
|
||||
expect(content).toContain("There is no longer a Settings → Workflow Steps manager or step CRUD form");
|
||||
expect(content).toContain("The legacy workflow-step CRUD routes were removed");
|
||||
expect(content).not.toContain("create a workflow step in Settings");
|
||||
expect(content).not.toContain("Use `POST /api/workflow-steps`");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user