Task hygiene (ACTIVE-TASKS.md)
This document describes tactical hygiene for rows in ACTIVE-TASKS.md — separate from goal stewardship (state/goals/), which is the strategic layer. See GOAL-STEWARDSHIP-OPERATOR.md for goals.
With activeTask.ledger: facts, the file is a projection from SQLite facts; see ACTIVE-TASKS-PROJECTION.md for timestamps, sections, filters, and the operator flow (active-tasks render, reconcile).
What it does
-
Heartbeat escalation — When
activeTask.taskHygiene.heartbeatEscalationis notfalseand the last user message matches a heartbeat pattern (same sources as goal stewardship: built-in defaults andgoalStewardship.heartbeatPatterns), the plugin prepends a short<task-hygiene>block after the usual active-task summary and optional stale warnings. The block reminds the agent to reconcile the file (complete work, update Next, verify subagents) before replying withHEARTBEAT_OK(or equivalent). -
Optional “consider a goal” hint — Set
activeTask.taskHygiene.suggestGoalAfterTaskAgeDaysto a positive number. On heartbeat turns, tasks whoseUpdatedtimestamp is older than that many days are listed as long-running, with a pointer toactive_task_propose_goaland thengoal_register. Default is0(off). This does not create goals automatically. -
Size cap —
activeTask.taskHygiene.heartbeatNudgeMaxChars(default 2500, minimum 200 in the config parser) limits the hygiene block length. -
Long-running workflow registration guard — For user requests that typically require multi-step external handling (for example: PR queue processing, “continue until merged”, CI monitoring, deployment workflows, or “fix all issues”), task hygiene can prepend an
<active-task-registration>block with a stable task label and draft payload.mode: "suggest"(default): suggest a task payload.mode: "confirm": guard mode; instructs the agent to confirm/register task tracking before proceeding.mode: "auto_main_private": auto-creates/updates the task row foragent:main:*oragent:private:*sessions, and still shows the payload.mode: "off": disable this behavior.
Configuration (plugin memory config)
"activeTask": {
"enabled": true,
"filePath": "ACTIVE-TASKS.md",
"taskHygiene": {
"heartbeatEscalation": true,
"suggestGoalAfterTaskAgeDays": 0,
"heartbeatNudgeMaxChars": 2500,
"longRunningRegistration": {
"mode": "suggest"
}
}
}
Heartbeat pattern matching always uses goalStewardship heartbeat settings (patterns and compilation). If you customize patterns, both goal stewardship prepends and task hygiene use the same matchers.
Agent tool: active_task_propose_goal
Parameters: task_label (string) — matches an active row label (exact match first, then case-insensitive).
Behavior: Reads ACTIVE-TASKS.md at the configured path (resolved from OPENCLAW_WORKSPACE), finds the task, and returns a draft JSON payload suitable for goal_register (label, description, acceptance_criteria). Refine with the user and respect goal_register confirmation policy (confirmed: true) when configured.
Requires activeTask.enabled. The tool is registered with the plugin regardless of goalStewardship.enabled; registering a goal still requires goal stewardship to be on and within global limits.
Operations
- CLI:
openclaw hybrid-mem active-tasks reconcile— keeps subagent bookkeeping honest before you trustACTIVE-TASKS.mdfor heartbeats or audits. - CLI:
openclaw hybrid-mem active-tasks hygiene --dry-run(or--apply) — reports and cleans stale failed/dead-session rows plus duplicate normalized entities while preserving history. - Goals mirror: When
goalStewardship.heartbeatRefreshActiveTaskis on, heartbeat also refreshes the## Active Goalsmirror inACTIVE-TASKS.md(do not edit that section by hand). - Pre-finalization guard (#1271): On
agent_end, unfinished external-workflow signals (e.g. CI pending, background command still running, scheduled recheck) can trigger a guard that warns or blocks finalization until checkpoint evidence exists. Satisfy by:- Calling
active_task_checkpoint(when available), or - Writing project facts (
category:project) withstatus(in_progress/waiting/blocked),next, freshtask_updated(default freshness window: 2 hours), andrelated_sessionbound to the current session (waitingalso needs a persisted wake link; goal-backed rows also needgoal_assessin the turn). False positives can be bypassed explicitly by addingCHECKPOINT_GUARD_BYPASS: <short reason>in the final assistant message.
- Calling
Multi-agent and Telegram (2026.5.190+): related_session matching now distinguishes the main checkpoint session from Telegram (or other channel) session refs, and the pre-finalization guard avoids false blocks when another agent’s related_session fact is unrelated to the finishing turn. If finalization still feels stuck in a multi-agent deployment, confirm project facts use the correct session ref for the agent that is ending, or use the bypass line above.
Related docs
- GOAL-STEWARDSHIP-DESIGN.md — goals vs tactical tasks
- GOAL-STEWARDSHIP-OPERATOR.md — enabling goals and CLI