test(workflows): cover coding optional gates
This commit is contained in:
@@ -170,7 +170,7 @@ Fusion ships built-in workflows as read-only references:
|
||||
- `builtin:quick-fix` — a short path for trivial or no-commit/decision work.
|
||||
- `builtin:review-heavy` — a standard execute/review/merge path with an additional gated security review.
|
||||
- `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.
|
||||
- `builtin:stepwise-coding` — Coding (per-step review): a graph variant with optional Plan Review before execution and per-step parse, execute, review, and rework structure.
|
||||
- `builtin:stepwise-coding` — Coding (per-step review): a graph variant with optional Plan Review before execution, per-step parse/execute/review/rework, and optional final Code Review before the final review/merge region.
|
||||
- `builtin:design` — a UI-heavy work path with a gated design/UX review before standard review and merge.
|
||||
|
||||
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.
|
||||
|
||||
@@ -50,7 +50,7 @@ Decision-only or investigation tasks can also declare `noCommitsExpected` / `**N
|
||||
| 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. |
|
||||
| Coding (per-step review) | `builtin:stepwise-coding` | Graph-executor workflow with default-on Plan Review before execution and per-step parse/execute/review/rework. |
|
||||
| Coding (per-step review) | `builtin:stepwise-coding` | Graph-executor workflow with default-on Plan Review before execution, per-step parse/execute/review/rework, and an optional final Code Review gate. |
|
||||
| Design | `builtin:design` | UI-heavy work path that implements, persists a user-facing design preview task document, runs a gated design/UX review, then performs the standard review and merge. |
|
||||
| PR lifecycle | `builtin:pr-workflow` | Reusable PR lifecycle graph fragment (create PR → await review → respond → gate → merge); it is a fragment, not directly selectable as a task workflow. |
|
||||
| Lead generation | `builtin:lead-generation` | Selectable business workflow for sourcing, qualifying, enriching, and contacting leads with custom lead fields, stage columns, and reviewable enrichment/outreach task documents; requires the workflow graph executor for custom board columns. |
|
||||
@@ -184,7 +184,7 @@ The default built-in catalog entry `builtin:coding` is backed by a Stepwise-deri
|
||||
|
||||
`builtin:legacy-coding` is backed by the original monolithic `BUILTIN_CODING_WORKFLOW_IR`: `planning` → `execute` → optional quality gates → `review` → merge region.
|
||||
|
||||
`builtin:stepwise-coding` displays as Coding (per-step review). It is backed by `BUILTIN_STEPWISE_CODING_WORKFLOW_IR`; it keeps the same lifecycle columns/traits while adding the default-on optional Plan Review before `parse-steps` and modeling per-step parse/execute/review/rework as authored graph structure.
|
||||
`builtin:stepwise-coding` displays as Coding (per-step review). It is backed by `BUILTIN_STEPWISE_CODING_WORKFLOW_IR`; it keeps the same lifecycle columns/traits while adding the default-on optional Plan Review before `parse-steps`, modeling per-step parse/execute/review/rework as authored graph structure, and retaining the post-foreach optional Code Review gate before its final review/merge region.
|
||||
|
||||
`builtin:marketing` is a non-coding content workflow with marketing-specific columns (`ideation`, `backlog`, `drafting`, `editorial-review`, `published`, `archived`) and prompt seams for content brief, draft, and editorial review. Its draft stage saves the primary content deliverable as a task document for human review, while the workflow uses the same lifecycle traits (`intake`, `hold`, `wip`, `merge-blocker`, `human-review`, `complete`, `archived`) and the same merge-gate/branch-group/merge-attempt primitive region as coding workflows, so scheduler, capacity, review blocking, and merge orchestration behavior remain standard.
|
||||
|
||||
@@ -346,7 +346,7 @@ 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.
|
||||
- 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.
|
||||
- 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.
|
||||
|
||||
@@ -86,6 +86,11 @@ describe("built-in workflows", () => {
|
||||
expect(ir.nodes.some((n) => n.id === "plan-review" && n.kind === "optional-group")).toBe(true);
|
||||
expect(ir.edges.some((edge) => edge.from === "plan" && edge.to === "plan-review")).toBe(true);
|
||||
expect(ir.edges.some((edge) => edge.from === "plan-review" && edge.to === "parse")).toBe(true);
|
||||
expect(ir.nodes.some((n) => n.id === "browser-verification" && n.kind === "optional-group")).toBe(true);
|
||||
expect(ir.nodes.some((n) => n.id === "code-review" && n.kind === "optional-group")).toBe(true);
|
||||
expect(ir.edges.some((edge) => edge.from === "steps" && edge.to === "browser-verification" && edge.condition === "success")).toBe(true);
|
||||
expect(ir.edges.some((edge) => edge.from === "browser-verification" && edge.to === "code-review" && edge.condition === "success")).toBe(true);
|
||||
expect(ir.edges.some((edge) => edge.from === "code-review" && edge.to === "review" && edge.condition === "success")).toBe(true);
|
||||
const foreach = ir.nodes.find((n) => n.kind === "foreach");
|
||||
expect(foreach).toBeDefined();
|
||||
const template = (
|
||||
@@ -130,6 +135,15 @@ describe("built-in workflows", () => {
|
||||
expect(template.edges.some((edge) => edge.kind === "rework")).toBe(false);
|
||||
});
|
||||
|
||||
it("all coding built-ins expose Browser Verification as an optional group", () => {
|
||||
for (const workflowId of ["builtin:coding", "builtin:legacy-coding", "builtin:stepwise-coding"]) {
|
||||
const workflow = getBuiltinWorkflow(workflowId)!;
|
||||
const browserVerification = workflow.ir.nodes.find((node) => node.id === "browser-verification");
|
||||
expect(browserVerification?.kind, workflowId).toBe("optional-group");
|
||||
expect(browserVerification?.config?.defaultOn, workflowId).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
it("includes the PR lifecycle built-in wiring the PR nodes end to end (U9)", () => {
|
||||
const pr = getBuiltinWorkflow("builtin:pr-workflow");
|
||||
expect(pr).toBeDefined();
|
||||
|
||||
@@ -287,7 +287,7 @@ describe("WorkflowGraphTaskRunner (CU-U2)", () => {
|
||||
const calls: string[] = [];
|
||||
const getWorkflowDefinition = vi.fn(async () => undefined);
|
||||
const store: WorkflowGraphRunnerStore = {
|
||||
getTaskWorkflowSelection: () => ({ workflowId: "builtin:coding", stepIds: [] }),
|
||||
getTaskWorkflowSelection: () => ({ workflowId: "builtin:legacy-coding", stepIds: [] }),
|
||||
getWorkflowDefinition,
|
||||
};
|
||||
const runner = new WorkflowGraphTaskRunner({
|
||||
@@ -299,8 +299,10 @@ describe("WorkflowGraphTaskRunner (CU-U2)", () => {
|
||||
const result = await runner.run(task, flagOn);
|
||||
|
||||
expect(result.disposition).toBe("completed");
|
||||
// U6: the coding built-in no longer carries a `workflow-step` seam; its
|
||||
// pre-merge browser-verification optional-group is default-OFF and bypassed.
|
||||
// FNXC:WorkflowBuiltins 2026-06-28-23:29:
|
||||
// Use Legacy coding here because default Coding is now stepwise and requires
|
||||
// parse/foreach task-step context. This still proves built-in registry fallback
|
||||
// works when the store intentionally does not return a persisted definition.
|
||||
expect(calls).toEqual(["planning", "execute", "review", "merge"]);
|
||||
expect(result.reason).toBeUndefined();
|
||||
expect(getWorkflowDefinition).not.toHaveBeenCalled();
|
||||
|
||||
Reference in New Issue
Block a user