FN-7509: add per-task planner oversight overrides
Add core support for tasks to carry a planner oversight override that can supersede workflow settings. - Add nullable plannerOversightLevel task storage, schema migration, store update/create/archive plumbing, and mesh replication support. - Export planner oversight level types/defaults and an effective-level resolver with task-over-workflow precedence. - Document override precedence and add regression coverage for migration, persistence, updates, and resolution. - Add a minor changeset for the published Fusion package. Files changed: .../fn-7509-per-task-planner-oversight-override.md | 7 ++ docs/settings-reference.md | 2 +- packages/core/src/__tests__/db.test.ts | 45 +++++++++++++ packages/core/src/__tests__/store-update.test.ts | 75 ++++++++++++++++++++++ .../__tests__/workflow-settings-resolver.test.ts | 28 ++++++++ packages/core/src/db.ts | 17 ++++- packages/core/src/index.ts | 5 +- packages/core/src/mesh-task-replication.ts | 2 + packages/core/src/store.ts | 15 ++++- packages/core/src/types.ts | 23 +++++++ packages/core/src/workflow-settings-resolver.ts | 28 ++++++++ 11 files changed, 240 insertions(+), 7 deletions(-) Fusion-Task-Id: FN-7509 Fusion-Task-Lineage: 41695cc5-34d2-4079-9e34-a8fb40f961fb Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@runfusion/fusion": minor
|
||||
---
|
||||
|
||||
summary: Tasks can override the workflow planner oversight level (Off, Observe, Steer, Autonomous recovery).
|
||||
category: feature
|
||||
dev: New nullable Task.plannerOversightLevel field (migration 137, SCHEMA_VERSION 137) mirroring executionMode; NULL inherits the workflow setting. Adds resolveEffectivePlannerOversightLevel precedence helper. Dashboard UI/API threading and engine behavior land in follow-up tasks.
|
||||
@@ -356,7 +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. |
|
||||
| `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. 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`). Dashboard UI/API threading for the per-task override and engine read-site behavior are follow-up work (FN-7515, FN-7510+). |
|
||||
|
||||
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.
|
||||
|
||||
|
||||
@@ -1778,6 +1778,51 @@ describe("schema migrations", () => {
|
||||
db.close();
|
||||
});
|
||||
|
||||
it("migrates v136 databases by adding plannerOversightLevel column with legacy rows staying NULL (no backfill)", () => {
|
||||
tmpDir = makeTmpDir();
|
||||
const fusionDir = join(tmpDir, ".fusion");
|
||||
const db = new Database(fusionDir);
|
||||
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS __meta (key TEXT PRIMARY KEY, value TEXT);
|
||||
CREATE TABLE IF NOT EXISTS tasks (
|
||||
id TEXT PRIMARY KEY,
|
||||
description TEXT NOT NULL,
|
||||
"column" TEXT NOT NULL,
|
||||
createdAt TEXT NOT NULL,
|
||||
updatedAt TEXT NOT NULL,
|
||||
executionMode TEXT DEFAULT 'standard'
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS config (
|
||||
id INTEGER PRIMARY KEY CHECK (id = 1),
|
||||
nextId INTEGER DEFAULT 1,
|
||||
nextWorkflowStepId INTEGER DEFAULT 1,
|
||||
settings TEXT DEFAULT '{}',
|
||||
workflowSteps TEXT DEFAULT '[]',
|
||||
updatedAt TEXT
|
||||
);
|
||||
`);
|
||||
db.exec("INSERT INTO __meta (key, value) VALUES ('schemaVersion', '136')");
|
||||
db.exec("INSERT INTO __meta (key, value) VALUES ('lastModified', '1000')");
|
||||
db.exec(`INSERT INTO tasks (id, description, "column", createdAt, updatedAt) VALUES ('FN-1', 'legacy', 'triage', '2026-01-01', '2026-01-01')`);
|
||||
|
||||
db.init();
|
||||
|
||||
expect(db.getSchemaVersion()).toBe(SCHEMA_VERSION);
|
||||
|
||||
const cols = db.prepare("PRAGMA table_info(tasks)").all() as Array<{ name: string }>;
|
||||
expect(cols.map((col) => col.name)).toContain("plannerOversightLevel");
|
||||
|
||||
// FNXC:PlannerOversight 2026-07-04-00:00: migration 137 is additive-only and must NOT backfill
|
||||
// legacy rows — a NULL value means "inherit workflow default".
|
||||
const task = db.prepare("SELECT plannerOversightLevel FROM tasks WHERE id = 'FN-1'").get() as {
|
||||
plannerOversightLevel: string | null;
|
||||
};
|
||||
expect(task.plannerOversightLevel).toBeNull();
|
||||
|
||||
db.close();
|
||||
});
|
||||
|
||||
it("migrates v43 databases by adding task token-usage aggregate columns with null-compatible defaults", () => {
|
||||
tmpDir = makeTmpDir();
|
||||
const fusionDir = join(tmpDir, ".fusion");
|
||||
|
||||
@@ -945,6 +945,81 @@ describe("TaskStore", () => {
|
||||
});
|
||||
});
|
||||
|
||||
// FNXC:PlannerOversight 2026-07-04-00:00: per-task override of the workflow-native
|
||||
// `plannerOversightLevel` setting (FN-7508/FN-7509); mirrors executionMode persistence.
|
||||
describe("plannerOversightLevel persistence", () => {
|
||||
it("sets plannerOversightLevel to 'steer' via createTask and persists", async () => {
|
||||
const created = await store.createTask({
|
||||
description: "Task with steer oversight override",
|
||||
plannerOversightLevel: "steer",
|
||||
});
|
||||
expect(created.plannerOversightLevel).toBe("steer");
|
||||
|
||||
const persisted = await store.getTask(created.id);
|
||||
expect(persisted.plannerOversightLevel).toBe("steer");
|
||||
});
|
||||
|
||||
it("persists plannerOversightLevel as undefined (inherit) by default when not specified", async () => {
|
||||
const created = await store.createTask({
|
||||
description: "Task without oversight override",
|
||||
});
|
||||
expect(created.plannerOversightLevel).toBeUndefined();
|
||||
|
||||
const persisted = await store.getTask(created.id);
|
||||
expect(persisted.plannerOversightLevel).toBeUndefined();
|
||||
});
|
||||
|
||||
it("updates plannerOversightLevel via updateTask", async () => {
|
||||
const created = await store.createTask({
|
||||
description: "Task for oversight override update",
|
||||
plannerOversightLevel: "observe",
|
||||
});
|
||||
expect(created.plannerOversightLevel).toBe("observe");
|
||||
|
||||
const updated = await store.updateTask(created.id, { plannerOversightLevel: "off" });
|
||||
expect(updated.plannerOversightLevel).toBe("off");
|
||||
|
||||
const reloaded = await store.getTask(created.id);
|
||||
expect(reloaded.plannerOversightLevel).toBe("off");
|
||||
});
|
||||
|
||||
it("clears plannerOversightLevel via null in updateTask (reverts to inherit)", async () => {
|
||||
const task = await store.createTask({
|
||||
description: "Task with oversight override to clear",
|
||||
plannerOversightLevel: "observe",
|
||||
});
|
||||
expect(task.plannerOversightLevel).toBe("observe");
|
||||
|
||||
const updated = await store.updateTask(task.id, { plannerOversightLevel: null });
|
||||
expect(updated.plannerOversightLevel).toBeUndefined();
|
||||
|
||||
const reloaded = await store.getTask(task.id);
|
||||
expect(reloaded.plannerOversightLevel).toBeUndefined();
|
||||
});
|
||||
|
||||
it("leaves plannerOversightLevel unchanged when updateTask omits it", async () => {
|
||||
const task = await store.createTask({
|
||||
description: "Task with oversight override to preserve",
|
||||
plannerOversightLevel: "steer",
|
||||
});
|
||||
const updated = await store.updateTask(task.id, { title: "Updated title" });
|
||||
expect(updated.plannerOversightLevel).toBe("steer");
|
||||
expect(updated.title).toBe("Updated title");
|
||||
});
|
||||
|
||||
it("returns plannerOversightLevel in listTasks", async () => {
|
||||
await store.createTask({ description: "Steer task", plannerOversightLevel: "steer" });
|
||||
await store.createTask({ description: "Unspecified oversight task" });
|
||||
|
||||
const tasks = await store.listTasks();
|
||||
const steerTask = tasks.find((t) => t.description === "Steer task");
|
||||
const unspecifiedTask = tasks.find((t) => t.description === "Unspecified oversight task");
|
||||
|
||||
expect(steerTask?.plannerOversightLevel).toBe("steer");
|
||||
expect(unspecifiedTask?.plannerOversightLevel).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("updateTask — PROMPT.md regeneration", () => {
|
||||
it("regenerates PROMPT.md when title is updated", async () => {
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
resolveEffectiveSettings,
|
||||
resolveEffectiveSettingsById,
|
||||
resolveOptionalReviewRevisionBudget,
|
||||
resolveEffectivePlannerOversightLevel,
|
||||
type WorkflowSettingsResolverStore,
|
||||
} from "../workflow-settings-resolver.js";
|
||||
|
||||
@@ -284,3 +285,30 @@ describe("resolveEffectiveSettingsById", () => {
|
||||
expect(eff.requirePrApproval).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
// FNXC:PlannerOversight 2026-07-04-00:00: task override > workflow effective > "autonomous" default (FN-7509).
|
||||
describe("resolveEffectivePlannerOversightLevel", () => {
|
||||
it("task override wins over workflow effective value", () => {
|
||||
expect(resolveEffectivePlannerOversightLevel("steer", "observe")).toBe("steer");
|
||||
});
|
||||
|
||||
it("uses workflow effective value when no task override", () => {
|
||||
expect(resolveEffectivePlannerOversightLevel(undefined, "observe")).toBe("observe");
|
||||
});
|
||||
|
||||
it("falls back to 'autonomous' when task override is an unknown/invalid string", () => {
|
||||
expect(resolveEffectivePlannerOversightLevel("bogus", "observe")).toBe("observe");
|
||||
});
|
||||
|
||||
it("falls back to 'autonomous' when workflow effective value is an unknown/invalid string", () => {
|
||||
expect(resolveEffectivePlannerOversightLevel(undefined, "bogus")).toBe("autonomous");
|
||||
});
|
||||
|
||||
it("falls back to 'autonomous' when both are unset", () => {
|
||||
expect(resolveEffectivePlannerOversightLevel(undefined, undefined)).toBe("autonomous");
|
||||
});
|
||||
|
||||
it("falls back to 'autonomous' when both are null", () => {
|
||||
expect(resolveEffectivePlannerOversightLevel(null, null)).toBe("autonomous");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -183,7 +183,7 @@ export function isFts5CorruptionError(error: unknown): boolean {
|
||||
|
||||
// ── Schema Definition ────────────────────────────────────────────────
|
||||
|
||||
const SCHEMA_VERSION = 136;
|
||||
const SCHEMA_VERSION = 137;
|
||||
|
||||
const TASKS_FTS_AUTOMERGE = 8;
|
||||
const TASKS_FTS_CRISISMERGE = 16;
|
||||
@@ -299,6 +299,7 @@ CREATE TABLE IF NOT EXISTS tasks (
|
||||
summary TEXT,
|
||||
thinkingLevel TEXT,
|
||||
executionMode TEXT DEFAULT 'standard',
|
||||
plannerOversightLevel TEXT,
|
||||
tokenUsageInputTokens INTEGER,
|
||||
tokenUsageOutputTokens INTEGER,
|
||||
tokenUsageCachedTokens INTEGER,
|
||||
@@ -5556,6 +5557,20 @@ export class Database {
|
||||
});
|
||||
}
|
||||
|
||||
if (version < 137) {
|
||||
/*
|
||||
* FNXC:PlannerOversight 2026-07-04-00:00:
|
||||
* Per-task override of the workflow-native `plannerOversightLevel` setting
|
||||
* (FN-7508/FN-7509). Additive-only: no SQL default and no backfill — a NULL
|
||||
* value means "inherit the workflow's effective oversight level", which is
|
||||
* distinct from executionMode's non-null 'standard' default. Legacy rows
|
||||
* must stay NULL.
|
||||
*/
|
||||
this.applyMigration(137, () => {
|
||||
this.addColumnIfMissing("tasks", "plannerOversightLevel", "TEXT");
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export { COLUMNS, DEFAULT_COLUMN, isColumn, normalizeColumn, COLUMN_LABELS, COLUMN_DESCRIPTIONS, VALID_TRANSITIONS, DEFAULT_SETTINGS, DEFAULT_GLOBAL_SETTINGS, DEFAULT_PROJECT_SETTINGS, GLOBAL_SETTINGS_KEYS, PROJECT_SETTINGS_KEYS, isGlobalSettingsKey, isProjectSettingsKey, isMergeRequestContractShadowEnabled, resolvePersistAgentThinkingLog, THINKING_LEVELS, THEME_MODES, COLOR_THEMES, SUPPORTED_LOCALES, DEFAULT_LOCALE, isLocale, AGENT_PERMISSIONS, PERMANENT_AGENT_ACTION_CATEGORIES, AGENT_PERMISSION_POLICY_ACTION_CATEGORIES, AGENT_PROVISIONING_APPROVAL_MODES, SANDBOX_PROVISIONING_APPROVAL_MODES, AGENT_PERMISSION_POLICY_PRESET_IDS, LEGACY_AGENT_PERMISSION_POLICY_ACTION_CATEGORY_ALIASES, APPROVAL_REQUEST_STATUSES, APPROVAL_REQUEST_AUDIT_EVENT_TYPES, normalizeApprovalRequestActionCategory, isValidApprovalRequestTransition, agentToConfigSnapshot, diffConfigSnapshots, isEphemeralAgent, hasAgentIdentity, CheckoutConflictError, DEFAULT_HEARTBEAT_PROCEDURE_PATH, getDefaultHeartbeatProcedurePath, EXECUTION_MODES, DEFAULT_EXECUTION_MODE, TASK_PRIORITIES, DEFAULT_TASK_PRIORITY, WORKFLOW_WORK_ITEM_KINDS, WORKFLOW_WORK_ITEM_STATES, HIGH_FANOUT_BLOCKER_TODO_THRESHOLD, STALE_HIGH_FANOUT_BLOCKER_AGE_THRESHOLD_MS, DASHBOARD_USER_ID, normalizeMessageParticipant, validateMessageMetadata, validateDockerNodeConfig, sanitizeDockerNodeConfigForResponse, normalizeMergeIntegrationWorktreeMode, normalizeMergeAdvanceAutoSyncMode, DEFAULT_GITLAB_API_BASE_URL, DEFAULT_GITLAB_INSTANCE_URL, resolveGitlabConfig, resolveGitlabEnabled, PLANNING_DEEPEN_CHECKPOINT_ID, PLANNING_DEEPEN_CHECKPOINT_QUESTION, PLANNING_DEEPEN_PROCEED_OPTION_ID, PLANNING_DEEPEN_PROCEED_RESPONSE_KEY, MERGE_ADVANCE_AUTO_SYNC_MODES, normalizeMergeConflictStrategy, normalizeMergeStrategyOverlapBehavior, normalizePostMergeAuditMode, POST_MERGE_AUDIT_MODES, normalizeMergeAuditAutoRecovery, MERGE_AUDIT_AUTO_RECOVERY_MODES, normalizeMergerMode, MERGER_MODES, normalizeAutoRecovery, AUTO_RECOVERY_MODES, buildResearchDocumentKey, REPO_OVERRIDE_RE, SHARED_STATE_SNAPSHOT_VERSION, sanitizeCliAgentSettings, sanitizeCliAgentsSettings, sanitizeMcpServers, CLI_AGENT_ADAPTER_IDS, CLI_AGENT_AUTONOMY_MODES, isMcpSecretRef } from "./types.js";
|
||||
export type { Column, ColumnId, IssueInfo, IssueState, TaskSourceIssue, TaskGitLabTracking, TaskGitLabTrackedItem, GitLabTrackedItemKind, PrInfo, PrConflictState, PrConflictDiagnostics, PrCheckState, PrCheckStatus, PrStatus, BranchGroup, BranchGroupCreateInput, BranchGroupUpdate, BranchGroupPrState, Task, TaskTokenUsage, TaskTokenUsagePerModel, TaskAttachment, TaskComment, TaskCommentInput, TaskDocument, TaskDocumentRevision, TaskDocumentCreateInput, TaskDocumentWithTask, ArtifactType, Artifact, ArtifactCreateInput, ArtifactWithTask, TaskCreateInput, MeshReplicatedTaskCreatePayload, MeshReplicatedTaskApplyResult, TaskSource, SourceType, TaskDetail, RetrySummary, InboxTask, TodoList, TodoItem, TodoListCreateInput, TodoListUpdateInput, TodoItemCreateInput, TodoItemUpdateInput, TodoListWithItems, AgentLogEntry, AgentLogType, AgentRole, BoardConfig, DistributedTaskIdReserveInput, DistributedTaskIdReserveResult, DistributedTaskIdCommitInput, DistributedTaskIdCommitResult, DistributedTaskIdAbortInput, DistributedTaskIdAbortResult, DistributedTaskIdStateInput, DistributedTaskIdStateResult, AutostashOrphanRecord, AutostashOutcome, MergeDetails, MergeResult, MergeIntegrationWorktreeMode, MergeAdvanceAutoSyncMode, MergeConflictStrategy, CanonicalMergeConflictStrategy, MergeStrategyOverlapBehavior, PostMergeAuditMode, MergeAuditAutoRecoveryMode, MergerMode, MergerSettings, AutoRecoveryMode, AutoRecoveryFailureClass, AutoRecoverySettings, DirectMergeCommitStrategy, Settings, GlobalSettings, ProjectSettings, SecretsEnvConfig, WebSearchBackend, ResearchEnabledSources, ResearchGlobalDefaults, ResearchProjectLimits, ResearchProjectSettings, SandboxBackendName, SandboxFailureMode, SandboxPolicy, SandboxProjectSettings, EvalFollowUpPolicy, EvalProjectSettings, ResolvedEvalSettings, SettingsScope, DaemonTokenSettings, TaskStep, StepStatus, TaskLogEntry, RunMutationContext, ActivityLogEntry, ActivityEventType, ThinkingLevel, ThemeMode, ColorTheme, Locale, ExecutionMode, TaskPriority, MergeQueueEntry, MergeQueueEnqueueOptions, MergeQueueAcquireOptions, MergeQueueReleaseOutcome, MergeRequestState, MergeRequestRecord, MergeRequestWorkflowProjectionOptions, CompletionHandoffMarker, WorkflowWorkItem, WorkflowWorkItemDueFilter, WorkflowWorkItemKind, WorkflowWorkItemState, WorkflowWorkItemTransitionPatch, WorkflowWorkItemUpsertInput, HandoffEvidence, HandoffToReviewOptions, UnavailableNodePolicy, OwningNodeHandoffPolicy, PlanningQuestion, PlanningSummary, PlanningResponse, PlanningQuestionType, ArchivedTaskEntry, BatchStatusRequest, BatchStatusResponse, BatchStatusEntry, BatchStatusResult, GithubIssueAction, ModelPreset, WorkflowStep, WorkflowStepMode, WorkflowStepGateMode, WorkflowStepPhase, WorkflowStepInput, WorkflowStepResult, WorkflowStepTemplate, Agent, OrgTreeNode, AgentState, AgentDetail, AgentCreateInput, AgentUpdateInput, AgentApiKey, AgentApiKeyCreateResult, AgentCapability, AgentPromptTemplate, AgentPromptsConfig, AgentPermission, PermanentAgentActionCategory, PermanentAgentSensitiveActionCategory, PermanentAgentGatingContext, AgentPermissionPolicy, AgentPermissionPolicyRules, AgentPermissionPolicyToolRules, AgentPermissionPolicyActionCategory, AgentProvisioningApprovalMode, SandboxProvisioningApprovalMode, LegacyAgentPermissionPolicyActionCategory, ApprovalRequestActionCategoryInput, ApprovalRequestActionCategory, AgentPermissionPolicyDisposition, AgentPermissionPolicyPresetId, ApprovalRequestStatus, ApprovalRequestAuditEventType, ApprovalRequestActorSnapshot, ApprovalRequestTargetAction, ApprovalRequestAuditEvent, ApprovalRequest, ApprovalRequestCreateInput, ApprovalRequestDecisionInput, ApprovalRequestCompletionInput, ApprovalRequestListInput, TaskAssignSource, AgentAccessState, AgentHeartbeatConfig, AgentBudgetConfig, AgentBudgetStatus, InstructionsBundleConfig, MessageResponseMode, AgentHeartbeatEvent, AgentHeartbeatRun, BlockedStateSnapshot, HeartbeatInvocationSource, AgentTaskSession, AgentRating, AgentRatingSummary, AgentRatingInput, AgentConfigSnapshot, RevisionFieldDiff, AgentConfigRevision, AgentStats, ReflectionTrigger, ReflectionMetrics, AgentReflection, AgentPerformanceSummary, NtfyNotificationEvent, NotificationEvent, NotificationPayload, NotificationProviderConfig, CustomProvider, SteeringComment, ParticipantType, MessageType, Message, MessageCreateInput, MessageFilter, MessageMetadata, MessageReplyReference, Mailbox, CheckoutLease, CheckoutClaimPrecondition, TaskClaimRow, CentralClaimStore, RunAuditDomain, RunAuditEvent, RunAuditEventInput, RunAuditEventFilter, AgentMemoryInclusionMode, HeartbeatPromptTemplate, HeartbeatScopeDisciplineMode, WorktrunkSettings, WorktrunkOnFailure, TaskBranchContext, CliAgentSettings, McpSecretRef, McpSensitiveValue, McpStdioTransport, McpSseTransport, McpStreamableHttpTransport, McpTransport, McpServerDefinition, McpServersSettings, GitlabConfigSettingsSource, ResolvedGitlabConfig, ResolveGitlabConfigInput, GitlabAuthTokenType } from "./types.js";
|
||||
export { COLUMNS, DEFAULT_COLUMN, isColumn, normalizeColumn, COLUMN_LABELS, COLUMN_DESCRIPTIONS, VALID_TRANSITIONS, DEFAULT_SETTINGS, DEFAULT_GLOBAL_SETTINGS, DEFAULT_PROJECT_SETTINGS, GLOBAL_SETTINGS_KEYS, PROJECT_SETTINGS_KEYS, isGlobalSettingsKey, isProjectSettingsKey, isMergeRequestContractShadowEnabled, resolvePersistAgentThinkingLog, THINKING_LEVELS, THEME_MODES, COLOR_THEMES, SUPPORTED_LOCALES, DEFAULT_LOCALE, isLocale, AGENT_PERMISSIONS, PERMANENT_AGENT_ACTION_CATEGORIES, AGENT_PERMISSION_POLICY_ACTION_CATEGORIES, AGENT_PROVISIONING_APPROVAL_MODES, SANDBOX_PROVISIONING_APPROVAL_MODES, AGENT_PERMISSION_POLICY_PRESET_IDS, LEGACY_AGENT_PERMISSION_POLICY_ACTION_CATEGORY_ALIASES, APPROVAL_REQUEST_STATUSES, APPROVAL_REQUEST_AUDIT_EVENT_TYPES, normalizeApprovalRequestActionCategory, isValidApprovalRequestTransition, agentToConfigSnapshot, diffConfigSnapshots, isEphemeralAgent, hasAgentIdentity, CheckoutConflictError, DEFAULT_HEARTBEAT_PROCEDURE_PATH, getDefaultHeartbeatProcedurePath, EXECUTION_MODES, DEFAULT_EXECUTION_MODE, PLANNER_OVERSIGHT_LEVELS, DEFAULT_PLANNER_OVERSIGHT_LEVEL, TASK_PRIORITIES, DEFAULT_TASK_PRIORITY, WORKFLOW_WORK_ITEM_KINDS, WORKFLOW_WORK_ITEM_STATES, HIGH_FANOUT_BLOCKER_TODO_THRESHOLD, STALE_HIGH_FANOUT_BLOCKER_AGE_THRESHOLD_MS, DASHBOARD_USER_ID, normalizeMessageParticipant, validateMessageMetadata, validateDockerNodeConfig, sanitizeDockerNodeConfigForResponse, normalizeMergeIntegrationWorktreeMode, normalizeMergeAdvanceAutoSyncMode, DEFAULT_GITLAB_API_BASE_URL, DEFAULT_GITLAB_INSTANCE_URL, resolveGitlabConfig, resolveGitlabEnabled, PLANNING_DEEPEN_CHECKPOINT_ID, PLANNING_DEEPEN_CHECKPOINT_QUESTION, PLANNING_DEEPEN_PROCEED_OPTION_ID, PLANNING_DEEPEN_PROCEED_RESPONSE_KEY, MERGE_ADVANCE_AUTO_SYNC_MODES, normalizeMergeConflictStrategy, normalizeMergeStrategyOverlapBehavior, normalizePostMergeAuditMode, POST_MERGE_AUDIT_MODES, normalizeMergeAuditAutoRecovery, MERGE_AUDIT_AUTO_RECOVERY_MODES, normalizeMergerMode, MERGER_MODES, normalizeAutoRecovery, AUTO_RECOVERY_MODES, buildResearchDocumentKey, REPO_OVERRIDE_RE, SHARED_STATE_SNAPSHOT_VERSION, sanitizeCliAgentSettings, sanitizeCliAgentsSettings, sanitizeMcpServers, CLI_AGENT_ADAPTER_IDS, CLI_AGENT_AUTONOMY_MODES, isMcpSecretRef } from "./types.js";
|
||||
export type { Column, ColumnId, IssueInfo, IssueState, TaskSourceIssue, TaskGitLabTracking, TaskGitLabTrackedItem, GitLabTrackedItemKind, PrInfo, PrConflictState, PrConflictDiagnostics, PrCheckState, PrCheckStatus, PrStatus, BranchGroup, BranchGroupCreateInput, BranchGroupUpdate, BranchGroupPrState, Task, TaskTokenUsage, TaskTokenUsagePerModel, TaskAttachment, TaskComment, TaskCommentInput, TaskDocument, TaskDocumentRevision, TaskDocumentCreateInput, TaskDocumentWithTask, ArtifactType, Artifact, ArtifactCreateInput, ArtifactWithTask, TaskCreateInput, MeshReplicatedTaskCreatePayload, MeshReplicatedTaskApplyResult, TaskSource, SourceType, TaskDetail, RetrySummary, InboxTask, TodoList, TodoItem, TodoListCreateInput, TodoListUpdateInput, TodoItemCreateInput, TodoItemUpdateInput, TodoListWithItems, AgentLogEntry, AgentLogType, AgentRole, BoardConfig, DistributedTaskIdReserveInput, DistributedTaskIdReserveResult, DistributedTaskIdCommitInput, DistributedTaskIdCommitResult, DistributedTaskIdAbortInput, DistributedTaskIdAbortResult, DistributedTaskIdStateInput, DistributedTaskIdStateResult, AutostashOrphanRecord, AutostashOutcome, MergeDetails, MergeResult, MergeIntegrationWorktreeMode, MergeAdvanceAutoSyncMode, MergeConflictStrategy, CanonicalMergeConflictStrategy, MergeStrategyOverlapBehavior, PostMergeAuditMode, MergeAuditAutoRecoveryMode, MergerMode, MergerSettings, AutoRecoveryMode, AutoRecoveryFailureClass, AutoRecoverySettings, DirectMergeCommitStrategy, Settings, GlobalSettings, ProjectSettings, SecretsEnvConfig, WebSearchBackend, ResearchEnabledSources, ResearchGlobalDefaults, ResearchProjectLimits, ResearchProjectSettings, SandboxBackendName, SandboxFailureMode, SandboxPolicy, SandboxProjectSettings, EvalFollowUpPolicy, EvalProjectSettings, ResolvedEvalSettings, SettingsScope, DaemonTokenSettings, TaskStep, StepStatus, TaskLogEntry, RunMutationContext, ActivityLogEntry, ActivityEventType, ThinkingLevel, ThemeMode, ColorTheme, Locale, ExecutionMode, PlannerOversightLevel, TaskPriority, MergeQueueEntry, MergeQueueEnqueueOptions, MergeQueueAcquireOptions, MergeQueueReleaseOutcome, MergeRequestState, MergeRequestRecord, MergeRequestWorkflowProjectionOptions, CompletionHandoffMarker, WorkflowWorkItem, WorkflowWorkItemDueFilter, WorkflowWorkItemKind, WorkflowWorkItemState, WorkflowWorkItemTransitionPatch, WorkflowWorkItemUpsertInput, HandoffEvidence, HandoffToReviewOptions, UnavailableNodePolicy, OwningNodeHandoffPolicy, PlanningQuestion, PlanningSummary, PlanningResponse, PlanningQuestionType, ArchivedTaskEntry, BatchStatusRequest, BatchStatusResponse, BatchStatusEntry, BatchStatusResult, GithubIssueAction, ModelPreset, WorkflowStep, WorkflowStepMode, WorkflowStepGateMode, WorkflowStepPhase, WorkflowStepInput, WorkflowStepResult, WorkflowStepTemplate, Agent, OrgTreeNode, AgentState, AgentDetail, AgentCreateInput, AgentUpdateInput, AgentApiKey, AgentApiKeyCreateResult, AgentCapability, AgentPromptTemplate, AgentPromptsConfig, AgentPermission, PermanentAgentActionCategory, PermanentAgentSensitiveActionCategory, PermanentAgentGatingContext, AgentPermissionPolicy, AgentPermissionPolicyRules, AgentPermissionPolicyToolRules, AgentPermissionPolicyActionCategory, AgentProvisioningApprovalMode, SandboxProvisioningApprovalMode, LegacyAgentPermissionPolicyActionCategory, ApprovalRequestActionCategoryInput, ApprovalRequestActionCategory, AgentPermissionPolicyDisposition, AgentPermissionPolicyPresetId, ApprovalRequestStatus, ApprovalRequestAuditEventType, ApprovalRequestActorSnapshot, ApprovalRequestTargetAction, ApprovalRequestAuditEvent, ApprovalRequest, ApprovalRequestCreateInput, ApprovalRequestDecisionInput, ApprovalRequestCompletionInput, ApprovalRequestListInput, TaskAssignSource, AgentAccessState, AgentHeartbeatConfig, AgentBudgetConfig, AgentBudgetStatus, InstructionsBundleConfig, MessageResponseMode, AgentHeartbeatEvent, AgentHeartbeatRun, BlockedStateSnapshot, HeartbeatInvocationSource, AgentTaskSession, AgentRating, AgentRatingSummary, AgentRatingInput, AgentConfigSnapshot, RevisionFieldDiff, AgentConfigRevision, AgentStats, ReflectionTrigger, ReflectionMetrics, AgentReflection, AgentPerformanceSummary, NtfyNotificationEvent, NotificationEvent, NotificationPayload, NotificationProviderConfig, CustomProvider, SteeringComment, ParticipantType, MessageType, Message, MessageCreateInput, MessageFilter, MessageMetadata, MessageReplyReference, Mailbox, CheckoutLease, CheckoutClaimPrecondition, TaskClaimRow, CentralClaimStore, RunAuditDomain, RunAuditEvent, RunAuditEventInput, RunAuditEventFilter, AgentMemoryInclusionMode, HeartbeatPromptTemplate, HeartbeatScopeDisciplineMode, WorktrunkSettings, WorktrunkOnFailure, TaskBranchContext, CliAgentSettings, McpSecretRef, McpSensitiveValue, McpStdioTransport, McpSseTransport, McpStreamableHttpTransport, McpTransport, McpServerDefinition, McpServersSettings, GitlabConfigSettingsSource, ResolvedGitlabConfig, ResolveGitlabConfigInput, GitlabAuthTokenType } from "./types.js";
|
||||
export { AGENT_VALID_TRANSITIONS, DUPLICATE_OF_METADATA_KEY, assertNotWorkspaceTaskMerge, isWorkspaceTask, WorkspaceTaskMergeError } from "./types.js";
|
||||
export {
|
||||
resolveEntryPointBranchAssignment,
|
||||
@@ -417,6 +417,7 @@ export {
|
||||
resolveEffectiveSettingsDetailed,
|
||||
resolveEffectiveSettingsById,
|
||||
resolveOptionalReviewRevisionBudget,
|
||||
resolveEffectivePlannerOversightLevel,
|
||||
PLAN_REVIEW_MAX_REVISIONS_SETTING_ID,
|
||||
CODE_REVIEW_MAX_REVISIONS_SETTING_ID,
|
||||
type WorkflowSettingsResolverStore,
|
||||
|
||||
@@ -101,6 +101,7 @@ export function taskMatchesReplicatedCreate(existing: TaskDetail, payload: MeshR
|
||||
assigneeUserId: existing.assigneeUserId,
|
||||
reviewLevel: existing.reviewLevel,
|
||||
executionMode: existing.executionMode,
|
||||
plannerOversightLevel: existing.plannerOversightLevel,
|
||||
priority: existing.priority,
|
||||
sourceIssue: existing.sourceIssue,
|
||||
source: toTaskSource({
|
||||
@@ -152,6 +153,7 @@ export function toReplicatedCreateInput(task: Task): TaskCreateInput {
|
||||
assigneeUserId: task.assigneeUserId,
|
||||
reviewLevel: task.reviewLevel,
|
||||
executionMode: task.executionMode,
|
||||
plannerOversightLevel: task.plannerOversightLevel,
|
||||
priority: task.priority,
|
||||
sourceIssue: task.sourceIssue,
|
||||
source: toTaskSource({
|
||||
|
||||
@@ -270,6 +270,7 @@ interface TaskRow {
|
||||
summary: string | null;
|
||||
thinkingLevel: string | null;
|
||||
executionMode: string | null;
|
||||
plannerOversightLevel: string | null;
|
||||
tokenUsageInputTokens: number | null;
|
||||
tokenUsageOutputTokens: number | null;
|
||||
tokenUsageCachedTokens: number | null;
|
||||
@@ -435,6 +436,7 @@ const TASK_COLUMN_DESCRIPTORS: TaskColumnDescriptor[] = [
|
||||
defineTaskColumn("summary", (task) => task.summary ?? null),
|
||||
defineTaskColumn("thinkingLevel", (task) => task.thinkingLevel ?? null),
|
||||
defineTaskColumn("executionMode", (task) => task.executionMode ?? null),
|
||||
defineTaskColumn("plannerOversightLevel", (task) => task.plannerOversightLevel ?? null),
|
||||
defineTaskColumn("tokenUsageInputTokens", (task) => task.tokenUsage?.inputTokens ?? null),
|
||||
defineTaskColumn("tokenUsageOutputTokens", (task) => task.tokenUsage?.outputTokens ?? null),
|
||||
defineTaskColumn("tokenUsageCachedTokens", (task) => task.tokenUsage?.cachedTokens ?? null),
|
||||
@@ -2119,6 +2121,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
summary: row.summary || undefined,
|
||||
thinkingLevel: (row.thinkingLevel || undefined) as Task["thinkingLevel"],
|
||||
executionMode: (row.executionMode || undefined) as Task["executionMode"],
|
||||
plannerOversightLevel: (row.plannerOversightLevel || undefined) as Task["plannerOversightLevel"],
|
||||
createdAt: row.createdAt,
|
||||
updatedAt: row.updatedAt,
|
||||
columnMovedAt: row.columnMovedAt || undefined,
|
||||
@@ -2665,7 +2668,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
"validatorModelProvider", "validatorModelId",
|
||||
"planningModelProvider", "planningModelId",
|
||||
"mergeRetries", "workflowStepRetries", "stuckKillCount", "resumeLimboCount", "graphResumeRetryCount", "resumeLimboTipSha", "resumeLimboStepSignature", "postReviewFixCount", "recoveryRetryCount", "taskDoneRetryCount", "worktreeSessionRetryCount", "completionHandoffLimboRecoveryCount", "verificationFailureCount", "mergeConflictBounceCount", "mergeAuditBounceCount", "mergeTransientRetryCount", "branchConflictRecoveryCount", "reviewerContextRetryCount", "reviewerFallbackRetryCount", "nextRecoveryAt",
|
||||
"error", "summary", "thinkingLevel", "executionMode",
|
||||
"error", "summary", "thinkingLevel", "executionMode", "plannerOversightLevel",
|
||||
"tokenUsageInputTokens", "tokenUsageOutputTokens", "tokenUsageCachedTokens", "tokenUsageCacheWriteTokens", "tokenUsageTotalTokens", "tokenUsageFirstUsedAt", "tokenUsageLastUsedAt", "tokenUsageModelProvider", "tokenUsageModelId", "tokenUsagePerModel", "tokenBudgetSoftAlertedAt", "tokenBudgetHardAlertedAt", "tokenBudgetOverride",
|
||||
"createdAt", "updatedAt", "columnMovedAt", "firstExecutionAt", "cumulativeActiveMs", "columnDwellMs", "executionStartedAt", "executionCompletedAt",
|
||||
"dependencies", "steps", "customFields", "comments", "review", "reviewState", "workflowStepResults", "steeringComments",
|
||||
@@ -2761,7 +2764,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
"validatorModelProvider", "validatorModelId",
|
||||
"planningModelProvider", "planningModelId",
|
||||
"mergeRetries", "workflowStepRetries", "stuckKillCount", "resumeLimboCount", "graphResumeRetryCount", "resumeLimboTipSha", "resumeLimboStepSignature", "postReviewFixCount", "recoveryRetryCount", "taskDoneRetryCount", "worktreeSessionRetryCount", "completionHandoffLimboRecoveryCount", "verificationFailureCount", "mergeConflictBounceCount", "mergeAuditBounceCount", "mergeTransientRetryCount", "branchConflictRecoveryCount", "reviewerContextRetryCount", "reviewerFallbackRetryCount", "nextRecoveryAt",
|
||||
"error", "summary", "thinkingLevel", "executionMode",
|
||||
"error", "summary", "thinkingLevel", "executionMode", "plannerOversightLevel",
|
||||
"tokenUsageInputTokens", "tokenUsageOutputTokens", "tokenUsageCachedTokens", "tokenUsageCacheWriteTokens", "tokenUsageTotalTokens", "tokenUsageFirstUsedAt", "tokenUsageLastUsedAt", "tokenUsageModelProvider", "tokenUsageModelId", "tokenUsagePerModel", "tokenBudgetSoftAlertedAt", "tokenBudgetHardAlertedAt", "tokenBudgetOverride",
|
||||
"createdAt", "updatedAt", "columnMovedAt", "firstExecutionAt", "cumulativeActiveMs", "columnDwellMs", "executionStartedAt", "executionCompletedAt",
|
||||
"dependencies", "steps", "customFields", "attachments", "steeringComments",
|
||||
@@ -5021,6 +5024,7 @@ ${TASK_UPSERT_SQL_ASSIGNMENTS}
|
||||
thinkingLevel: input.thinkingLevel,
|
||||
reviewLevel: input.reviewLevel,
|
||||
executionMode: input.executionMode,
|
||||
plannerOversightLevel: input.plannerOversightLevel,
|
||||
baseBranch: input.baseBranch,
|
||||
branch: input.branch,
|
||||
missionId: input.missionId,
|
||||
@@ -8313,7 +8317,7 @@ ${TASK_UPSERT_SQL_ASSIGNMENTS}
|
||||
|
||||
async updateTask(
|
||||
id: string,
|
||||
updates: { title?: string; description?: string; priority?: TaskPriority | null; prompt?: string; worktree?: string | null; workspaceWorktrees?: import("./types.js").Task["workspaceWorktrees"]; status?: string | null; dependencies?: string[]; steps?: import("./types.js").TaskStep[]; customFields?: Record<string, unknown>; currentStep?: number; blockedBy?: string | null; overlapBlockedBy?: string | null; assignedAgentId?: string | null; pausedByAgentId?: string | null; pausedReason?: string | null; tokenBudgetSoftAlertedAt?: string | null; worktrunkFallbackAlertedAt?: string | null; worktrunkFailure?: import("./types.js").Task["worktrunkFailure"] | null; tokenBudgetHardAlertedAt?: string | null; tokenBudgetOverride?: import("./types.js").TaskTokenBudgetOverride | null; dispatchStormCount?: number | null; lastDispatchAt?: string | null; assigneeUserId?: string | null; scopeOverride?: boolean | null; scopeOverrideReason?: string | null; scopeAutoWiden?: string[] | null; nodeId?: string | null; effectiveNodeId?: string | null; effectiveNodeSource?: string | null; checkedOutBy?: string | null; checkedOutAt?: string | null; checkoutNodeId?: string | null; checkoutRunId?: string | null; checkoutLeaseRenewedAt?: string | null; checkoutLeaseEpoch?: number | null; paused?: boolean; baseBranch?: string | null; autoMerge?: boolean | null; branch?: string | null; executionStartBranch?: string | null; baseCommitSha?: string | null; size?: "S" | "M" | "L"; reviewLevel?: number; executionMode?: import("./types.js").ExecutionMode | null; mergeRetries?: number; workflowStepRetries?: number; stuckKillCount?: number | null; resumeLimboCount?: number | null; graphResumeRetryCount?: number | null; resumeLimboTipSha?: string | null; resumeLimboStepSignature?: string | null; postReviewFixCount?: number | null; recoveryRetryCount?: number | null; taskDoneRetryCount?: number | null; worktreeSessionRetryCount?: number | null; completionHandoffLimboRecoveryCount?: number | null; verificationFailureCount?: number | null; mergeConflictBounceCount?: number | null; mergeAuditBounceCount?: number | null; mergeTransientRetryCount?: number | null; branchConflictRecoveryCount?: number | null; reviewerContextRetryCount?: number | null; reviewerFallbackRetryCount?: number | null; nextRecoveryAt?: string | null; enabledWorkflowSteps?: string[]; noCommitsExpected?: boolean | null; modelProvider?: string | null; modelId?: string | null; validatorModelProvider?: string | null; validatorModelId?: string | null; planningModelProvider?: string | null; planningModelId?: string | null; thinkingLevel?: string | null; error?: string | null; summary?: string | null; sessionFile?: string | null; firstExecutionAt?: string | null; cumulativeActiveMs?: number | null; executionStartedAt?: string | null; executionCompletedAt?: string | null; review?: import("./types.js").TaskReview | null; reviewState?: import("./types.js").TaskReviewState | null; workflowStepResults?: import("./types.js").WorkflowStepResult[] | null; mergeDetails?: import("./types.js").MergeDetails | null; sourceIssue?: import("./types.js").TaskSourceIssue | null; sourceMetadataPatch?: Record<string, unknown> | null; githubTracking?: import("./types.js").TaskGithubTracking | null; gitlabTracking?: (Omit<import("./types.js").TaskGitLabTracking, "item"> & { item?: import("./types.js").TaskGitLabTrackedItem | null }) | null; tokenUsage?: import("./types.js").TaskTokenUsage | null; modifiedFiles?: string[] | null; workflowTransitionNotification?: import("./types.js").Task["workflowTransitionNotification"] | null; missionId?: string | null; sliceId?: string | null },
|
||||
updates: { title?: string; description?: string; priority?: TaskPriority | null; prompt?: string; worktree?: string | null; workspaceWorktrees?: import("./types.js").Task["workspaceWorktrees"]; status?: string | null; dependencies?: string[]; steps?: import("./types.js").TaskStep[]; customFields?: Record<string, unknown>; currentStep?: number; blockedBy?: string | null; overlapBlockedBy?: string | null; assignedAgentId?: string | null; pausedByAgentId?: string | null; pausedReason?: string | null; tokenBudgetSoftAlertedAt?: string | null; worktrunkFallbackAlertedAt?: string | null; worktrunkFailure?: import("./types.js").Task["worktrunkFailure"] | null; tokenBudgetHardAlertedAt?: string | null; tokenBudgetOverride?: import("./types.js").TaskTokenBudgetOverride | null; dispatchStormCount?: number | null; lastDispatchAt?: string | null; assigneeUserId?: string | null; scopeOverride?: boolean | null; scopeOverrideReason?: string | null; scopeAutoWiden?: string[] | null; nodeId?: string | null; effectiveNodeId?: string | null; effectiveNodeSource?: string | null; checkedOutBy?: string | null; checkedOutAt?: string | null; checkoutNodeId?: string | null; checkoutRunId?: string | null; checkoutLeaseRenewedAt?: string | null; checkoutLeaseEpoch?: number | null; paused?: boolean; baseBranch?: string | null; autoMerge?: boolean | null; branch?: string | null; executionStartBranch?: string | null; baseCommitSha?: string | null; size?: "S" | "M" | "L"; reviewLevel?: number; executionMode?: import("./types.js").ExecutionMode | null; plannerOversightLevel?: import("./types.js").PlannerOversightLevel | null; mergeRetries?: number; workflowStepRetries?: number; stuckKillCount?: number | null; resumeLimboCount?: number | null; graphResumeRetryCount?: number | null; resumeLimboTipSha?: string | null; resumeLimboStepSignature?: string | null; postReviewFixCount?: number | null; recoveryRetryCount?: number | null; taskDoneRetryCount?: number | null; worktreeSessionRetryCount?: number | null; completionHandoffLimboRecoveryCount?: number | null; verificationFailureCount?: number | null; mergeConflictBounceCount?: number | null; mergeAuditBounceCount?: number | null; mergeTransientRetryCount?: number | null; branchConflictRecoveryCount?: number | null; reviewerContextRetryCount?: number | null; reviewerFallbackRetryCount?: number | null; nextRecoveryAt?: string | null; enabledWorkflowSteps?: string[]; noCommitsExpected?: boolean | null; modelProvider?: string | null; modelId?: string | null; validatorModelProvider?: string | null; validatorModelId?: string | null; planningModelProvider?: string | null; planningModelId?: string | null; thinkingLevel?: string | null; error?: string | null; summary?: string | null; sessionFile?: string | null; firstExecutionAt?: string | null; cumulativeActiveMs?: number | null; executionStartedAt?: string | null; executionCompletedAt?: string | null; review?: import("./types.js").TaskReview | null; reviewState?: import("./types.js").TaskReviewState | null; workflowStepResults?: import("./types.js").WorkflowStepResult[] | null; mergeDetails?: import("./types.js").MergeDetails | null; sourceIssue?: import("./types.js").TaskSourceIssue | null; sourceMetadataPatch?: Record<string, unknown> | null; githubTracking?: import("./types.js").TaskGithubTracking | null; gitlabTracking?: (Omit<import("./types.js").TaskGitLabTracking, "item"> & { item?: import("./types.js").TaskGitLabTrackedItem | null }) | null; tokenUsage?: import("./types.js").TaskTokenUsage | null; modifiedFiles?: string[] | null; workflowTransitionNotification?: import("./types.js").Task["workflowTransitionNotification"] | null; missionId?: string | null; sliceId?: string | null },
|
||||
runContext?: RunMutationContext,
|
||||
): Promise<Task> {
|
||||
return this.withTaskLock(id, () => this.updateTaskUnlocked(id, updates, runContext));
|
||||
@@ -9129,6 +9133,11 @@ ${TASK_UPSERT_SQL_ASSIGNMENTS}
|
||||
} else if (updates.executionMode !== undefined) {
|
||||
task.executionMode = updates.executionMode as import("./types.js").ExecutionMode;
|
||||
}
|
||||
if (updates.plannerOversightLevel === null) {
|
||||
task.plannerOversightLevel = undefined;
|
||||
} else if (updates.plannerOversightLevel !== undefined) {
|
||||
task.plannerOversightLevel = updates.plannerOversightLevel as import("./types.js").PlannerOversightLevel;
|
||||
}
|
||||
if (updates.error === null) {
|
||||
task.error = undefined;
|
||||
} else if (updates.error !== undefined) {
|
||||
|
||||
@@ -272,6 +272,18 @@ export type ExecutionMode = (typeof EXECUTION_MODES)[number];
|
||||
/** Default execution mode for new tasks */
|
||||
export const DEFAULT_EXECUTION_MODE: ExecutionMode = "standard";
|
||||
|
||||
/*
|
||||
* FNXC:PlannerOversight 2026-07-04-00:00:
|
||||
* Per-task override of the workflow-native `plannerOversightLevel` setting
|
||||
* (declared in `BUILTIN_OVERSIGHT_SETTINGS`, packages/core/src/builtin-workflow-settings.ts).
|
||||
* When a task sets this field, it wins over the workflow's effective oversight
|
||||
* value; unset (NULL in storage) means "inherit the workflow default". Values,
|
||||
* order, and default here must stay in sync with `BUILTIN_OVERSIGHT_SETTINGS`.
|
||||
*/
|
||||
export const PLANNER_OVERSIGHT_LEVELS = ["off", "observe", "steer", "autonomous"] as const;
|
||||
export type PlannerOversightLevel = (typeof PLANNER_OVERSIGHT_LEVELS)[number];
|
||||
export const DEFAULT_PLANNER_OVERSIGHT_LEVEL: PlannerOversightLevel = "autonomous";
|
||||
|
||||
/** Controls whether triage should require completion documentation artifacts in task specs. */
|
||||
export const COMPLETION_DOCUMENTATION_MODES = ["off", "changeset", "changelog"] as const;
|
||||
export type CompletionDocumentationMode = (typeof COMPLETION_DOCUMENTATION_MODES)[number];
|
||||
@@ -2456,6 +2468,11 @@ export interface Task {
|
||||
* - "fast": Expedited execution with minimal overhead for simple tasks
|
||||
* Defaults to "standard" when not specified. */
|
||||
executionMode?: ExecutionMode;
|
||||
/** Per-task override of the workflow-native planner oversight level (FNXC:PlannerOversight).
|
||||
* When set, wins over the workflow's effective `plannerOversightLevel`. Unset means
|
||||
* "inherit workflow default" — see `resolveEffectivePlannerOversightLevel` in
|
||||
* workflow-settings-resolver.ts for precedence. */
|
||||
plannerOversightLevel?: PlannerOversightLevel;
|
||||
/** Explicitly assigned agent ID for task-agent linking. Distinct from Agent.taskId active execution state. */
|
||||
assignedAgentId?: string;
|
||||
/** Per-task node override. When set, this task routes to the specified node instead of the project's default node. Undefined means use the project default. Use empty string to explicitly clear. */
|
||||
@@ -2733,6 +2750,10 @@ export interface TaskCreateInput {
|
||||
* - "fast": Expedited execution with minimal overhead for simple tasks
|
||||
* Defaults to "standard" when not specified. */
|
||||
executionMode?: ExecutionMode;
|
||||
/** Per-task override of the workflow-native planner oversight level (FNXC:PlannerOversight).
|
||||
* When set, wins over the workflow's effective `plannerOversightLevel`. Unset means
|
||||
* "inherit workflow default". */
|
||||
plannerOversightLevel?: PlannerOversightLevel;
|
||||
}
|
||||
|
||||
// ── Todo List Types ──────────────────────────────────────────────────────
|
||||
@@ -4878,6 +4899,8 @@ export interface ArchivedTaskEntry {
|
||||
* - "standard": Full execution with complete review workflow (default)
|
||||
* - "fast": Expedited execution with minimal overhead for simple tasks */
|
||||
executionMode?: ExecutionMode;
|
||||
/** Per-task override of the workflow-native planner oversight level at time of archival. */
|
||||
plannerOversightLevel?: PlannerOversightLevel;
|
||||
prInfo?: PrInfo;
|
||||
prInfos?: PrInfo[];
|
||||
issueInfo?: IssueInfo;
|
||||
|
||||
@@ -35,6 +35,7 @@ import {
|
||||
import { resolveEffectiveSettingValues, findOrphanedSettingValues } from "./workflow-settings.js";
|
||||
import { BUILTIN_WORKFLOW_SETTINGS } from "./builtin-workflow-settings.js";
|
||||
import type { WorkflowSettingDefinition, WorkflowIr, WorkflowOptionalGroupConfig } from "./workflow-ir-types.js";
|
||||
import { PLANNER_OVERSIGHT_LEVELS, DEFAULT_PLANNER_OVERSIGHT_LEVEL, type PlannerOversightLevel } from "./types.js";
|
||||
|
||||
export const PLAN_REVIEW_MAX_REVISIONS_SETTING_ID = "planReviewMaxRevisions";
|
||||
export const CODE_REVIEW_MAX_REVISIONS_SETTING_ID = "codeReviewMaxRevisions";
|
||||
@@ -226,3 +227,30 @@ export async function resolveEffectiveSettingsDetailed(
|
||||
}
|
||||
return effectiveFrom(store, ir, effectiveWorkflowId, projectId);
|
||||
}
|
||||
|
||||
function isPlannerOversightLevel(value: unknown): value is PlannerOversightLevel {
|
||||
return typeof value === "string" && (PLANNER_OVERSIGHT_LEVELS as readonly string[]).includes(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* FNXC:PlannerOversight 2026-07-04-00:00:
|
||||
* Resolves the effective planner oversight level for a task: a per-task
|
||||
* `Task.plannerOversightLevel` override (FN-7509) always wins over the
|
||||
* workflow's effective `plannerOversightLevel` setting value (declared in
|
||||
* `BUILTIN_OVERSIGHT_SETTINGS`, resolved via {@link resolveEffectiveSettings}).
|
||||
* If neither is set, or either value is an unrecognized string (defensive
|
||||
* normalization — never trust arbitrary/legacy input), falls back to
|
||||
* `DEFAULT_PLANNER_OVERSIGHT_LEVEL` ("autonomous"). Pure and never throws.
|
||||
*/
|
||||
export function resolveEffectivePlannerOversightLevel(
|
||||
taskOverride: PlannerOversightLevel | string | null | undefined,
|
||||
workflowEffective: PlannerOversightLevel | string | null | undefined,
|
||||
): PlannerOversightLevel {
|
||||
if (isPlannerOversightLevel(taskOverride)) {
|
||||
return taskOverride;
|
||||
}
|
||||
if (isPlannerOversightLevel(workflowEffective)) {
|
||||
return workflowEffective;
|
||||
}
|
||||
return DEFAULT_PLANNER_OVERSIGHT_LEVEL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user