FN-7518: add configurable planner-overseer notification verbosity setting
Adds a workflow-native plannerOversightNotificationLevel enum setting so operators can control how noisy planner-overseer notifications are. - Declare BUILTIN_OVERSIGHT_SETTINGS entry `plannerOversightNotificationLevel` (silent/errors/important/all, default important) - Document the new setting alongside plannerOversightLevel in docs/settings-reference.md - Add regression coverage in builtin-workflow-settings-triage.test.ts and workflow-settings-resolver.test.ts - Add changeset (minor) describing the new operator-facing verbosity control Files changed: .changeset/fn-7518-oversight-notification-verbosity.md | 7 +++++ docs/settings-reference.md | 3 +- packages/core/src/__tests__/builtin-workflow-settings-triage.test.ts | 36 +++++++++++++++++++++- packages/core/src/__tests__/workflow-settings-resolver.test.ts | 1 + packages/core/src/builtin-workflow-settings.ts | 17 ++++++++++ 5 files changed, 62 insertions(+), 2 deletions(-) Fusion-Task-Id: FN-7518 Fusion-Task-Lineage: fe6e2bde-0e58-4f29-b5cc-efdf81efcfa5 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
7
.changeset/fn-7518-oversight-notification-verbosity.md
Normal file
7
.changeset/fn-7518-oversight-notification-verbosity.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@runfusion/fusion": minor
|
||||
---
|
||||
|
||||
summary: Add a configurable planner-overseer notification verbosity level (Silent/Errors/Important/All).
|
||||
category: feature
|
||||
dev: New workflow-native enum setting `plannerOversightNotificationLevel` in BUILTIN_OVERSIGHT_SETTINGS; default `important`. Resolves via resolveEffectiveSettings; emission gating that reads it lands in FN-7519/FN-7520.
|
||||
@@ -325,7 +325,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`) |
|
||||
| **Planner oversight** | `plannerOversightLevel` (workflow-native; values: `off`, `observe`, `steer`, `autonomous`); `plannerOversightNotificationLevel` (workflow-native; values: `silent`, `errors`, `important`, `all`) |
|
||||
| **Per-phase model lanes** | `executionProvider`/`executionModelId`, `planningProvider`/`planningModelId` (+ fallbacks), `validatorProvider`/`validatorModelId` (+ fallbacks) |
|
||||
|
||||
### Workflow-native triage policy settings
|
||||
@@ -360,6 +360,7 @@ The built-in workflows also declare triage/spec policy settings that were **not*
|
||||
| `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 — but merge/PR progression and any destructive or external-service side effect ALWAYS require an explicit, recorded human confirmation before they run, even at `autonomous` (FN-7513's confirmation gate; see `docs/architecture.md` → "Planner overseer confirmation gate"). Tasks may set a nullable `Task.plannerOversightLevel` override (same four values) that wins over this workflow value when present; `null`/unset means "inherit the workflow value". `resolveEffectivePlannerOversightLevel` in `@fusion/core` computes the effective level (task override → workflow effective → `autonomous`). The per-task override is exposed in the dashboard as a "Planner oversight" selector (Inherit from workflow / Off / Observe / Steer / Autonomous recovery) in both the New Task dialog and Task Detail edit form, threaded through `createTask`/`updateTask` (FN-7515); the project/global default is set via the **Workflow Editor → Values** tab on the default workflow's `plannerOversightLevel` value, not in Project Settings. FN-7517 additionally exposes a quick inline oversight-level select in the Task Detail modal's meta-controls cluster (same `updateTask` override plumbing, no parallel path) plus manual nudge/stop-oversight/explain-current-action controls that call the overseer runtime directly — see `docs/dashboard-guide.md`. Engine read-site behavior beyond the FN-7513 confirmation gate remains follow-up work (FN-7510+). |
|
||||
| `plannerOversightNotificationLevel` | `important` | Workflow-native planner-overseer notification verbosity (FN-7518). `silent` suppresses overseer notifications; `errors` notifies only on failures/escalations; `important` (the default) notifies on interventions/recovery actions and errors; `all` notifies on every observation. Resolves through the generic `resolveEffectiveSettings` default path with no special-casing, alongside `plannerOversightLevel`. This is a declaration-only setting: the notification-emission gating that reads it lands downstream in FN-7519 (intervention timeline) and FN-7520 (run-audit/activity events). |
|
||||
|
||||
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.
|
||||
|
||||
|
||||
@@ -86,7 +86,10 @@ describe("workflow-native built-in workflow settings", () => {
|
||||
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"]);
|
||||
expect(BUILTIN_OVERSIGHT_SETTINGS.map((setting) => setting.id)).toEqual([
|
||||
"plannerOversightLevel",
|
||||
"plannerOversightNotificationLevel",
|
||||
]);
|
||||
const oversight = BUILTIN_OVERSIGHT_SETTINGS[0];
|
||||
expect(oversight).toMatchObject({
|
||||
type: "enum",
|
||||
@@ -110,6 +113,37 @@ describe("workflow-native built-in workflow settings", () => {
|
||||
movedKeyIds.has("plannerOversightLevel"),
|
||||
"plannerOversightLevel should not be in MOVED_SETTINGS_KEYS",
|
||||
).toBe(false);
|
||||
|
||||
const notificationLevel = BUILTIN_OVERSIGHT_SETTINGS[1];
|
||||
expect(notificationLevel).toMatchObject({
|
||||
id: "plannerOversightNotificationLevel",
|
||||
type: "enum",
|
||||
default: "important",
|
||||
});
|
||||
expect(notificationLevel.options?.map((option) => option.value)).toEqual([
|
||||
"silent",
|
||||
"errors",
|
||||
"important",
|
||||
"all",
|
||||
]);
|
||||
expect(notificationLevel.options?.map((option) => option.label)).toEqual([
|
||||
"Silent",
|
||||
"Errors only",
|
||||
"Important",
|
||||
"All",
|
||||
]);
|
||||
expect(
|
||||
fullIds.has("plannerOversightNotificationLevel"),
|
||||
"plannerOversightNotificationLevel should be in the full built-in catalog",
|
||||
).toBe(true);
|
||||
expect(
|
||||
movedIds.has("plannerOversightNotificationLevel"),
|
||||
"plannerOversightNotificationLevel should not be in the moved-key catalog",
|
||||
).toBe(false);
|
||||
expect(
|
||||
movedKeyIds.has("plannerOversightNotificationLevel"),
|
||||
"plannerOversightNotificationLevel should not be in MOVED_SETTINGS_KEYS",
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("renders placeholders from resolved settings and rejects dangling tokens", () => {
|
||||
|
||||
@@ -150,6 +150,7 @@ describe("resolveEffectiveSettings (per-task)", () => {
|
||||
}
|
||||
}
|
||||
expect(eff.plannerOversightLevel).toBe("autonomous");
|
||||
expect(eff.plannerOversightNotificationLevel).toBe("important");
|
||||
});
|
||||
|
||||
it("a stored value for (workflow, project) is returned over the default", async () => {
|
||||
|
||||
@@ -435,6 +435,9 @@ 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.
|
||||
*
|
||||
* FNXC:PlannerOversight 2026-07-04-12:00:
|
||||
* FN-7518 adds `plannerOversightNotificationLevel`, a sibling workflow-native enum letting operators configure how noisy planner-overseer notifications are: Silent suppresses all, Errors only notifies on failures/escalations, Important (the default) notifies on interventions/recovery actions plus errors, and All notifies on every observation. Default is `important` (not `all`) to avoid noisy-by-default behavior. This setting stays workflow-native (out of project/global settings schemas and `MOVED_SETTINGS_KEYS`) and resolves through the generic `resolveEffectiveSettings` default path with no special-casing. This task only declares the setting — the emission gating that reads it lands downstream in FN-7519 (intervention timeline) and FN-7520 (run-audit/activity events).
|
||||
*/
|
||||
export const BUILTIN_OVERSIGHT_SETTINGS: WorkflowSettingDefinition[] = [
|
||||
{
|
||||
@@ -451,6 +454,20 @@ export const BUILTIN_OVERSIGHT_SETTINGS: WorkflowSettingDefinition[] = [
|
||||
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.",
|
||||
},
|
||||
{
|
||||
id: "plannerOversightNotificationLevel",
|
||||
name: "Planner oversight notification level",
|
||||
type: "enum",
|
||||
default: "important",
|
||||
options: [
|
||||
{ value: "silent", label: "Silent" },
|
||||
{ value: "errors", label: "Errors only" },
|
||||
{ value: "important", label: "Important" },
|
||||
{ value: "all", label: "All" },
|
||||
],
|
||||
description:
|
||||
"Planner overseer notification verbosity: Silent suppresses overseer notifications; Errors only notifies on failures/escalations; Important notifies on interventions/recovery actions and errors; All notifies on every observation. Notification-emission gating that reads this value is follow-up work (FN-7519/FN-7520).",
|
||||
},
|
||||
];
|
||||
|
||||
export const BUILTIN_WORKFLOW_SETTINGS: WorkflowSettingDefinition[] = [
|
||||
|
||||
Reference in New Issue
Block a user