FN-7144: complete compound engineering workflow audit
Adds the missing CE document-review stage and tightens workflow docs, compilation, and tests. - Add optional advisory ce-doc-review support to the compound engineering built-in workflow. - Register and document the compound-engineering ce-doc-review skill for markdown CE plan review. - Preserve optional-group workflow semantics when compiling legacy steps and cover the CE workflow seams with tests. - Update operator docs and add a published package changeset. Files changed: .changeset/fn-7144-compound-engineering-audit.md | 7 +++ docs/workflow-editor.md | 2 +- docs/workflow-steps.md | 4 +- .../core/src/__tests__/builtin-workflows.test.ts | 29 +++++++++- packages/core/src/builtin-workflows.ts | 62 ++++++++++++++++++++-- packages/core/src/workflow-compiler.ts | 3 +- .../__tests__/ce-workflow-step-conventions.test.ts | 8 +++ .../src/__tests__/interpreter-merge-seam.test.ts | 3 +- .../src/__tests__/manifest.test.ts | 1 + .../src/skills.ts | 13 +++++ .../src/skills/ce-doc-review/SKILL.md | 54 +++++++++++++++++++ 11 files changed, 175 insertions(+), 11 deletions(-) Fusion-Task-Id: FN-7144 Fusion-Task-Lineage: bedbfad4-d6e8-489e-a555-803991a1ad54 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
7
.changeset/fn-7144-compound-engineering-audit.md
Normal file
7
.changeset/fn-7144-compound-engineering-audit.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@runfusion/fusion": minor
|
||||
---
|
||||
|
||||
summary: Add optional Compound Engineering document review to the built-in CE workflow.
|
||||
category: feature
|
||||
dev: Bundles ce-doc-review and documents autoMerge-off CE PR routing before Fusion's merge seam.
|
||||
@@ -134,7 +134,7 @@ Fusion ships built-in workflows as read-only references:
|
||||
- `builtin:coding` — the default coding lifecycle and fallback for tasks without a workflow selection.
|
||||
- `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 workflow for Compound Engineering skill lanes.
|
||||
- `builtin:compound-engineering` — a plugin-gated Compound Engineering pipeline: `/ce-plan` writes the CE plan doc, optional `ce-doc-review` can pressure-test markdown plans, `/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` — a graph variant that models per-step parse, execute, review, and rework structure.
|
||||
- `builtin:design` — a UI-heavy work path with a gated design/UX review before standard review and merge.
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ Decision-only or investigation tasks can also declare `noCommitsExpected` / `**N
|
||||
| Quick fix | `builtin:quick-fix` | Short path for trivial or no-commit/decision work; omits the standard review stage. |
|
||||
| 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 workflow that invokes Compound Engineering skills for planning, work, review, PR/feedback, and learnings capture. |
|
||||
| Compound engineering | `builtin:compound-engineering` | Plugin-gated CE workflow that invokes `/ce-plan`, optional advisory `ce-doc-review`, `/ce-work`, merge-blocking `/ce-code-review`, CE PR/feedback skills, Fusion merge, and learnings capture. |
|
||||
| Stepwise coding | `builtin:stepwise-coding` | Graph-executor workflow that models per-step parse/execute/review/rework explicitly. |
|
||||
| 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. |
|
||||
@@ -140,6 +140,8 @@ The default built-in catalog entry `builtin:coding` is backed by the canonical `
|
||||
|
||||
`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.
|
||||
|
||||
`builtin:compound-engineering` is plugin-gated by `fusion-plugin-compound-engineering`. Its graph runs `/ce-plan` first and expects the CE plan document artifact under `docs/plans/`; an optional default-off `ce-doc-review` advisory step can then review markdown plans without blocking merge. Implementation runs `/ce-work`, merge-blocking code review runs `/ce-code-review`, and the PR lane runs `/ce-commit-push-pr` then `/ce-resolve-pr-feedback` before Fusion's native merge seam. When project `autoMerge` is off, that merge seam no-ops into manual review instead of forcing an unattended board merge, so the CE-created pull request remains the human merge path.
|
||||
|
||||
During triage/planning sessions, agents can call `fn_workflow_list` to discover available built-in and custom workflows and read their descriptions before routing work. They can call `fn_workflow_select` only when the user explicitly requested a workflow or when selecting a workflow for a task they created, and they can pass `workflow_id` when creating child tasks with `fn_task_create`; decision-only or investigation tasks can also set `noCommitsExpected` / `**No commits expected:** true` when no code changes are expected. The built-in triage thresholds, decision-only verb list, and default routing IDs are workflow-native typed settings resolved from the selected workflow.
|
||||
|
||||
#### Runtime invariant criterion
|
||||
|
||||
@@ -407,10 +407,12 @@ describe("built-in workflows", () => {
|
||||
const ce = getBuiltinWorkflow("builtin:compound-engineering")!;
|
||||
const steps = compileWorkflowToSteps(ce.ir);
|
||||
// plan + execute (ce-work) + code-review (pre-merge) + commit-pr +
|
||||
// resolve-feedback + document (post-merge) — merge seams are skipped.
|
||||
// resolve-feedback + document (post-merge) — merge seams and graph-native
|
||||
// optional-groups are skipped by the legacy step compiler.
|
||||
expect(steps.length).toBeGreaterThanOrEqual(6);
|
||||
expect(steps.some((s) => s.name === "Plan")).toBe(true);
|
||||
expect(steps.filter((s) => s.skillName === "compound-engineering:ce-code-review")).toHaveLength(1);
|
||||
expect(steps.some((s) => s.name === "CE Doc Review")).toBe(false);
|
||||
expect(steps.some((s) => s.name === "Review" && !s.skillName)).toBe(false);
|
||||
});
|
||||
|
||||
@@ -443,6 +445,8 @@ describe("built-in workflows", () => {
|
||||
for (const [nodeId, slashCommand] of expectedPrompts) {
|
||||
expect(String(byId(nodeId)?.config?.prompt ?? "")).toContain(slashCommand);
|
||||
}
|
||||
const docReviewTemplate = byId("ce-doc-review")?.config?.template as { nodes?: Array<{ config?: Record<string, unknown> }> } | undefined;
|
||||
expect(String(docReviewTemplate?.nodes?.[0]?.config?.prompt ?? "")).toContain("/ce-doc-review");
|
||||
expect(String(byId("merge")?.config?.prompt ?? "")).not.toContain("/ce-");
|
||||
});
|
||||
|
||||
@@ -452,8 +456,11 @@ describe("built-in workflows", () => {
|
||||
expect(byId("commit-pr")?.config?.skillName).toBe("compound-engineering:ce-commit-push-pr");
|
||||
expect(byId("commit-pr")?.config?.toolMode).toBe("coding");
|
||||
expect(byId("resolve-feedback")?.config?.skillName).toBe("compound-engineering:ce-resolve-pr-feedback");
|
||||
expect(String(byId("commit-pr")?.config?.prompt ?? "")).toContain("When project autoMerge is off");
|
||||
expect(String(byId("commit-pr")?.config?.prompt ?? "")).toContain("do not perform the Fusion board-state merge");
|
||||
// KTD-6: the Fusion board-merge seam is preserved (CE prepares the PR, Fusion
|
||||
// owns the merge transition).
|
||||
// owns the merge transition). With autoMerge:false, the runtime seam no-ops
|
||||
// into manual review; the CE PR skills are still ordered before this seam.
|
||||
expect(byId("merge")?.config?.seam).toBe("merge");
|
||||
// Ordering: commit-pr → resolve-feedback → merge → document.
|
||||
const ids = ce.ir.nodes.map((n) => n.id);
|
||||
@@ -468,6 +475,7 @@ describe("built-in workflows", () => {
|
||||
const authoredNodeIds = ce.ir.nodes.filter((node) => node.id !== "start" && node.id !== "end").map((node) => node.id);
|
||||
expect(authoredNodeIds).toEqual([
|
||||
"plan",
|
||||
"ce-doc-review",
|
||||
"execute",
|
||||
"code-review",
|
||||
"commit-pr",
|
||||
@@ -477,6 +485,21 @@ describe("built-in workflows", () => {
|
||||
]);
|
||||
expect(ce.ir.nodes.some((node) => node.config?.seam === "review")).toBe(false);
|
||||
|
||||
const docReview = byId("ce-doc-review");
|
||||
expect(docReview?.kind).toBe("optional-group");
|
||||
expect(docReview?.config?.name).toBe("CE Doc Review");
|
||||
expect(docReview?.config?.defaultOn).toBe(false);
|
||||
const docReviewTemplate = docReview?.config?.template as { nodes?: Array<{ id: string; kind: string; config?: Record<string, unknown> }> } | undefined;
|
||||
expect(docReviewTemplate?.nodes?.[0]).toMatchObject({
|
||||
id: "ce-doc-review-step",
|
||||
kind: "prompt",
|
||||
config: {
|
||||
skillName: "compound-engineering:ce-doc-review",
|
||||
toolMode: "coding",
|
||||
gateMode: "advisory",
|
||||
},
|
||||
});
|
||||
|
||||
const codeReview = byId("code-review");
|
||||
expect(codeReview?.kind).toBe("gate");
|
||||
expect(codeReview?.config?.name).toBe("Code Review");
|
||||
@@ -489,6 +512,8 @@ describe("built-in workflows", () => {
|
||||
for (let i = 1; i < ce.ir.nodes.length; i += 1) {
|
||||
expect(layout[ce.ir.nodes[i].id].x - layout[ce.ir.nodes[i - 1].id].x).toBe(170);
|
||||
}
|
||||
expect(ce.ir.edges.some((edge) => edge.from === "plan" && edge.to === "ce-doc-review")).toBe(true);
|
||||
expect(ce.ir.edges.some((edge) => edge.from === "ce-doc-review" && edge.to === "execute")).toBe(true);
|
||||
expect(ce.ir.edges.some((edge) => edge.from === "execute" && edge.to === "code-review")).toBe(true);
|
||||
expect(ce.ir.edges.some((edge) => edge.from === "code-review" && edge.to === "commit-pr")).toBe(true);
|
||||
});
|
||||
|
||||
@@ -6,8 +6,8 @@ import { BUILTIN_STEPWISE_CODING_WORKFLOW_IR } from "./builtin-stepwise-coding-w
|
||||
import { BUILTIN_WORKFLOW_SETTINGS } from "./builtin-workflow-settings.js";
|
||||
import { builtinPromptConfig } from "./builtin-workflow-prompts.js";
|
||||
import type { WorkflowDefinition } from "./workflow-definition-types.js";
|
||||
import type { WorkflowIr } from "./workflow-ir-types.js";
|
||||
import { parseWorkflowIr } from "./workflow-ir.js";
|
||||
import type { WorkflowIr, WorkflowIrNode } from "./workflow-ir-types.js";
|
||||
import { DEFAULT_WORKFLOW_COLUMN_IDS, parseWorkflowIr } from "./workflow-ir.js";
|
||||
|
||||
/** Prefix marking a workflow as a read-only built-in template. */
|
||||
export const BUILTIN_WORKFLOW_ID_PREFIX = "builtin:";
|
||||
@@ -51,6 +51,16 @@ interface BuiltinSpec {
|
||||
nodes: Array<{ id: string; kind: WorkflowIr["nodes"][number]["kind"]; config?: Record<string, unknown> }>;
|
||||
}
|
||||
|
||||
const V1_LINEAR_NODE_KINDS = new Set<WorkflowIrNode["kind"]>(["start", "prompt", "script", "gate", "end"]);
|
||||
|
||||
function defaultColumnForLinearNode(node: WorkflowIrNode): string {
|
||||
const seam = node.config?.seam;
|
||||
if (seam === "execute") return "in-progress";
|
||||
if (seam === "review") return "in-review";
|
||||
if (seam === "merge") return "in-review";
|
||||
return "todo";
|
||||
}
|
||||
|
||||
/** Build a linear IR (start → nodes… → end) with simple x-spaced layout. */
|
||||
function linear(spec: BuiltinSpec): WorkflowDefinition {
|
||||
const nodes: WorkflowIr["nodes"] = [
|
||||
@@ -72,7 +82,16 @@ function linear(spec: BuiltinSpec): WorkflowDefinition {
|
||||
nodes.forEach((node, i) => {
|
||||
layout[node.id] = { x: 60 + i * 170, y: 160 };
|
||||
});
|
||||
const ir = parseWorkflowIr({ version: "v1", name: spec.name, nodes, edges });
|
||||
const hasV2OnlyNode = nodes.some((node) => !V1_LINEAR_NODE_KINDS.has(node.kind));
|
||||
const ir = hasV2OnlyNode
|
||||
? parseWorkflowIr({
|
||||
version: "v2",
|
||||
name: spec.name,
|
||||
columns: DEFAULT_WORKFLOW_COLUMN_IDS.map((id) => ({ id, name: id, traits: [] })),
|
||||
nodes: nodes.map((node) => (node.column ? node : { ...node, column: defaultColumnForLinearNode(node) })),
|
||||
edges,
|
||||
})
|
||||
: parseWorkflowIr({ version: "v1", name: spec.name, nodes, edges });
|
||||
// Attach the moved-key settings catalog (U1/U3, R4) so every built-in workflow
|
||||
// carries its declarations through the resolver path (resolveWorkflowIrById →
|
||||
// resolveEffectiveSettings). v1 graphs upgrade to v2 on parse, so the parsed IR
|
||||
@@ -195,7 +214,36 @@ export const BUILTIN_WORKFLOWS: WorkflowDefinition[] = [
|
||||
// fn_spawn_agent (registered only for coding-mode steps). It is not
|
||||
// meant to write — see the accepted write-capability posture (Risk-1).
|
||||
toolMode: "coding",
|
||||
prompt: "Run /ce-plan to produce a short implementation plan for this task before any code is written.",
|
||||
prompt: "Run /ce-plan to produce the CE plan document artifact for this task under docs/plans/ before any code is written.",
|
||||
},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* FNXC:Workflows 2026-06-27-00:00:
|
||||
* FN-7144 requires compound-engineering to expose the markdown-only ce-doc-review pass as an optional non-blocking stage after planning. This preserves the WHAT/HOW boundary: ce-plan writes the HOW plan doc, ce-doc-review checks coherence and scope alignment, and merge-blocking code review remains the later ce-code-review gate.
|
||||
*/
|
||||
id: "ce-doc-review",
|
||||
kind: "optional-group",
|
||||
config: {
|
||||
name: "CE Doc Review",
|
||||
defaultOn: false,
|
||||
template: {
|
||||
nodes: [
|
||||
{
|
||||
id: "ce-doc-review-step",
|
||||
kind: "prompt",
|
||||
config: {
|
||||
name: "CE Doc Review",
|
||||
executor: "skill",
|
||||
skillName: "compound-engineering:ce-doc-review",
|
||||
toolMode: "coding",
|
||||
gateMode: "advisory",
|
||||
prompt: "Run /ce-doc-review in headless advisory mode against the markdown CE plan document produced by /ce-plan (normally the latest docs/plans artifact). Apply only safe markdown fixes; if no markdown CE plan is available, report the skip as notes without blocking execution.",
|
||||
},
|
||||
},
|
||||
],
|
||||
edges: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -246,8 +294,12 @@ export const BUILTIN_WORKFLOWS: WorkflowDefinition[] = [
|
||||
// push / PR creation; it does NOT perform the board-state merge — that
|
||||
// stays with Fusion's merge seam below (workflow-owned merge), so the
|
||||
// two never race the same branch state.
|
||||
/*
|
||||
* FNXC:Workflows 2026-06-27-00:00:
|
||||
* FN-7144 confirms the autoMerge-off CE route: ce-commit-push-pr and ce-resolve-pr-feedback prepare the human PR flow, while the later Fusion merge seam no-ops into manual review instead of forcing an unattended board merge.
|
||||
*/
|
||||
toolMode: "coding",
|
||||
prompt: "Run /ce-commit-push-pr to commit the work in logical commits, push the branch, and open a pull request with a value-first description.",
|
||||
prompt: "Run /ce-commit-push-pr to commit the work in logical commits, push the branch, and open a pull request with a value-first description. When project autoMerge is off, this PR is the human merge/review path; do not perform the Fusion board-state merge here.",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -312,7 +312,8 @@ export function compileWorkflowToSteps(ir: WorkflowIr): WorkflowStepInput[] {
|
||||
|
||||
if (seam === "merge") {
|
||||
phase = "post-merge";
|
||||
} else if (!seam && node.kind !== "start" && node.kind !== "end") {
|
||||
} else if (!seam && node.kind !== "start" && node.kind !== "end" && node.kind !== "optional-group") {
|
||||
// FNXC:WorkflowOptionalGroup 2026-06-27-00:00: Optional-group nodes are graph-native enable containers keyed by node id; compiling them into legacy WorkflowStepInput rows would create an empty duplicate step and bypass the per-task toggle semantics.
|
||||
steps.push(nodeToStepInput(node, phase));
|
||||
}
|
||||
|
||||
|
||||
@@ -148,6 +148,7 @@ describe("U1: normalized CE skill request-form resolution", () => {
|
||||
mkdirSync(projectRootDir, { recursive: true });
|
||||
mkdirSync(agentDir, { recursive: true });
|
||||
materialize("ce-work");
|
||||
materialize("ce-doc-review");
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -179,6 +180,13 @@ describe("U1: normalized CE skill request-form resolution", () => {
|
||||
expect(resolved.filter((n) => n === "ce-work")).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("optional ce-doc-review resolves from bare and namespaced workflow-step requests", () => {
|
||||
expect(resolveFor(["ce-doc-review"])).toContain("ce-doc-review");
|
||||
expect(resolveFor(["compound-engineering:ce-doc-review"])).toContain("ce-doc-review");
|
||||
const resolved = resolveFor(["compound-engineering:ce-doc-review", "ce-doc-review"]);
|
||||
expect(resolved.filter((n) => n === "ce-doc-review")).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("without the install dir on the discovery path, the request does NOT resolve", () => {
|
||||
// Repoint discovery away from the install root: name alone is insufficient
|
||||
// for every normalized request form.
|
||||
|
||||
@@ -67,12 +67,13 @@ describe("interpreter merge seam", () => {
|
||||
};
|
||||
}
|
||||
|
||||
it("returns merged:false and does NOT force a merge when autoMerge is off", async () => {
|
||||
it("returns merged:false/noOp and does NOT force a merge when autoMerge is off", async () => {
|
||||
const onMerge = vi.fn();
|
||||
const fakeEngine = fakeEngineWith({ autoEligible: false, onMerge });
|
||||
const result = await (ProjectEngine.prototype as any).requestInterpreterMerge.call(fakeEngine, "FN-3");
|
||||
|
||||
expect(result.merged).toBe(false);
|
||||
expect(result.noOp).toBe(true);
|
||||
expect(onMerge).not.toHaveBeenCalled(); // the human "merge now" bypass is never invoked
|
||||
});
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ describe("compound engineering plugin manifest", () => {
|
||||
"ce-brainstorm",
|
||||
"ce-plan",
|
||||
"ce-work",
|
||||
"ce-doc-review",
|
||||
"ce-code-review",
|
||||
"ce-debug",
|
||||
"ce-compound",
|
||||
|
||||
@@ -58,6 +58,19 @@ export const COMPOUND_ENGINEERING_SKILLS: PluginSkillContribution[] = [
|
||||
enabled: true,
|
||||
triggerPatterns: ["do the work", "implement", "execute the plan", "finish this feature"],
|
||||
},
|
||||
{
|
||||
/*
|
||||
* FNXC:CompoundEngineering 2026-06-27-00:00:
|
||||
* FN-7144 bundles ce-doc-review because ce-plan and ce-brainstorm invoke it as a named markdown document-review skill, and the built-in CE workflow now exposes it as an optional advisory stage after planning.
|
||||
*/
|
||||
skillId: "ce-doc-review",
|
||||
name: "ce-doc-review",
|
||||
description:
|
||||
"Review CE markdown plan documents for coherence, feasibility, scope alignment, and safe markdown-only fixes.",
|
||||
skillFiles: ["skills/ce-doc-review/SKILL.md"],
|
||||
enabled: true,
|
||||
triggerPatterns: ["doc review", "document review", "review the plan", "pressure-test the requirements"],
|
||||
},
|
||||
{
|
||||
skillId: "ce-code-review",
|
||||
name: "ce-code-review",
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
name: ce-doc-review
|
||||
description: "Review Compound Engineering markdown plan documents for coherence, feasibility, scope alignment, and safe markdown-only fixes. Use headless mode for automated plan handoff review."
|
||||
argument-hint: "[mode:headless] <markdown-plan-path>"
|
||||
---
|
||||
|
||||
# CE Document Review
|
||||
|
||||
Review a Compound Engineering markdown plan or requirements document. This skill is intentionally markdown-only: do not mutate HTML artifacts. If the target is HTML, missing, or not a CE plan/requirements document, report a non-blocking skip with notes.
|
||||
|
||||
## Modes
|
||||
|
||||
- `mode:headless <path>`: run an automated advisory pass, apply only safe markdown fixes, and return a concise review envelope.
|
||||
- `<path>` without `mode:headless`: run the same review, but include actionable findings clearly enough for an interactive caller to decide what to apply.
|
||||
|
||||
## Review boundary
|
||||
|
||||
`ce-brainstorm` owns WHAT: product requirements, actors, flows, acceptance examples, and scope boundaries.
|
||||
|
||||
`ce-plan` owns HOW: technical decisions, implementation units, dependencies, risks, verification contract, and handoff posture.
|
||||
|
||||
`ce-doc-review` checks whether the document preserves that boundary and is usable by downstream `ce-work`, PR reviewers, and humans. Do not turn document review into code review; `ce-code-review` owns implementation diff review later in the pipeline.
|
||||
|
||||
## Procedure
|
||||
|
||||
1. Resolve the target path from the arguments. Prefer an explicit path. If no path is provided, inspect `docs/plans/` for the most recent markdown plan-like artifact and use that; if none exists, skip non-blockingly.
|
||||
2. Confirm the target is markdown (`.md`). If it is not markdown, skip and explain that HTML document review is not supported yet.
|
||||
3. Read the document enough to evaluate structure and consistency. For long documents, scan headings first, then read the Goal Capsule/Product Contract/Plan/Implementation Units/Verification/Definition of Done sections as present.
|
||||
4. Check for:
|
||||
- Product scope drift: requirements or Product Contract rewritten without a clear preservation note.
|
||||
- HOW gaps: implementation units lacking files, dependencies, risks, or verification scenarios.
|
||||
- Coherence gaps: contradictory decisions, stale handoff instructions, duplicated or inconsistent artifact readiness metadata.
|
||||
- Feasibility gaps: sequencing that cannot work, missing prerequisite decisions, or verification that cannot prove the stated Definition of Done.
|
||||
- Markdown-only hygiene that is safe to fix automatically: broken heading levels, obvious duplicate blank lines, malformed checklists, or typo-level wording that does not change meaning.
|
||||
5. In headless mode, apply only `safe_auto` fixes directly to the markdown file. Do not apply changes that alter product scope, technical decisions, acceptance criteria, or verification obligations; report those as findings.
|
||||
6. If findings remain, classify each as:
|
||||
- `proposed_fix`: a safe but non-trivial improvement the user may accept.
|
||||
- `decision`: a scope/technical judgment that needs human or planner choice.
|
||||
- `fyi`: useful observation that does not need routing.
|
||||
7. End with a concise summary and exactly one trailing JSON object on the final line.
|
||||
|
||||
## Output contract
|
||||
|
||||
Use this shape for the final line:
|
||||
|
||||
```json
|
||||
{"verdict":"APPROVE|APPROVE_WITH_NOTES|REVISE","fixes_applied":0,"proposed_fixes_count":0,"decisions_count":0,"fyi_count":0,"notes":"short summary"}
|
||||
```
|
||||
|
||||
- `APPROVE`: no actionable issues remain.
|
||||
- `APPROVE_WITH_NOTES`: non-blocking observations or skipped review; this is the normal result for optional workflow use.
|
||||
- `REVISE`: only for severe document issues that make downstream work unsafe or impossible. In the Fusion built-in workflow this skill is advisory/non-blocking, but the verdict still helps humans see severity.
|
||||
|
||||
Do not wrap the final JSON in markdown fences.
|
||||
Reference in New Issue
Block a user