You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Once a burn step is a reference to a scheduled task, the runner needs a way to invoke that task. server/services/quotaBurnJobs/agentPrompt.js currently queues directly through cosTaskStore.js with a synthesized free-form task, bypassing canonical task generation and its gates. #6372 requires a shared invocation path instead — and explicitly rules out an HTTP loopback or a synthetic task.
Scope
Shared invocation path. Resolve and validate the reference, reuse canonical task generation (server/services/taskSchedule.js#triggerOnDemandTask and cosTaskGenerator.js for built-ins; the autonomous-job generation in server/services/autonomousJobs/skillTemplates.js for custom jobs), and pass the step's immutable run overrides through to the resulting task. Add a distinct quota-burn origin to ON_DEMAND_ORIGINS (server/services/taskSchedule.js), carrying family, limiting-reset, burn-step id, and request/task identity.
Gates that must survive. Built-in master Improve gate, enabled state, instance-feature gate, scope, and invocation eligibility; custom-job approval and lifecycle rules. server/routes/cosJobRoutes.js's manual endpoint deliberately bypasses approval and revives/force-spawns tasks — an automated burn must not inherit those privileges. force may bypass the existing quota gates only, never task eligibility or approval.
Finite semantics. Selecting a perpetual task must invoke it once; it must not restart or drain its perpetual loop.
Picker eligibility. Restrict selectable references to eligible AI agent tasks plus the explicitly supported programmatic scheduled handlers. Exclude shell jobs, unrelated scripts, and system-managed-only actions.
countPending contract. Define a shared countPending(reference) → { count, detail, context? } on resolved references, matching the existing job-module contract documented in server/services/quotaBurnJobs/index.js:
an eligible AI agent task reports one ready unit after eligibility and pending/running checks;
an ineligible or already-active task reports zero with its reason;
a programmatic handler supplies its domain backlog count.
server/services/quotaBurnRunner.js keeps first-enabled-unspent-with-positive-count selection; zero-work steps are skipped. Reuse the single gate ladder in server/services/quotaBurn.js (evaluateFamily, selectBurnCandidates, evaluateFamilies) that the runner and the status page already share — do not add a second ladder. getQuotaBurnStatus must keep stripping the opaque probe context from the wire. Probes must enqueue nothing and call no AI provider.
Acceptance criteria
Service tests: resolved effective settings (overrides layered over the task's saved settings), scope validation, and refusal paths for disabled task, feature off, master-Improve off, missing custom-job approval, wrong-family provider pin, and dangling reference — each with a distinct reason and no dispatch.
A burn invocation of a custom job does not get the manual endpoint's approval bypass or force-spawn/revive behavior; asserted directly.
force: true bypasses the quota gate but still refuses an ineligible or unapproved task.
Invoking a perpetual task runs exactly one unit and leaves its perpetual loop untouched.
The generated task carries the quota-burn origin (family, limiting reset, burn-step id, request/task identity) and it survives persistence.
countPending returns one unit for an eligible agent task, zero-with-reason for an inactive/missing/already-active one, and the domain backlog count for a programmatic handler; ordered selection in the runner is preserved.
A probe test asserts zero writes, zero enqueues, and zero provider calls.
Notes
Depends on the burn-step reference model child. Blocks the accounting, audit-mode, migration, and editor children.
Problem / Goal
Once a burn step is a reference to a scheduled task, the runner needs a way to invoke that task.
server/services/quotaBurnJobs/agentPrompt.jscurrently queues directly throughcosTaskStore.jswith a synthesized free-form task, bypassing canonical task generation and its gates. #6372 requires a shared invocation path instead — and explicitly rules out an HTTP loopback or a synthetic task.Scope
Shared invocation path. Resolve and validate the reference, reuse canonical task generation (
server/services/taskSchedule.js#triggerOnDemandTaskandcosTaskGenerator.jsfor built-ins; the autonomous-job generation inserver/services/autonomousJobs/skillTemplates.jsfor custom jobs), and pass the step's immutable run overrides through to the resulting task. Add a distinct quota-burn origin toON_DEMAND_ORIGINS(server/services/taskSchedule.js), carrying family, limiting-reset, burn-step id, and request/task identity.Gates that must survive. Built-in master Improve gate, enabled state, instance-feature gate, scope, and invocation eligibility; custom-job approval and lifecycle rules.
server/routes/cosJobRoutes.js's manual endpoint deliberately bypasses approval and revives/force-spawns tasks — an automated burn must not inherit those privileges.forcemay bypass the existing quota gates only, never task eligibility or approval.Finite semantics. Selecting a perpetual task must invoke it once; it must not restart or drain its perpetual loop.
Picker eligibility. Restrict selectable references to eligible AI agent tasks plus the explicitly supported programmatic scheduled handlers. Exclude shell jobs, unrelated scripts, and system-managed-only actions.
countPendingcontract. Define a sharedcountPending(reference) → { count, detail, context? }on resolved references, matching the existing job-module contract documented inserver/services/quotaBurnJobs/index.js:server/services/quotaBurnRunner.jskeeps first-enabled-unspent-with-positive-count selection; zero-work steps are skipped. Reuse the single gate ladder inserver/services/quotaBurn.js(evaluateFamily,selectBurnCandidates,evaluateFamilies) that the runner and the status page already share — do not add a second ladder.getQuotaBurnStatusmust keep stripping the opaque probecontextfrom the wire. Probes must enqueue nothing and call no AI provider.Acceptance criteria
force: truebypasses the quota gate but still refuses an ineligible or unapproved task.countPendingreturns one unit for an eligible agent task, zero-with-reason for an inactive/missing/already-active one, and the domain backlog count for a programmatic handler; ordered selection in the runner is preserved.Notes
Depends on the burn-step reference model child. Blocks the accounting, audit-mode, migration, and editor children.
Part of #6372
When this ships, tick its box in the
## Decomposed intochecklist on #6372. If it is the last unchecked box, close #6372.