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>
70 lines
2.4 KiB
C++
70 lines
2.4 KiB
C++
#include <gtest/gtest.h>
|
|
|
|
#include "logos_core/protocol_gate.h"
|
|
#include "logos_protocol.h"
|
|
|
|
// Gate tests (land with the gate, per the versioning design):
|
|
// (a) a module stamped with a different MAJOR is refused,
|
|
// (b) an unstamped (legacy) module is allowed permissively,
|
|
// (c) equal major / different minor loads silently.
|
|
// The stamp values are exercised against both a fixed major and the real
|
|
// LOGOS_PROTOCOL_VERSION_MAJOR the host links.
|
|
|
|
using LogosCore::evaluateProtocolGate;
|
|
using LogosCore::protocolVersionMajor;
|
|
using LogosCore::ProtocolGateDecision;
|
|
|
|
TEST(ProtocolGate, RefusesDifferentMajor)
|
|
{
|
|
const auto r = evaluateProtocolGate("2.0.0", 1);
|
|
EXPECT_EQ(r.decision, ProtocolGateDecision::Refuse);
|
|
EXPECT_EQ(r.moduleMajor, 2);
|
|
|
|
// Against the real host major: a deliberately bumped stamp is refused.
|
|
const int hostMajor = LOGOS_PROTOCOL_VERSION_MAJOR;
|
|
const std::string bumped = std::to_string(hostMajor + 1) + ".0.0";
|
|
EXPECT_EQ(evaluateProtocolGate(bumped, hostMajor).decision,
|
|
ProtocolGateDecision::Refuse);
|
|
}
|
|
|
|
TEST(ProtocolGate, MissingStampLoadsPermissively)
|
|
{
|
|
const auto r = evaluateProtocolGate("", LOGOS_PROTOCOL_VERSION_MAJOR);
|
|
EXPECT_EQ(r.decision, ProtocolGateDecision::AllowLegacy);
|
|
EXPECT_EQ(r.moduleMajor, -1);
|
|
}
|
|
|
|
TEST(ProtocolGate, UnparseableStampLoadsPermissively)
|
|
{
|
|
EXPECT_EQ(evaluateProtocolGate("garbage", 1).decision,
|
|
ProtocolGateDecision::AllowLegacy);
|
|
EXPECT_EQ(evaluateProtocolGate("-1.0.0", 1).decision,
|
|
ProtocolGateDecision::AllowLegacy);
|
|
}
|
|
|
|
TEST(ProtocolGate, EqualMajorDifferentMinorAllowsSilently)
|
|
{
|
|
const int hostMajor = LOGOS_PROTOCOL_VERSION_MAJOR;
|
|
const std::string newerMinor =
|
|
std::to_string(hostMajor) + ".99.7";
|
|
const auto r = evaluateProtocolGate(newerMinor, hostMajor);
|
|
EXPECT_EQ(r.decision, ProtocolGateDecision::Allow);
|
|
EXPECT_EQ(r.moduleMajor, hostMajor);
|
|
}
|
|
|
|
TEST(ProtocolGate, HostOwnVersionAllows)
|
|
{
|
|
EXPECT_EQ(evaluateProtocolGate(LOGOS_PROTOCOL_VERSION_STRING,
|
|
LOGOS_PROTOCOL_VERSION_MAJOR).decision,
|
|
ProtocolGateDecision::Allow);
|
|
}
|
|
|
|
TEST(ProtocolGate, MajorParser)
|
|
{
|
|
EXPECT_EQ(protocolVersionMajor("0.1.0"), 0);
|
|
EXPECT_EQ(protocolVersionMajor("12.3.4"), 12);
|
|
EXPECT_EQ(protocolVersionMajor("1"), 1);
|
|
EXPECT_EQ(protocolVersionMajor(""), -1);
|
|
EXPECT_EQ(protocolVersionMajor("x.y.z"), -1);
|
|
}
|