This commit is contained in:
team 1
2026-05-07 14:42:12 +02:00
parent 5237bb0c63
commit f136bec0d7
4 changed files with 193 additions and 129 deletions

View File

@@ -187,8 +187,7 @@ parameters:
product_roles: product_roles:
description: Current water-analysis product role vocabulary. For another genre, replace these terms with that genre's main-product, accessory and consumable roles. description: Current water-analysis product role vocabulary. For another genre, replace these terms with that genre's main-product, accessory and consumable roles.
primary_product_terms: primary_product_terms:
source_paths: origin: genre_native
- vocabulary.classes.device
terms: terms:
- analysegerät - analysegerät
- analysegeraet - analysegeraet
@@ -214,8 +213,7 @@ parameters:
- anlage - anlage
- anlagen - anlagen
accessory_product_terms: accessory_product_terms:
source_paths: origin: genre_native
- vocabulary.classes.accessory
terms: terms:
- zubehör - zubehör
- zubehor - zubehor
@@ -239,8 +237,7 @@ parameters:
- serviceset - serviceset
- service-set - service-set
requested_accessory_code_terms: requested_accessory_code_terms:
source_paths: origin: genre_native
- vocabulary.classes.requested_accessory_code_terms
terms: terms:
- indikatortyp - indikatortyp
- indikator - indikator
@@ -248,13 +245,7 @@ parameters:
- reagenz - reagenz
- reagent - reagent
shop_views: shop_views:
source_paths: origin: genre_native
- vocabulary.views.shop.device_query.add
- vocabulary.views.shop.accessory_query.add
- vocabulary.views.shop.device_product.add
- vocabulary.views.shop.accessory_product.add
- vocabulary.views.shop.device_focus.add
- vocabulary.views.shop.accessory_focus.add
device_query_terms: device_query_terms:
- analysegerät - analysegerät
- analysegeraet - analysegeraet
@@ -420,11 +411,7 @@ parameters:
- kalibrierlösung - kalibrierlösung
- kalibrierloesung - kalibrierloesung
prompt_views: prompt_views:
source_paths: origin: genre_native
- vocabulary.views.prompt.main_device_request_keywords.add
- vocabulary.views.prompt.accessory_request_keywords.add
- vocabulary.views.prompt.main_device_product_keywords.add
- vocabulary.views.prompt.accessory_product_keywords.add
main_device_request_keywords: main_device_request_keywords:
- messanlage - messanlage
- messanlagen - messanlagen
@@ -531,8 +518,6 @@ parameters:
- ph indikatoren - ph indikatoren
no_llm_fallback_terms: no_llm_fallback_terms:
source_paths: source_paths:
- vocabulary.classes.agent_no_llm_main_device_request_keywords
- vocabulary.classes.agent_no_llm_accessory_product_keywords
- agent.no_llm_fallback.product_roles.vocabulary_views.main_device_request_keywords - agent.no_llm_fallback.product_roles.vocabulary_views.main_device_request_keywords
- agent.no_llm_fallback.product_roles.vocabulary_views.accessory_product_keywords - agent.no_llm_fallback.product_roles.vocabulary_views.accessory_product_keywords
main_device_request_keywords: main_device_request_keywords:
@@ -585,12 +570,8 @@ parameters:
description: Current genre attributes and constraint terms. Fashion would typically replace these with size, color, material, fit and variant constraints. description: Current genre attributes and constraint terms. Fashion would typically replace these with size, color, material, fit and variant constraints.
direct_attribute_cleanup: direct_attribute_cleanup:
source_paths: source_paths:
- vocabulary.classes.direct_product_attribute_stop_terms
- vocabulary.views.search_repair.direct_product_type_terms.add
- vocabulary.views.search_repair.direct_product_attribute_stop_terms.include
- agent.shop_runtime.attribute_cleanup.vocabulary_views.product_type_terms - agent.shop_runtime.attribute_cleanup.vocabulary_views.product_type_terms
- agent.shop_runtime.attribute_cleanup.vocabulary_views.stop_terms - agent.shop_runtime.attribute_cleanup.vocabulary_views.stop_terms
- agent.shop_runtime.attribute_cleanup.comparative_constraint_patterns
product_type_terms: product_type_terms:
- anschlusskabel - anschlusskabel
- kabel - kabel
@@ -653,9 +634,6 @@ parameters:
- /\b(?:länger|laenger|kürzer|kuerzer|größer|groesser|kleiner|über|ueber|unter|mindestens|maximal|maximum|minimum|ab|bis|mehr\s+als|weniger\s+als)\s+(?P<value>\d+(?:[,.]\d+)?\s*[\p{L}µ°%]*)\b/iu - /\b(?:länger|laenger|kürzer|kuerzer|größer|groesser|kleiner|über|ueber|unter|mindestens|maximal|maximum|minimum|ab|bis|mehr\s+als|weniger\s+als)\s+(?P<value>\d+(?:[,.]\d+)?\s*[\p{L}µ°%]*)\b/iu
size_and_color_terms: size_and_color_terms:
source_paths: source_paths:
- intent.commerce.size_token_terms
- intent.commerce.size_terms
- intent.commerce.color_terms
- intent.commerce.patterns.size_extraction_template - intent.commerce.patterns.size_extraction_template
- intent.commerce.patterns.size_value_template - intent.commerce.patterns.size_value_template
- intent.commerce.patterns.size_token_value_template - intent.commerce.patterns.size_token_value_template
@@ -716,15 +694,13 @@ parameters:
brands_and_canonical_terms: brands_and_canonical_terms:
description: Genre-specific brands, canonical tokens and query enrichment rules. description: Genre-specific brands, canonical tokens and query enrichment rules.
known_brands: known_brands:
source_paths: origin: genre_native
- commerce_query.known_brands
terms: terms:
- heyl - heyl
- horiba - horiba
- neomeris - neomeris
canonical_terms: canonical_terms:
source_paths: origin: genre_native
- commerce_query.search_token_canonical_map
map: map:
indikatoren: indikator indikatoren: indikator
indicators: indikator indicators: indikator
@@ -734,8 +710,7 @@ parameters:
reagent: reagenz reagent: reagenz
produkte: produkt produkte: produkt
query_enrichment_rules: query_enrichment_rules:
source_paths: origin: genre_native
- query_enrichment.rules
rules: rules:
Wasserhärte: Resthärte Wasserhärte: Resthärte
Gerät: Modell Gerät: Modell
@@ -749,8 +724,7 @@ parameters:
store: shop store: shop
Indikatortyp: Indikator Indikatortyp: Indikator
accessory_focus_variants: accessory_focus_variants:
source_paths: origin: genre_native
- vocabulary.maps.shop.accessory_focus_variants
map: map:
values: values:
indicator_terms: indicator_terms:
@@ -777,8 +751,7 @@ parameters:
serviceset: service_set_terms serviceset: service_set_terms
service-set: service_set_terms service-set: service_set_terms
rag_evidence_synonyms: rag_evidence_synonyms:
source_paths: origin: genre_native
- vocabulary.maps.agent.rag_evidence_guard.synonyms
map: map:
values: values:
salinity_terms: salinity_terms:
@@ -815,7 +788,6 @@ parameters:
description: Genre-specific words and patterns that steer commerce/advisory routing. description: Genre-specific words and patterns that steer commerce/advisory routing.
fuzzy_routing_terms: fuzzy_routing_terms:
source_paths: source_paths:
- vocabulary.classes.input_normalization_fuzzy_routing_terms
- agent.input_normalization.fuzzy_routing.vocabulary_views.terms - agent.input_normalization.fuzzy_routing.vocabulary_views.terms
terms: terms:
- shop - shop
@@ -886,10 +858,6 @@ parameters:
- empfiehl - empfiehl
commerce_intent: commerce_intent:
source_paths: source_paths:
- intent.commerce.strong_signals
- intent.commerce.advisory_signals
- intent.commerce.advisory_product_selection_patterns
- intent.commerce.explicit_commerce_intent_patterns
- intent.commerce.patterns.model_like_product - intent.commerce.patterns.model_like_product
strong_signals: strong_signals:
- shop - shop
@@ -1057,8 +1025,7 @@ parameters:
query_template_with_model: '{model} indikator' query_template_with_model: '{model} indikator'
query_template_without_model: indikator query_template_without_model: indikator
referential_terms: referential_terms:
source_paths: origin: genre_native
- agent.shop_runtime.context_resolution.context_usage.referential_terms
terms: terms:
- der - der
- die - die
@@ -1083,10 +1050,7 @@ parameters:
- selben - selben
history_anchor_enrichment: history_anchor_enrichment:
source_paths: source_paths:
- vocabulary.classes.agent_shop_context_anchor_trigger_terms
- agent.shop_runtime.context_resolution.history_anchor_enrichment.vocabulary_views.trigger_terms - agent.shop_runtime.context_resolution.history_anchor_enrichment.vocabulary_views.trigger_terms
- agent.shop_runtime.context_resolution.history_anchor_enrichment.anchor_patterns
- agent.shop_runtime.context_resolution.history_anchor_enrichment.template
trigger_terms: trigger_terms:
- indikator - indikator
- indikatortyp - indikatortyp
@@ -1102,9 +1066,7 @@ parameters:
template: '{anchor} {query}' template: '{anchor} {query}'
max_query_terms: 2 max_query_terms: 2
meta_query_guard: meta_query_guard:
source_paths: origin: genre_native
- agent.shop_runtime.context_resolution.meta_query_guard.meta_only_terms
- agent.shop_runtime.context_resolution.meta_query_guard.context_fallback_filter_terms
meta_only_terms: meta_only_terms:
- shop - shop
- preis - preis
@@ -1129,11 +1091,7 @@ parameters:
- messen - messen
- gemessen - gemessen
rag_anchor_enrichment: rag_anchor_enrichment:
source_paths: origin: genre_native
- agent.shop_runtime.context_resolution.rag_anchor_enrichment.numeric_focus_patterns
- agent.shop_runtime.context_resolution.rag_anchor_enrichment.product_title_patterns
- agent.shop_runtime.context_resolution.rag_anchor_enrichment.anchor_bonus_patterns
- agent.shop_runtime.context_resolution.rag_anchor_enrichment.subject_terms
numeric_focus_patterns: numeric_focus_patterns:
- /(?P<value>\d+(?:[,.]\d+)?)\s*(?P<unit>°?\s*d\s*h|dh|dH)/iu - /(?P<value>\d+(?:[,.]\d+)?)\s*(?P<unit>°?\s*d\s*h|dh|dH)/iu
product_title_patterns: product_title_patterns:
@@ -1156,7 +1114,6 @@ parameters:
description: Current direct Shopware query cleanup and deterministic answer wording for this genre. description: Current direct Shopware query cleanup and deterministic answer wording for this genre.
current_input_preservation_terms: current_input_preservation_terms:
source_paths: source_paths:
- vocabulary.classes.agent_shop_current_input_preservation_terms
- agent.shop_runtime.query_cleanup.current_input_preservation.vocabulary_views.terms - agent.shop_runtime.query_cleanup.current_input_preservation.vocabulary_views.terms
terms: terms:
- ph - ph
@@ -1167,8 +1124,7 @@ parameters:
- orp - orp
- 0,02 - 0,02
stopword_cleanup: stopword_cleanup:
source_paths: origin: genre_native
- agent.shop_runtime.query_cleanup.stopword_cleanup.terms
terms: terms:
- zeige - zeige
- zeig - zeig
@@ -1212,14 +1168,12 @@ parameters:
- meter - meter
- metern - metern
compound_prefix_match: compound_prefix_match:
source_paths: origin: genre_native
- agent.shop_runtime.result_identity.compound_prefix_match.terms
terms: terms:
- puffer - puffer
- kalibrierpuffer - kalibrierpuffer
primary_identity_repair: primary_identity_repair:
source_paths: origin: genre_native
- agent.shop_runtime.result_identity.primary_identity_repair.stop_terms
stop_terms: stop_terms:
- messgerät - messgerät
- messgeraet - messgeraet
@@ -1240,8 +1194,7 @@ parameters:
- messkoffer - messkoffer
- koffer - koffer
semantic_shop_search_tokens: semantic_shop_search_tokens:
source_paths: origin: genre_native
- vocabulary.views.shop.semantic_search_tokens.add
terms: terms:
- indikator - indikator
- indicator - indicator
@@ -1285,12 +1238,7 @@ parameters:
- controller - controller
- system - system
direct_answer: direct_answer:
source_paths: origin: genre_native
- agent.shop_runtime.direct_answer.intro
- agent.shop_runtime.direct_answer.no_results
- agent.shop_runtime.direct_answer.sorted_by_length_note
- agent.shop_runtime.direct_answer.min_length_filter_note
- agent.shop_runtime.direct_answer.max_length_filter_note
enabled: true enabled: true
max_results: 10 max_results: 10
intro: 'Aus den Shopdaten ergeben sich folgende passende Treffer:' intro: 'Aus den Shopdaten ergeben sich folgende passende Treffer:'
@@ -1301,12 +1249,7 @@ parameters:
result_identity_and_answer_policy: result_identity_and_answer_policy:
description: Current role separation, fact-grounding and response-format rules that are genre-sensitive. description: Current role separation, fact-grounding and response-format rules that are genre-sensitive.
prompt_rules: prompt_rules:
source_paths: origin: genre_native
- prompt.output_priority.technical_rules
- prompt.response_format.technical_rules
- prompt.response_format.accessory_rules
- prompt.fact_grounding.technical_rules
- prompt.fact_grounding.with_shop_rules
output_priority_technical: output_priority_technical:
- '- For technical questions, answer the exact requested fact first and keep it as the main answer.' - '- For technical questions, answer the exact requested fact first and keep it as the main answer.'
- '- If one source chunk contains both the best matching value and nearby comparison values, use the nearby values only as context and do not include them unless the user asks for comparison or alternatives.' - '- If one source chunk contains both the best matching value and nearby comparison values, use the nearby values only as context and do not include them unless the user asks for comparison or alternatives.'
@@ -1394,8 +1337,7 @@ parameters:
- '- If the user asks for the price or availability of a referenced accessory, indicator, reagent, kit, set, or consumable, use commercial fields only from a shop result that clearly matches that accessory identity and code.' - '- If the user asks for the price or availability of a referenced accessory, indicator, reagent, kit, set, or consumable, use commercial fields only from a shop result that clearly matches that accessory identity and code.'
- '- For such accessory price follow-ups, do not answer with the price, URL, product number, or availability of the main device or of unrelated reagents; if no matching accessory shop item is present, say that the price is not available in the provided shop data.' - '- For such accessory price follow-ups, do not answer with the price, URL, product number, or availability of the main device or of unrelated reagents; if no matching accessory shop item is present, say that the price is not available in the provided shop data.'
prompt_keyword_views: prompt_keyword_views:
source_paths: origin: genre_native
- vocabulary.views.prompt.technical_product_keywords.add
technical_product_keywords: technical_product_keywords:
- technisch - technisch
- technical - technical
@@ -1443,11 +1385,7 @@ parameters:
- chlor - chlor
- chlormessung - chlormessung
measurement_evidence_guard_terms: measurement_evidence_guard_terms:
source_paths: origin: genre_native
- vocabulary.views.prompt.measurement_evidence_guard.accessory_lookup_guard_terms.add
- vocabulary.views.prompt.measurement_evidence_guard.accessory_lookup_passthrough_terms.add
- vocabulary.views.prompt.measurement_evidence_guard.generic_positive_context_terms.add
- vocabulary.views.prompt.measurement_evidence_guard.generic_negative_context_terms.add
accessory_lookup_guard_terms: accessory_lookup_guard_terms:
- indikator - indikator
- indikatoren - indikatoren
@@ -1493,10 +1431,7 @@ parameters:
- störungsfrei - störungsfrei
- stoerungsfrei - stoerungsfrei
measurement_evidence_maps: measurement_evidence_maps:
source_paths: origin: genre_native
- vocabulary.maps.prompt.measurement_evidence_guard.request_terms
- vocabulary.maps.prompt.measurement_evidence_guard.positive_terms
- vocabulary.maps.prompt.measurement_evidence_guard.non_equivalent_terms
request_terms: request_terms:
ph: ph:
- ph - ph
@@ -1543,20 +1478,17 @@ parameters:
search_repair: search_repair:
description: Current search repair tokens, candidate patterns and exact identifier helpers. description: Current search repair tokens, candidate patterns and exact identifier helpers.
direct_product_attribute_lookup: direct_product_attribute_lookup:
source_paths: origin: genre_native
- search_repair.direct_product_attribute_lookup
enabled: true enabled: true
min_query_tokens_after_cleanup: 2 min_query_tokens_after_cleanup: 2
comparative_constraint_patterns: comparative_constraint_patterns:
- /\b(?:länger|laenger|kürzer|kuerzer|größer|groesser|kleiner|über|ueber|unter|mindestens|maximal|maximum|minimum|ab|bis|mehr\s+als|weniger\s+als)\s+(?P<value>\d+(?:[,.]\d+)?\s*[\p{L}µ°%]*)\b/iu - /\b(?:länger|laenger|kürzer|kuerzer|größer|groesser|kleiner|über|ueber|unter|mindestens|maximal|maximum|minimum|ab|bis|mehr\s+als|weniger\s+als)\s+(?P<value>\d+(?:[,.]\d+)?\s*[\p{L}µ°%]*)\b/iu
requested_accessory_code_terms: requested_accessory_code_terms:
source_paths: origin: genre_native
- vocabulary.views.search_repair.requested_accessory_code_terms.include
terms: terms:
- requested_accessory_code_terms - requested_accessory_code_terms
candidate_patterns: candidate_patterns:
source_paths: source_paths:
- search_repair.specific_model_candidate_patterns
- search_repair.patterns.model_candidate - search_repair.patterns.model_candidate
- search_repair.patterns.accessory_candidate_template - search_repair.patterns.accessory_candidate_template
- search_repair.patterns.requested_accessory_code - search_repair.patterns.requested_accessory_code
@@ -1576,12 +1508,7 @@ parameters:
whitespace_collapse: /\s+/u whitespace_collapse: /\s+/u
tokenize_cleanup: /[^\p{L}\p{N}\s\-]+/u tokenize_cleanup: /[^\p{L}\p{N}\s\-]+/u
candidate_terms: candidate_terms:
source_paths: origin: genre_native
- vocabulary.views.search_repair.model_candidate_exclude_terms.include
- vocabulary.views.search_repair.generic_candidate_tokens.add
- vocabulary.views.search_repair.accessory_candidate_terms.add
- vocabulary.views.search_repair.accessory_or_bundle_terms.add
- vocabulary.views.search_repair.specificity_boost_terms.add
model_candidate_exclude_terms: model_candidate_exclude_terms:
- requested_accessory_code_terms - requested_accessory_code_terms
- shop_meta_terms - shop_meta_terms
@@ -1632,8 +1559,7 @@ parameters:
retrieval_and_language: retrieval_and_language:
description: Current protected terms, cleanup profiles and exact-selection helpers that are genre-sensitive. Retrieval engine parameters remain outside this area. description: Current protected terms, cleanup profiles and exact-selection helpers that are genre-sensitive. Retrieval engine parameters remain outside this area.
protected_terms: protected_terms:
source_paths: origin: genre_native
- language.protected_terms
terms: terms:
- nicht - nicht
- kein - kein
@@ -1683,15 +1609,7 @@ parameters:
meta_term_groups: meta_term_groups:
- presentation - presentation
retrieval_vocabulary_views: retrieval_vocabulary_views:
source_paths: origin: genre_native
- vocabulary.views.retrieval.generic_product_tokens.add
- vocabulary.views.retrieval.important_short_model_tokens.add
- vocabulary.views.retrieval.family_descriptor_tokens.add
- vocabulary.views.retrieval.looks_like_reagent_tokens.add
- vocabulary.views.retrieval.looks_like_safety_docs.add
- vocabulary.views.retrieval.looks_like_device_words.add
- vocabulary.views.retrieval.looks_like_document_words.add
- vocabulary.views.retrieval.looks_like_safety_words.add
generic_product_tokens: generic_product_tokens:
- produkt - produkt
- produkte - produkte
@@ -1818,15 +1736,7 @@ parameters:
- lagerung - lagerung
- piktogramm - piktogramm
exact_selection: exact_selection:
source_paths: origin: genre_native
- retrieval.exact_selection_token_variant_prefixes
- retrieval.exact_selection_indicator_question_tokens
- retrieval.exact_selection_indicator_question_phrases
- retrieval.exact_selection_indicator_table_heading_patterns
- retrieval.exact_selection_indicator_table_header_patterns
- retrieval.exact_selection_indicator_table_row_patterns
- retrieval.exact_selection_indicator_table_required_primary_terms
- retrieval.exact_selection_indicator_table_required_context_terms
token_variant_prefixes: token_variant_prefixes:
indikator: indikator:
- indikator - indikator
@@ -1889,8 +1799,7 @@ parameters:
governance_and_regression: governance_and_regression:
description: Current guardrail terms that intentionally protect this genre during audits and regression checks. description: Current guardrail terms that intentionally protect this genre during audits and regression checks.
regression_baseline: regression_baseline:
source_paths: origin: genre_native
- governance.regression_baseline
protected_short_model_tokens: protected_short_model_tokens:
- th - th
- tc - tc
@@ -1947,8 +1856,7 @@ parameters:
- ph - ph
- redox - redox
vocabulary_guardrails: vocabulary_guardrails:
source_paths: origin: genre_native
- governance.vocabulary
core_pattern_audit: core_pattern_audit:
source_paths: source_paths:
- governance.core_pattern_audit - governance.core_pattern_audit

View File

@@ -0,0 +1,109 @@
# RetrieX Patch 59A - Genre Native Source Path Cleanup
## Ziel
Dieser Patch startet die kontrollierte Aufraeumphase nach der Genre-Zentralisierung.
Er entfernt leere Legacy-`source_paths` aus `config/retriex/genre.yaml`, ohne eingefrorene
nicht-leere Fallbacks, Runtime-Resolved-Pfade oder fachliche Runtime-Logik zu veraendern.
## Hintergrund
Nach p58 ist `genre.yaml` fuer viele fachliche Werte bereits die zentrale Pflegeflaeche.
Die alten YAML-Pfade wurden aber noch als leere Legacy-Fallbacks in
`genre.configuration_values.*.source_paths` mitgefuehrt. Diese Referenzen sind fuer die
fachliche Pflege nicht mehr notwendig und erzeugen unnoetige Audit-/Migrationslast.
## Aenderungen
### `config/retriex/genre.yaml`
- 92 leere Legacy-`source_paths` wurden entfernt.
- 30 Value-Nodes, die dadurch keine Legacy-Quelle mehr brauchen, wurden mit
`origin: genre_native` markiert.
- Gemischte Nodes behalten weiterhin ihre nicht-leeren/frozen Source-Pfade.
- Nicht-leere frozen Fallbacks bleiben unveraendert.
- Runtime-Resolved-Pfade bleiben unveraendert:
- `commerce.max_shop_results`
- `commerce.store_api_base_url`
### `src/Config/GenreSourceOfTruthGuard.php`
- Der Guard erlaubt nun `origin: genre_native` als explizite native Herkunft fuer
`genre.configuration_values`-Nodes.
- `origin` wird als Metadatenfeld behandelt, analog zu `source_paths` und `description`.
- Native Nodes zaehlen als abgedeckt und muessen keine Legacy-`source_paths` mehr deklarieren.
- Die Guard-Summary enthaelt zusaetzlich `genre_native_value_nodes`.
## Bewusst nicht geaendert
- Keine Aenderung an Retrieval-, Prompt-, Scoring-, Commerce- oder Shopware-Runtime-Logik.
- Keine neuen fachlichen Token-/Stringlisten im PHP-Core.
- Keine Entfernung der eingefrorenen nicht-leeren Fallbacks.
- Keine Entfernung technischer Runtime-Pfade.
- Keine Bereinigung der `adaptation_surface`-Inventarlisten; diese sollten separat klassifiziert werden.
## Ergebnis der lokalen Strukturpruefung
Vor Patch:
- 131 deklarierte `source_paths` in `genre.configuration_values`
- 92 davon zeigten auf leere Legacy-Fallbacks
- 39 zeigten auf nicht-leere/frozen bzw. Runtime-resolved Werte
Nach Patch:
- 39 deklarierte `source_paths`
- 0 leere Legacy-`source_paths`
- 30 `genre_native` Value-Nodes
- 0 Coverage-Fehler in der lokalen Guard-Simulation
- 0 fehlende frozen Source-Pfade
- 0 frozen Hash-Mismatches in der lokalen Guard-Simulation
## Lokale Checks
Ausgefuehrt im entpackten Patch-Arbeitsstand:
```bash
php -l src/Config/GenreSourceOfTruthGuard.php
php -l src/Config/GenreConfig.php
php -l src/Config/RetriexEffectiveConfigProvider.php
```
Alle PHP-Lints waren erfolgreich.
Zusaetzlich wurde `config/retriex/genre.yaml` mit PyYAML geparst und eine lokale
Guard-Simulation fuer Source-Path-Abdeckung, leere Legacy-Pfade und frozen Hashes ausgefuehrt.
## Nicht lokal ausfuehrbar
Die Symfony-Console-Checks konnten in der bereitgestellten ZIP nicht ausgefuehrt werden,
da `vendor/` fehlt:
```text
Dependencies are missing. Try running "composer install".
```
Bitte im vollstaendigen Projekt mit Dependencies ausfuehren:
```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
```
## Erwartete Audit-Auswirkung
`genre_value_paths_with_source_paths` und `genre_declared_source_paths` sollten sinken,
weil leere Legacy-Referenzen entfernt wurden. Das ist beabsichtigt.
`legacy_fallback_empty` sollte im Genre-Source-of-Truth-Guard auf 0 fallen.
`genre_native_value_nodes` sollte die nativ markierten Value-Nodes ausweisen.
## Naechster moeglicher Patch
p59B sollte die `adaptation_surface`-Inventarlisten separat klassifizieren:
- Welche Pfade sind weiterhin technische Review-/Audit-Inventare?
- Welche leeren Legacy-Pfade koennen auch aus der Surface-Liste entfernt werden?
- Welche nicht-leeren frozen Pfade bleiben bewusst technische Fallbacks?

View File

@@ -58,7 +58,7 @@ input, textarea, select {
} }
.container { .container {
max-width: 900px; max-width: 1024px;
margin: 0 auto; margin: 0 auto;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -85,8 +85,8 @@ input, textarea, select {
flex: 1; flex: 1;
overflow-y: auto; overflow-y: auto;
padding: 1rem; padding: 1rem;
background: #121a25; /* background: #121a25;
/*border: 1px solid var(--border);*/ border: 1px solid var(--border);*/
border-radius: 6px 6px 0 0; border-radius: 6px 6px 0 0;
/*box-shadow: 0px 0px 20px #ffffff26;*/ /*box-shadow: 0px 0px 20px #ffffff26;*/
} }

View File

@@ -96,6 +96,7 @@ final readonly class GenreSourceOfTruthGuard
$coverageErrors = $this->validateConfigurationValueCoverage($configurationValues); $coverageErrors = $this->validateConfigurationValueCoverage($configurationValues);
array_push($errors, ...$coverageErrors); array_push($errors, ...$coverageErrors);
$nativeValueNodes = $this->countGenreNativeValueNodes($configurationValues);
$declaredSourcePaths = $this->collectSourcePaths($configurationValues); $declaredSourcePaths = $this->collectSourcePaths($configurationValues);
$uniqueSourcePaths = []; $uniqueSourcePaths = [];
foreach ($declaredSourcePaths as $valuePath => $sourcePaths) { foreach ($declaredSourcePaths as $valuePath => $sourcePaths) {
@@ -157,6 +158,7 @@ final readonly class GenreSourceOfTruthGuard
$summary = $this->summarizeRows($rows); $summary = $this->summarizeRows($rows);
$summary['configuration_value_groups'] = count($configurationValues); $summary['configuration_value_groups'] = count($configurationValues);
$summary['genre_native_value_nodes'] = $nativeValueNodes;
$summary['source_path_value_nodes'] = count($declaredSourcePaths); $summary['source_path_value_nodes'] = count($declaredSourcePaths);
$summary['declared_source_paths'] = count($uniqueSourcePaths); $summary['declared_source_paths'] = count($uniqueSourcePaths);
$summary['violations'] = count($errors); $summary['violations'] = count($errors);
@@ -190,10 +192,15 @@ final readonly class GenreSourceOfTruthGuard
{ {
$sourcePaths = $value['source_paths'] ?? null; $sourcePaths = $value['source_paths'] ?? null;
$hasSourcePaths = is_array($sourcePaths) && $sourcePaths !== []; $hasSourcePaths = is_array($sourcePaths) && $sourcePaths !== [];
$hasGenreNativeOrigin = $this->hasGenreNativeOrigin($value);
if (array_key_exists('source_paths', $value) && !$hasSourcePaths && $path !== '') { if (array_key_exists('source_paths', $value) && !$hasSourcePaths && $path !== '') {
$errors[] = sprintf('genre.configuration_values.%s.source_paths must be a non-empty list when declared.', $path); $errors[] = sprintf('genre.configuration_values.%s.source_paths must be a non-empty list when declared.', $path);
} }
if (array_key_exists('origin', $value) && !$hasGenreNativeOrigin && $path !== '') {
$errors[] = sprintf('genre.configuration_values.%s.origin must be genre_native when declared.', $path);
}
if ($hasSourcePaths) { if ($hasSourcePaths) {
$seen = []; $seen = [];
foreach ($sourcePaths as $sourcePath) { foreach ($sourcePaths as $sourcePath) {
@@ -209,13 +216,13 @@ final readonly class GenreSourceOfTruthGuard
} }
} }
$covered = $coveredBySourcePath || $hasSourcePaths; $covered = $coveredBySourcePath || $hasSourcePaths || $hasGenreNativeOrigin;
if ($path !== '' && !$covered && $this->hasDirectPayload($value)) { if ($path !== '' && !$covered && $this->hasDirectPayload($value)) {
$errors[] = sprintf('genre.configuration_values.%s must declare source_paths or inherit them from a parent value node.', $path); $errors[] = sprintf('genre.configuration_values.%s must declare source_paths or inherit them from a parent value node.', $path);
} }
foreach ($value as $key => $child) { foreach ($value as $key => $child) {
if ($key === 'source_paths' || $key === 'description' || !is_string($key) || !is_array($child)) { if ($this->isMetadataKey($key) || !is_string($key) || !is_array($child)) {
continue; continue;
} }
@@ -230,7 +237,7 @@ final readonly class GenreSourceOfTruthGuard
private function hasDirectPayload(array $value): bool private function hasDirectPayload(array $value): bool
{ {
foreach ($value as $key => $child) { foreach ($value as $key => $child) {
if ($key === 'source_paths' || $key === 'description') { if ($this->isMetadataKey($key)) {
continue; continue;
} }
if (!is_array($child)) { if (!is_array($child)) {
@@ -241,6 +248,45 @@ final readonly class GenreSourceOfTruthGuard
return false; return false;
} }
/** @param array<int|string, mixed> $value */
private function hasGenreNativeOrigin(array $value): bool
{
$origin = $value['origin'] ?? null;
return is_string($origin) && trim($origin) === 'genre_native';
}
private function isMetadataKey(mixed $key): bool
{
return $key === 'source_paths' || $key === 'description' || $key === 'origin';
}
/**
* @param array<string, mixed> $configurationValues
*/
private function countGenreNativeValueNodes(array $configurationValues): int
{
return $this->countGenreNativeValueNodesRecursive($configurationValues, '');
}
/** @param array<int|string, mixed> $value */
private function countGenreNativeValueNodesRecursive(array $value, string $path): int
{
$count = $path !== '' && $this->hasGenreNativeOrigin($value) ? 1 : 0;
foreach ($value as $key => $child) {
if ($this->isMetadataKey($key) || !is_string($key) || !is_array($child)) {
continue;
}
$childPath = $path === '' ? $key : $path . '.' . $key;
$count += $this->countGenreNativeValueNodesRecursive($child, $childPath);
}
return $count;
}
/** /**
* @param array<string, mixed> $configurationValues * @param array<string, mixed> $configurationValues
* @return array<string, string[]> * @return array<string, string[]>
@@ -277,7 +323,7 @@ final readonly class GenreSourceOfTruthGuard
} }
foreach ($value as $key => $child) { foreach ($value as $key => $child) {
if ($key === 'source_paths' || $key === 'description' || !is_string($key) || !is_array($child)) { if ($this->isMetadataKey($key) || !is_string($key) || !is_array($child)) {
continue; continue;
} }
$childPath = $path === '' ? $key : $path . '.' . $key; $childPath = $path === '' ? $key : $path . '.' . $key;
@@ -485,6 +531,7 @@ final readonly class GenreSourceOfTruthGuard
'configuration_value_groups' => 0, 'configuration_value_groups' => 0,
'source_path_value_nodes' => 0, 'source_path_value_nodes' => 0,
'declared_source_paths' => 0, 'declared_source_paths' => 0,
'genre_native_value_nodes' => 0,
'legacy_fallback_empty' => 0, 'legacy_fallback_empty' => 0,
'legacy_frozen_non_empty' => 0, 'legacy_frozen_non_empty' => 0,
'legacy_non_empty_unregistered' => 0, 'legacy_non_empty_unregistered' => 0,