mirror of
https://github.com/logos-co/logos-cpp-sdk.git
synced 2026-08-30 17:21:15 +00:00
The dynamic (by-name) invoke path already existed and was already ungated at every layer — lp_client_create / lp_invoke in the C ABI, logos::LpClient above it, and the Qt client above that. Nothing checked a host service; there was no gate to open. What was missing was the ERGONOMICS, which is what turned a supported capability into something callers reached around the umbrella to get. Three additive pieces, no gate touched: 1. LogosModuleContext::moduleName() — the module's own registry name, i.e. the origin it authenticates as. The typed wrappers bake their origin in at codegen time; a by-name call has to state one, and a wrong origin authenticates as nobody and fails far from the call site. Set through a NEW `_logosCoreSetModuleName_`, deliberately not a fourth parameter on `_logosCoreSetContext_`: every generated provider calls that signature, so widening it would break each one until regenerated, for a value the generator knows statically. Set before the context, so moduleName() is live inside onContextReady(). 2. LogosModules::dynamic(target) on the origin-bound umbrella — the untyped client, with the origin baked in exactly as the typed members' is, and cached per target because LpClient owns a connection. The typed members over metadata.json#dependencies stay the ordinary way to call another module; this is for the cases whose target is a runtime value (a proxy, a router). 3. LpClient::getMethods() over the already-exported lp_get_methods. Invoke without introspect is guessing — a caller that cannot ask what exists can only hardcode, and a wrong guess fails at runtime like a typo. Verified: #default builds, and both checks pass (tests, generator-cli). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>