From 68f5153e17082c1ab83c7735c569a606d4a4a97f Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Sat, 4 Jul 2026 11:26:31 -0700 Subject: [PATCH] FN-7508: add planner oversight workflow setting Declare a workflow-native planner oversight level with release notes and docs. - Add the plannerOversightLevel enum setting with Off, Observe, Steer, and Autonomous recovery values. - Export the oversight settings catalog and include it in built-in workflow defaults. - Cover consistency, resolver defaults, and catalog membership with core tests. - Document the workflow setting and add the published package changeset. Files changed: .../fn-7508-planner-oversight-level-setting.md | 7 +++++ docs/settings-reference.md | 8 ++++-- docs/workflow-steps.md | 17 +++++++----- .../builtin-workflow-settings-triage.test.ts | 32 ++++++++++++++++++++++ .../src/__tests__/settings-consistency.test.ts | 4 ++- .../__tests__/workflow-settings-resolver.test.ts | 1 + packages/core/src/builtin-workflow-settings.ts | 26 ++++++++++++++++++ packages/core/src/index.ts | 1 + 8 files changed, 86 insertions(+), 10 deletions(-) Fusion-Task-Id: FN-7508 Fusion-Task-Lineage: 1adc7ce6-9e0e-475e-956a-ee36edae0cdc Co-authored-by: Fusion (runfusion.ai) --- ...fn-7508-planner-oversight-level-setting.md | 7 ++++ docs/settings-reference.md | 8 +++-- docs/workflow-steps.md | 17 ++++++---- .../builtin-workflow-settings-triage.test.ts | 32 +++++++++++++++++++ .../__tests__/settings-consistency.test.ts | 4 ++- .../workflow-settings-resolver.test.ts | 1 + .../core/src/builtin-workflow-settings.ts | 26 +++++++++++++++ packages/core/src/index.ts | 1 + 8 files changed, 86 insertions(+), 10 deletions(-) create mode 100644 .changeset/fn-7508-planner-oversight-level-setting.md diff --git a/.changeset/fn-7508-planner-oversight-level-setting.md b/.changeset/fn-7508-planner-oversight-level-setting.md new file mode 100644 index 0000000000..8fb77762f5 --- /dev/null +++ b/.changeset/fn-7508-planner-oversight-level-setting.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": minor +--- + +summary: Add a per-workflow planner oversight level setting (Off, Observe, Steer, Autonomous recovery). +category: feature +dev: New workflow setting `plannerOversightLevel` declared in BUILTIN_OVERSIGHT_SETTINGS; default `autonomous`. Per-task override and engine behavior land in follow-up tasks. diff --git a/docs/settings-reference.md b/docs/settings-reference.md index 7af6b5a8fe..2da00161f8 100644 --- a/docs/settings-reference.md +++ b/docs/settings-reference.md @@ -280,8 +280,10 @@ Actions. It has two tabs: controls. Built-in Plan Review/spec and Code Review revision caps also live here: leave `planReviewMaxRevisions` or `codeReviewMaxRevisions` empty for unbounded automatic revisions, enter a non-negative integer to cap attempts, or enter `0` - to disable automatic revision for that path. Edits batch and commit through a - single **Save** in the Values tab. + to disable automatic revision for that path. `plannerOversightLevel` is the + workflow-native planner oversight mode and accepts `off`, `observe`, `steer`, + or `autonomous` (default). Edits batch and commit through a single **Save** in + the Values tab. **How values resolve.** The engine resolves *effective settings* per task as `stored value ?? declaration default`. The task-detail Workflow, Chat, and Agent @@ -320,6 +322,7 @@ These groups moved out of project settings and into workflow settings (built-in |---|---| | **Step execution** | `workflowStepTimeoutMs`, `runStepsInNewSessions`, `maxParallelSteps`, `workflowStepScopeEnforcement`, `strictScopeEnforcement`, `verificationFixRetries`, `maxPostReviewFixes`, `buildRetryCount` | | **Review / approval** | Workflow values: `requirePrApproval`, `requirePlanApproval`, `reviewHandoffPolicy`, `maxReviewerContextRetries`, `maxReviewerFallbackRetries`, `planReviewMaxRevisions`, `codeReviewMaxRevisions`; project override: `planApprovalMode` | +| **Planner oversight** | `plannerOversightLevel` (workflow-native; values: `off`, `observe`, `steer`, `autonomous`) | | **Per-phase model lanes** | `executionProvider`/`executionModelId`, `planningProvider`/`planningModelId` (+ fallbacks), `validatorProvider`/`validatorModelId` (+ fallbacks) | ### Workflow-native triage policy settings @@ -353,6 +356,7 @@ The built-in workflows also declare triage/spec policy settings that were **not* | `autoApproveSpec` | `false` | Legacy compatibility setting. Workflow Plan Review now owns optional pre-execution AI plan approval. | | `planReviewMaxRevisions` | unset | Workflow-native Plan Review/spec revision cap. Unset/empty means unbounded automatic replans; a non-negative integer caps attempts; `0` disables automatic Plan Review revision. | | `codeReviewMaxRevisions` | unset | Workflow-native Code Review remediation cap. Unset/empty means unbounded automatic code-fix passes; a non-negative integer caps attempts; `0` disables automatic Code Review remediation. | +| `plannerOversightLevel` | `autonomous` | Workflow-native planner oversight mode. `off` disables oversight; `observe` watches only; `steer` injects guidance or suggests revisions; `autonomous` enables bounded retry and targeted-fix recovery. Per-task overrides and engine behavior are follow-up work. | When `triageProactiveSubtaskSplittingEnabled` is `true` (the default), triage may proactively replace a large task with 2-5 child tasks when the size, step-count, package breadth, file-scope, or remediation-batch signals justify the coordination overhead. When it is `false`, those automatic oversized-task signals are advisory only for writing a realistic single-task spec; triage must not split solely because the task is large. The per-task `breakIntoSubtasks: true` flag is separate and remains mandatory: if a user explicitly asks for subtask breakdown, triage still evaluates and creates child tasks when the work is meaningfully decomposable. diff --git a/docs/workflow-steps.md b/docs/workflow-steps.md index 23eda071f6..5ec0fcb37d 100644 --- a/docs/workflow-steps.md +++ b/docs/workflow-steps.md @@ -829,13 +829,16 @@ engine resolves *effective settings* per task as `stored value ?? declaration default`, dropping any stored value that no longer validates against the current declaration (drop-on-orphan) and falling back to the default. -The **step-execution**, **review/approval**, **per-phase model-lane**, and -**triage/spec policy** knobs are workflow settings declared by `builtin:coding`. -Triage policy includes `triageProactiveSubtaskSplittingEnabled` (default `true`), -which controls automatic large-task splitting guidance for oversized M/L work. -Set it to `false` in a workflow's Values tab when triage should keep large tasks -whole unless the task explicitly has `breakIntoSubtasks: true`; explicit subtask -requests still follow the mandatory split flow. See +The **step-execution**, **review/approval**, **per-phase model-lane**, +**triage/spec policy**, and **planner oversight** knobs are workflow settings +declared by `builtin:coding`. Triage policy includes +`triageProactiveSubtaskSplittingEnabled` (default `true`), which controls +automatic large-task splitting guidance for oversized M/L work. Set it to `false` +in a workflow's Values tab when triage should keep large tasks whole unless the +task explicitly has `breakIntoSubtasks: true`; explicit subtask requests still +follow the mandatory split flow. Planner oversight uses `plannerOversightLevel` +(default `autonomous`) with `off`, `observe`, `steer`, and `autonomous` values; +per-task override and engine runtime behavior are follow-up work. See [Settings Reference → Workflow Settings](./settings-reference.md#workflow-settings) for the full moved-key catalog, the editor walkthrough, and the export/sync posture. diff --git a/packages/core/src/__tests__/builtin-workflow-settings-triage.test.ts b/packages/core/src/__tests__/builtin-workflow-settings-triage.test.ts index a84d5c58d3..cc9a33d1e6 100644 --- a/packages/core/src/__tests__/builtin-workflow-settings-triage.test.ts +++ b/packages/core/src/__tests__/builtin-workflow-settings-triage.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from "vitest"; import { BUILTIN_MOVED_WORKFLOW_SETTINGS, + BUILTIN_OVERSIGHT_SETTINGS, BUILTIN_REVIEW_REVISION_SETTINGS, BUILTIN_TRIAGE_POLICY_SETTINGS, BUILTIN_WORKFLOW_SETTINGS, @@ -80,6 +81,37 @@ describe("workflow-native built-in workflow settings", () => { } }); + it("declares planner oversight level as a workflow-native enum outside moved/project settings", () => { + const fullIds = new Set(BUILTIN_WORKFLOW_SETTINGS.map((setting) => setting.id)); + const movedIds = new Set(BUILTIN_MOVED_WORKFLOW_SETTINGS.map((setting) => setting.id)); + const movedKeyIds = new Set(MOVED_SETTINGS_KEYS); + + expect(BUILTIN_OVERSIGHT_SETTINGS.map((setting) => setting.id)).toEqual(["plannerOversightLevel"]); + const oversight = BUILTIN_OVERSIGHT_SETTINGS[0]; + expect(oversight).toMatchObject({ + type: "enum", + default: "autonomous", + }); + expect(oversight.options?.map((option) => option.value)).toEqual(["off", "observe", "steer", "autonomous"]); + expect(oversight.options?.map((option) => option.label)).toEqual([ + "Off", + "Observe", + "Steer", + "Autonomous recovery", + ]); + expect(fullIds.has("plannerOversightLevel"), "plannerOversightLevel should be in the full built-in catalog").toBe( + true, + ); + expect( + movedIds.has("plannerOversightLevel"), + "plannerOversightLevel should not be in the moved-key catalog", + ).toBe(false); + expect( + movedKeyIds.has("plannerOversightLevel"), + "plannerOversightLevel should not be in MOVED_SETTINGS_KEYS", + ).toBe(false); + }); + it("renders placeholders from resolved settings and rejects dangling tokens", () => { const prompt = [ "Size S (<{{triageSizeSmallMaxHours}}h)", diff --git a/packages/core/src/__tests__/settings-consistency.test.ts b/packages/core/src/__tests__/settings-consistency.test.ts index 7a48d7091f..4b3aa53178 100644 --- a/packages/core/src/__tests__/settings-consistency.test.ts +++ b/packages/core/src/__tests__/settings-consistency.test.ts @@ -12,6 +12,7 @@ import { describe, it, expect } from "vitest"; import { MOVED_SETTINGS_KEYS } from "../moved-settings.js"; import { + BUILTIN_OVERSIGHT_SETTINGS, BUILTIN_REVIEW_REVISION_SETTINGS, BUILTIN_TRIAGE_POLICY_SETTINGS, BUILTIN_WORKFLOW_SETTINGS, @@ -50,11 +51,12 @@ describe("settings consistency (U5)", () => { const nativeCatalogs = [ { name: "BUILTIN_TRIAGE_POLICY_SETTINGS", ids: BUILTIN_TRIAGE_POLICY_SETTINGS.map((s) => s.id) }, { name: "BUILTIN_REVIEW_REVISION_SETTINGS", ids: BUILTIN_REVIEW_REVISION_SETTINGS.map((s) => s.id) }, + { name: "BUILTIN_OVERSIGHT_SETTINGS", ids: BUILTIN_OVERSIGHT_SETTINGS.map((s) => s.id) }, ]; const native = new Set(nativeCatalogs.flatMap((catalog) => catalog.ids)); /* * FNXC:SettingsRegimes 2026-07-02-08:20: - * Workflow-native settings include triage policy and review/revision policy. They must be recognized by the consistency guard without being tombstoned in MOVED_SETTINGS_KEYS or reintroduced into project/global schemas. + * Workflow-native settings include triage policy, review/revision policy, and planner oversight policy. They must be recognized by the consistency guard without being tombstoned in MOVED_SETTINGS_KEYS or reintroduced into project/global schemas. */ // Every moved key has a declaration. diff --git a/packages/core/src/__tests__/workflow-settings-resolver.test.ts b/packages/core/src/__tests__/workflow-settings-resolver.test.ts index bc6f7ef1c6..6956718c0f 100644 --- a/packages/core/src/__tests__/workflow-settings-resolver.test.ts +++ b/packages/core/src/__tests__/workflow-settings-resolver.test.ts @@ -148,6 +148,7 @@ describe("resolveEffectiveSettings (per-task)", () => { expect(eff[s.id]).toStrictEqual(s.default); } } + expect(eff.plannerOversightLevel).toBe("autonomous"); }); it("a stored value for (workflow, project) is returned over the default", async () => { diff --git a/packages/core/src/builtin-workflow-settings.ts b/packages/core/src/builtin-workflow-settings.ts index d48f2d1b63..377bb0bbad 100644 --- a/packages/core/src/builtin-workflow-settings.ts +++ b/packages/core/src/builtin-workflow-settings.ts @@ -21,6 +21,10 @@ import type { WorkflowSettingDefinition } from "./workflow-ir-types.js"; * `BUILTIN_REVIEW_REVISION_SETTINGS` is workflow-native review-loop policy. * These keys also never lived in project/global settings and intentionally omit * declaration defaults: an unset workflow value means unbounded remediation. + * + * `BUILTIN_OVERSIGHT_SETTINGS` is workflow-native planner oversight policy. + * These keys never lived in project/global settings and must never be added to + * `MOVED_SETTINGS_KEYS`. */ /** @@ -428,10 +432,32 @@ export const BUILTIN_REVIEW_REVISION_SETTINGS: WorkflowSettingDefinition[] = [ }, ]; +/** + * FNXC:PlannerOversight 2026-07-04-00:00: + * Workflows declare a default planner oversight level before per-task override and engine reader support land in FN-7509/FN-7510. The workflow-native enum stays out of project settings and `MOVED_SETTINGS_KEYS`; its schema default is `autonomous` so built-in workflows preserve full steering/control until operators choose Off, Observe, or Steer. + */ +export const BUILTIN_OVERSIGHT_SETTINGS: WorkflowSettingDefinition[] = [ + { + id: "plannerOversightLevel", + name: "Planner oversight level", + type: "enum", + default: "autonomous", + options: [ + { value: "off", label: "Off" }, + { value: "observe", label: "Observe" }, + { value: "steer", label: "Steer" }, + { value: "autonomous", label: "Autonomous recovery" }, + ], + description: + "Workflow planner oversight mode: Off disables oversight; Observe watches only; Steer injects guidance or suggests revisions; Autonomous recovery enables bounded retry and targeted-fix recovery.", + }, +]; + export const BUILTIN_WORKFLOW_SETTINGS: WorkflowSettingDefinition[] = [ ...BUILTIN_MOVED_WORKFLOW_SETTINGS, ...BUILTIN_TRIAGE_POLICY_SETTINGS, ...BUILTIN_REVIEW_REVISION_SETTINGS, + ...BUILTIN_OVERSIGHT_SETTINGS, ]; const TRIAGE_POLICY_DEFAULTS = new Map( diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 78d589d7d4..8eb684f44b 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -187,6 +187,7 @@ export { BUILTIN_WORKFLOW_SETTINGS, BUILTIN_MOVED_WORKFLOW_SETTINGS, BUILTIN_TRIAGE_POLICY_SETTINGS, + BUILTIN_OVERSIGHT_SETTINGS, renderTriagePolicyPlaceholders, } from "./builtin-workflow-settings.js"; export {