From 500d2c4c677576b2119304599330937a6d56d4d0 Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 12 Sep 2026 11:51:38 +0200 Subject: [PATCH] Forward glossary provenance without transcript substitution --- CHANGELOG.md | 2 ++ PROJECT_KNOWLEDGE.md | 5 +++++ README.md | 5 +++++ src/mka/application/glossary.py | 5 +++++ src/mka/application/meeting_service.py | 8 +++++++- tests/test_meeting_service.py | 15 +++++++++++++++ 6 files changed, 39 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15f5d7f..34dc0c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ ### Changed +- Record active glossary configuration without rewriting protocol transcript input. + - Reconciled the documented MVP with the validated Meeting Lab backend. - Selected `whisper.cpp` for transcription and made diarization optional. - Defined the Python API, progress-event and Meeting Context integration diff --git a/PROJECT_KNOWLEDGE.md b/PROJECT_KNOWLEDGE.md index 594d415..ef7fa96 100644 --- a/PROJECT_KNOWLEDGE.md +++ b/PROJECT_KNOWLEDGE.md @@ -164,3 +164,8 @@ product work, not a current MVP requirement. - no automatic identity claims - human review of generated protocols - small modules and simple interfaces + +Active glossary aliases are forwarded to Meeting Lab as provenance metadata. +Canonical terminology remains Meeting Context guidance; the exact protocol +transcript input and the raw Whisper/diarization artifacts are not rewritten. +`glossary_replacements` remains empty. diff --git a/README.md b/README.md index e29bf63..2eed545 100644 --- a/README.md +++ b/README.md @@ -229,3 +229,8 @@ transcription; Meeting Assistant does not duplicate audio conversion. See [Architecture](docs/architecture.md), [Project Knowledge](PROJECT_KNOWLEDGE.md), [Roadmap](ROADMAP.md) and [ADR 0011](docs/adr/0011-use-meeting-lab-mvp-backend.md). + +Active glossary aliases are forwarded to Meeting Lab as provenance metadata. +Canonical terminology remains Meeting Context guidance; the exact protocol +transcript input and the raw Whisper/diarization artifacts are not rewritten. +`glossary_replacements` remains empty. diff --git a/src/mka/application/glossary.py b/src/mka/application/glossary.py index 03fb398..1438b47 100644 --- a/src/mka/application/glossary.py +++ b/src/mka/application/glossary.py @@ -355,6 +355,11 @@ def render_glossary_terms(entries: Iterable[GlossaryEntry]) -> list[str]: return rendered +def glossary_alias_mapping(entries: Iterable[GlossaryEntry]) -> dict[str, str]: + """Return explicit alias configuration for provenance, not substitution.""" + return {alias: entry.canonical_term for entry in entries for alias in entry.aliases} + + def _timestamp() -> str: return datetime.now(UTC).isoformat(timespec="seconds") diff --git a/src/mka/application/meeting_service.py b/src/mka/application/meeting_service.py index 851add6..baae273 100644 --- a/src/mka/application/meeting_service.py +++ b/src/mka/application/meeting_service.py @@ -15,7 +15,11 @@ from uuid import uuid4 import yaml from mka.application.config import AppSettings -from mka.application.glossary import GlossaryRepository, render_glossary_terms +from mka.application.glossary import ( + GlossaryRepository, + glossary_alias_mapping, + render_glossary_terms, +) from mka.application.performance import DEFAULT_PERFORMANCE_PROFILE, resolve_ollama_num_thread STAGES = ("preparing", "transcription", "diarization", "protocol_generation") @@ -231,6 +235,7 @@ class MeetingProcessingService: "model": self.settings.protocol_model, "ollama_endpoint": self.settings.ollama_endpoint, "protocol_num_ctx": self.settings.protocol_num_ctx, + "glossary_aliases": glossary_alias_mapping(self.glossary.list(active_only=True)), "protocol_num_thread": resolve_ollama_num_thread(options.performance_profile), "protocol_safe_input_token_budget": ( self.settings.protocol_safe_input_token_budget @@ -405,6 +410,7 @@ class MeetingProcessingService: model=self.settings.protocol_model, ollama_endpoint=self.settings.ollama_endpoint, protocol_num_ctx=self.settings.protocol_num_ctx, + glossary_aliases=glossary_alias_mapping(self.glossary.list(active_only=True)), protocol_num_thread=resolve_ollama_num_thread(performance_profile), protocol_safe_input_token_budget=(self.settings.protocol_safe_input_token_budget), ) diff --git a/tests/test_meeting_service.py b/tests/test_meeting_service.py index c7dfaa7..55ddbdd 100644 --- a/tests/test_meeting_service.py +++ b/tests/test_meeting_service.py @@ -512,6 +512,7 @@ def test_protocol_only_regeneration_persists_mappings_without_rewriting_transcri "SPEAKER_00": "martin" } assert gateway.regeneration["options"]["protocol_num_ctx"] == 32_768 + assert gateway.regeneration["options"]["glossary_aliases"] == {"Enlyse": "ENLYZE"} assert events[0].stage == "protocol_generation" assert source.read_bytes() == original_source @@ -608,3 +609,17 @@ def test_protocol_regeneration_propagates_explicit_profile(tmp_path: Path) -> No assert gateway.regeneration is not None assert gateway.regeneration["options"]["protocol_num_thread"] == 16 + + +def test_process_passes_only_active_explicit_glossary_aliases(tmp_path: Path) -> None: + service, gateway = make_service(tmp_path) + service.glossary.create("Luminy", "product", aliases=("Lumini",)) + inactive = service.glossary.create("PBAT", "acronym", aliases=("PBRT",)) + service.glossary.set_active(inactive.id, False) + audio = tmp_path / "meeting.wav" + audio.write_bytes(b"audio") + + service.process(audio, meeting(), participants(), ProcessingOptions()) + + assert gateway.config_values is not None + assert gateway.config_values["glossary_aliases"] == {"Lumini": "Luminy"}