Skip to content

Type the makeExo __getMethodNames__ meta-method #742

Description

@0xpatrickbot

What is the Problem Being Solved?

makeExo instances provide the runtime __getMethodNames__ meta-method, but
the published TypeScript declarations do not expose a typed accessor through
the returned Exo capability or through E(ref).

This forces conformance code and narrow capability adapters to use a structural
cast even when the object is known to be a makeExo instance.
The gap is separate from issue #640, which concerns guard and interface naming
conventions.

Description of the Design

The relevant runtime and type-level symbols are makeExo and its
InterfaceGuard/RemotableBrand result in @endo/exo, the pass-style
GET_METHOD_NAMES runtime symbol in @endo/pass-style, and E/ERef in
@endo/eventual-send.

The current conformance test uses the following narrow structural cast in
packages/daemon/test/mount-platform-fs-conformance.test.js:

const methods = await E(
  /** @type {{ __getMethodNames__: () => Promise<string[]> }} */ (mount),
).__getMethodNames__();

The minimal TypeScript reproducer is:

declare const mount: EndoMount;
await E(mount).__getMethodNames__();
// Property '__getMethodNames__' does not exist on the declared ERef surface.

The runtime value is still a makeExo instance, so this is an introspection
typing omission rather than an interface-guard method that should be added to
every user-facing M.interface.

Security Considerations

The accessor reveals method names that are already observable through the
runtime Exo meta-method and does not grant invocation authority.
The declaration must not make __getMethodNames__ part of ordinary interface
guard matching or imply that it is an application capability method.

Scaling Considerations

A shared typed meta-method on the Exo/ERef capability machinery avoids one
structural cast per conformance test, adapter, and capability introspection
consumer.

Test Plan

Add a type-level test that makeExo(...) results and E(ref) expose
__getMethodNames__(): Promise<string[]> while ordinary interface method
guards remain unchanged.
Keep a runtime test covering the existing method-name conformance behavior.

Compatibility Considerations

This is an additive declaration improvement.
It should not change the runtime GET_METHOD_NAMES symbol or the wire-level
Exo interface.

Upgrade Considerations

No migration is required.
Consumers can remove local structural casts after the declaration is released.

Suggested Fix

Define a named typed meta-method result in the shared Exo/pass-style type
machinery and have makeExo return an object whose ERef view includes
__getMethodNames__(): Promise<string[]>.
The eventual-send E(ref) helper should preserve that accessor for Exo
instances without adding it to M.interface guard payloads.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions