Skip to content

feat(runtime): expose typed request context to operation handlers and the test harness (#223) - #273

Merged
ScriptedAlchemy merged 3 commits into
mainfrom
feat/223-handler-context
Sep 2, 2026
Merged

feat(runtime): expose typed request context to operation handlers and the test harness (#223)#273
ScriptedAlchemy merged 3 commits into
mainfrom
feat/223-handler-context

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Owner

Summary

Delivers the #223 handler-context slice: defineOperation handlers now receive the transport-installed AgentRequestContext as optional context.request on the second execute argument — the identical handle await agent() returns for that invocation (same ALS lease, no divergent snapshot). Identity axes stay honest Observed values: available with a source when the transport knows them, unavailable with a typed reason when it cannot; nothing is fabricated, and business input can never override request identity.

Contract

  • RscOperationContext gains optional readonly request?: AgentRequestContext (additive: existing single-argument handlers and direct execute(input, { signal }) callers compile and behave unchanged). A caller-supplied request wins; otherwise the wrapper resolves the live handle via a new non-throwing internal probe currentAgentRequest(); outside any invocation the field stays absent.
  • The rsc-runtime MCP server now observes host from the negotiated client identity (getClientVersion().name, source native) alongside the existing native sessionId session and authInfo.clientId actor. CLI keeps derived workspace + typed unavailable('unsupported-surface') host, now proven by test.
  • Route components keep the issue-sanctioned await agent() path (the route graph retired the execute/render split via AB4811); ToolRouteProps / CliRouteProps / AgentEventRouteProps and docs/entry-conventions.md now document the context contract, including that generated event scopes mount no actor principal (typed absent, per the finding recorded on Track remaining #98 state-kernel scope: warm-runtime process state, generated-runtime state mounting, budgets, lifetime visibility #233).

Harness spoof/injection surface

  • renderRoute(..., { context }) is the documented identity-injection seam (host/session/actor/workspace/capabilities, built with available/unavailable).
  • New tool:harness/context fixture route reports the observed axes; proofs cover: default typed-unavailable axes, injected axes with preserved sources, lookalike business-input fields not treated as identity, and event-route actor honestly absent.

Honest transport findings encoded in tests

  • mcp-in-memory projection installs no identity — asserted as typed not-provided, not faked.
  • Generated MCP tool scopes currently forward no host/session/workspace (stdio supplies no session) — asserted honestly in the generated-server suite; generated event scopes mount native host/session/workspace with actor unavailable.

Also includes a one-line repair of state-packaging.test.ts: the #99 stage-3 merge (ef1bcdf) added the ./notices/inbox-route export but missed the exports pin, leaving the runtime package tests red on latest main.

Changeset: minor for @agent-bundle/runtime and agent-bundle.

Gates (local, on the rebased branch)

  • pnpm build + pnpm typecheck — pass
  • pnpm lint — 0 errors / 0 warnings (929 files)
  • pnpm --filter @agent-bundle/runtime test — 245 passed, 1 skipped, 0 failed
  • pnpm test:route-unit — 18/18
  • pnpm test:projection — 44/44
  • generated-route-server integration (scoped, prebuilt) — 9/9

Refs #223, #233, #251, #255.

@changeset-bot

changeset-bot Bot commented Sep 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: afde7a2

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@agent-bundle/runtime Minor
agent-bundle Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-02T03:37:43.657893Z 765bb55 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

…xports list

The #99 stage-3 merge (ef1bcdf) added the ./notices/inbox-route export but
missed this pin, leaving the runtime package test red on main.

@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: 765bb5528f

ℹ️ 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".

};

export const currentAgentRequest = (): AgentRequestContext | undefined => {
const lease = getStore().storage.getStore();

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 Avoid initializing the global store from the context probe

When defineOperation.execute runs outside an invocation, this probe now calls getStore(), which both creates the realm-wide Symbol.for('@agent-bundle/runtime/request-store') store and throws if another installed runtime version already owns it. Consequently, an otherwise context-free direct operation can either fail with store-version-conflict in a mixed-version process or claim the symbol and cause the other runtime to fail later, even though direct execution previously did not touch request storage. Make the non-throwing probe inspect an existing compatible store without creating or rejecting on an unrelated version.

Useful? React with 👍 / 👎.

@ScriptedAlchemy
ScriptedAlchemy force-pushed the feat/223-handler-context branch from 765bb55 to afde7a2 Compare September 2, 2026 03:54
@ScriptedAlchemy
ScriptedAlchemy merged commit 074c87c into main Sep 2, 2026
4 checks passed
ScriptedAlchemy added a commit that referenced this pull request Sep 2, 2026
…ds (#102 stage 4) (#275)

* feat(cli): project MCP tools into routed commands (#102)

Compile selected generated MCP tools into the shared CLI graph with fail-closed mutation confirmation and route-contract parity.

* test: reconcile MCP projection expectations with the #273 harness tools
ScriptedAlchemy added a commit that referenced this pull request Sep 2, 2026
…tool scopes (#223) (#276)

* feat(runtime): observe transport identity in generated MCP request scopes (#223)

Generated MCP tool, resource, and prompt request scopes now observe the
negotiated client identity as a native host and derive workspace from the
server process cwd, alongside the existing native session and authInfo
actor, forwarding all four axes into the Flight worker. Typed
unavailability is preserved where a transport genuinely lacks an axis
(bare stdio supplies no sessionId or authInfo). The in-memory projection
level mirrors the worker boundary so mcp-in-memory stays faithful, with
the harness context seam still winning. Proof assertions flip from
honest absence to the positive contract at the generated-server
integration, mcp-in-memory, and packed journey levels; also repairs the
packed listTools assertion left stale when #273 added the context
fixture route.

* test(packed): reconcile packed listTools with the mutation-probe harness tool (#275)
@ScriptedAlchemy
ScriptedAlchemy deleted the feat/223-handler-context branch September 3, 2026 05:24
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