Skip to content

feat: LogosCore as a shell, over core_service, with core_service's contract - #169

Draft
dlipicar wants to merge 5 commits into
feat/runtime-delegate-exportfrom
feat/core-service-client
Draft

dlipicar wants to merge 5 commits into
feat/runtime-delegate-exportfrom
feat/core-service-client

Conversation

@dlipicar

Copy link
Copy Markdown
Contributor

Phase 7 of the runtime-control plan: logos::host::LogosCore can act as a shell, a named consumer of the runtime, instead of reaching modules through the C API and a mirrored token store.

Stacked on #168 (feat/runtime-delegate-export). It also merges #167 (feat/core-token-listener, d9617aa), because the apps moving to this API still use #167's token listener during the transition. The diff therefore shows #167's two files as well.

What changes in logos_host_core.h

  • Protected input. Config gains:

    • bundledModulesDirs
    • placementPolicyJson
    • shellName

    This is the input feat: one token authority, core_service embedded in liblogos, and the shell binding logos-liblogos#227 takes before start. If liblogos refuses one, the constructor cleans up and throws std::invalid_argument.

  • The shell binding. With a shellName, start() takes liblogos' shell binding. It gets one only when capability_module runs in-process as the token authority. From then on:

    • loadModule, unloadModule, refreshModules, knownModules, loadedModules and allStats/stats go through core_service as that identity, with per-call deadlines (120 s for lifecycle calls, 15 s for queries). LogosLoadDeps maps onto loadModule's new deps argument.
    • admitConsumer(name) returns the credential capability minted for a UI plugin; retireConsumer(name) ends that consumer.
    • shellCredential() hands the shell identity to a co-process or to a Qt LogosAPI.
    • shellBinding() is for calls and subscriptions this class does not wrap.

    Without a binding, the C API serves exactly as before, so a host can set shellName whatever mode the runtime runs in.

  • Deprecated: tokenListener. Once capability_module is the authority, core saves no tokens.

  • Mirror. logos_core_set_bundled_modules_dirs, logos_core_set_placement_policy, logos_core_set_shell_identity, logos_core_take_shell_binding and logos_consumer_*. As with feat: let a host observe the tokens core saves #167, a host needs the liblogos that exports them (#227).

cpp/core_service.lidl

This is core_service's contract: every method and its scope, the answer shapes, and the moduleStateChanged and module_event events. It is installed at share/logos/core_service.lidl. logos-cpp-generator --lidl parses it and generates a client.

Tests

tests/sdk/test_logos_host_core.cpp stubs the new entry points and adds seven cases:

  • the protected input lands before start, and the binding is taken after it;
  • a refused setting throws after cleanup;
  • lifecycle calls go through core_service with the right arguments, and the C API is bypassed;
  • an error answer is a failed load;
  • without a binding, the C API serves;
  • consumers are admitted and retired through core_service;
  • the binding is released before cleanup.

macOS: checks.tests passes 394/394.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

📊 cpp-sdk doc-test report

The real accounts module, run through a logoscore daemon with the whole stack built against this commit of the C++ SDK — rendered alongside the commands actually run and their output (updated each run, commit b82a0db):

Pages can take a minute to update after the run finishes.

dlipicar and others added 4 commits October 3, 2026 09:43
LogosCore::Config::tokenListener installs liblogos'
logos_core_set_token_listener() before start() and removes it before
cleanup. An embedder whose modules calls read their own token store (a Qt
host's TokenManager) mirrors core's module tokens from it, instead of
relying on core sharing that store.

The listener is removed before logos_core_cleanup(); liblogos waits out a
running call on removal, so the std::function can be destroyed after it.
A throwing listener is swallowed rather than unwound into liblogos.

Tests: the stub core records the install before start and the removal
before cleanup, and a token it reports reaches the listener; no listener
means no call.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ntract

- Config gains bundledModulesDirs, placementPolicyJson and shellName, the
  protected input logos-liblogos#227 takes before start. A refused one
  throws std::invalid_argument after cleaning up.
- With a shell name, start() takes the shell binding (when capability_module
  is the token authority). Load, unload, refresh, the module lists and the
  stats then go through core_service as that identity; admitConsumer() and
  retireConsumer() admit UI plugins; shellCredential() hands the identity to
  a co-process or a Qt LogosAPI. Without a binding the C API serves, as
  before.
- tokenListener is deprecated: a runtime whose capability_module is the
  authority saves no tokens.
- cpp/core_service.lidl is core_service's contract, installed at share/logos.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mirrors logos_core_set_package_config (logos-liblogos#227): the runtime
applies package_manager's directories and signature policy as it loads,
since a shell calling as itself can no longer set them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dlipicar
dlipicar force-pushed the feat/runtime-delegate-export branch from 4e5f8c8 to cb91ad8 Compare October 3, 2026 12:46
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dlipicar
dlipicar force-pushed the feat/core-service-client branch from 5e3245d to 18c224c Compare October 3, 2026 12:47

This branch has not been deployed

No deployments
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