Skip to content

feat(core): enforce continuation provider compatibility at runtime#205

Merged
seanbrar merged 1 commit into
mainfrom
feat/public-continuation
Jun 16, 2026
Merged

feat(core): enforce continuation provider compatibility at runtime#205
seanbrar merged 1 commit into
mainfrom
feat/public-continuation

Conversation

@seanbrar

@seanbrar seanbrar commented Jun 16, 2026

Copy link
Copy Markdown
Owner

Summary

Complete the public Continuation primitive. The type, its
version/provider-stamped to_jsonable/from_jsonable round-trip, and the api
reference were already in place. The missing piece was the runtime half of the
"Continuation compatibility is a Pollux contract" requirement: nothing stopped an
app from passing Input(continuation=output.continuation) back under a different
provider.

validate_interaction now rejects, before dispatch, reusing a continuation whose
producing provider differs from the active one. A live continuation records its
provider, and its provider_state (response ids, provider-specific replay blocks
such as Anthropic's signed thinking blocks) is not portable, so replaying it under
another provider would corrupt the turn. This mirrors the serialized-side check in
Continuation.from_jsonable(expected_provider=...).

Related issue

None

Test plan

  • just check408 passed, 6 skipped (ruff format/lint, rumdl, mypy, pytest).
  • uv run mkdocs build --strict → clean.
  • tests/interaction/test_continuation_compat.py (3): a cross-provider
    continuation is rejected with an actionable error; a matching-provider
    continuation runs; a continuation without a provider marker (hand-built or
    history-derived) is left alone.
  • Existing tests/interaction/test_continuation.py (serialization round-trip,
    version/provider rejection) still passes.

Notes

Continuations without a provider marker are deliberately not rejected - they arise
from plain history or hand construction and carry no provider-specific state.

Complete the public Continuation primitive (slice 5). The type, its
version/provider-stamped to_jsonable/from_jsonable round-trip, and the api
reference were already in place; the missing piece was the runtime half of the
"Continuation compatibility is a Pollux contract" requirement.

validate_interaction now rejects reusing a continuation produced by a different
provider before dispatch. A live continuation records its producing provider,
and its provider_state (response ids, provider-specific replay blocks such as
Anthropic's signed thinking blocks) is not portable, so replaying it under
another provider would corrupt the turn. Continuations without a provider marker
(hand-built, or derived from plain history) are left alone. This mirrors the
serialized-side check in Continuation.from_jsonable(expected_provider=...).

Scope: provider-match is the load-bearing, clearly-correct compatibility check.
A broader environment/tools/sources fingerprint is deliberately not built — reusing
a continuation against a changed environment is not inherently broken.
@codecov

codecov Bot commented Jun 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.90909% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/pollux/interaction/validate.py 90.90% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@seanbrar seanbrar merged commit fabbe41 into main Jun 16, 2026
8 of 10 checks passed
@seanbrar seanbrar deleted the feat/public-continuation branch June 16, 2026 05:58
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.

1 participant