Skip to content

Add a MaintenanceTask base class so site-scoped tasks default to requiresAgentContext()=false #566

@chubes4

Description

@chubes4

Context

Follow-up hardening from #564 / PR #565.

Every system task in this plugin is site-scoped workspace maintenance — disk/file/git cleanup driven by the Workspace service and gated by PluginSettings. None of them act as an agent or invoke an agent-scoped ability. Yet they all extends SystemTask, whose requiresAgentContext() defaults to true (the safe default for content-mutating tasks in data-machine core).

That default is wrong for this plugin's domain. It means every DMC task author must remember to override requiresAgentContext(): bool { return false; }, and forgetting fails quietly: the task is registered as an agent-less recurring schedule (per_agent => false), so TaskScheduler::schedule() rejects it at the agent-context gate and logs an error every tick — the cleanup just silently stops running.

That is exactly what happened in #564: workspace_disk_emergency_cleanup logged 213 identical hourly errors over 7 days and never cleaned disk. PR #565 fixed it by adding the override to five task classes (WorkspaceDiskEmergencyCleanupTask, WorktreeCleanupTask, WorkspaceRetentionCleanupTask, WorkspaceHygieneReportTask, WorktreeCleanupChunkTask) — five hand-copied identical methods.

Proposal

Introduce a thin MaintenanceTask base class in this plugin that sets the site-scoped default once, mirroring core's existing DataMachine\Engine\AI\System\Tasks\Retention\RetentionTask (which already does exactly this for retention cleanup):

namespace DataMachineCode\Tasks;

use DataMachine\Engine\AI\System\Tasks\SystemTask;

abstract class MaintenanceTask extends SystemTask {

    /**
     * DMC tasks are site-scoped workspace maintenance with no agent owner.
     * Opt out of the agent-context gate by default; a task that genuinely
     * needs agent context can override back to true.
     */
    public function requiresAgentContext(): bool {
        return false;
    }
}

Then reparent the five maintenance tasks to extends MaintenanceTask and delete the five duplicated overrides.

Why this is the right shape

  • Makes the correct-for-DMC choice the default, so the failure mode in workspace_disk_emergency_cleanup fails hourly: queued task requires agent context (cleanup dead 7+ days) #564 cannot recur by omission.
  • Removes five copies of an identical method (DRY) and gives one obvious place to document the site-scoped contract.
  • Has direct precedent in data-machine core (RetentionTask does the same opt-out in its base).
  • A task that ever does need agent context can still override back to true explicitly — the escape hatch stays open in the other direction.

Acceptance criteria

  • New MaintenanceTask abstract base in inc/Tasks/ sets requiresAgentContext(): false.
  • The five existing maintenance tasks extend it and drop their individual overrides.
  • No behavior change vs PR fix: opt workspace-maintenance tasks out of the agent-context gate #565 — all five still report requiresAgentContext() === false.
  • php -l clean; existing task scheduling continues to pass the gate.

Constraints

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions