Skip to content

feat(ocap-kernel): reference-marker sigil at queueMessage RPC boundary - #984

Open
FUDCo wants to merge 2 commits into
mainfrom
feature/queue-message-ref-sigil
Open

feat(ocap-kernel): reference-marker sigil at queueMessage RPC boundary#984
FUDCo wants to merge 2 commits into
mainfrom
feature/queue-message-ref-sigil

Conversation

@FUDCo

@FUDCo FUDCo commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds a compact @@NAME string-sigil convention at the queueMessage RPC boundary so external JSON-RPC callers can pass live kernel object references as method arguments.
  • The handler walks the parsed args, replaces each sigil string with a kslot(NAME) standin, then hands the transformed args to kernel.queueMessage. kser sees a real remotable and encodes it as a slot in the dispatched CapData.
  • No changes to Kernel.ts, kernel-marshal.ts, KernelQueue.ts, or any other internal path. The walk lives strictly at the RPC boundary; internal callers of Kernel.queueMessage never see markers.

Why

JSON has no native way to express an ocap reference. Anyone speaking JSON-RPC to queueMessage — plugin code over the daemon socket, users typing message sends at a terminal, test harnesses composing RPC calls — has been unable to invoke methods whose arguments are references. This gap surfaced concretely in the orchestration demo when the LLM producer needed to pass a receive-shipment endpoint (obtained from a prior call) as an argument to a later service call, but it's a general limitation of the queueMessage RPC surface.

Design

NAME must be alphanumeric ([A-Za-z0-9]+), which fits current krefs (ko\d+ / kp\d+) and leaves room for a future registry mapping symbolic names to krefs without changing the sigil syntax.

Caveat: a legitimate string arg that begins with @@ followed by alphanumerics will be misinterpreted as a reference marker. Callers needing to send such a literal string must wrap it inside an object so the sigil isn't the whole string value. Judged an acceptable trade for the ergonomics of a compact CLI-friendly notation.

Test plan

  • yarn workspace @metamask/ocap-kernel test:dev:quiet — all tests pass, including new coverage for the sigil expansion (top-level, nested-in-array, nested-in-record, pass-through of non-sigil strings, rejection of bare @@, rejection of non-alphanumeric NAME, rejection of malformed kref).
  • yarn workspace @metamask/ocap-kernel lint — clean.
  • Validated end-to-end via a downstream consumer (an orchestration-demo plugin that emits @@koN strings on the wire and observes live remotables arriving at receiving vats).

🤖 Generated with Claude Code


Note

Low Risk
Scoped to the RPC adapter with validation on malformed krefs; the main caveat is accidental expansion of literal @@ + alphanumeric strings used as whole argument values.

Overview
Adds @@NAME reference markers on the queueMessage JSON-RPC path so external callers can pass live kernel object refs in message args without building remotables in-process.

Before forwarding to kernel.queueMessage, the handler recursively walks the parsed args and replaces whole strings matching @@ + alphanumeric NAME with kslot standins (after insistKRef), so kser emits real CapData slots. Nested arrays and plain objects are supported; internal Kernel.queueMessage callers are unchanged.

Malformed krefs fail before the kernel is invoked. Literal strings that look like markers (e.g. @@ko7 as a full arg value) are expanded—callers must structure those literals to avoid the sigil. Changelog and unit tests cover expansion, pass-through, and rejection cases.

Reviewed by Cursor Bugbot for commit 02852a4. Bugbot is set up for automated code reviews on this repo. Configure here.

JSON has no native way to express an ocap reference, so the queueMessage
RPC boundary — which accepts args as plain JSON — has no way to name a
live kernel object as a call argument. That leaves external callers
(plugin code speaking JSON over the daemon socket, CLI users typing
message sends at a terminal, test harnesses composing RPC calls)
without a way to invoke methods that take a reference argument.

This introduces a compact sigil convention at the queueMessage handler:
anywhere in the args tree, a string of the form `@@NAME` (where NAME
is one or more alphanumeric characters) is interpreted as a reference
marker naming the kernel object with that reference. The handler walks
the parsed args, replaces each marker with a `kslot(NAME)` standin, and
hands the transformed args to `kernel.queueMessage` as usual. `kser`
sees a real remotable and encodes it as a slot in the resulting CapData.

NAME must currently be a well-formed kref (`ko\d+` or `kp\d+`); a
future registry mapping symbolic names to krefs could accept richer
NAMEs while preserving the sigil syntax. Internal callers of
`Kernel.queueMessage` never traffic in markers and are unaffected —
the walk lives strictly at the RPC boundary.

Caveat: a legitimate string argument that begins with `@@` followed by
alphanumerics will be misinterpreted as a reference marker. Callers
that need to send such a literal string must wrap it inside an object
so the sigil isn't the whole string value.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@FUDCo
FUDCo requested a review from a team as a code owner July 28, 2026 22:12
@FUDCo
FUDCo marked this pull request as draft July 28, 2026 22:14
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 71.37%
⬆️ +0.04%
8891 / 12457
🔵 Statements 71.2%
⬆️ +0.05%
9042 / 12699
🔵 Functions 72.48%
⬆️ +0.02%
2142 / 2955
🔵 Branches 64.9%
⬆️ +0.06%
3596 / 5540
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/ocap-kernel/src/rpc/kernel-control/queue-message.ts 100%
🟰 ±0%
100%
🟰 ±0%
100%
🟰 ±0%
100%
🟰 ±0%
Generated in workflow #4559 for commit 02852a4 by the Vitest Coverage Report Action

@FUDCo
FUDCo marked this pull request as ready for review July 28, 2026 23:51
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