Skip to content

feat: add should_complete to CompletionConfig - #605

Open
ayushiahjolia wants to merge 1 commit into
mainfrom
feat/custom-completion-predicate
Open

feat: add should_complete to CompletionConfig#605
ayushiahjolia wants to merge 1 commit into
mainfrom
feat/custom-completion-predicate

Conversation

@ayushiahjolia

@ayushiahjolia ayushiahjolia commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Issue #, if available: #519

Description of changes:
Adds a should_complete predicate to CompletionConfig for map and parallel operations, giving full control over when a batch completes early.

from aws_durable_execution_sdk_python import complete_batch, continue_batch

config = CompletionConfig(
    should_complete=lambda status: (
        complete_batch() if status.success_count >= 2
        else continue_batch()
    )
)

The predicate receives a CompletionStatus snapshot (counts + per-item statuses) and returns a CompletionDecision - either continue_batch() or complete_batch(outcome). The outcome determines whether CUSTOM_COMPLETION_SUCCEEDED or CUSTOM_COMPLETION_FAILED is reported.

Key design decisions -

  • Cannot be combined with threshold fields (raises ValidationError)
  • Predicate must be deterministic and side-effect-free
  • Replay uses the checkpointed decision, never re-invokes the predicate
  • On resumed invocations, deferred until prior checkpoints replay

Testing -

  • Unit tests, integration tests and examples

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@ayushiahjolia
ayushiahjolia force-pushed the feat/custom-completion-predicate branch from 862e017 to c72785b Compare July 31, 2026 05:22
@ayushiahjolia ayushiahjolia changed the title feat: custom completion predicate feat: add should_complete to CompletionConfig Jul 31, 2026
@ayushiahjolia
ayushiahjolia temporarily deployed to ai-pr-review-runtime July 31, 2026 05:36 — with GitHub Actions Inactive
@ayushiahjolia
ayushiahjolia temporarily deployed to ai-pr-review-runtime July 31, 2026 05:36 — with GitHub Actions Inactive
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@ayushiahjolia
ayushiahjolia force-pushed the feat/custom-completion-predicate branch from c72785b to 306c81c Compare July 31, 2026 19:22
@ayushiahjolia
ayushiahjolia had a problem deploying to ai-pr-review-runtime July 31, 2026 19:39 — with GitHub Actions Failure
@ayushiahjolia
ayushiahjolia had a problem deploying to ai-pr-review-runtime July 31, 2026 19:39 — with GitHub Actions Failure
@ayushiahjolia
ayushiahjolia force-pushed the feat/custom-completion-predicate branch from 306c81c to 5483a62 Compare July 31, 2026 19:44
@ayushiahjolia
ayushiahjolia temporarily deployed to ai-pr-review-runtime July 31, 2026 20:13 — with GitHub Actions Inactive
@ayushiahjolia
ayushiahjolia temporarily deployed to ai-pr-review-runtime July 31, 2026 20:13 — with GitHub Actions Inactive
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@ayushiahjolia
ayushiahjolia force-pushed the feat/custom-completion-predicate branch from 5483a62 to fffee6d Compare July 31, 2026 21:17
@ayushiahjolia
ayushiahjolia temporarily deployed to ai-pr-review-runtime July 31, 2026 21:18 — with GitHub Actions Inactive
@ayushiahjolia
ayushiahjolia temporarily deployed to ai-pr-review-runtime July 31, 2026 21:18 — with GitHub Actions Inactive
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@ayushiahjolia
ayushiahjolia force-pushed the feat/custom-completion-predicate branch from fffee6d to 7ad4242 Compare July 31, 2026 21:55
@ayushiahjolia
ayushiahjolia force-pushed the feat/custom-completion-predicate branch from 7ad4242 to 302330d Compare July 31, 2026 21:56
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

if self.policy.should_complete is not None
else ()
)
decision = self.policy.evaluate(succeeded, failed, items_snapshot)

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 AI review

[P1] Restore prior branch state before invoking the predicate

On a resumed invocation, all branches start in memory as PENDING and prior terminal checkpoints are replayed concurrently. The predicate is therefore evaluated against partial, synthetic snapshots whose order depends on worker scheduling. For example, if A previously succeeded before B failed, replay may report B first; a deterministic predicate such as “fail when B fails unless A succeeded” can now choose a different outcome and omit previously started branches. Add a restoration barrier that reconstructs all branch state present at invocation start before evaluating should_complete, then add a resume test that reverses prior checkpoint event order.

@github-actions

Copy link
Copy Markdown
Contributor

Codex AI review

Found one high-severity replay-determinism defect. Current resume coverage only exercises a monotonic predicate and cannot detect restoration-order changes across multiple prior branches.

Reviewed commit 8131d24c2715a047913ba2e02e38b2bb1612bea9. Workflow run

@yaythomas yaythomas 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.

just two minor noin-func nits :)

The predicate must be deterministic and side-effect-free, and
depend only on the CompletionStatus provided, never on external
state. For a completion that must survive a mid-run resume,
prefer a monotonic decision (for example success_count >= n) so

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.

nit: "prefer" is a "must"? You argued on the codex review comments that resume determinism relies on monotonicity as a hard contract. A predicate that is false on the suspension time terminal set is false on every subset of it, but only if monotonicity is required.

assert result.status is InvocationStatus.SUCCEEDED
assert result.result is not None

import json

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.

inline `import. Please move it to the top of the module. Google style §3.13 via CONTRIBUTING → General style.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants