This commit is contained in:
team 1
2026-05-07 16:21:47 +02:00
parent e02f3d7143
commit 734134c209
7 changed files with 256 additions and 5 deletions

View File

@@ -12,6 +12,8 @@
# source path is visible with its cleanup classification. p59D moves
# those legacy/runtime source declarations out of configuration_values so
# the value surface stays native and maintenance-focused.
# p59F adds machine-readable review-group metadata so the remaining
# compatibility paths can be removed or kept deliberately by category.
parameters:
retriex.genre.config:
id: water_analysis
@@ -31,6 +33,9 @@ parameters:
review_path_groups:
frozen_compatibility_views:
description: Legacy no-LLM product-role vocabulary views. Keep frozen until the fallback reads only from genre.configuration_values.product_roles.
classification: legacy_compatibility_view
source_state: legacy_frozen_non_empty
cleanup_action: rewire_to_genre_value_and_remove_legacy_view
paths:
- agent.no_llm_fallback.product_roles.vocabulary_views.main_device_request_keywords
- agent.no_llm_fallback.product_roles.vocabulary_views.accessory_product_keywords
@@ -43,6 +48,9 @@ parameters:
review_path_groups:
frozen_runtime_views:
description: Legacy shop-runtime attribute and length helpers mirrored by genre values. Rewire candidates, not user-facing maintenance paths.
classification: legacy_runtime_helper
source_state: legacy_frozen_non_empty
cleanup_action: rewire_runtime_accessor_to_genre_value
paths:
- agent.shop_runtime.attribute_cleanup.vocabulary_views.product_type_terms
- agent.shop_runtime.attribute_cleanup.vocabulary_views.stop_terms
@@ -50,6 +58,9 @@ parameters:
- agent.shop_runtime.answer_constraints.length_filter
regex_templates:
description: Intent regex templates that still belong to the technical matcher layer and should remain frozen while genre terms live in configuration_values.
classification: technical_regex_template
source_state: legacy_frozen_non_empty
cleanup_action: keep_until_dedicated_regex_template_migration
paths:
- intent.commerce.patterns.size_extraction_template
- intent.commerce.patterns.size_value_template
@@ -72,14 +83,23 @@ parameters:
review_path_groups:
frozen_runtime_views:
description: Legacy fuzzy-routing vocabulary view kept only as frozen compatibility metadata until routing uses the genre value directly.
classification: legacy_runtime_helper
source_state: legacy_frozen_non_empty
cleanup_action: rewire_runtime_accessor_to_genre_value
paths:
- agent.input_normalization.fuzzy_routing.vocabulary_views.terms
regex_templates:
description: Commerce intent regex template for model-like product terms; technical matcher fallback, not a genre maintenance list.
classification: technical_regex_template
source_state: legacy_frozen_non_empty
cleanup_action: keep_until_dedicated_regex_template_migration
paths:
- intent.commerce.patterns.model_like_product
sales_signal_fallbacks:
description: Sales/advisory signal lists mirrored by genre values and frozen to prevent drift outside genre.yaml.
classification: legacy_signal_fallback
source_state: legacy_frozen_non_empty
cleanup_action: remove_legacy_fallback_after_genre_accessor_coverage
paths:
- intent.sales.sales_signals
- intent.sales.comparison_signals
@@ -97,10 +117,16 @@ parameters:
review_path_groups:
frozen_runtime_views:
description: Legacy history-anchor trigger view mirrored by genre values. Candidate for later runtime accessor cleanup.
classification: legacy_runtime_helper
source_state: legacy_frozen_non_empty
cleanup_action: rewire_runtime_accessor_to_genre_value
paths:
- agent.shop_runtime.context_resolution.history_anchor_enrichment.vocabulary_views.trigger_terms
commercial_follow_up_fallbacks:
description: Commercial follow-up anchor patterns and query templates kept frozen while the follow-up resolver is migrated fully to genre values.
classification: legacy_context_fallback
source_state: legacy_frozen_non_empty
cleanup_action: rewire_follow_up_resolver_to_genre_value
paths:
- agent.follow_up_context.commercial_table_follow_up.history_anchor_patterns
- agent.follow_up_context.commercial_table_follow_up.indicator_marker_patterns
@@ -118,6 +144,9 @@ parameters:
review_path_groups:
frozen_runtime_views:
description: Legacy current-input preservation vocabulary view mirrored by genre values and kept frozen until the query optimizer reads only from genre.yaml.
classification: legacy_runtime_helper
source_state: legacy_frozen_non_empty
cleanup_action: rewire_runtime_accessor_to_genre_value
paths:
- agent.shop_runtime.query_cleanup.current_input_preservation.vocabulary_views.terms
result_identity_and_answer_policy:
@@ -137,6 +166,9 @@ parameters:
review_path_groups:
regex_templates:
description: Search-repair regex templates still owned by the technical matcher layer. Frozen source paths prevent silent divergence from genre values.
classification: technical_regex_template
source_state: legacy_frozen_non_empty
cleanup_action: keep_until_dedicated_regex_template_migration
paths:
- search_repair.patterns.model_candidate
- search_repair.patterns.accessory_candidate_template
@@ -154,6 +186,9 @@ parameters:
review_path_groups:
technical_cleanup_profiles:
description: Shared language cleanup profiles with runtime structure beyond simple genre vocabulary. Keep as technical review paths until a dedicated cleanup-profile migration removes the legacy copies.
classification: technical_cleanup_profile
source_state: legacy_frozen_non_empty
cleanup_action: keep_until_dedicated_cleanup_profile_migration
paths:
- language.cleanup_profiles.commerce_query
- language.cleanup_profiles.rag_evidence
@@ -168,6 +203,9 @@ parameters:
review_path_groups:
technical_shop_mapping:
description: Shop matching field and role-guard configuration. Installation-specific, but still technical runtime mapping rather than simple genre vocabulary.
classification: technical_shop_mapping
source_state: legacy_frozen_non_empty
cleanup_action: keep_as_technical_runtime_mapping
paths:
- shop_matching.custom_fields
- shop_matching.text.custom_field_join_separator
@@ -175,6 +213,9 @@ parameters:
- shop_matching.role_guard
runtime_resolved_connection:
description: Runtime environment values intentionally allowed by governance as resolved outside genre.yaml.
classification: runtime_resolved_connection
source_state: legacy_runtime_resolved_allowed
cleanup_action: keep_runtime_resolved_outside_genre_values
paths:
- commerce.store_api_base_url
- commerce.max_shop_results
@@ -187,6 +228,9 @@ parameters:
review_path_groups:
governance_guardrails:
description: Technical audit policy for core-pattern checks. Keep outside genre values but visible in the adaptation surface.
classification: governance_guardrail
source_state: legacy_frozen_non_empty
cleanup_action: keep_as_governance_policy
paths:
- governance.core_pattern_audit
configuration_values:

View File

@@ -0,0 +1,58 @@
# RetrieX Patch 59E - Genre Validation Warning Cleanup
## Purpose
Patch 59E removes validation false positives that appeared after the genre.yaml source-of-truth cleanup.
The affected warnings were caused by comparing legacy/raw YAML inventory values against effective runtime values that are now intentionally resolved through genre.yaml or the effective vocabulary facade.
## Changes
- `RetriexEffectiveConfigProvider::validateRetrieval()` now skips legacy inventory drift warnings for retrieval exact-selection keys when those keys are backed by `genre.configuration_values.retrieval_and_language.exact_selection`.
- `RetriexEffectiveConfigProvider::validateVocabulary()` now checks protected short-model tokens against the active vocabulary view, not only the raw legacy `vocabulary.yaml` add-list.
## Scope
This is a validation/audit cleanup only.
No changes were made to:
- retrieval ranking
- vector/keyword retrieval
- prompt building
- shop query generation
- intent detection
- search repair
- response generation
- genre.yaml values
## Why this is safe
The exact-selection warning was a false positive: the active retriever config reads the exact-selection lists from `genre.yaml`, while `retrieval.inventory` still represents the legacy/raw parameter snapshot.
The protected-short-model warning was also a false positive: `vocabulary.views.retrieval.important_short_model_tokens.add` is intentionally empty after the genre migration, while the active `DomainVocabularyConfig` view resolves the required tokens from `genre.yaml`.
## Expected result
After this patch, the following previously reported warnings should disappear:
- `retrieval.inventory.exact_selection_* differs from active retriever config`
- `vocabulary.views.retrieval.important_short_model_tokens should contain protected token ...`
## Required checks
Run:
```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
```
Expected:
- config validation OK without the p59D false-positive warnings
- regression baseline OK
- source audit OK
- pattern audit OK

View File

@@ -0,0 +1,78 @@
# RetrieX Patch 59F - Genre Review Group Metadata
## Purpose
Patch 59F continues the p59 cleanup after the p59A-p59E genre migration work.
It does not remove remaining legacy/runtime paths yet. Instead, it makes every
remaining `genre.yaml` review group machine-readable so the next cleanup patches
can decide per category whether a path should be rewired, kept as technical
configuration, kept as runtime-resolved configuration, or kept as governance.
## Changes
- Adds machine-readable metadata to every `genre.adaptation_surface.*.review_path_groups.*` group:
- `classification`
- `source_state`
- `cleanup_action`
- Extends `validateGenre()` so declared review groups must now include this metadata.
- Keeps all existing `paths` entries unchanged.
- Keeps all governance hashes unchanged.
## Review group classifications
Current classifications:
- `legacy_compatibility_view`
- `legacy_runtime_helper`
- `technical_regex_template`
- `legacy_signal_fallback`
- `legacy_context_fallback`
- `technical_cleanup_profile`
- `technical_shop_mapping`
- `runtime_resolved_connection`
- `governance_guardrail`
Current source states:
- `legacy_frozen_non_empty`
- `legacy_runtime_resolved_allowed`
## Runtime impact
No runtime behavior change is intended.
This patch does not change:
- retrieval ranking
- prompt building
- shop query logic
- search repair logic
- intent routing
- scoring
- genre values
- governance hash values
## Local checks
Run in a dependency-complete project checkout:
```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
```
In the ZIP-only local workspace, `vendor/` was missing, so Symfony console checks
could not be executed here. Local structural checks were run instead:
- PHP lint for `src/Config/RetriexEffectiveConfigProvider.php`
- YAML parse for `config/retriex/genre.yaml`
- Review group metadata completeness simulation
## Next step
A later p59G can start removing or rewiring one classification group at a time.
Good candidates are the low-risk legacy compatibility/signal fallback groups,
while technical regex templates, shop mapping, runtime connection values and
governance guardrails should remain separate until dedicated cleanup patches.

View File

@@ -264,6 +264,13 @@ document.addEventListener('DOMContentLoaded', () => {
const msg = document.createElement('div');
msg.className = 'message ' + role;
if (role === "user") {
const svg = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chat-right-fill" viewBox="0 0 16 16">\n' +
' <path d="M14 0a2 2 0 0 1 2 2v12.793a.5.5 0 0 1-.854.353l-2.853-2.853a1 1 0 0 0-.707-.293H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2z"/>\n' +
'</svg>';
html = svg + ' ' + html;
}
const bubble = document.createElement('div');
bubble.className = 'bubble ' + extra;
bubble.innerHTML = html;

View File

@@ -75,6 +75,9 @@ input, textarea, select {
align-items: center;
gap: 0.75rem;
margin-bottom: 1rem;
border-bottom: 1px solid #324154;
padding-bottom: 1rem;
border-radius: 6px;
}
.header .spacer {
@@ -86,10 +89,9 @@ input, textarea, select {
overflow-y: auto;
padding-right: 1rem;
padding-bottom: 1rem;
/* background: #121a25;
border: 1px solid var(--border);*/
border-radius: 6px 6px 0 0;
/*box-shadow: 0px 0px 20px #ffffff26;*/
scrollbar-width: thin;
scrollbar-color: #324054 transparent;
}
.message {
@@ -495,6 +497,7 @@ span.think {
font-size: 0.84rem;
border-radius: 6px;
background-color: transparent !important;
border-top: 1px solid #324154;
}
.retriex-option-toggle {

View File

@@ -35,7 +35,7 @@
<div id="ai-cloud" class="ai-cloud d-none"></div>
<div id="chat" class="chat"></div>
<div id="retriex-chat-options" class="retriex-chat-options bg-dark p-2" aria-label="Chat-Anzeigeoptionen">
<div id="retriex-chat-options" class="retriex-chat-options p-2" aria-label="Chat-Anzeigeoptionen">
<label class="retriex-option-toggle" for="toggle-retriex-cards">
<input id="toggle-retriex-cards" type="checkbox">
<span>Statusinfo anzeigen</span>

View File

@@ -1149,6 +1149,21 @@ final readonly class RetriexEffectiveConfigProvider
$flattened = [];
$this->flattenGenreParameterPaths($flattened);
$allowedReviewClassifications = [
'legacy_compatibility_view',
'legacy_runtime_helper',
'technical_regex_template',
'legacy_signal_fallback',
'legacy_context_fallback',
'technical_cleanup_profile',
'technical_shop_mapping',
'runtime_resolved_connection',
'governance_guardrail',
];
$allowedReviewSourceStates = [
'legacy_frozen_non_empty',
'legacy_runtime_resolved_allowed',
];
foreach ($effectiveConfig as $root => $value) {
if ($root === 'genre') {
continue;
@@ -1257,6 +1272,25 @@ final readonly class RetriexEffectiveConfigProvider
continue;
}
$classification = $reviewDefinition['classification'] ?? null;
if (!is_string($classification) || trim($classification) === '') {
$errors[] = sprintf('genre.adaptation_surface.%s.review_path_groups.%s.classification must be a non-empty string.', $group, $reviewGroup);
} elseif (!in_array(trim($classification), $allowedReviewClassifications, true)) {
$errors[] = sprintf('genre.adaptation_surface.%s.review_path_groups.%s.classification has unsupported value: %s.', $group, $reviewGroup, trim($classification));
}
$sourceState = $reviewDefinition['source_state'] ?? null;
if (!is_string($sourceState) || trim($sourceState) === '') {
$errors[] = sprintf('genre.adaptation_surface.%s.review_path_groups.%s.source_state must be a non-empty string.', $group, $reviewGroup);
} elseif (!in_array(trim($sourceState), $allowedReviewSourceStates, true)) {
$errors[] = sprintf('genre.adaptation_surface.%s.review_path_groups.%s.source_state has unsupported value: %s.', $group, $reviewGroup, trim($sourceState));
}
$cleanupAction = $reviewDefinition['cleanup_action'] ?? null;
if (!is_string($cleanupAction) || trim($cleanupAction) === '') {
$errors[] = sprintf('genre.adaptation_surface.%s.review_path_groups.%s.cleanup_action must be a non-empty string.', $group, $reviewGroup);
}
$paths = $reviewDefinition['paths'] ?? null;
if (!is_array($paths) || $paths === []) {
$errors[] = sprintf('genre.adaptation_surface.%s.review_path_groups.%s.paths must be a non-empty list.', $group, $reviewGroup);
@@ -1599,11 +1633,37 @@ final readonly class RetriexEffectiveConfigProvider
return false;
}
if (in_array($key, $this->retrievalGenreBackedInventoryKeys(), true)) {
return false;
}
$vocabulary = $retrieval['vocabulary'] ?? [];
return !is_array($vocabulary) || !array_key_exists($key, $vocabulary);
}
/** @return string[] */
private function retrievalGenreBackedInventoryKeys(): array
{
$exactSelection = $this->genreConfig->getValueArray('retrieval_and_language.exact_selection');
if ($exactSelection === []) {
return [];
}
$out = [];
foreach ($exactSelection as $key => $value) {
if (!is_string($key) || in_array($key, ['origin', 'description', 'source_paths'], true)) {
continue;
}
if (is_array($value) && $value !== []) {
$out[] = 'exact_selection_' . $key;
}
}
return $out;
}
/** @return string[] */
private function retrievalVocabularyBackedInventoryKeys(): array
{
@@ -1922,8 +1982,9 @@ final readonly class RetriexEffectiveConfigProvider
if (is_array($retrievalViews)) {
$shortModel = $retrievalViews['important_short_model_tokens']['add'] ?? [];
if (is_array($shortModel)) {
$activeShortModel = $this->domainVocabularyConfig->view('retrieval.important_short_model_tokens', []);
foreach ($this->governanceConfig->getVocabularyProtectedShortModelTokens() as $token) {
if (!in_array($token, $shortModel, true)) {
if (!in_array($token, $shortModel, true) && !in_array($token, $activeShortModel, true)) {
$warnings[] = 'vocabulary.views.retrieval.important_short_model_tokens should contain protected token ' . $token . '.';
}
}