FN-7510: default planner oversight to autonomous
Enable full planner steering/control by default while preserving explicit workflow and task opt-outs. - Document that planner oversight resolves as task override, workflow setting, then autonomous default. - Add regression coverage for built-in workflow defaults, stored workflow overrides, and per-task overrides. - Add a minor changeset for the published Fusion package. Files changed: .changeset/fn-7510-oversight-default.md | 7 ++ docs/workflow-steps.md | 9 ++- .../plannerOversightLevel-default.test.ts | 79 ++++++++++++++++++++++ 3 files changed, 93 insertions(+), 2 deletions(-) Fusion-Task-Id: FN-7510 Fusion-Task-Lineage: 2dbf8273-4239-4754-9713-e089f75be930 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
7
.changeset/fn-7510-oversight-default.md
Normal file
7
.changeset/fn-7510-oversight-default.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
"@runfusion/fusion": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
summary: Planner oversight now defaults to full steering/control for every workflow unless explicitly changed.
|
||||||
|
category: feature
|
||||||
|
dev: Confirms the `plannerOversightLevel` workflow-setting default is the highest (autonomous) level; unset workflow value and unset per-task override both resolve to full steering via `resolveEffectivePlannerOversightLevel` (task override → workflow effective value → autonomous), adding dedicated regression coverage for the "unless explicitly disabled" precedence.
|
||||||
@@ -837,8 +837,13 @@ 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
|
in a workflow's Values tab when triage should keep large tasks whole unless the
|
||||||
task explicitly has `breakIntoSubtasks: true`; explicit subtask requests still
|
task explicitly has `breakIntoSubtasks: true`; explicit subtask requests still
|
||||||
follow the mandatory split flow. Planner oversight uses `plannerOversightLevel`
|
follow the mandatory split flow. Planner oversight uses `plannerOversightLevel`
|
||||||
(default `autonomous`) with `off`, `observe`, `steer`, and `autonomous` values;
|
(default `autonomous`) with `off`, `observe`, `steer`, and `autonomous` values —
|
||||||
per-task override and engine runtime behavior are follow-up work. See
|
full steering/control is ON for every workflow unless explicitly changed. Tasks
|
||||||
|
may set a nullable `Task.plannerOversightLevel` override that wins over the
|
||||||
|
workflow value when present; `resolveEffectivePlannerOversightLevel` in
|
||||||
|
`@fusion/core` resolves the effective level as task override → workflow
|
||||||
|
effective value → `autonomous`. The overseer runtime/monitoring behavior that
|
||||||
|
acts on this level is still follow-up work (FN-7511+). See
|
||||||
[Settings Reference → Workflow Settings](./settings-reference.md#workflow-settings)
|
[Settings Reference → Workflow Settings](./settings-reference.md#workflow-settings)
|
||||||
for the full moved-key catalog, the editor walkthrough, and the export/sync posture.
|
for the full moved-key catalog, the editor walkthrough, and the export/sync posture.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* FNXC:PlannerOversight 2026-07-04-13:00:
|
||||||
|
* FN-7510 dedicated regression coverage: planner oversight defaults to full
|
||||||
|
* steering/control ("autonomous") for every workflow unless explicitly
|
||||||
|
* disabled at the workflow-setting scope or the per-task override scope.
|
||||||
|
* Precedence is task override -> workflow effective value -> "autonomous"
|
||||||
|
* declaration default (see resolveEffectivePlannerOversightLevel).
|
||||||
|
*/
|
||||||
|
import { describe, it, expect, vi } from "vitest";
|
||||||
|
|
||||||
|
import { BUILTIN_OVERSIGHT_SETTINGS, BUILTIN_WORKFLOW_SETTINGS } from "../builtin-workflow-settings.js";
|
||||||
|
import { DEFAULT_PLANNER_OVERSIGHT_LEVEL } from "../types.js";
|
||||||
|
import {
|
||||||
|
resolveEffectiveSettingsById,
|
||||||
|
resolveEffectivePlannerOversightLevel,
|
||||||
|
type WorkflowSettingsResolverStore,
|
||||||
|
} from "../workflow-settings-resolver.js";
|
||||||
|
|
||||||
|
const PROJECT = "proj-1";
|
||||||
|
|
||||||
|
function makeStore(values?: Record<string, unknown>): WorkflowSettingsResolverStore {
|
||||||
|
return {
|
||||||
|
getTaskWorkflowSelection: vi.fn(() => undefined),
|
||||||
|
getWorkflowDefinition: vi.fn(async () => undefined),
|
||||||
|
getWorkflowSettingValues: vi.fn(() => values ?? {}),
|
||||||
|
getWorkflowSettingsProjectId: vi.fn(() => PROJECT),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("plannerOversightLevel default (FN-7510)", () => {
|
||||||
|
it("(a) the declaration default is the full-steering value 'autonomous'", () => {
|
||||||
|
const decl = BUILTIN_OVERSIGHT_SETTINGS.find((s) => s.id === "plannerOversightLevel");
|
||||||
|
expect(decl).toBeDefined();
|
||||||
|
expect(decl?.default).toBe("autonomous");
|
||||||
|
expect(decl?.default).toBe(DEFAULT_PLANNER_OVERSIGHT_LEVEL);
|
||||||
|
// The declaration lives in the composed catalog every built-in workflow spreads.
|
||||||
|
expect(BUILTIN_WORKFLOW_SETTINGS.some((s) => s.id === "plannerOversightLevel")).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("(b) resolveEffectiveSettingsById for a built-in workflow with no stored value returns full steering", async () => {
|
||||||
|
const store = makeStore({});
|
||||||
|
const eff = await resolveEffectiveSettingsById(store, "builtin:coding", PROJECT);
|
||||||
|
expect(eff.plannerOversightLevel).toBe("autonomous");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("(c) an explicit stored workflow value overrides the default ('off')", async () => {
|
||||||
|
const store = makeStore({ plannerOversightLevel: "off" });
|
||||||
|
const eff = await resolveEffectiveSettingsById(store, "builtin:coding", PROJECT);
|
||||||
|
expect(eff.plannerOversightLevel).toBe("off");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("(c) an explicit stored workflow value overrides the default ('steer')", async () => {
|
||||||
|
const store = makeStore({ plannerOversightLevel: "steer" });
|
||||||
|
const eff = await resolveEffectiveSettingsById(store, "builtin:coding", PROJECT);
|
||||||
|
expect(eff.plannerOversightLevel).toBe("steer");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("(d) an unset per-task override falls through to the workflow/default level", () => {
|
||||||
|
expect(resolveEffectivePlannerOversightLevel(undefined, "autonomous")).toBe("autonomous");
|
||||||
|
expect(resolveEffectivePlannerOversightLevel(null, "steer")).toBe("steer");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("(d) an explicit per-task override wins over the workflow value", () => {
|
||||||
|
expect(resolveEffectivePlannerOversightLevel("steer", "autonomous")).toBe("steer");
|
||||||
|
expect(resolveEffectivePlannerOversightLevel("off", "autonomous")).toBe("off");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("(e) 'off' is honored at the workflow scope when no task override is set", () => {
|
||||||
|
expect(resolveEffectivePlannerOversightLevel(undefined, "off")).toBe("off");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("(e) 'off' is honored at the per-task scope even when the workflow value is full steering", () => {
|
||||||
|
expect(resolveEffectivePlannerOversightLevel("off", "autonomous")).toBe("off");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("both workflow value and task override unset resolve to full steering (unless-explicitly-disabled)", () => {
|
||||||
|
expect(resolveEffectivePlannerOversightLevel(undefined, undefined)).toBe(DEFAULT_PLANNER_OVERSIGHT_LEVEL);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user