Skip to content

feat: Waves 5–7 — Core module gap closure: 119 new tests, 7 modules hardened (auth/server/transaction/rag/llm/voice/analytics) - #6074

Merged
makr-code merged 37 commits into
developfrom
copilot/core-modules-gaps-analysis
Aug 26, 2026
Merged

feat: Waves 5–7 — Core module gap closure: 119 new tests, 7 modules hardened (auth/server/transaction/rag/llm/voice/analytics)#6074
makr-code merged 37 commits into
developfrom
copilot/core-modules-gaps-analysis

Conversation

Copilot AI commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Pull Request

For EPIC-branch workflow PRs, use .github/PULL_REQUEST_TEMPLATE/epic-branch-flow.md.
This applies to both feature/* -> epic/* and epic/* -> develop integration PRs.

Target Version (Required)

Target Version: v2.5.0-alpha1

Implements Wave A→B roadmap items targeting Q4 2026 milestones; all changes land on develop.


Description

Three sequential waves of subagent-driven gap closure targeting the core module backlog from src/MODULE_GAP_ANALYSIS_WAVE2.md. 119 new regression tests across 7 modules, 3 latent bugs fixed, 5 new production classes created.

Wave 5/6 — Security & Correctness Hardening (auth / server / transaction)

Auth Wave 4-B (src/auth/)

  • A1: injected 7 AuthAuditLogger call sites in passkey_authenticator.cpp::verifyAuthentication() (was zero)
  • A2–A7: confirmed mTLS/federated/JWT key-rotation/role-change/passkey-register audit paths present
  • B1–B4: confirmed LDAP/federated/PKCE/device-flow retry loops with jitter present
  • C1–C3: confirmed COSE alg allowlist (reject kty=2 if alg≠-7), mTLS EKU check, RSA ≥2048 guard present
  • 20 tests (test_wave4b_auth_hardening2.cpp)

Server Wave 4-A (src/server/)

  • S1/S2: path-traversal guard (weakly_canonical() + model-store root escape) and integrity-gate bypass (HTTP 400 on empty path) confirmed active in llm_api_handler.cpp
  • S3–S7: added [AUDIT] authorize result=ALLOW/DENY scope={} to bpmn_api_handler, cache_admin_api_handler, entity_api_handler (3 handlers missing; lora/import/replication already covered)
  • S8: upgraded mcp_server.cpp non-Linux platform gap to canonical 4-field STUB/SIMULATION NOTE
  • 14 tests (test_wave4a_server_hardening2.cpp)

Transaction T1–T4 (src/transaction/)

  • T1: canonical 4-field STUB NOTE on both Phase-1/Phase-2 RPC bridges; PRODUCTION_REQUIREMENTS.md entry added
  • T2: [TXLOCK] mutual-upgrade deadlock warn with key=/tx_a=/tx_b= fields
  • T3: GTM Phase-2 snapshot-then-release confirmed correct
  • T4: predicate_lock_drops_ atomic counter + predicateLockDropCount() accessor + THEMIS_WARN on capacity reject; also closed latent stats_deadlocks_ ODR gap (referenced in .cpp, missing from header)
  • 13 tests (test_wave4c_t1t4_hardening.cpp)

Wave 5 Continuation — Voice & Analytics (voice / analytics)

Voice Wave A (src/voice/)

  • V1: wake-word/command/intent exception paths wrapped with [VOICE-FALLBACK] THEMIS_WARN + safe defaults
  • V2: liveness check fail-closed on backend exception (security-critical: reject not accept)
  • V3: adversarial noisy wake-word test expansion
  • 8 tests (test_voice_wave_a_noisy_wakeword.cpp)

Analytics AN1/AN2 (src/analytics/)

  • AN1: per-shard federated query retry — exponential backoff + ±20% jitter; permanent errors (invalid query, permission denied, auth) skip retry
  • AN2: CRC-32/ISO-HDLC checksum appended on serialize(), verified on deserialize() (mismatch throws; missing checksum → THEMIS_WARN passthrough for legacy models)
  • 8 tests (test_wave_next_analytics_hardening.cpp)

Wave 7 — RAG Phase B + LLM Infrastructure

RAG: TensorRagCostModel + RetrievalGuardrail + RagQualityMonitor (new files)

  • TensorRagCostModel::estimate() — 5-phase linear model: C_RAG = C_embed + C_retrieve + C_rerank + C_assemble + C_generate; injected coefficients; confidence 0.8 (warm) / 0.5 (cold)
  • RetrievalGuardrail::checkFederatedCost() — returns GuardrailDecision{allow, deny_reason, estimated_cost_ms}; cross-DC uses tighter 200ms threshold; THEMIS_WARN on deny
  • RagQualityMonitor — 300-sample deque ring buffer; Prometheus gauge emit via structured log (no external lib); z-score ≥3 anomaly detection for low_recall, high_latency, guardrail_deny_rate
  • 14 tests (test_wave7_rag_costmodel_guardrail.cpp)

RAG: BM25+ Positional + FTS phrase/proximity (src/rag/wiki_index_store.cpp)

  • Added positional_index_ (term → doc_id → position list) populated atomically with IDF rebuild under existing idx_mutex
  • searchPhrase("exact phrase") — strict consecutive-position filter; single-term delegates to searchBM25
  • searchProximity(term1, term2, distance) — two-pointer min-distance scan; term1==term2 handled via consecutive-pair scan
  • computePositionalBM25Score() — wraps existing BM25+ with ×1.5 bonus when all query terms co-occur within 8 tokens
  • 12 tests (test_wave7_bm25_positional_fts.cpp)

LLM: PagedKVCache LRU eviction (include/llm/paged_kv_cache.h + .cpp)

  • Previously: allocateBlocks() returning empty on exhaustion caused silent store() failure
  • Now: store()bool; on allocation failure calls evictLRU() and retries up to 3×; LRU tracked via std::list<uint64_t> + unordered_map iterator cache (O(1) promote on retrieve()); evictionCount() atomic accessor; explicit release() does not bump eviction counter
  • 10 tests (in test_wave7_llm_kvcache_lru_checkpoint.cpp)

LLM: InlineTrainingEngine RocksDB checkpoint (src/llm/inline_training_engine.cpp)

  • setCheckpointDb(shared_ptr<rocksdb::DB>) wires RocksDB handle
  • saveCheckpoint() dual-writes: RocksDB Put(path, json) first, then filesystem JSON (durability)
  • loadCheckpoint() RocksDB-first, fallback to filesystem on NotFound; guarded by #ifdef THEMIS_USE_ROCKSDB
  • 5 tests (in test_wave7_llm_kvcache_lru_checkpoint.cpp)

LLM: Thread-safety top-20 audit + deadlock fix (src/llm/ml_model_manager.*)

  • models_mutex_ was referenced at 18 sites in .cpp but never declared in header — compile error waiting to happen; added mutable std::mutex models_mutex_
  • Critical deadlock fixed: healthMonitorLoop() held models_mutex_ then called healthCheck() which re-acquired the same non-recursive mutex → snapshot-then-release pattern applied
  • MLModelInstance::active_requestsstd::atomic<size_t>; metrics_lock_ guard on updateInstanceMetrics(); plugin_operation_count_ atomic in LlmPluginManager
  • 4 tests (test_wave_next_llm_threadsafety.cpp)

LLM Wiki: RocksDB backend (src/llm_wiki/rocksdb_wiki_store.cpp)

  • Wired RocksDbWikiStore replacing in-memory mock for put/get/scan/close; persistence round-trip verified
  • Fixed transitive TBB/CUDA include chain (extracted Status into llm_wiki_status.h); fixed nested /* */ comment termination bug
  • 11 tests (test_wave_next_llm_wiki_rocksdb.cpp)

Total new tests: 119 across 9 test files. All registered with release_critical labels.
Latent bugs fixed: models_mutex_ missing declaration (ODR), healthMonitorLoop deadlock, stats_deadlocks_ ODR gap in lock_manager.h, PagedKVCache silent exhaustion failure.

Linked Issues

Type of Change

  • Bug fix (non-breaking)
  • New feature (non-breaking)
  • Refactoring (non-breaking)
  • Documentation
  • Breaking change (requires MAJOR version bump — see VERSIONING.md)
  • Security fix
  • Other:

Breaking Change Checklist

N/A

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • Benchmarks run (if performance-sensitive change)

Security Tiering Impact (Required for Runtime Changes)

  • Impacted tier(s):

    • T0 Trusted Core
    • T1 Security & Platform Services — auth audit injection, passkey COSE alg allowlist, mTLS EKU check, RSA key-size floor
    • T2 Data Plane Engines — LLM deadlock fix, KV-cache LRU, transaction lock-upgrade deadlock, GTM global-lock release
    • T3 Interface & Protocol Edge — server path-traversal guard, integrity-gate bypass fix, handler audit logs
    • T4 Managed Extension Runtime
    • T5 Plugin Boundary
    • N/A (docs-only / non-runtime)
  • Trust-boundary crossings documented in PR description (T3→T2 for server→LLM model load path; T1 auth audit paths)

  • Boundary controls validated for affected T3/T4/T5 paths (path-traversal + integrity-gate guards; auth audit injection)

  • Boundary-focused tests added/updated or explicit N/A rationale provided

  • If trust level/privilege increased, security maintainer approval is attached

📚 Research & Knowledge (wenn applicable)

  • Diese PR basiert auf wissenschaftlichen Paper(s) oder Best Practices?
    • BM25+ Positional Scorer: Robertson & Zaragoza 2009 (lower-bound term frequency δ=0.5)
    • CRC-32 checksum: ISO 3309 / ITU-T V.42 (HDLC polynomial 0xEDB88320)
    • Speculative decoding / KV-cache: standard transformer inference patterns

Relevante Quellen:

  • Paper:
  • Best Practice:
  • Architecture Decision:

AI-Generated Code (KI-generierter Code)

  • Symbol-Referenzen mit GetSymbolReferences_CppTools geprüft (siehe .github/instructions/cpp-language-service-tools.instructions.md)
  • Keine rohen Pointer und kein new/delete ohne explizites Review eingeführt — all new allocations use std::shared_ptr / RAII
  • RAII und Exception-Safety für neue/angepasste Pfade geprüft — PagedKVCache::evictLRU(), ScopedDbConnection, RocksDbWikiStore
  • Keine unnötig komplexen KI-Abstraktionen eingeführt
  • Performance-Metriken geprüft, falls Hotpath betroffen — LRU O(1) promote via std::list splice; BM25+ positional index O(N·L) rebuild same cost class as existing IDF rebuild

AI Review Workflow (Required for AI-assisted PRs)

  • Findings-first review performed with .github/prompts/pr-diff-findings-review.prompt.md
  • Security hardening review performed for security-sensitive/runtime changes with .github/prompts/security-hardening-review.prompt.md (or N/A documented)
  • API impact review performed for API/contract changes with .github/prompts/api-change-impact-review.prompt.md (or N/A documented)
  • All Critical/High findings are resolved or explicitly accepted with rationale in PR description
  • Residual risks and follow-up actions documented in PR description
  • Severity policy applied according to .github/copilot/REVIEW_SEVERITY_POLICY.md

High-Finding Exception Record (only if High is accepted)

  • High-finding exception claimed in this PR

Release Readiness Gate (Required for release-scoped changes)

  • Release readiness reviewed with .github/prompts/release-readiness-check.prompt.md for branch transition scope
  • Branch governance validated against BRANCHING_STRATEGY.md and RELEASE_STRATEGY.md
  • Versioning/changelog impact validated against VERSIONING.md and CHANGELOG.md

Checklist

  • Code follows project style guidelines (clang-format / clang-tidy)
  • Self-review completed
  • Documentation updated (if needed) — src/MODULE_GAP_ANALYSIS_WAVE2.md §7–9, ROADMAP.md Wave A/B items, per-module ROADMAP.md files, PRODUCTION_REQUIREMENTS.md
  • CHANGELOG.md updated under [Unreleased]
  • No new warnings introduced
  • Security-sensitive paths reviewed by security maintainer (if applicable)

Scanner and IntelliSense Gates

  • IntelliSense/Compiler: no new errors in changed files
  • clang-tidy/cppcheck: no new high-risk findings in changed files
  • Gap Scanner: no new critical findings in categories security, input_validation, query_correctness, distributed_consistency, concurrency, memory
  • Gap Scanner: no new high findings in the same categories (or explicitly approved)
  • Gap Scanner delta report attached (baseline vs current), not only absolute totals
  • New unknown scanner findings triaged (fixed, re-categorized, or justified)

Copilot AI and others added 30 commits August 25, 2026 18:08
Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…8-26)

- Full inline grep scan across all 70+ src/ modules
- 4 parallel subagents: llm, rag, rag+concurrency, query/storage/sharding, analytics/training/server
- Wave 5 ranking: llm P1 (~1400 IMPL), rag P2 (~25-30 real), server P3 (~11), auth P4, acceleration P5
- Confirmed closed: sharding (∞ inflation, 0 gaps), storage (590× inflation, fail-closed), query (2296× inflation)
- Updated sections: header, Wave5 ranking table, all triage sections, implementation plan Phase 1-3, acceptance criteria, Core-First Priorisierung"

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…e-2 lock release, predicate lock warning, STUB #279 governance docs

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…ensor_bridge STUB #263a/b/c

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…LLM P1, Transaction T1-T4, Storage #263a/b/c, Query Q1 all complete

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…BM25+/RRF compilation fixes

R1 (distributed_rag_evaluator): Replace indefinite blocking future.get()
in the no-timeout branch with a 30 s fallback via wait_for(kEvalTimeout).

R8 (rlaif_trainer): Change ~RLAIFTrainer() = default to explicit noexcept
dtor wrapping impl_.reset() in try/catch to suppress any exception.

R9/R10 (wiki_index_store): Fix two compilation bugs introduced in prior commit:
- Add #include <memory> to header (required for std::unique_ptr<Impl>)
- Hoist Config struct (WikiIndexStoreConfig) before class to avoid
  default-member-initializer-in-default-parameter GCC error
- Remove duplicate ~WikiIndexStore() declaration
- Replace braced-initializer push_back({}) with explicit IndexResult{}

tests/rag/CMakeLists.txt: Add explicit target registration for
test_wave5_rag_hardening_focused (bypasses GLOB cache miss on new files).

R2 (llm_integration): No bare thread.join() found in file (584 lines, verified).
R3 (knowledge_gap_detector): Already uses std::shared_mutex — compliant.
R4 (continuous_learning_orchestrator): Already uses std::atomic<bool> — compliant.
R5 (evaluation_report_exporter): No uninitialized buffer; snprintf bounded — compliant.
R6 (calibration_manager): Already uses std::ifstream/ofstream RAII — compliant.
R7 (quality_control_pipeline): No iterator invalidation found — compliant.

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…lization, audit logs, MCP/gRPC/timeseries STUB notes + test file

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…M25+/RRF implementation, HNSW/cache STUB notes + 25 tests

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…U check, RSA floor, OAuth/LDAP retry backoff + 18 tests; fix securityEventTypeToString for new enum values

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…ce docs, acceleration checkbox sync

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
… tests added

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…failure, noisy wake-word tests

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…h extracted, 11 tests pass

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…hMonitorLoop resolved, 4 tests

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…adlock, LLM Wiki RocksDB) – 31 tests, 4 modules

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…dlock, GTM unlock, predicate drop counter

T1 (distributed_transaction_manager.cpp:67,91):
- Replace verbose Phase-1/Phase-2 STUB comments with canonical 4-field
  STUB/SIMULATION NOTE format (Purpose/Activation/Production Delta/Removal Plan)
- Add RPC transport injection requirement entry to PRODUCTION_REQUIREMENTS.md

T2 (lock_manager.cpp:258-265):
- Mutual upgrade deadlock detection already implemented; update THEMIS_WARN
  to include [TXLOCK] prefix with key/tx_a/tx_b fields per spec

T3 (global_transaction_manager.cpp:248-252):
- Snapshot-then-release pattern already implemented correctly; confirmed
  via source inspection tests (runPhase2 outside lock)

T4 (lock_manager.cpp:530-538):
- Update THEMIS_WARN to [TXLOCK] prefix with max/tx_id fields per spec
- Add std::atomic<uint64_t> predicate_lock_drops_ counter to header
- Increment counter on every capacity-based predicate lock drop
- Expose predicateLockDropCount() accessor in LockManager public API
- Add stats_deadlocks_ to header (was used in .cpp but missing from header)

Tests (tests/transaction/test_wave4c_t1t4_hardening.cpp):
- 13 tests covering T1 (4×source inspection), T2 (3×upgrade deadlock),
  T3 (2×source inspection), T4 (4×counter/drop behaviour)
- Registered in tests/transaction/CMakeLists.txt with wave_c release_critical labels

Docs:
- ROADMAP.md: T1-T4 flipped to [x] Done 2026-08-26

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
S1 (integrity_gate_bypass): confirmed — empty-path → HTTP 400 already
  at llm_api_handler.cpp:976-981; guard verified in test T01/T02.

S2 (path_traversal): confirmed — weakly_canonical + model-store root
  escape check at llm_api_handler.cpp:983-999; tests T03/T04/T05.

S3 (lora audit): lora_api_handler.cpp already emits [AUDIT] result=ALLOW
  and result=DENY at bearer-token validation level; tests T06/T07.

S4 (import audit): import_api_handler.cpp already emits [AUDIT]
  result=ALLOW on PostgreSQL/MySQL import endpoints; tests T08/T09.

S5/S6 (replication_topology, postgres_session): confirmed — AUDIT logs
  already present; no additional injection required.

S7 (3 missing-audit-log handlers):
  - bpmn_api_handler.cpp: THEMIS_INFO/WARN [AUDIT] authorize result=
    ALLOW/DENY after auth_->authorize()
  - cache_admin_api_handler.cpp: same pattern
  - entity_api_handler.cpp: same pattern

S8 (mcp_server.cpp:2814): STUB/SIMULATION NOTE updated to 4-field format
  covering Unix socket abstract namespace / non-Linux fallback:
  Purpose / Activation / Production Delta / Removal Plan (Q2 2027).

Tests: tests/server/test_wave4a_server_hardening2.cpp (14 GTest cases)
  Labels: wave_a release_critical server hardening
  Registered in tests/server/CMakeLists.txt

ROADMAP: src/server/ROADMAP.md S1-S8 items flipped to [x] 2026-08-26.

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
A1: inject audit calls into PasskeyAuthenticator::verifyAuthentication()
directly, covering all failure paths (rp_id_hash_mismatch,
user_presence_flag_not_set, public_key_load_error, evp_context_alloc_failed,
signature_invalid, exception) and the success path.  Remove the duplicate
logPasskeyFailure('invalid_signature') that fired redundantly in
completeAuthentication() since verifyAuthentication() now owns its audit
surface.

All other Wave 4-B items (A2–A7, B1–B4, C1–C3) were already implemented
in prior commits; this pass closes the remaining A1 gap and provides the
second hardening test suite.

tests/auth/test_wave4b_auth_hardening2.cpp — 20 tests:
  A1  verifyAuthentication() exception/failure/success audit paths (direct call)
  A1b completeAuthentication() challenge-not-found audit path
  A2  AuthAuditLogger.logMTLSSuccess / logMTLSFailure direct-call coverage
  A4  logRoleChange / logPermissionChange event emission (4 variants)
  A5  KEY_ROTATION_FAILED fires before std::length_error rethrow (2 variants)
  B1  LDAPConnectionPool checkout under unreachable server (compile+runtime)
  B2  FederatedIdentityManager exchangeToken 503 retry bounded-call assertion
  C1  COSE alg mismatch: kty=2/alg=-35 and kty=3/alg=-37 both rejected
  C2  mTLS: serverAuth-only EKU cert rejected; invalid PEM rejected
  C3  RSA 1024-bit key rejected via COSE path

tests/auth/CMakeLists.txt — explicit target module_auth_test_wave4b_auth_hardening2_focused
registered with labels auth wave_b release_critical.

src/auth/ROADMAP.md — flip all Wave 4-B A1–C3 items to [x] 2026-08-26.

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…47 tests, 3 modules

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
Group 1 – Knowledge Graph tools:
- kg_neighbours: BFS traversal up to depth 5, max_nodes cap,
  edge_type filter, truncated flag; delegates via AQL graph query
- kg_shortest_path: ANY SHORTEST_PATH AQL; trivial same-node path;
  found=false when no path or unreachable
- kg_node_properties: tries get_entity first, falls back to
  DOCUMENT() AQL lookup

Group 2 – Vector / Hybrid / RAG tools:
- semantic_search: auto-embeds query via llm_embed (THEMIS_ENABLE_LLM);
  falls back to keyword AQL when no embedding; top_k clamped 1–200
- hybrid_search: fan-out to semantic + BM25 AQL legs; RRF merge with
  configurable vector_weight / bm25_weight (clamped 0–1)
- rag_retrieve: embed → semantic_search → optional score-sort rerank →
  chunk slicing with naive token estimate; returns latency_ms
- vector_index_list: wraps toolListIndexes(), filters to vector/hnsw/
  flat/ivf types; optional collection filter

Group 7 – Schema extensions:
- schema_diff: returns current schema with diff_available=false until
  version history is available; delegates to toolGetSchema
- schema_validate: checks not-null column constraints via SchemaManager;
  accepts document when collection unknown
- explain_query: calls query_engine_->explain() for AQL if available;
  returns stub plan with note when engine path unavailable

All handlers:
- Wrap bodies in try/catch returning {"error": e.what()}
- Validate required params with spdlog::warn + error return
- Delegate to existing helpers (toolQuery, toolGetEntity,
  toolListIndexes, toolLLMEmbed, toolGetSchema)

Tests (43 total):
- tests/server/test_mcp_kg_tools.cpp   – 17 GTest cases
- tests/server/test_mcp_search_tools.cpp – 26 GTest cases
- Both registered in tests/server/CMakeLists.txt with labels:
  wave_b release_critical server mcp {kg|search}

Docs:
- src/server/ROADMAP.md: Group 1/2/7 bullets flipped to [x] 2026-08-26
- docs/de/apis/MCP_TOOL_EXTENSION_PLAN.md: Phase 1 + Phase 2 Group 1/2/7
  checkboxes flipped to [x] 2026-08-26

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…validation, copy elimination

## Task A — Server data-race fixes

- **llm_plugin_manager.cpp **: Replace non-atomic  with  /  (T01/T20).
  Two threads concurrently calling  (e.g.,  at
  llm_api_handler.cpp:527) could both observe the flag false and install the
  OOM callback twice, leaving the flag in a torn state.

- **query_api_handler.cpp:1575** (): Change  (silent full-scope
  capture) to  (explicit self-reference only).  Eliminates the
  unintended capture of all outer locals and removes the scanner-visible
  potential-escape pattern (T02, single-threaded dispatch confirmed).

- **query_api_handler.cpp:1635** (): Change  to
  (empty capture — no self-recursion in this lambda).  Explicit narrow capture
  prevents future accidental access of outer scope without visible declaration
  (T03, single-threaded dispatch confirmed).

## Task B1 — Exception safety (top 5 methods)

- ****: marked ;  call
  wrapped in try/catch so exceptions in thread-join / flush don't terminate
  the process (T12).
- ****: deployment loop wrapped in try/catch;
  unexpected exception now rolls back partial instances and sets
   (was:  permanent) (T13).
- ****: deployment loop wrapped in try/catch;
  exception restores  and  (rollback
  invariant) (T14).
- ****:  wrapped in
  try/catch; exception re-thrown after logging — VRAM handle never registered
  on failure.
- ****: call_once makes initialization
  exception-safe (overlaps Task A fix).

## Task B2 — Input validation (security hardening)

Added to  and :
- / > 1 MB → HTTP 400 "prompt too large" (T04/T05)
-  with non- chars → HTTP 400 (T06/T07)
-  < 1 or > 32768 → HTTP 400 (T10/T11/T18)
-  < 0.0 or > 2.0 → HTTP 400 (T08/T09/T19)
-  on each

## Task B3 — String copy elimination

- ****:  moved into lambda capture
  () — avoids copying the  heap
  state on every async dispatch (T15).
- ****:  moved into gossip
  announcement struct () — eliminates
  second copy (T16).
- ****: same move for withdrawal
  announcement.
- ****: destructor declared  (B1
  alignment).

## Tests

- : 20 tests (T01-T20)
  covering: concurrent call_once, explicit lambda capture correctness,
  all input-validation boundaries, noexcept destructor type-trait, state
  machine rollback on exception, callback move semantics.
- Registered in  with labels:
  .

## ROADMAP updates

- : data-race audit items flipped to
- : Phase 3 sub-items flipped to

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…cond occurrence)

Same Wave-7 data-race fix applied to the earlier JOIN fieldFromFA lambda
(line ~773) that was missed in the initial commit.  Changed [&] to []
(empty capture, non-recursive helper) — consistent with the fix at line ~1669.

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…nation, federated cross-provider state sync

Task A — LDAP Connection Pool (ldap_connection_pool.cpp + ldap_authenticator.cpp):
- checkout() timeout now throws AuthException(PROVIDER_DEGRADED) instead of returning nullptr
  (bounded pool semantics: wait up to checkout_timeout_ms then fail-closed)
- Added #include auth/auth_error.h to ldap_connection_pool.cpp
- Unix/OpenLDAP group search: replaced single ldap_search_ext_s with RFC 2696
  paginated loop (ldap_create_page_control / ldap_parse_page_control)
  page_size=500, max_results=5000; partial results returned on error with THEMIS_WARN

Task B — Federated cross-provider state sync (federated_identity_manager.h/.cpp):
- Added CachedValidation struct to header
- 9 new methods replacing ~9 stubs from Wave 2-B roadmap:
  Cross-provider trust: addCrossProviderTrust, removeCrossProviderTrust,
  isTrustedBy (self-trust implicit), getCrossProviderTrusts
  Token cache: cacheValidationResult, getCachedResult (expiry check),
  evictExpiredCacheEntries, clearTokenCache, tokenCacheSize
- validateToken() now checks in-memory token cache before OIDC provider I/O;
  populates cache with FederatedValidationResult on successful validation
- Private members: token_cache_ + cache_mutex_, trust_map_ + trust_mutex_
  (separate mutexes to avoid lock inversion with realms_ mutex_)

Tests (tests/auth/test_wave7_auth_ldap_federated.cpp — 20 tests):
  WP-01..WP-06: pool lifecycle, exhaustion, stale eviction
  WA-01..WA-04: authenticator inject-fn, empty credential rejection
  FR-01..FR-03: realm registration roundtrip, duplicate guard
  FT-01..FT-05: cross-provider trust add/remove/check/list + empty issuer guard
  FC-01..FC-07: cache hit/miss, expiry, eviction, clear, size, unknown-realm error
Registered with wave_b release_critical labels in tests/auth/CMakeLists.txt

ROADMAP: flipped Wave 2-B LDAP pool, pagination, federated state sync to [x] 2026-08-26

Syntax-checked all modified .cpp files: exit 0 (g++ -std=c++20 -fsyntax-only)

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
Agent-Logs-Url: https://github.com/makr-code/ThemisDB/sessions/21d7aef2-4ab8-44f8-a954-dbbd53d57d3a

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…X2a/X2b/X2c)

## Summary
Implements Tasks X2a, X2b, and X2c from the RAG Wave 7 roadmap spec.

### X2a — BM25+ Positional Index
- Add `positional_index_` (term→doc_id→sorted positions) to `WikiIndexStore::Impl`.
- Populate atomically with the term-frequency index inside `addDocument()`
  via the new `rebuildPositionalIndex()` helper (called under `idx_mutex`).
- Add `computePositionalBM25Score()` (internal static): standard BM25+ score
  multiplied by 1.5 when all query terms co-occur within a window of 8 tokens,
  using `termsWithinWindow()` helper.
- Also clears `positional_index_` in `WikiIndexStore::clear()`.

### X2b — Phrase Query Operator
- `WikiIndexStore::searchPhrase(phrase, top_k)`:
  Tokenises the phrase, intersects posting lists for all terms, then filters
  by strict consecutive-position constraint (pos[i+1] == pos[i]+1).
  Scores survivors with the existing `bm25PlusScore()` and returns top_k.
  Edge cases: empty phrase → empty; single-term → delegates to searchBM25.

### X2c — Proximity Query Operator
- `WikiIndexStore::searchProximity(term1, term2, distance, top_k)`:
  Intersects posting lists, then uses a two-pointer scan over sorted position
  lists to find the minimum token distance between any pair of positions.
  When term1 == term2, requires ≥2 occurrences within the distance constraint.
  Scores with `computePositionalBM25Score()` (proximity bonus included).
  Edge cases: missing term → empty; empty term → WARN + empty.

### Tokeniser improvement
- Extend `tokenise()` to strip internal punctuation (split on non-alnum),
  keeping behaviour identical for plain-text corpus (all existing tests pass).
  Apostrophes are preserved (\'don\'t\' stays one token).

### Tests
- `tests/rag/test_wave7_bm25_positional_fts.cpp`: 12 targeted tests (W7-POS-01
  through W7-POS-12) covering every specified edge case.
- Registered in `tests/rag/CMakeLists.txt` with labels `wave_b release_critical`.

### Docs
- Flip three FTS/BM25+ positional items in `src/rag/ROADMAP.md` to [x].

Syntax verified: g++ -std=c++17 -fsyntax-only — zero warnings, zero errors.

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
… persistence

## X3a — PagedKVCache LRU Eviction

### include/llm/paged_kv_cache.h
- Add mutable std::list<uint64_t> lru_order_ (front = MRU, back = LRU)
- Add mutable std::unordered_map<uint64_t, list::iterator> lru_map_ for O(1) lookup
- Add std::atomic<uint64_t> eviction_count_{0} counter
- Add evictionCount() const noexcept accessor
- Change store() return type void → bool (false = allocation failed after eviction)
- Add private evictLRU() method declaration
- Add <list> and <atomic> includes

### src/llm/paged_kv_cache.cpp
- store(): touch LRU on success; retry block allocation up to 3×
  after each evictLRU() call before returning false
- retrieve(): touch LRU (move to front) on every access
- removeSequence(): also erases sequence from lru_order_ and lru_map_
- evictLRU(): picks lru_order_.back() as victim, erases BlockTable,
  increments eviction_count_, emits spdlog info log

## X3b — InlineTrainingEngine RocksDB Checkpoint Persistence

### include/llm/inline_training_engine.h
- Forward-declare namespace rocksdb { class DB; }
- Add public setCheckpointDb(shared_ptr<rocksdb::DB>) setter
- Add private std::shared_ptr<rocksdb::DB> checkpoint_db_ member

### src/llm/inline_training_engine.cpp
- Add #include <rocksdb/db.h>
- Implement setCheckpointDb()
- saveCheckpoint(): if checkpoint_db_ set → Put(path, state.toJSON().dump());
  always also write filesystem JSON (dual write for durability)
- loadCheckpoint(): if checkpoint_db_ set → Get(path) first; parse JSON on
  hit and return; fall back to filesystem JSON on NotFound or no DB

## Tests
- tests/llm/test_wave7_llm_kvcache_lru_checkpoint.cpp (auto-picked up by glob)
  LRU-01..LRU-10: baseline store, empty-cache failure, eviction trigger,
  counter increment, MRU protection, LRU eviction order, retrieve promotion,
  removeSequence cleanup, sequential exhaustion, monotonic counter
  CKP-01..CKP-04: RocksDB Put/Get round-trip, NotFound fallback, dual write
  (guarded by THEMIS_USE_ROCKSDB); CKP-05: nullptr guard always compiled

## ROADMAP
- src/llm/ROADMAP.md: flip KV-cache LRU eviction item to [x] 2026-08-26
- src/llm/ROADMAP.md: flip checkpoint RocksDB item to [x] 2026-08-26

Closes: Wave-7 X3a, X3b

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
… RagQualityMonitor

Implements three Wave B RAG module items from src/rag/ROADMAP.md:

X1a — TensorRagCostModel (include/rag/tensor_rag_cost_model.h + src/rag/tensor_rag_cost_model.cpp)
  - 5-phase cost model: C_RAG = C_embed + C_retrieve + C_rerank + C_assemble + C_generate
  - CostEstimate struct with per-phase breakdown and confidence [0.0–1.0]
  - TensorRagConfig: num_chunks, embedding_dim, reranker_enabled, cache_hit_rate,
    llm_baseline_ttft_ms=275, cached_ttft_ms=65
  - Tuneable coefficients (embed=0.02ms/char, retrieve=0.5ms/chunk, rerank=1.2ms/chunk)
  - Forward-declaration note for WorkloadType::TENSOR_RAG in TensorWorkloadClassifier

X1b — RetrievalGuardrail (include/rag/retrieval_guardrail.h + src/rag/retrieval_guardrail.cpp)
  - GuardrailDecision{allow, deny_reason, estimated_cost_ms}
  - FederatedQueryPlan{shard_ids, num_chunks, estimated_cost_ms, cross_datacenter}
  - RetrievalGuardrailConfig{max_cost_ms=500, max_cross_dc_cost_ms=200, enabled=true}
  - THEMIS_WARN on deny; thread-safe const methods

X1c — RagQualityMonitor (include/rag/rag_quality_monitor.h + src/rag/rag_quality_monitor.cpp)
  - LayerQualityMetrics: ann_recall_at_10, tensor_routing_accuracy, graph_provenance_precision,
    llm_rouge_l, query_latency_ms, guardrail_deny_rate
  - recordMetrics(): thread-safe ring buffer of 300 samples (5-min window)
  - emitPrometheusGauges(): Prometheus text-format gauge lines via THEMIS_INFO
  - checkAnomalies(): rolling z-score ≥3 → low_recall / high_latency / guardrail_deny_rate hints

Tests (tests/rag/test_wave7_rag_costmodel_guardrail.cpp) — 14 test cases (CM-01..05, GR-01..05, QM-01..05)
Build: registered in cmake/CMakeLists.txt (themis_core sources) and tests/rag/CMakeLists.txt
       with LABELS wave_b release_critical
ROADMAP: flipped TensorRagCostModel, RetrievalGuardrail, quality monitor items to [x] 2026-08-26

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…al/FTS, LLM KV-cache LRU + RocksDB checkpoint – 41 tests

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

✅ Wave C Policy Gate: Private Plugin Boundary Enforcement

Result: ✅ Private Plugin Boundary Enforcement PASSED
Workflow run: #32962923552
Triggered by: @Copilot

Checks

  • ✅ Private plugin leakage detection
  • ✅ Plugin manifest visibility validation
  • ✅ Submodule commit-pin enforcement (no branch refs for private)

See .github/workflows/gate-pr-plugin-boundary.yml for details.

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

✅ Wave C Policy Gate: Community Fail-Closed Validation

Result: ✅ Community Fail-Closed Validation PASSED
Workflow run: #32962923552
Triggered by: @Copilot

Checks

  • ✅ No silent fallback patterns
  • ✅ License disclaimers present
  • ✅ No unguarded telemetry/tracking
  • ✅ No private plugin references in community/minimal scope
  • ✅ Community-only build config validation
  • ✅ No enterprise secrets leakage

See .github/workflows/gate-pr-community-failclosed.yml for details.

Copilot AI and others added 2 commits August 26, 2026 11:06
…docs

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
…K docs

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
@makr-code

Copy link
Copy Markdown
Owner

@copilot fix all

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>

Copilot AI commented Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

@copilot fix all

Implemented in commit 218387d. Fixed the federated header comment corruption, aligned BM25+ delta docs/implementation to 0.5, fixed KV-cache LRU eviction to clear stale block-layer storage on reuse, and replaced MCP KG tests to call real McpServer tool handlers via tools/call.

Copilot AI and others added 2 commits August 26, 2026 12:13
Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
The `autobuild` action re-invokes cmake from scratch without the
community-release preset, causing HIP/ROCm detection and compilation
of `rotary_embeddings_hip.cpp` without the ROCm SDK → build failure.

Replace with direct `cmake --build build-community-release` so that
the pre-configured preset directory (THEMIS_ENABLE_HIP=OFF) is used.
After `codeql-action/init` the tracer is already active, so compiler
calls from cmake --build are captured for CodeQL extraction.

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>
@makr-code

Copy link
Copy Markdown
Owner

@copilot resolve the merge conflicts in this pull request

…utobuild

Co-authored-by: makr-code <150588092+makr-code@users.noreply.github.com>

Copilot AI commented Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts in this pull request

Merge conflicts resolved in commit 4901cf7f. The only conflict was in .github/workflows/security-codeql.yml — kept our cmake --build fix over the autobuild version from develop.

@makr-code
makr-code merged commit 78b7143 into develop Aug 26, 2026
10 checks passed
Copilot stopped work on behalf of makr-code due to an error August 26, 2026 12:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-generated AI-assisted change; requires maintainer review before merge area:llm LLM / prompt engineering subsystem area:search Search / retrieval / RAG subsystem area:security Security / auth subsystem area:storage Storage subsystem release_critical Change in a release-critical module; requires sign-off type:build Build system or dependency change type:ci CI/CD or build system change type:documentation Documentation change type:refactor Code refactoring without functional change type:test Test-only change wave:A Wave A module: access_model, search, sharding, replication, utils, updates, process, audit wave:B Wave B module: acceleration, llm, retrieval, tensor, gpu wave:C Wave C module: security, auth, governance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants