Skip to content

Native: abandoned remote activities must outlive their run (cancellation_policy abandon) #971

Open

Description

@rmcdaniel

Split from #958 / #969 after Security's review (#969 (comment)).

Today: native refuses an explicit cancellation_policy: abandon on schedule_activity with 409 activity_cancellation_policy_not_supported and unavailable: ["installed_runtime_activity_policy"] (#969). try_cancel and wait_cancellation_completed are supported.

Why: under Core 2.15.12, an abandoned remote activity keeps running after its parent run reaches its cooperative-cancelled terminal state, until it finishes or its own schedule_to_close deadline expires (DefaultActivityTaskBridge::poll, ActivityAbandonment::allows). Native ties activity work to an active parent:

  • both activity candidate queries (TASK_CANDIDATES_SQL and the cross-kind poll) require the parent pending, running or waiting;
  • complete_activity (and failure, heartbeat and lease paths, to be audited) go through active_run and refuse run_closed.

An abandoned task would be stranded once the run closes.

Needed: a narrow, fail-closed post-run authority. It requires the exact ActivityScheduled abandon snapshot, its schedule_to_close_deadline_at, and the run's matching canonical cooperative-cancelled close. Ordinary activities keep today's refusals. Cases from Security's review:

  1. an unclaimed ready abandoned activity stays pollable after the parent canonically cancels;
  2. a previously leased abandoned activity can complete or fail after that close, and records its terminal history;
  3. ordinary activities, and runs closed as completed, failed or terminated (or with corrupt history), stay refused;
  4. expiry still closes the activity at its original schedule-to-close deadline.

Then admit abandon again: the policy, its finite schedule_to_close_timeout (422), the snapshot deadline, and delivery without cancelling are already in #969's history.

Activity

  1. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    Server open-item pass, 2026-11-04.

    Owner: Server. I retained the Security-derived four-boundary plan: only a canonical cooperative-cancel close plus the exact abandon snapshot/original schedule-to-close deadline can authorize post-run activity polling/completion/failure. Completed, failed, terminated, corrupt and ordinary activity cases remain refused.

    Next source artifact audits candidate selection, heartbeat/renewal, failure/completion and deadline expiry together, with retained ready and already-leased cases plus negative controls. The current explicit abandon refusal stays until that complete bounded authority is qualified; removing active_run checks alone would widen authority incorrectly. General: schedule this native cancellation-parity slice after the current accepted train or name a higher-priority consumer dependency. No new runtime, schema or advertised support was introduced.

  2. rmcdaniel commented on Nov 11, 2026

    @rmcdaniel
    MemberAuthor

    Triage 2026-11-11: native still refuses cancellation_policy abandon explicitly (store.rs). Next: post-run authority for abandoned activities plus the four Security cases. Owner: server.

  3. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    Current reference audit found a contract change since the issue's Core 2.15.12 snapshot. Published Workflow 2.28.0 ClosingRunOpenWork retains remote abandon activities at ordinary completion, failure and continue-as-new, lists their identities in the terminal event's abandoned_activities, and suppresses later outcomes from the closed history. Its abandonedAtClose verifies the matching run, policy and terminal listing. ActivityAbandonment separately retains the canonical cooperative-cancel/deadline authority described by the original issue.

    The old criterion that all completed/failed runs must refuse, and that a later terminal activity outcome appends history, must therefore be reconciled with current Core before implementation. I asked Workflow to confirm these two explicit authority paths and the immutable closed prefix. Native continues to refuse abandon; current #1193 close settlement and the 3.9.1 notes make that boundary explicit.

    Owner server: after active release/customer correctness work, implement the current accepted authority at every candidate, claim, heartbeat, renew, completion/failure and expiry path, with exact policy/deadline/terminal identity negatives, no reopened run and no post-terminal history/task. Qualify ready and already-leased activities, finite deadline expiry, corrupt/missing terminal listings, restart and concurrent close. This remains a separate feature from the unchanged-schema correction release.

  4. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    Workflow confirms the current parity target has two distinct remote-abandon authority paths. Released Workflow2.28 (8ac207da, PR1121/1117 follow-through) added retention explicitly named by the matching WorkflowCompleted/WorkflowFailed/WorkflowContinuedAsNew terminal event's abandoned_activities. Current Security-approved draft1129 b930facd89321ce8a1454d9268a773e3be92fe21 extends that closure family to timeout cleanup and keeps a terminal-listed activity's own deadline/lease/attempt authority independent of the closed parent's hard deadlines.

    The separate canonical cooperative path in ActivityAbandonment::allows() requires the recorded ActivityScheduled abandon policy and matching original finite schedule-to-close deadline, current canonical cancellation context, and no ActivityCancelled outcome. After terminal cancellation it additionally requires the original recorded delivery and WorkflowCancelled bound to that same cancellation command. A legacy terminal cancel or termination cannot borrow this identity. The explicit terminal-list exception to parent deadline checks is separate; do not infer a blanket parent-deadline exemption from a row policy alone.

    Both accepted post-close paths preserve an immutable closed run history prefix. They may settle the independent activity/attempt/task rows and projections; they do not append its later outcome to the closed run. Missing terminal-list authority on an ordinary close is refused as run_closed. Own activity deadline expiry and stale lease/attempt fencing remain authoritative. This corrects the old2.15.12 acceptance description; it does not claim native implementation/publication. Server retains implementation after the active3.9.1 correctness release; Workflow owns portable/embedded clarification and final cross-runtime qualification.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:serverkind:defectA public product behavior is incorrectpriority:P3Lower-priority product improvementstatus:readyReady for implementation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions