mirror of
https://github.com/logos-co/logos-liblogos.git
synced 2026-08-27 12:51:10 +00:00
* Qt-split retarget + protocol-version load gate - Link the split SDK stack: logos-qt-sdk (LogosAPI/provider glue; the logos_sdk alias now points at logos-qt-sdk::logos_qt_sdk, chaining logos-protocol) + Qt-free logos-cpp-sdk headers. - Protocol-version load gate (the first real consumer of module metadata pre-load): ModuleManager reads the module's embedded logos_protocol_version before runtime.load() and applies the one compatibility rule — equal protocol MAJOR loads, different MAJOR is refused with a diagnostic naming both versions, missing/unparseable stamp (pre-protocol modules) loads permissively with a warning. The decision logic is std-only (logos_core/protocol_gate.h) and unit tested (refuse bumped major / warn-load legacy / silent minor skew). - ModuleDescriptor.rawMetadata is now actually populated for runtimes. * lock: pin extraction-chain branch revs for standalone CI Temporary — drop when the chain PRs merge (re-lock against masters). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * doctest: pin logoscore-cli to its qt-split branch head The doc-test builds logoscore-cli at latest master with only liblogos overridden to the commit under test; master logoscore-cli cannot build against qt-split liblogos. Pin the runtime to the chain branch (logos-co/logos-logoscore-cli#43) so the doc-test exercises the coherent stack. Temporary — revert to the unpinned URL when the chain merges. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * host: surface the spawn auth token as a LogosAPI property cdylib-authored modules run their own statically-linked protocol stack whose TokenManager is a separate copy of the singleton; the generated Qt glue reads this property (cross-image-safe, like modulePath) and seeds the cdylib's stack via logos_module_accept_token so the module's outbound calls authenticate. * host: set the authToken property before registerObject registerObject runs the provider object's init() — where the cdylib glue reads the property. Setting it afterwards meant cdylib modules always saw an empty token. * lock: protocol+cpp-sdk merged to master — pins advance (protocol 9de4165, cpp-sdk f0fe8cb, qt-sdk 722e590) * lock: qt-sdk#1 merged — pin advances to qt-sdk master * gate: drop QJson from the Qt-free core — parse rawMetadataJson with nlohmann The protocol-version load gate had pulled QJsonDocument/QJsonObject into src/logos_core (Qt-free territory). logos-module now exposes the embedded metadata as a compact JSON string, so the gate reads it via nlohmann and the std::string extractMetadata overload. * lock: logos-module b42805d (result-lm untracked) --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
60 lines
2.2 KiB
C++
60 lines
2.2 KiB
C++
#ifndef LOGOS_PROTOCOL_GATE_H
|
|
#define LOGOS_PROTOCOL_GATE_H
|
|
|
|
#include <cstdlib>
|
|
#include <string>
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Protocol-version load gate (pure decision logic, std-only).
|
|
//
|
|
// Every module built by a current logos-module-builder carries the
|
|
// logos-protocol semver it was compiled against in its embedded metadata
|
|
// (`logos_protocol_version`). One rule governs Logos load/call
|
|
// compatibility: two participants interoperate iff they share the same
|
|
// protocol MAJOR. The host (this library) refuses to load a module whose
|
|
// major differs from its own; modules with no stamp predate the scheme and
|
|
// load permissively ("legacy") so the existing fleet never hard-fails.
|
|
//
|
|
// The caller (ModuleManager::loadModuleInternal) extracts the stamp from the
|
|
// plugin metadata pre-load and logs according to the decision.
|
|
// ---------------------------------------------------------------------------
|
|
|
|
namespace LogosCore {
|
|
|
|
enum class ProtocolGateDecision {
|
|
Allow, // same major — compatible
|
|
AllowLegacy, // no/unparseable stamp — pre-protocol module, load + warn
|
|
Refuse, // different major — incompatible, do not load
|
|
};
|
|
|
|
struct ProtocolGateResult {
|
|
ProtocolGateDecision decision;
|
|
int moduleMajor = -1; // -1 when absent/unparseable
|
|
};
|
|
|
|
// Parse the MAJOR component of "MAJOR.MINOR.PATCH". Returns -1 when the
|
|
// string does not start with a non-negative integer.
|
|
inline int protocolVersionMajor(const std::string& version)
|
|
{
|
|
if (version.empty()) return -1;
|
|
char* end = nullptr;
|
|
const long major = std::strtol(version.c_str(), &end, 10);
|
|
if (end == version.c_str() || major < 0) return -1;
|
|
return static_cast<int>(major);
|
|
}
|
|
|
|
inline ProtocolGateResult evaluateProtocolGate(const std::string& moduleVersion,
|
|
int hostMajor)
|
|
{
|
|
const int moduleMajor = protocolVersionMajor(moduleVersion);
|
|
if (moduleMajor < 0)
|
|
return {ProtocolGateDecision::AllowLegacy, -1};
|
|
if (moduleMajor == hostMajor)
|
|
return {ProtocolGateDecision::Allow, moduleMajor};
|
|
return {ProtocolGateDecision::Refuse, moduleMajor};
|
|
}
|
|
|
|
} // namespace LogosCore
|
|
|
|
#endif // LOGOS_PROTOCOL_GATE_H
|