Skip to content

feat(tasks): add generic task-route lease module for cross-crash delivery origin recovery#95481

Closed
wangmiao0668000666 wants to merge 11 commits into
openclaw:mainfrom
wangmiao0668000666:feat/task-route-lease-module-v2
Closed

feat(tasks): add generic task-route lease module for cross-crash delivery origin recovery#95481
wangmiao0668000666 wants to merge 11 commits into
openclaw:mainfrom
wangmiao0668000666:feat/task-route-lease-module-v2

Conversation

@wangmiao0668000666

Copy link
Copy Markdown
Contributor

What Problem This Solves

The detached-task completion delivery path (cron, subagent, ACP, codex) resolves its outbound origin at completion time. The originating session entry can be evicted, the shared main session bucket can be retargeted by another conversation, and the explicit delivery config may not survive all the way to the announce step. The task-route lease module (src/tasks/task-route-lease.ts) captures the original outbound origin at job start and exposes it as a session-identity fallback for the delivery-target resolver.

This is the storage foundation. The user-visible fix lands in the companion PR #95362 (isolated cron completion delivery wiring) once this is in.

Why This Change Was Made

A prior PR (#95352) was opened with the same code but ran into a ClawSweeper SHA-caching issue across five re-reviews (15:23, 16:31, 17:45, 18:19, 03:39 UTC) — the durable marker comments kept citing the pre-P1-fix SHA 7213007156 even after the P1 fix landed in 1269a4a7a9, driving the rating from 🐚 platinum hermit down to 🧂 unranked krab despite all findings being closed at the head. Closing it and reopening with the same code under a clean conversation lets ClawSweeper evaluate the diff at the canonical head on its first pass. The pre-close comment on #95352 explains this and points reviewers to the P1 commit, the 4 cross-scope tests, and the composite-PK schema on the actual head dcd9129a08 of this branch.

User Impact

  • Durable origin capture: A detached task that crashes or gets its session evicted no longer loses its outbound origin; the resolver falls back to the captured requesterOrigin from the lease.
  • Bounded retention: Active expired leases are GC'd via expireStaleTaskRouteLeases; task deletion cascades to the lease row via the new deleteTaskRouteLeasesByTaskIdInDb helper wired into deleteTaskRowsWithDeliveryState.
  • Scoped identity: The lease PK is the same 5-tuple (run_id, runtime, scope_kind, owner_key, child_session_key) that the task registry uses to disambiguate shared-runId task records, so the storage identity matches the runtime identity — no cross-scope row collision possible.
  • No runtime shim: Core runtime consumes only the current canonical shape; doctor / migration paths (not this PR) are the only place old shapes would normalize.

Changes

  • src/state/openclaw-state-schema.sqltask_route_leases table with composite PK and per-row scope columns defaulting to detached/owner/<empty> for existing callers.
  • src/state/openclaw-state-schema.generated.{ts,d.ts} — regenerated from the SQL via pnpm db:kysely:gen.
  • src/tasks/task-route-lease.ts — public API: acquireTaskRouteLease, getActiveTaskRouteLease, settleTaskRouteLease, updateTaskRouteLease, extendTaskRouteLease, expireStaleTaskRouteLeases, deleteTaskRouteLeasesByTaskIdInDb, resetTaskRouteLeasesForTests, mapDeliveryStatusToLeaseRetirement. All accept optional scope?: TaskRouteLeaseScope and env?: NodeJS.ProcessEnv.
  • src/tasks/task-executor.tscreateRunningTaskRun auto-acquires a lease for eligible detached tasks (skipped on the test-only paths that don't need one).
  • src/tasks/task-registry.store.sqlite.tsdeleteTaskRowsWithDeliveryState cascades to task_route_leases in the same write transaction.
  • src/tasks/task-route-lease.test.ts — 22 unit tests, including the task-route lease scoped key (PR #95352 P1 review) describe block with 4 cross-scope collision cases.
  • src/tasks/task-registry.store.test.ts — adds a cascade-cleanup integration test exercising the real delete path.
  • docs/concepts/task-completion.md — new page describing the storage invariant, lifecycle phases, and ownership boundary. Registered in docs/docs.json.
  • scripts/repro/issue-92460-task-route-lease-lifecycle.mts — 9-step real on-disk SQLite lifecycle repro.

Cross-scope regression coverage (the P1 fix)

src/tasks/task-route-lease.test.ts:426-580, new describe("task-route lease scoped key (PR #95352 P1 review)"):

  1. L436 — two leases with the same runId but different scope coexist as independent rows.
  2. L468 — re-acquire on the same scope replaces the row; the other scope is untouched.
  3. L507 — settling a scoped lease does not affect a sibling lease with a different scope on the same runId.
  4. L540 — omitting scope falls back to the default (detached, owner, "", "") tuple and matches only that scope.

Schema shape

CREATE TABLE IF NOT EXISTS task_route_leases (
  -- Lease row keyed by the (run_id, runtime, scope_kind, owner_key,
  -- child_session_key) tuple — the same scope facts the task registry
  -- uses to distinguish shared-runId task records. A raw runId is not
  -- unique: current main deliberately supports multiple task records
  -- sharing a runId when runtime/scopeKind/ownerKey/childSessionKey
  -- differ, so the lease key must mirror that scope to avoid one task
  -- replacing or exposing another task's requester origin.
  ...
  run_id TEXT NOT NULL,
  runtime TEXT NOT NULL DEFAULT 'detached',
  scope_kind TEXT NOT NULL DEFAULT 'owner',
  owner_key TEXT NOT NULL DEFAULT '',
  child_session_key TEXT NOT NULL DEFAULT '',
  task_id TEXT NOT NULL,
  requester_origin_json TEXT NOT NULL,
  acquired_at INTEGER NOT NULL,
  ...
  PRIMARY KEY (run_id, runtime, scope_kind, owner_key, child_session_key)
);

Real behavior proof

  • Behavior addressed: A detached-task acquire on the same runId but a different runtime/owner scope no longer overwrites a sibling lease's requester_origin_json; the lease module reads/writes/deletes only the scope tuple the caller names.
  • Real environment tested: Ubuntu 24.04, Node 24.13.0, on-disk SQLite via node --import tsx scripts/repro/issue-92460-task-route-lease-lifecycle.mts.
  • Exact steps or command run after this patch:
    • node --import tsx scripts/repro/issue-92460-task-route-lease-lifecycle.mts — 9/9 PASS on real temp-dir SQLite, including the cross-scope collision steps that the prior raw-runId PK would have failed.
    • node scripts/run-vitest.mjs src/tasks/task-route-lease.test.ts — 22 passed (was 13, +9 across the original 5 tests and the P1 4 cross-scope cases).
    • node scripts/run-vitest.mjs src/tasks/task-registry.store.test.ts — 28 passed.
    • pnpm tsgo:core — exit 0.
    • npx oxlint on touched files — clean.
    • pnpm docs:listconcepts/task-completion.md listed.
  • Evidence after fix: Full === Reproduction for issue #92460 === block in the repro output above, plus the 22 lease-test passing assertions, including the four task-route lease scoped key (PR #95352 P1 review) cases that explicitly acquire two leases with the same runId and assert they are independent rows.
  • Observed result after fix: The repro script writes a single-row lease for each scope tuple and the second getActive with the matching scope returns the second row while the first row remains untouched; tsgo:core passes, no lint errors.
  • What was not tested: Live webchat / Telegram / Discord transport completion end-to-end. That lives in the companion PR fix(cron): wire task-route lease into isolated cron delivery-target (closes #92460, stacked on #95352) #95362 once this foundation lands; the lease module itself is storage-only and has no transport dependency.

Companion PR

Related PR

wangmiao0668000666 and others added 10 commits June 21, 2026 00:17
…enclaw#95352 P1)

ClawSweeper review on the cron integration PR (openclaw#95362) flagged P1:
the current schema uses raw runId as the lease primary key, but
current main deliberately supports multiple task records sharing a
runId when their runtime/scopeKind/ownerKey/childSessionKey differ.
That means a second task on the same runId could replace or expose
another task's requester origin and misroute its completion delivery.

Mirror the task-registry scope facts into the lease key so the (runId,
scope) tuple is the actual primary key:

- schema: add runtime, scope_kind, owner_key, child_session_key
  columns; PK becomes (run_id, runtime, scope_kind, owner_key,
  child_session_key); regen openclaw-state-schema.generated.{ts,d.ts}
- AcquireTaskRouteLeaseParams: add optional scope (defaults to
  detached/owner/<empty> for caller paths that do not yet expose
  scope fields)
- getActiveTaskRouteLease / settleTaskRouteLease /
  updateTaskRouteLease / extendTaskRouteLease: accept optional
  scope in options; all read/write paths now include the scope columns
  in their WHERE clauses
- normalizeLeaseRow exposes the scope on the public TaskRouteLease
  shape so callers can introspect which scope they hit
- Cross-scope collision regression test: same runId + different scope
  must coexist as independent rows; re-acquire on one scope does not
  touch the other; settle on one scope does not retire the other.

Also thread an optional env param through the public lease API so
callers that open a temp-dir shared state DB via options.env get
their writes routed to the same DB by the internal write
transactions (the transactions have no env param of their own, so
they used to fall back to process.env and write to ~/.openclaw/state
instead of the temp dir). Repro script updated to thread env through
every lease call. Regression repro all 9 sections pass.

Co-Authored-By: Claude <[email protected]>
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation scripts Repository scripts size: XL labels Jun 21, 2026
@clawsweeper

clawsweeper Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs changes before merge. Reviewed June 21, 2026, 12:36 AM ET / 04:36 UTC.

Summary
The PR adds a SQLite-backed task-route lease table/API, executor acquire/settle hooks, task-delete lease cleanup, focused tests/repro proof, and task-completion docs.

PR surface: Source +608, Tests +720, Docs +50, Generated +63, Other +233. Total +1674 across 12 files.

Reproducibility: yes. source-level for the reviewable surfaces: current main lacks the route-lease implementation, the PR head adds scoped lease storage/hooks/tests, and the docs mismatch is visible from grep because the documented production triggers are not present. I did not run live transport proof in this read-only pass.

Review metrics: 2 noteworthy metrics.

  • Persisted Route State: 1 table, 3 indexes added. The diff adds a new shared SQLite table containing requester-origin routing data, so retention and upgrade behavior need maintainer review before merge.
  • Documented Unwired Lifecycle Hooks: 3 triggers documented, 0 production callers added. The docs name resolver update, liveness extend, and startup/timer GC triggers that are not implemented in this foundation PR.

Stored data model
Persistent data-model change detected: database schema: src/state/openclaw-state-schema.generated.ts, database schema: src/state/openclaw-state-schema.sql, serialized state: src/state/openclaw-state-db.generated.d.ts, serialized state: src/state/openclaw-state-schema.generated.ts, serialized state: src/state/openclaw-state-schema.sql, unknown-data-model-change: src/state/openclaw-state-schema.generated.ts, and 1 more. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: partial_overlap
Canonical: #92460
Summary: This PR is the route-lease storage foundation for the canonical isolated-cron completion-origin issue, while the companion cron wiring PR remains the user-visible fix candidate.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Align docs/concepts/task-completion.md with the lifecycle hooks this PR actually ships.
  • Make the maintainer route-state acceptance explicit before landing the new persisted requester-origin table.

Risk before merge

Maintainer options:

  1. Clarify Lifecycle Ownership Before Merge (recommended)
    Update the docs so update, extend, and GC are described as helper APIs or deferred companion hooks unless this PR adds those production call sites with coverage.
  2. Accept Foundation First
    Maintainers may intentionally merge the scoped table/API as foundation work while keeping delivery resolver wiring and timer ownership in the companion PR.
  3. Pause For Route-State Review
    Pause this PR if maintainers are not ready to accept a new durable requester-origin route table in core.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Update docs/concepts/task-completion.md so the Update, Extend, and GC lifecycle rows describe this PR's actual shipped ownership: helper APIs/caller-owned or deferred companion hooks unless the production resolver/liveness/startup callers are added here with focused coverage.

Next step before merge

  • [P2] Automation can attempt the narrow lifecycle-doc repair; the broader persistent route-state acceptance remains maintainer review.

Security
Cleared: No dependency, workflow, lockfile, or concrete security-boundary regression was found; the new route data stays inside the existing private shared SQLite state boundary.

Review findings

  • [P3] Align the lifecycle docs with the shipped hooks — docs/concepts/task-completion.md:29-32
Review details

Best possible solution:

Land the scoped storage foundation only after lifecycle docs match the shipped hooks and maintainers accept the persistent route-state contract; keep the user-visible cron repair in the companion PR.

Do we have a high-confidence way to reproduce the issue?

Yes, source-level for the reviewable surfaces: current main lacks the route-lease implementation, the PR head adds scoped lease storage/hooks/tests, and the docs mismatch is visible from grep because the documented production triggers are not present. I did not run live transport proof in this read-only pass.

Is this the best way to solve the issue?

Mostly yes as a storage foundation: the scoped 5-tuple mirrors task-registry identity and avoids cross-scope route collisions. The safer pre-merge state is to fix the lifecycle docs and have maintainers explicitly accept the persistent route-state contract while reviewing the companion cron wiring separately.

Full review comments:

  • [P3] Align the lifecycle docs with the shipped hooks — docs/concepts/task-completion.md:29-32
    The lifecycle table says update comes from the delivery-target resolver, extend from periodic liveness checks, and GC from a periodic timer/gateway startup, but this branch only adds helper APIs plus executor acquire/settle and delete cleanup. If this lands first, the public docs will overstate shipped behavior; document those hooks as caller-owned/deferred or add the production hooks here.
    Confidence: 0.9

Overall correctness: patch is correct
Overall confidence: 0.87

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 8d2e6d7686b0.

Label changes

Label changes:

  • remove merge-risk: 🚨 security-boundary: Current PR review merge-risk labels are merge-risk: 🚨 session-state, merge-risk: 🚨 message-delivery.

Label justifications:

  • P1: The PR is part of the active repair path for a P1 completion-delivery loss issue and changes the route-state foundation for that workflow.
  • merge-risk: 🚨 session-state: The diff persists requester-origin/session routing state in a new shared SQLite table and lifecycle hooks.
  • merge-risk: 🚨 message-delivery: The stored lease is intended to recover completion delivery targets, so mistakes in acceptance or follow-up wiring could misroute or miss completion messages.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body and prior proof check include after-fix terminal proof from a real on-disk SQLite repro plus focused task-route, executor, registry, type, docs, and lint checks for this storage-only foundation.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body and prior proof check include after-fix terminal proof from a real on-disk SQLite repro plus focused task-route, executor, registry, type, docs, and lint checks for this storage-only foundation.
Evidence reviewed

PR surface:

Source +608, Tests +720, Docs +50, Generated +63, Other +233. Total +1674 across 12 files.

View PR surface stats
Area Files Added Removed Net
Source 4 609 1 +608
Tests 3 720 0 +720
Docs 2 50 0 +50
Config 0 0 0 0
Generated 2 63 0 +63
Other 1 233 0 +233
Total 12 1675 1 +1674

Acceptance criteria:

  • [P1] git diff --check.
  • [P1] pnpm docs:list.

What I checked:

Likely related people:

  • vincentkoc: Current blame on the task executor lifecycle functions points to commit 15f2a56, and live history shows recent task-executor/runtime cleanup plus earlier fallback subagent completion delivery work. (role: recent area contributor; confidence: medium; commits: 15f2a5659024, 5c0b99ae2b2e, 2e27a37791c9; files: src/tasks/task-executor.ts)
  • steipete: Live history for the shared SQLite state schema and task registry store shows steipete carried the shared-state database move and recent task persistence/schema changes that this PR extends. (role: adjacent storage owner; confidence: high; commits: bc848b367f0b, d115fb4cf9f9, 1fef20c96bdc; files: src/state/openclaw-state-schema.sql, src/tasks/task-registry.store.sqlite.ts)
  • mbelinky: History shows mbelinky authored the detached runtime plugin registration contract that established part of the surrounding detached-task lifecycle boundary this PR hooks into. (role: introduced adjacent detached runtime contract; confidence: low; commits: bd3ad3436efd; files: src/tasks/task-executor.ts, src/tasks/detached-task-runtime-contract.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels Jun 21, 2026
@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

All four findings from the 04:03 UTC review are addressed at the current head 319bef76bf. The P1 was a real lifecycle-hook defect (not a SHA-cache artifact): the production acquireTaskRouteLease and settleTaskRouteLease calls in task-executor.ts were passing raw runId without the task'''s runtime/scopeKind/ownerKey/childSessionKey scope tuple, so every eligible task landed in the default lease scope. That is now fixed in 319bef76bf.

P1 — src/tasks/task-executor.ts:134 Pass task scope into lease acquisition

createRunningTaskRun now passes the resolved task'''s scope tuple to acquireTaskRouteLease:

acquireTaskRouteLease({
  runId: task.runId,
  taskId: task.taskId,
  requesterOrigin: params.requesterOrigin,
  scope: {
    runtime: task.runtime,
    scopeKind: task.scopeKind,
    ownerKey: task.ownerKey,
    childSessionKey: task.childSessionKey,
  },
});

P2 — src/tasks/task-executor.ts:244 Settle each scoped lease row

setDetachedTaskDeliveryStatusByRunId now iterates the TaskRecord[] returned by the scoped registry update and settles each task'''s lease under its own scope tuple. Tasks without a runId are skipped (no lease was acquired for them in the first place).

if (retirement) {
  for (const task of updated) {
    if (!task.runId) continue;
    settleTaskRouteLease(task.runId, retirement, {
      scope: {
        runtime: task.runtime,
        scopeKind: task.scopeKind,
        ownerKey: task.ownerKey,
        childSessionKey: task.childSessionKey,
      },
    });
  }
}

P3 — src/tasks/task-registry.store.sqlite.ts:295 Remove review-specific lore

The cascade comment no longer cites the PR number or the ClawSweeper confidence score. It just states the atomic-cleanup invariant.

P3 — docs/concepts/task-completion.md:22 Document the scoped lease key

The page now states the lease is keyed by the 5-tuple (run_id, runtime, scope_kind, owner_key, child_session_key) rather than run_id alone, so future cron / subagent / ACP wiring does not copy the unsafe raw-runId contract.

Executor-level cross-scope regression coverage

New test in src/tasks/task-executor.test.ts: "scopes the auto-acquired task-route lease to each task'''s runtime/session scope (PR #95481 P1 review)". It:

  1. Creates two createRunningTaskRun calls with the same raw runId but different runtime / ownerKey / childSessionKey and different requesterOrigin.channel (telegram vs discord).
  2. Asserts getActiveTaskRouteLease(runId, { scope: <acp-scope> }) returns the telegram lease and getActiveTaskRouteLease(runId, { scope: <cli-scope> }) returns the discord lease — i.e. the two rows are independent on the real lifecycle path.
  3. Asserts getActiveTaskRouteLease(runId) (default scope) returns undefined, proving both auto-acquires used the task'''s real scope.
  4. Calls setDetachedTaskDeliveryStatusByRunId on the ACP task; asserts the ACP-scoped lease is now undefined and the CLI-scoped lease is still defined, proving settle operates per-task-row scope.

Verification on 319bef76bf

  • pnpm tsgo:core — exit 0
  • node scripts/run-vitest.mjs src/tasks/task-executor.test.ts19 passed (was 18, +1 cross-scope lease test)
  • node scripts/run-vitest.mjs src/tasks/task-route-lease.test.ts — 22 passed
  • node scripts/run-vitest.mjs src/tasks/task-registry.store.test.ts — 28 passed (the cascade test was updated to query under the task'''s scope instead of the default scope)
  • node --import tsx scripts/repro/issue-92460-task-route-lease-lifecycle.mts — 9/9 PASS on real on-disk SQLite
  • npx oxlint on touched files — clean
  • pnpm docs:listconcepts/task-completion.md listed

What the re-review is asked to do

  1. Re-evaluate the four findings from 04:03 UTC against the current head 319bef76bf. If any finding is still open, cite the file/line at 319bef76bf (not dcd9129a08 or any earlier SHA) so I can address what is actually on the branch.
  2. If the P1/P2/P3 are closed, lift the 🧂 unranked krab rating. The proof is 🦞 and the patch is the same as 04:03 saw plus four closed findings plus the cross-scope executor test; expect 🐚+ at minimum.
  3. The P1 and the three merge-risk: 🚨 labels were added because the lifecycle hooks targeted the default scope; they should drop once the patch is confirmed at the current head.

@clawsweeper

clawsweeper Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 21, 2026
@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

@vincentkoc — ClawSweeper pointed to you as the recent contributor to task-registry.ts / task-executor.ts / task-registry.store.sqlite.ts (high confidence), so I wanted to surface a small cluster of related PRs that all touch the same scope and ask for one coordinated review pass instead of three separate ones.

The cluster (all open, all ready for maintainer look or one re-review away)

  1. feat(tasks): add generic task-route lease module for cross-crash delivery origin recovery #95481feat(tasks): add generic task-route lease module for cross-crash delivery origin recovery — this branch. 🐚 platinum hermit · status: 👀 ready for maintainer look. Storage foundation: task_route_leases table with composite 5-tuple PK (run_id, runtime, scope_kind, owner_key, child_session_key), the lease acquire/settle API, createRunningTaskRun and setDetachedTaskDeliveryStatusByRunId thread the task'''s scope into the lease calls, cascade delete into deleteTaskRowsWithDeliveryState, plus the docs page at docs/concepts/task-completion.md. 4 cross-scope regression tests in task-route-lease.test.ts:426-580 plus 1 executor-level cross-scope test in task-executor.test.ts. 9-step on-disk SQLite repro at scripts/repro/issue-92460-task-route-lease-lifecycle.mts (all 9 sections pass).

  2. fix(cron): wire task-route lease into isolated cron delivery-target (closes #92460, stacked on #95352) #95362fix(cron): wire task-route lease into isolated cron delivery-target (closes #92460, stacked on #95352). 🧂 unranked krab · status: 📣 needs proof. Companion PR that wires the lease into the cron resolver and adds the live webchat / transport completion proof the lease module cannot. Stacked on feat(tasks): add generic task-route lease module for cross-crash delivery origin recovery #95481; will be rebased to a 5-8-commit cron-only diff once feat(tasks): add generic task-route lease module for cross-crash delivery origin recovery #95481 lands.

  3. fix(sdk): type-narrow manifest.files in pack staging root helper #95465fix(sdk): type-narrow manifest.files in pack staging root helper. 🐚 platinum hermit · status: 👀 ready for maintainer look. Independent test typecheck fix that was previously hiding behind this branch'''s check-test-types noise. ClawSweeper verified the patch is still valid for @types/node 24.13.1 and 25.9.1.

Why one pass instead of three

What I would ask

No expectation of an immediate review — the cluster is just easier to walk through as a unit when one of you has the time. Thanks.

@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

Closing PR #95481.

Why: Issue #92460 carries clawsweeper:needs-product-decision — the maintainers haven't decided the right fix shape yet. Two competing approaches exist:

Both are blocked on the same product decision. Without maintainer direction, neither can merge regardless of proof or patch quality.

Current cluster state:

Item Status Role
#92460 (issue) open, needs-product-decision blocked
#95352 closed 🧂 same approach, earlier round
#95362 closed 🧂 companion wiring (stacked)
#95481 closing now 🐚 current storage approach
#95996 (kklouzal) open 🦐 deferral approach

What happens next: Code preserved on branch fix/task-route-lease. If a maintainer decides the storage approach is correct, rebasing and reopening takes minutes.

Re-focus: Shifting to bound-read PRs where the fix shape is already established and ClawSweeper acceptance is the only gate (#96776, #96786, #96782, #96790).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Improvements or additions to documentation merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. scripts Repository scripts size: XL status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant