Semantic-neighbor maintenance aborted the daemon during startup: std::clamp<float> asserted '!(__hi < __lo)' because the adaptive cosine threshold could exceed 1.0 for a legal pair of identical vectors. The same work was also admitted while the daemon was still initializing, so the 300-second starvation guard forced a pass before readiness. + semanticInverseNorm/semanticCosineSimilarity/semanticExplicitThreshold in the existing embed policy header, shared by the streamed and corpus branches; non-finite vectors or scores produce no neighbor and legal scores are bounded before ranking and threshold selection + startupMaintenanceEligible() requires ServiceManagerState::Ready, not stopping and idle, and is evaluated before ResourceGovernor::admitDeferrable(), so an elapsed deferral deadline can no longer manufacture missing readiness + StartupPhaseTracker (two atomics, no mutex) plus a warn-level init-waiter line reporting state, phase and phase_elapsed_ms instead of a debug-level state number; a 53-minute startup previously logged nothing actionable + regression through the public backfill and corpus-rebuild APIs using a 64-D vector whose old float inverse norm rounds its self-cosine above 1 - removed the duplicated inverse-norm and cosine lambdas from EmbeddingService - renamed __test_setModelProvider/__test_setKgStore to testing_* because they used reserved identifiers, across 11 files - re-anchored 13 pre-existing raw-environment allowlist entries to their new line numbers; no new exception was added Startup is still blocked by corpus-sized memory-sync scans; this change stops the abort and names the blocking phase, it does not make startup fast. Signed-off-by: trvon <git@trevon.dev>
34 lines
1.3 KiB
C++
34 lines
1.3 KiB
C++
// Copyright (c) 2025 YAMS Contributors
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
// Validates degraded->ready recovery via ServiceManager's FSM helper.
|
|
#include <catch2/catch_test_macros.hpp>
|
|
|
|
#include <yams/daemon/components/DaemonLifecycleFsm.h>
|
|
#include <yams/daemon/components/EmbeddingProviderFsm.h>
|
|
#include <yams/daemon/components/ServiceManager.h>
|
|
|
|
using namespace yams::daemon;
|
|
|
|
TEST_CASE("EmbeddingProviderRecovery: degraded then recovered to ready", "[daemon]") {
|
|
#ifdef _WIN32
|
|
SKIP("EmbeddingProvider FSM tests skipped on Windows - see daemon IPC plan");
|
|
#endif
|
|
DaemonConfig cfg; // defaults are fine; no plugins needed
|
|
StateComponent state{};
|
|
DaemonLifecycleFsm lifecycleFsm;
|
|
|
|
ServiceManager sm(cfg, state, lifecycleFsm);
|
|
|
|
// Simulate degraded provider
|
|
sm.testing_setModelProviderDegraded(true, "unit-test degraded");
|
|
auto s1 = sm.getEmbeddingProviderFsmSnapshot();
|
|
CHECK(s1.state == EmbeddingProviderState::Degraded);
|
|
CHECK(s1.lastError.find("degraded") != std::string::npos);
|
|
|
|
// Simulate recovery (helper dispatches ModelLoadedEvent with dimension 0)
|
|
sm.testing_setModelProviderDegraded(false, "");
|
|
auto s2 = sm.getEmbeddingProviderFsmSnapshot();
|
|
CHECK(s2.state == EmbeddingProviderState::ModelReady);
|
|
CHECK(s2.embeddingDimension == 0u);
|
|
}
|