Skip to content

feat: add shared payment runtime - #184

Open
parvahuja wants to merge 2 commits into
parv/mcp-sdk-v1-compatfrom
parv/payment-runtime-v0.11
Open

feat: add shared payment runtime#184
parvahuja wants to merge 2 commits into
parv/mcp-sdk-v1-compatfrom
parv/payment-runtime-v0.11

Conversation

@parvahuja

@parvahuja parvahuja commented Jul 28, 2026

Copy link
Copy Markdown
Member

Runtime stack 1 of 5 · depends on #195 · next: #189

Summary

  • add a borrowed PaymentRuntime that runs on the caller's event loop
  • centralize intent-aware challenge matching, lifecycle events, and credential creation
  • add sync and async runtime context managers
  • reuse the public Method protocol from the existing async transport

Review boundary

This PR adds no HTTP policy, retry ledger, owned loop, thread bridge, sync transport, HTTPX patching, or MCP integration. Production delta is 154 lines.

Validation

  • full suite: 791 passed, 41 skipped
  • defensive method identity and intent mismatch coverage
  • Ruff, formatting, Pyright, package build, and strict Twine validation pass

@parvahuja
parvahuja marked this pull request as ready for review July 28, 2026 03:13

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

Copy link
Copy Markdown

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: 6a4c272614

ℹ️ 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/mpp/runtime.py Outdated
try:
cleanup(self._bridge.cancel_pending)
if self._method_stack is not None:
cleanup(lambda: self._bridge.run(self._teardown_methods()))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep async context managers in their entering task context

When a factory returns an async context manager that uses task-local state, this submits _teardown_methods() as a new task even though __aenter__ ran in the earlier _initialize_methods() task. For example, an @asynccontextmanager that sets a ContextVar and resets its token in finally consistently raises ValueError: Token was created in a different Context during close(), potentially interrupting cleanup. Keep the exit stack alive in one supervisor task that performs both entry and exit rather than resubmitting teardown separately.

AGENTS.md reference: AGENTS.md:L68-L69

Useful? React with 👍 / 👎.

@parvahuja
parvahuja marked this pull request as draft July 28, 2026 17:19
@parvahuja
parvahuja force-pushed the parv/payment-runtime-v0.11 branch 2 times, most recently from 5d60b7d to b5a4293 Compare July 28, 2026 17:25
@parvahuja
parvahuja changed the base branch from main to parv/mcp-sdk-v1-compat July 28, 2026 17:25
@parvahuja
parvahuja force-pushed the parv/payment-runtime-v0.11 branch from b5a4293 to 07d5dc8 Compare July 28, 2026 18:24
@parvahuja
parvahuja force-pushed the parv/payment-runtime-v0.11 branch from 07d5dc8 to 42cfb85 Compare July 28, 2026 18:26
@parvahuja
parvahuja changed the base branch from parv/mcp-sdk-v1-compat to parv/stacked-pr-ci July 28, 2026 18:28
@parvahuja
parvahuja force-pushed the parv/payment-runtime-v0.11 branch from a9005de to 4aae448 Compare July 29, 2026 00:43
@parvahuja
parvahuja force-pushed the parv/payment-runtime-v0.11 branch 2 times, most recently from 8763962 to 3b8966f Compare July 29, 2026 03:33
@parvahuja
parvahuja changed the base branch from parv/stacked-pr-ci to parv/mcp-sdk-v1-compat July 29, 2026 03:40
@parvahuja
parvahuja force-pushed the parv/payment-runtime-v0.11 branch from 3b8966f to 27fa696 Compare July 29, 2026 19:25
@parvahuja
parvahuja marked this pull request as ready for review July 29, 2026 19:44

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

Copy link
Copy Markdown

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: 27fa696319

ℹ️ 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/mpp/runtime.py Outdated
self.start()
if not any(candidate is method for candidate in self.methods):
raise ValueError("Method is not installed in this PaymentRuntime")
if challenge.method != method.name or challenge.intent not in _method_intents(method):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor name-only matches during credential creation

When match_challenge(..., allow_name_only=True) selects a legacy method for an intent not exposed by _method_intents, passing that returned pair into the documented create_credential flow always raises here because credential creation unconditionally reapplies intent validation. This makes allow_name_only unusable for the runtime's advertised match-then-create composition; credential creation needs a corresponding override, or matching must not return pairs it will reject.

AGENTS.md reference: AGENTS.md:L53-L60

Useful? React with 👍 / 👎.

Comment thread src/mpp/runtime.py
allow_name_only: bool = False,
) -> tuple[Challenge, Method]:
"""Return the first compatible challenge and method."""
pairs = (

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Check closure before matching challenges

After close() or exiting either context manager, match_challenge() remains usable because it is the only public runtime operation that does not call start(). This contradicts close()'s promise to prevent new runtime operations and can either select a borrowed method for use after the runtime's lifetime or defer the closed-state error until the subsequent credential-creation step; check the closed state before matching.

Useful? React with 👍 / 👎.

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