Skip to content

fix(tasks): harden task-flow restore and maintenance#59672

Merged
vincentkoc merged 1 commit into
mainfrom
vk/taskflow-hardening
Apr 2, 2026
Merged

fix(tasks): harden task-flow restore and maintenance#59672
vincentkoc merged 1 commit into
mainfrom
vk/taskflow-hardening

Conversation

@vincentkoc

Copy link
Copy Markdown
Member

Summary

  • harden task-flow registry restore so failures degrade into audit findings instead of crashing first access
  • add task-flow audit and maintenance for stale, stuck, cancel-requested, and old terminal flows
  • fold task-flow checks into openclaw tasks audit and openclaw tasks maintenance

Testing

  • pnpm test -- src/cli/program/register.status-health-sessions.test.ts src/commands/doctor-workspace-status.test.ts src/plugins/runtime/index.test.ts src/tasks/task-flow-registry.audit.test.ts src/tasks/task-flow-registry.maintenance.test.ts src/tasks/task-flow-registry.test.ts src/tasks/task-executor.test.ts src/plugins/runtime/runtime-taskflow.test.ts
  • pnpm check
  • pnpm build

@vincentkoc vincentkoc self-assigned this Apr 2, 2026
@openclaw-barnacle openclaw-barnacle Bot added commands Command implementations size: L maintainer Maintainer-authored PR labels Apr 2, 2026
@vincentkoc
vincentkoc marked this pull request as ready for review April 2, 2026 12:38
@aisle-research-bot

aisle-research-bot Bot commented Apr 2, 2026

Copy link
Copy Markdown

🔒 Aisle Security Analysis

We found 1 potential security issue(s) in this PR:

# Severity Title
1 🟡 Medium Delayed detection of orphaned managed TaskFlows due to stale-threshold gate
1. 🟡 Delayed detection of orphaned managed TaskFlows due to stale-threshold gate
Property Value
Severity Medium
CWE CWE-778
Location src/tasks/task-flow-registry.audit.ts:225-236

Description

The missing_linked_tasks audit finding (for managed TaskFlows in running|waiting|blocked state with no linked tasks and no blocking metadata) is now only emitted after the flow age exceeds the relevant stale threshold.

  • ageMs is computed from now - (flow.updatedAt ?? flow.createdAt) and clamped to >= 0.
  • The new condition delays reporting of orphaned managed flows for up to stale*Ms (default 30 minutes).
  • If this audit is relied upon for anomaly/unauthorized-flow detection, repeatedly recreating/restarting flows (updating createdAt/updatedAt) can keep ageMs below the threshold and avoid generating findings.

Vulnerable code:

if (
  flow.syncMode === "managed" &&
  (flow.status === "running" || flow.status === "waiting" || flow.status === "blocked") &&
  ageMs >=
    (flow.status === "running"
      ? staleRunningMs
      : flow.status === "waiting"
        ? staleWaitingMs
        : staleBlockedMs) &&
  linkedTasks.length === 0 &&
  !hasBlockingMetadata(flow)
) {// ... createFinding({ code: "missing_linked_tasks", ... })
}

Recommendation

If orphaned managed flows are a security/operational signal, emit a finding immediately and add a separate stale-threshold escalation (e.g., warn immediately, error when stale), rather than suppressing the signal for up to stale*Ms.

Example approach:

if (
  flow.syncMode === "managed" &&
  (flow.status === "running" || flow.status === "waiting" || flow.status === "blocked") &&
  linkedTasks.length === 0 &&
  !hasBlockingMetadata(flow)
) {
  const threshold = flow.status === "running" ? staleRunningMs
                  : flow.status === "waiting" ? staleWaitingMs
                  : staleBlockedMs;

  findings.push(createFinding({
    severity: ageMs >= threshold ? (flow.status === "running" ? "error" : "warn") : "warn",
    code: "missing_linked_tasks",
    flow,
    ageMs,
    detail: "managed TaskFlow has no linked tasks or wait state",
  }));
}

Alternatively, introduce a short, dedicated threshold (e.g., 30–60s) for missing-linked-tasks detection distinct from stale-running/waiting/blocked thresholds.


Analyzed PR: #59672 at commit e1c85f9

Last updated on: 2026-04-02T13:57:35Z

@greptile-apps

greptile-apps Bot commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR hardens the task-flow registry by catching restore failures and degrading them into audit findings, and adds new listTaskFlowAuditFindings / maintenance helpers that are folded into the existing openclaw tasks audit and openclaw tasks maintenance commands. The implementation is well-structured and the new test files cover the primary scenarios (restore failure, stale/stuck flows, cancel reconciliation, pruning).

Two minor points worth noting:

  • The missing_linked_tasks audit check has no minimum-age gate (unlike stale_running's 30-minute threshold), which could emit spurious error findings for brand-new managed flows before their first child task is linked.
  • The --json output shape for both audit and maintenance changed structurally (summary.byCode is now nested under summary.tasks.byCode; auditBefore/auditAfter gained a tasks/taskFlows wrapper), which is a breaking change for any external JSON consumers.

Confidence Score: 5/5

  • Safe to merge; all findings are P2 style suggestions with no blocking defects.
  • No P0 or P1 issues found. The restore-failure hardening, audit logic, and maintenance reconciliation are all correct. The retry loop in finalizeCancelledFlow handles concurrent-update conflicts gracefully. The two P2 notes (no stale gate on missing_linked_tasks, JSON schema change) are informational and do not affect correctness or reliability of the primary runtime path.
  • No files require special attention beyond the two P2 notes on task-flow-registry.audit.ts and commands/tasks.ts.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/tasks/task-flow-registry.audit.ts
Line: 225-240

Comment:
**`missing_linked_tasks` has no minimum-age gate**

Unlike `stale_running` (which requires `ageMs >= 30 min`), the `missing_linked_tasks` check fires immediately — including for a managed flow that was just created in `"running"` status before its first child task is linked. If task linkage can lag flow-status promotion by even one tick, this will emit a spurious error-severity finding. Consider guarding with a small minimum threshold (e.g. the same `staleRunningMs`) or restricting to the already-stale case:

```ts
if (
  flow.syncMode === "managed" &&
  (flow.status === "running" || flow.status === "waiting" || flow.status === "blocked") &&
  ageMs >= (flow.status === "running" ? staleRunningMs : staleWaitingMs) &&
  linkedTasks.length === 0 &&
  !hasBlockingMetadata(flow)
) {
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/commands/tasks.ts
Line: 231-238

Comment:
**Breaking change to `--json` audit summary shape**

The `summary` object previously returned `{ total, errors, warnings, byCode }` (from `summarizeTaskAuditFindings`). It now returns `{ total, errors, warnings, tasks: {…byCode…}, taskFlows: {…} }`, so `summary.byCode` is gone. Any downstream consumers (scripts, integrations) reading `summary.byCode` directly will silently break. Similarly, the maintenance `--json` output's `auditBefore`/`auditAfter` moved from a flat `TaskAuditSummary` to `{ tasks, taskFlows }`, which is also a structural break. Worth a note in the PR or a changelog entry if external consumers exist.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "Merge branch 'main' into vk/taskflow-har..." | Re-trigger Greptile

Comment thread src/tasks/task-flow-registry.audit.ts
Comment thread src/commands/tasks.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1c8918427e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/commands/tasks.ts
@vincentkoc

Copy link
Copy Markdown
Member Author

Addressed the three review points in b6887a1010.

  • missing_linked_tasks now waits until the flow is already stale for its current status before emitting a finding, so a freshly-promoted managed flow does not false-positive before its first child task is linked.
  • tasks audit --json and tasks maintenance --json keep the existing task summary shape for compatibility and add TaskFlow data as additive fields instead of replacing the structure.
  • Combined task + TaskFlow audit findings are now globally sorted before --limit is applied, so limited output still surfaces the highest-priority findings first.

Verification:

  • pnpm test -- src/tasks/task-flow-registry.audit.test.ts src/tasks/task-flow-registry.maintenance.test.ts
  • pnpm check

@vincentkoc
vincentkoc force-pushed the vk/taskflow-hardening branch from b6887a1 to e1c85f9 Compare April 2, 2026 12:56
@vincentkoc
vincentkoc merged commit 12bd6b7 into main Apr 2, 2026
41 of 43 checks passed
@vincentkoc
vincentkoc deleted the vk/taskflow-hardening branch April 2, 2026 13:02
steipete pushed a commit to duncanita/openclaw that referenced this pull request Apr 4, 2026
lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
Nachx639 pushed a commit to Nachx639/clawdbot that referenced this pull request Jun 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commands Command implementations maintainer Maintainer-authored PR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant