fix: opt workspace-maintenance tasks out of the agent-context gate#565
Merged
Conversation
The recurring workspace-maintenance system tasks (workspace_disk_emergency_cleanup, worktree_cleanup, workspace_retention_cleanup, workspace_hygiene_report) are registered as agent-less recurring schedules in data-machine-code.php, but each extends SystemTask without overriding requiresAgentContext(). They therefore inherited the base default of true, so TaskScheduler::schedule() logged "queued task requires agent context" (error_code task_scheduler_agent_context_required) and returned false before the task ran. On the live install workspace_disk_emergency_cleanup logged 213 identical hourly errors and the disk cleanup never ran. These are pure disk/file/git maintenance tasks driven by the Workspace service and gated by PluginSettings; none act as an agent or invoke an agent-scoped ability (the only agent_id they touch is read from task params, defaulting to 0, to forward into child cleanup chunk jobs). The honest fix is to opt out of the gate via requiresAgentContext(): false, not to fabricate agent identity. WorktreeCleanupChunkTask is fixed for the same reason: it is fanned out by the recurring parents which forward agent_id=0, so without the override the actual destructive cleanup chunks would be rejected by the same gate even after the parents are fixed. Fixes #564
Contributor
Homeboy Results —
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #564
Root cause
The recurring workspace-maintenance system tasks are registered in
data-machine-code.php(datamachine_recurring_schedulesfilter, ~lines 339–383) as agent-less schedules — noagent_id/agent_slug, notper_agent. But every one of themextends SystemTaskwithout overridingrequiresAgentContext(), so they inherited the base-class default oftrue.In
data-machinecoreTaskScheduler::schedule()(inc/Engine/Tasks/TaskScheduler.php ~161), when there is no agent context (empty($context['agent_slug']) && empty($context['agent_id'])) andrequiresAgentContext() === true, it logsTaskScheduler: queued task requires agent context(error_code: task_scheduler_agent_context_required) andreturn false— the task is rejected before it runs.On the live extrachill.com install,
workspace_disk_emergency_cleanupfired hourly and logged 213 identical errors (2026-05-30 → 2026-06-06, 100% of the DM error log); the emergency disk cleanup never executed.Tasks changed and why
All fixed by overriding
public function requiresAgentContext(): bool { return false; }— the opt-out theSystemTaskdocblock explicitly documents for "pure internal maintenance tasks." Notper_agent— disk cleanup is site-scoped; you do not want N cleanups fanned out per agent. No agent identity is fabricated.workspace_disk_emergency_cleanupworkspace_retention_cleanupworktree_cleanupworkspace_hygiene_reportworktree_cleanup_chunkSibling tasks affected and fixed in this PR
workspace_retention_cleanupisdefault_enabled => trueand was silently failing on the same gate daily.worktree_cleanupandworkspace_hygiene_reportare disabled by default but are registered the identical agent-less way and would fail immediately on enable. All three are fixed here.Why
worktree_cleanup_chunkis also fixedworktree_cleanup_chunkis the child task that performs the actual destructive cleanup (artifact deletion / worktree removal). The recurring parents schedule it viaTaskScheduler::scheduleBatch(), forwarding'agent_id' => (int)($params['agent_id'] ?? 0). Under an agent-less recurring run that isagent_id = 0, which isempty()— soscheduleBatch→schedule()would hit the same gate and reject every chunk. Without this override the fix would only move the failure one layer down and the real cleanup still would never run.Evidence that
executeTask()is pure maintenance (no agent-scoped calls)Read each
executeTask()end-to-end. Every one:PluginSettings::get(SETTING_KEY, ...),DataMachineCode\Workspace\Workspaceservice (disk/file/git operations),datamachine_logaction and callscompleteJob()/failJob().None read
agent_idfrom the engine snapshot and none invoke an agent-scoped ability. The onlyagent_idreference is(int)($params['agent_id'] ?? 0)forwarded intoscheduleBatch()for child-job linkage — it is never used as an ownership/authorization input.Verification
php -lclean on all five touched files.SystemTaskand reflectedrequiresAgentContext()— all returnfalse, each declared on its own class:Per the
TaskScheduler::schedule()gate logic (lines 161–175),requiresAgentContext() === falsemeans an agent-less recurring run no longer takes the error branch — it builds the system job snapshot and enqueues the workflow. Full end-to-end "completed job row" verification on prod requires the deployed plugin to carry this code (deploy is out of scope for this PR).