From 707143f13e676bcd503d4ed6423e05d06c867366 Mon Sep 17 00:00:00 2001 From: team 1 Date: Tue, 5 May 2026 19:13:56 +0200 Subject: [PATCH] p43K --- config/retriex/agent.yaml | 74 +-------------- config/retriex/governance.yaml | 35 +++---- config/retriex/vocabulary.yaml | 71 ++++++++++++++ ...ON_FUZZY_ROUTING_VOCABULARY_VIEW_README.md | 60 ++++++++++++ ...E_PROTECTED_SHORT_MODEL_FALLBACK_README.md | 70 ++++++++++++++ ...RNANCE_REQUIRED_PROFILE_DEFAULTS_README.md | 93 +++++++++++++++++++ src/Config/AgentRunnerConfig.php | 5 +- src/Config/GovernanceConfig.php | 60 +++++++++++- 8 files changed, 369 insertions(+), 99 deletions(-) create mode 100644 patch_history/RETRIEX_PATCH_43I_INPUT_NORMALIZATION_FUZZY_ROUTING_VOCABULARY_VIEW_README.md create mode 100644 patch_history/RETRIEX_PATCH_43J_GOVERNANCE_PROTECTED_SHORT_MODEL_FALLBACK_README.md create mode 100644 patch_history/RETRIEX_PATCH_43K_GOVERNANCE_REQUIRED_PROFILE_DEFAULTS_README.md diff --git a/config/retriex/agent.yaml b/config/retriex/agent.yaml index 98294ec..0ca7b3a 100644 --- a/config/retriex/agent.yaml +++ b/config/retriex/agent.yaml @@ -52,75 +52,11 @@ parameters: max_distance_long: 3 min_similarity_percent: 72 # Canonical routing terms only, not typo variants. - # The code fuzzy-matches user tokens against these terms when the LLM leaves - # an obvious routing typo unchanged. - terms: - - shop - - suche - - suchen - - such - - finde - - finden - - kostet - - kosten - - preis - - preise - - preisen - - preiswert - - preiswerte - - günstig - - guenstig - - kaufen - - bestellen - - produkt - - produkte - - artikel - - sku - - online - - analysegerät - - analysegeraet - - messgerät - - messgeraet - - handmessgerät - - handmessgeraet - - pockettester - - analysator - - analyzer - - indikator - - indikatoren - - reagenz - - reagenzien - - verbrauchsmaterial - - zubehör - - zubehoer - - ersatzteil - - ersatzteile - - anschlusskabel - - kabel - - sensorkabel - - elektrode - - elektrodenkabel - - puffer - - kalibrierpuffer - - kalibrierlösung - - kalibrierloesung - - kalibrierung - - lösung - - loesung - - messen - - messung - - überwachen - - ueberwachen - - kontrollieren - - schwimmbad - - pool - - becken - - wasseranalyse - - geeignet - - passend - - empfehlung - - empfehlen - - empfiehl + # Resolved from config/retriex/vocabulary.yaml view + # agent.input_normalization_fuzzy_routing_terms. + # A local terms list may still be added here as an explicit project override. + vocabulary_views: + terms: agent.input_normalization_fuzzy_routing_terms follow_up_context: strong_reference_patterns: diff --git a/config/retriex/governance.yaml b/config/retriex/governance.yaml index 3eb8660..788d62e 100644 --- a/config/retriex/governance.yaml +++ b/config/retriex/governance.yaml @@ -59,14 +59,10 @@ parameters: shop_query_current_input_preservation_terms: - ph - redox - vocabulary: - protected_short_model_tokens: - - th - - tc - - tp - - tm - - ph - - rx + # Protected vocabulary tokens fall back to + # regression_baseline.protected_short_model_tokens. + # Add vocabulary.protected_short_model_tokens only for an explicit override. + vocabulary: {} language: protected_stopword_terms: - nicht @@ -86,28 +82,19 @@ parameters: - rag_evidence - shop_context_fallback - retrieval_reference_cleanup + required_profile_term_defaults: + stopwords: + - der + - dieser + - mit + - bitte required_profile_terms: commerce_query: - stopwords: - - der - - dieser - - mit - - bitte phrases: - ich suche - suche im shop - rag_evidence: - stopwords: - - der - - dieser - - mit - - bitte + rag_evidence: {} shop_context_fallback: - stopwords: - - der - - dieser - - mit - - bitte phrases: - zeige mir - suche im shop diff --git a/config/retriex/vocabulary.yaml b/config/retriex/vocabulary.yaml index 337641c..d37c635 100644 --- a/config/retriex/vocabulary.yaml +++ b/config/retriex/vocabulary.yaml @@ -100,6 +100,73 @@ parameters: - mehr - weniger - als + input_normalization_fuzzy_routing_terms: + - shop + - suche + - suchen + - such + - finde + - finden + - kostet + - kosten + - preis + - preise + - preisen + - preiswert + - preiswerte + - günstig + - guenstig + - kaufen + - bestellen + - produkt + - produkte + - artikel + - sku + - online + - analysegerät + - analysegeraet + - messgerät + - messgeraet + - handmessgerät + - handmessgeraet + - pockettester + - analysator + - analyzer + - indikator + - indikatoren + - reagenz + - reagenzien + - verbrauchsmaterial + - zubehör + - zubehoer + - ersatzteil + - ersatzteile + - anschlusskabel + - kabel + - sensorkabel + - elektrode + - elektrodenkabel + - puffer + - kalibrierpuffer + - kalibrierlösung + - kalibrierloesung + - kalibrierung + - lösung + - loesung + - messen + - messung + - überwachen + - ueberwachen + - kontrollieren + - schwimmbad + - pool + - becken + - wasseranalyse + - geeignet + - passend + - empfehlung + - empfehlen + - empfiehl views: shop: device_query: @@ -666,6 +733,10 @@ parameters: - ph indikator - ph-indikatoren - ph indikatoren + agent: + input_normalization_fuzzy_routing_terms: + include: + - input_normalization_fuzzy_routing_terms maps: agent: rag_evidence_guard: diff --git a/patch_history/RETRIEX_PATCH_43I_INPUT_NORMALIZATION_FUZZY_ROUTING_VOCABULARY_VIEW_README.md b/patch_history/RETRIEX_PATCH_43I_INPUT_NORMALIZATION_FUZZY_ROUTING_VOCABULARY_VIEW_README.md new file mode 100644 index 0000000..77c79ef --- /dev/null +++ b/patch_history/RETRIEX_PATCH_43I_INPUT_NORMALIZATION_FUZZY_ROUTING_VOCABULARY_VIEW_README.md @@ -0,0 +1,60 @@ +# RetrieX Patch 43I - Input Normalization Fuzzy Routing Vocabulary View + +## Ziel + +p43I reduziert eine weitere lokale YAML-Begriffsliste ohne fachliche Runtime-Änderung. +Die Canonical Fuzzy-Routing-Terms der Input-Normalisierung werden zentral in `config/retriex/vocabulary.yaml` gepflegt und aus `agent.yaml` nur noch per Vocabulary-View referenziert. + +## Änderungen + +- `config/retriex/agent.yaml` + - lokale Liste `input_normalization.fuzzy_routing.terms` entfernt + - neue Referenz `input_normalization.fuzzy_routing.vocabulary_views.terms` ergänzt + - Kommentar ergänzt, dass lokale `terms` weiterhin als expliziter Projekt-Override möglich sind + +- `config/retriex/vocabulary.yaml` + - neue Klasse `input_normalization_fuzzy_routing_terms` ergänzt + - neue View `agent.input_normalization_fuzzy_routing_terms` ergänzt + - Reihenfolge und Werte entsprechen exakt dem vorherigen p43H-Stand + +- `src/Config/AgentRunnerConfig.php` + - `getInputNormalizationFuzzyRoutingTerms()` nutzt nun `getConfiguredStringListOrVocabularyView()` + - lokale Override-Liste bleibt möglich + +## Nicht geändert + +- keine neue Fachlogik +- keine Scoringänderung +- keine Retrievaländerung +- keine Prompt-Regeländerung +- keine Admin-UI +- keine neuen harten Listen im PHP-Core + +## Lokale Prüfungen + +Ausgeführt: + +```bash +php -l src/Config/AgentRunnerConfig.php +php -l src/Config/SearchRepairConfig.php +php -l src/Config/PromptBuilderConfig.php +python3 YAML parse check for config/retriex/*.yaml +python3 effective p43H-vs-p43I fuzzy routing terms comparison +``` + +Ergebnis: grün. + +Die effektive Liste `input_normalization.fuzzy_routing.terms` ist gegenüber p43H identisch geblieben. + +## Hinweis zu Symfony-Checks + +Die folgenden Checks konnten in dieser Umgebung nicht lokal ausgeführt werden, weil der ZIP-Stand kein `vendor/` enthält und `bin/console` dadurch mit fehlenden Dependencies abbricht: + +```bash +bin/console mto:agent:config:validate +bin/console mto:agent:regression:test +bin/console mto:agent:config:audit-source --details +bin/console mto:agent:config:audit-patterns --details +``` + +Sie sollen nach dem Einspielen im vollständigen Projekt ausgeführt werden. diff --git a/patch_history/RETRIEX_PATCH_43J_GOVERNANCE_PROTECTED_SHORT_MODEL_FALLBACK_README.md b/patch_history/RETRIEX_PATCH_43J_GOVERNANCE_PROTECTED_SHORT_MODEL_FALLBACK_README.md new file mode 100644 index 0000000..b0d865f --- /dev/null +++ b/patch_history/RETRIEX_PATCH_43J_GOVERNANCE_PROTECTED_SHORT_MODEL_FALLBACK_README.md @@ -0,0 +1,70 @@ +# RetrieX Patch p43J – Governance Protected Short Model Fallback + +## Ziel + +Kleiner Konsolidierungsschritt nach p43I: eine doppelt gepflegte Governance-Liste entfernen, ohne die unabhängige Regression-Baseline zu schwächen. + +## Inhalt + +- `config/retriex/governance.yaml` + - Die lokale Duplikatliste `vocabulary.protected_short_model_tokens` wurde entfernt. + - `regression_baseline.protected_short_model_tokens` bleibt bewusst als unabhängige Guardrail-Baseline erhalten. + - `vocabulary` bleibt als leerer Override-Block erhalten; ein lokaler Override kann später wieder explizit gesetzt werden. + +- `src/Config/GovernanceConfig.php` + - `getVocabularyProtectedShortModelTokens()` nutzt nun `vocabulary.protected_short_model_tokens`, falls lokal gesetzt. + - Wenn kein lokaler Override vorhanden ist, fällt die Methode auf `getRegressionProtectedShortModelTokens()` zurück. + - Neue interne Helper: + - `optionalStringList()` + - `optionalValue()` + +## Bewusst nicht geändert + +- Keine Runtime-Fachlogik +- Keine Prompt-Regeländerung +- Keine Retrievaländerung +- Keine Scoringänderung +- Keine Admin-UI +- Keine neuen harten Listen im PHP-Core +- Die Regression-Baseline bleibt YAML-owned und unabhängig von der zu prüfenden Retrieval-/Vocabulary-View. + +## Effektive Werte + +Vorher und nachher identisch: + +- `regression_baseline.protected_short_model_tokens`: 6 / 6 +- effektive `vocabulary.protected_short_model_tokens`: 6 / 6 + +Werte: + +```text +th, tc, tp, tm, ph, rx +``` + +## Lokale Prüfungen + +Ausgeführt: + +```bash +php -l src/Config/GovernanceConfig.php +php -l src/Config/AgentRunnerConfig.php +php -l src/Config/SearchRepairConfig.php +php -l src/Config/PromptBuilderConfig.php +python3 YAML parse check for config/retriex/*.yaml +python3 effective governance protected short model token comparison +``` + +Ergebnis: grün. + +## Nicht lokal ausführbar + +Die Symfony-Console-Checks konnten in der ChatGPT-Arbeitsumgebung nicht ausgeführt werden, weil der ZIP-Stand kein `vendor/` enthält und `bin/console` mit fehlenden Dependencies abbricht. + +Bitte im Projekt ausführen: + +```bash +bin/console mto:agent:config:validate +bin/console mto:agent:regression:test +bin/console mto:agent:config:audit-source --details +bin/console mto:agent:config:audit-patterns --details +``` diff --git a/patch_history/RETRIEX_PATCH_43K_GOVERNANCE_REQUIRED_PROFILE_DEFAULTS_README.md b/patch_history/RETRIEX_PATCH_43K_GOVERNANCE_REQUIRED_PROFILE_DEFAULTS_README.md new file mode 100644 index 0000000..90ffae3 --- /dev/null +++ b/patch_history/RETRIEX_PATCH_43K_GOVERNANCE_REQUIRED_PROFILE_DEFAULTS_README.md @@ -0,0 +1,93 @@ +# RetrieX Patch p43K - Governance Required Profile Term Defaults + +## Ziel + +Kleiner Config-/Accessor-Konsolidierungsschritt nach p43J. + +Der Patch reduziert doppelte Governance-Listen innerhalb von `language.required_profile_terms`, ohne fachliche Runtime-Logik, Scoring, Prompt-Regeln, Retrieval oder Admin-UI zu ändern. + +## Änderungen + +### `config/retriex/governance.yaml` + +Neu eingeführt: + +```yaml +language: + required_profile_term_defaults: + stopwords: + - der + - dieser + - mit + - bitte +``` + +Entfernt wurden die identischen lokalen `stopwords`-Listen aus: + +- `language.required_profile_terms.commerce_query.stopwords` +- `language.required_profile_terms.rag_evidence.stopwords` +- `language.required_profile_terms.shop_context_fallback.stopwords` + +Die Profile behalten ihre spezifischen `phrases` und `meta_terms` unverändert. + +### `src/Config/GovernanceConfig.php` + +`getLanguageRequiredProfileTerms()` verwendet jetzt optionale Defaults aus: + +```text +language.required_profile_term_defaults +``` + +Lokale Profilwerte bleiben weiterhin möglich und überschreiben die Defaults pro Profilfeld. + +Neuer interner Helper: + +```php +languageRequiredProfileTermDefaults() +``` + +## Effektive Werte + +Die effektiven Werte bleiben gegenüber p43J identisch: + +- `commerce_query.stopwords`: 4 / identisch +- `commerce_query.phrases`: 2 / identisch +- `rag_evidence.stopwords`: 4 / identisch +- `shop_context_fallback.stopwords`: 4 / identisch +- `shop_context_fallback.phrases`: 2 / identisch +- `shop_context_fallback.meta_terms`: 3 / identisch + +## Keine fachlichen Änderungen + +Nicht geändert: + +- keine neue Fachlogik +- keine Scoringänderung +- keine Retrievaländerung +- keine Prompt-Regeländerung +- keine Admin-UI +- keine neuen harten Listen im PHP-Core + +## Lokale Prüfungen + +Grün: + +```bash +php -l src/Config/GovernanceConfig.php +php -l src/Config/AgentRunnerConfig.php +php -l src/Config/SearchRepairConfig.php +php -l src/Config/PromptBuilderConfig.php +python3 YAML parse check for config/retriex/*.yaml +python3 effective p43J-vs-p43K governance required profile terms comparison +``` + +Lokal nicht ausführbar wegen fehlendem `vendor/` im ZIP-Stand: + +```bash +bin/console mto:agent:config:validate +bin/console mto:agent:regression:test +bin/console mto:agent:config:audit-source --details +bin/console mto:agent:config:audit-patterns --details +``` + +`bin/console` bricht mit `Dependencies are missing. Try running "composer install".` ab. diff --git a/src/Config/AgentRunnerConfig.php b/src/Config/AgentRunnerConfig.php index 8812cd3..0ac9032 100644 --- a/src/Config/AgentRunnerConfig.php +++ b/src/Config/AgentRunnerConfig.php @@ -281,7 +281,10 @@ final class AgentRunnerConfig */ public function getInputNormalizationFuzzyRoutingTerms(): array { - return $this->getRequiredStringList('input_normalization.fuzzy_routing.terms'); + return $this->getConfiguredStringListOrVocabularyView( + 'input_normalization.fuzzy_routing.terms', + 'input_normalization.fuzzy_routing.vocabulary_views.terms' + ); } private function getRequiredInt(string $key): int diff --git a/src/Config/GovernanceConfig.php b/src/Config/GovernanceConfig.php index 56d56d1..2958f09 100644 --- a/src/Config/GovernanceConfig.php +++ b/src/Config/GovernanceConfig.php @@ -129,7 +129,10 @@ final class GovernanceConfig /** @return string[] */ public function getVocabularyProtectedShortModelTokens(): array { - return $this->requiredStringList('vocabulary.protected_short_model_tokens'); + return $this->optionalStringList( + 'vocabulary.protected_short_model_tokens', + $this->getRegressionProtectedShortModelTokens() + ); } /** @return string[] */ @@ -152,6 +155,8 @@ final class GovernanceConfig throw $this->invalid('language.required_profile_terms', 'must be a map of cleanup profile term lists'); } + $defaults = $this->languageRequiredProfileTermDefaults(); + $out = []; foreach ($value as $profileName => $profileTerms) { if (!is_string($profileName) || trim($profileName) === '' || !is_array($profileTerms)) { @@ -160,9 +165,9 @@ final class GovernanceConfig $normalizedProfileName = trim($profileName); $out[$normalizedProfileName] = [ - 'stopwords' => $this->normalizeStringList($profileTerms['stopwords'] ?? []), - 'phrases' => $this->normalizeStringList($profileTerms['phrases'] ?? []), - 'meta_terms' => $this->normalizeStringList($profileTerms['meta_terms'] ?? []), + 'stopwords' => $this->normalizeStringList($profileTerms['stopwords'] ?? $defaults['stopwords']), + 'phrases' => $this->normalizeStringList($profileTerms['phrases'] ?? $defaults['phrases']), + 'meta_terms' => $this->normalizeStringList($profileTerms['meta_terms'] ?? $defaults['meta_terms']), ]; if ($out[$normalizedProfileName]['stopwords'] === [] @@ -180,6 +185,29 @@ final class GovernanceConfig return $out; } + /** @return array{stopwords:string[], phrases:string[], meta_terms:string[]} */ + private function languageRequiredProfileTermDefaults(): array + { + $value = $this->optionalValue('language.required_profile_term_defaults'); + if ($value === null) { + return [ + 'stopwords' => [], + 'phrases' => [], + 'meta_terms' => [], + ]; + } + + if (!is_array($value)) { + throw $this->invalid('language.required_profile_term_defaults', 'must be a map of cleanup profile term lists'); + } + + return [ + 'stopwords' => $this->normalizeStringList($value['stopwords'] ?? []), + 'phrases' => $this->normalizeStringList($value['phrases'] ?? []), + 'meta_terms' => $this->normalizeStringList($value['meta_terms'] ?? []), + ]; + } + /** @return string[] */ public function getCorePatternAuditSourceRoots(): array { @@ -299,6 +327,18 @@ final class GovernanceConfig return $this->nonEmptyStringList($path, $this->requiredValue($path)); } + /** @return string[] */ + private function optionalStringList(string $path, array $fallback = []): array + { + $value = $this->optionalValue($path); + if ($value === null) { + return $this->normalizeStringList($fallback); + } + + $out = $this->normalizeStringList($value); + return $out !== [] ? $out : $this->normalizeStringList($fallback); + } + /** @return string[] */ private function nonEmptyStringList(string $path, mixed $value): array { @@ -337,11 +377,21 @@ final class GovernanceConfig } private function requiredValue(string $path): mixed + { + $value = $this->optionalValue($path); + if ($value === null) { + throw $this->missing($path); + } + + return $value; + } + + private function optionalValue(string $path): mixed { $value = $this->config; foreach (explode('.', $path) as $segment) { if (!is_array($value) || !array_key_exists($segment, $value)) { - throw $this->missing($path); + return null; } $value = $value[$segment];