From d3ae51c551136026d048be4a0daf33c54e0768a1 Mon Sep 17 00:00:00 2001 From: team 1 Date: Thu, 7 May 2026 15:06:50 +0200 Subject: [PATCH] p59b --- config/retriex/genre.yaml | 187 +++++++----------- ...EX_PATCH_44_RUNTIME_ANSWER_GUARD_README.md | 0 ...X_PATCH_53_CONFIG_LAYOUT_CLEANUP_README.md | 0 ...H_54_SINGLE_GENRE_CONFIG_SURFACE_README.md | 0 ..._CONFIG_VALUES_VALIDATION_HOTFIX_README.md | 0 ...CH_55_SINGLE_GENRE_CONFIG_VALUES_README.md | 0 ...CH_56_SINGLE_GENRE_CONFIG_WIRING_README.md | 0 ...TCH_57_SINGLE_GENRE_SOURCE_AUDIT_README.md | 0 ...GLE_GENRE_LEGACY_VALUE_REDUCTION_README.md | 0 ...GENRE_ADAPTATION_SURFACE_CLEANUP_README.md | 75 +++++++ ...X_PATCH_59_COMPLETE_GENRE_WIRING_README.md | 0 ...ASUREMENT_VOCABULARY_VIEW_HOTFIX_README.md | 0 ..._60_LEGACY_VALUE_REDUCTION_FINAL_README.md | 0 ...H_61_GENRE_SOURCE_OF_TRUTH_GUARD_README.md | 0 public/assets/styles/base.css | 14 +- src/Config/RetriexEffectiveConfigProvider.php | 107 +++++++--- 16 files changed, 235 insertions(+), 148 deletions(-) rename RETRIEX_PATCH_44_RUNTIME_ANSWER_GUARD_README.md => patch_history/RETRIEX_PATCH_44_RUNTIME_ANSWER_GUARD_README.md (100%) rename RETRIEX_PATCH_53_CONFIG_LAYOUT_CLEANUP_README.md => patch_history/RETRIEX_PATCH_53_CONFIG_LAYOUT_CLEANUP_README.md (100%) rename RETRIEX_PATCH_54_SINGLE_GENRE_CONFIG_SURFACE_README.md => patch_history/RETRIEX_PATCH_54_SINGLE_GENRE_CONFIG_SURFACE_README.md (100%) rename RETRIEX_PATCH_55B_GENRE_CONFIG_VALUES_VALIDATION_HOTFIX_README.md => patch_history/RETRIEX_PATCH_55B_GENRE_CONFIG_VALUES_VALIDATION_HOTFIX_README.md (100%) rename RETRIEX_PATCH_55_SINGLE_GENRE_CONFIG_VALUES_README.md => patch_history/RETRIEX_PATCH_55_SINGLE_GENRE_CONFIG_VALUES_README.md (100%) rename RETRIEX_PATCH_56_SINGLE_GENRE_CONFIG_WIRING_README.md => patch_history/RETRIEX_PATCH_56_SINGLE_GENRE_CONFIG_WIRING_README.md (100%) rename RETRIEX_PATCH_57_SINGLE_GENRE_SOURCE_AUDIT_README.md => patch_history/RETRIEX_PATCH_57_SINGLE_GENRE_SOURCE_AUDIT_README.md (100%) rename RETRIEX_PATCH_58_SINGLE_GENRE_LEGACY_VALUE_REDUCTION_README.md => patch_history/RETRIEX_PATCH_58_SINGLE_GENRE_LEGACY_VALUE_REDUCTION_README.md (100%) create mode 100644 patch_history/RETRIEX_PATCH_59B_GENRE_ADAPTATION_SURFACE_CLEANUP_README.md rename RETRIEX_PATCH_59_COMPLETE_GENRE_WIRING_README.md => patch_history/RETRIEX_PATCH_59_COMPLETE_GENRE_WIRING_README.md (100%) rename RETRIEX_PATCH_60B_PROMPT_MEASUREMENT_VOCABULARY_VIEW_HOTFIX_README.md => patch_history/RETRIEX_PATCH_60B_PROMPT_MEASUREMENT_VOCABULARY_VIEW_HOTFIX_README.md (100%) rename RETRIEX_PATCH_60_LEGACY_VALUE_REDUCTION_FINAL_README.md => patch_history/RETRIEX_PATCH_60_LEGACY_VALUE_REDUCTION_FINAL_README.md (100%) rename RETRIEX_PATCH_61_GENRE_SOURCE_OF_TRUTH_GUARD_README.md => patch_history/RETRIEX_PATCH_61_GENRE_SOURCE_OF_TRUTH_GUARD_README.md (100%) diff --git a/config/retriex/genre.yaml b/config/retriex/genre.yaml index 485fee7..d62f284 100644 --- a/config/retriex/genre.yaml +++ b/config/retriex/genre.yaml @@ -5,10 +5,10 @@ # configuration areas that must be reviewed when the same software is repurposed # for another genre such as fashion, furniture, spare parts or electronics. # -# p54 introduced `adaptation_surface` as the path inventory. p55 adds -# `configuration_values` as the first central value surface. Runtime code still -# reads the legacy YAML paths until a later wiring patch migrates selected -# getters to this file. +# p54 introduced `adaptation_surface` as the migration inventory. p55 adds +# `configuration_values` as the central value surface. p59B keeps the +# adaptation surface focused on native genre value paths plus explicitly +# reviewable non-empty technical/frozen legacy paths. parameters: retriex.genre.config: id: water_analysis @@ -18,59 +18,42 @@ parameters: adaptation_surface: product_roles: description: Main product, accessory and consumable role vocabulary used for routing, shop matching and answer guards. - paths: - - vocabulary.classes.device - - vocabulary.classes.accessory - - vocabulary.classes.requested_accessory_code_terms - - 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.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 + value_paths: + - configuration_values.product_roles.primary_product_terms + - configuration_values.product_roles.accessory_product_terms + - configuration_values.product_roles.requested_accessory_code_terms + - configuration_values.product_roles.shop_views + - configuration_values.product_roles.prompt_views + - configuration_values.product_roles.no_llm_fallback_terms + review_paths: - agent.no_llm_fallback.product_roles.vocabulary_views.main_device_request_keywords - agent.no_llm_fallback.product_roles.vocabulary_views.accessory_product_keywords - - prompt.detection.technical_product_keywords - - prompt.detection.accessory_request_keywords product_attributes: description: Genre-specific attributes and constraints, for example measurement values now or size/color/material later. - 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.product_type_terms - - agent.shop_runtime.attribute_cleanup.stop_terms - - agent.shop_runtime.attribute_cleanup.comparative_constraint_patterns - - agent.shop_runtime.answer_constraints.length_sort.trigger_patterns - - agent.shop_runtime.answer_constraints.length_sort.value_patterns - - agent.shop_runtime.answer_constraints.length_filter.min_patterns - - agent.shop_runtime.answer_constraints.length_filter.max_patterns - - intent.commerce.size_token_terms - - intent.commerce.size_terms - - intent.commerce.color_terms + value_paths: + - configuration_values.product_attributes.direct_attribute_cleanup + - configuration_values.product_attributes.size_and_color_terms + - configuration_values.product_attributes.numeric_length_constraints + review_paths: - intent.commerce.patterns.size_extraction_template - intent.commerce.patterns.size_value_template - intent.commerce.patterns.size_token_value_template - intent.commerce.patterns.color_value_template brands_and_canonical_terms: description: Known brands, canonical token mappings and query enrichment rules that change with the shop genre. - paths: - - commerce_query.known_brands - - commerce_query.search_token_canonical_map - - query_enrichment.rules - - vocabulary.maps.shop.accessory_focus_variants - - vocabulary.maps.agent.rag_evidence_guard.synonyms + value_paths: + - configuration_values.brands_and_canonical_terms.known_brands + - configuration_values.brands_and_canonical_terms.canonical_terms + - configuration_values.brands_and_canonical_terms.query_enrichment_rules + - configuration_values.brands_and_canonical_terms.accessory_focus_variants + - configuration_values.brands_and_canonical_terms.rag_evidence_synonyms intent_and_routing: description: Genre-specific commerce/advisory signals and fuzzy routing terms. - paths: - - vocabulary.classes.input_normalization_fuzzy_routing_terms - - agent.input_normalization.fuzzy_routing.terms - - intent.commerce.strong_signals - - intent.commerce.advisory_signals - - intent.commerce.advisory_product_selection_patterns - - intent.commerce.explicit_commerce_intent_patterns + value_paths: + - configuration_values.intent_and_routing.fuzzy_routing_terms + - configuration_values.intent_and_routing.commerce_intent + - configuration_values.intent_and_routing.sales_intent + review_paths: - intent.commerce.patterns.model_like_product - intent.sales.sales_signals - intent.sales.comparison_signals @@ -79,63 +62,41 @@ parameters: - intent.sales.roi_signals context_resolution: description: Follow-up anchors and meta-query handling for referential shop questions in the current genre. - paths: + value_paths: + - configuration_values.context_resolution.commercial_table_follow_up + - configuration_values.context_resolution.referential_terms + - configuration_values.context_resolution.history_anchor_enrichment + - configuration_values.context_resolution.meta_query_guard + - configuration_values.context_resolution.rag_anchor_enrichment + review_paths: - agent.follow_up_context.commercial_table_follow_up.history_anchor_patterns - agent.follow_up_context.commercial_table_follow_up.indicator_marker_patterns - agent.follow_up_context.commercial_table_follow_up.query_template_with_model - agent.follow_up_context.commercial_table_follow_up.query_template_without_model - - agent.shop_runtime.context_resolution.context_usage.referential_terms - - agent.shop_runtime.context_resolution.history_anchor_enrichment.trigger_terms - - agent.shop_runtime.context_resolution.history_anchor_enrichment.anchor_patterns - - agent.shop_runtime.context_resolution.history_anchor_enrichment.template - - agent.shop_runtime.context_resolution.meta_query_guard.meta_only_terms - - agent.shop_runtime.context_resolution.meta_query_guard.context_fallback_filter_terms - - 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 shop_query_runtime: description: Shop query cleanup and direct Shopware search behavior that needs genre-specific terms but no PHP branching. - paths: - - vocabulary.classes.agent_shop_current_input_preservation_terms - - vocabulary.classes.agent_shop_context_anchor_trigger_terms - - agent.shop_runtime.query_cleanup.current_input_preservation.terms - - vocabulary.views.shop.semantic_search_tokens.add - - agent.shop_runtime.query_cleanup.stopword_cleanup.terms - - agent.shop_runtime.result_identity.compound_prefix_match.terms - - agent.shop_runtime.result_identity.primary_identity_repair.stop_terms - - 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 + value_paths: + - configuration_values.shop_query_runtime.current_input_preservation_terms + - configuration_values.shop_query_runtime.stopword_cleanup + - configuration_values.shop_query_runtime.compound_prefix_match + - configuration_values.shop_query_runtime.primary_identity_repair + - configuration_values.shop_query_runtime.semantic_shop_search_tokens + - configuration_values.shop_query_runtime.direct_answer result_identity_and_answer_policy: description: Grounding, role separation and atomicity rules that must match the active product genre. - paths: - - prompt.rules.output_priority_technical - - prompt.rules.response_format_technical - - prompt.rules.response_format_accessory - - prompt.rules.fact_grounding_technical - - prompt.rules.fact_grounding_with_shop - - vocabulary.views.prompt.technical_product_keywords.add - - 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 - - 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 + value_paths: + - configuration_values.result_identity_and_answer_policy.prompt_rules + - configuration_values.result_identity_and_answer_policy.prompt_keyword_views + - configuration_values.result_identity_and_answer_policy.measurement_evidence_guard_terms + - configuration_values.result_identity_and_answer_policy.measurement_evidence_maps search_repair: description: Genre-specific repair tokens, candidate patterns and exact identifier behavior. - paths: - - search_repair.direct_product_attribute_lookup - - vocabulary.views.search_repair.requested_accessory_code_terms.include - - search_repair.specific_model_candidate_patterns - - 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 + value_paths: + - configuration_values.search_repair.direct_product_attribute_lookup + - configuration_values.search_repair.requested_accessory_code_terms + - configuration_values.search_repair.candidate_patterns + - configuration_values.search_repair.candidate_terms + review_paths: - search_repair.patterns.model_candidate - search_repair.patterns.accessory_candidate_template - search_repair.patterns.requested_accessory_code @@ -144,30 +105,23 @@ parameters: - search_repair.patterns.specificity_boost_template retrieval_and_language: description: Genre-specific protected terms, exact selection helpers and retrieval vocabulary. Engine parameters stay outside this surface. - paths: - - language.protected_terms + value_paths: + - configuration_values.retrieval_and_language.protected_terms + - configuration_values.retrieval_and_language.cleanup_profiles + - configuration_values.retrieval_and_language.retrieval_vocabulary_views + - configuration_values.retrieval_and_language.exact_selection + review_paths: - language.cleanup_profiles.commerce_query - language.cleanup_profiles.rag_evidence - language.cleanup_profiles.shop_context_fallback - - retrieval.vocabulary.generic_product_tokens - - retrieval.vocabulary.important_short_model_tokens - - retrieval.vocabulary.family_descriptor_tokens - - retrieval.vocabulary.looks_like_reagent_tokens - - retrieval.vocabulary.looks_like_safety_docs - - retrieval.vocabulary.looks_like_device_words - - retrieval.vocabulary.looks_like_document_words - - retrieval.vocabulary.looks_like_safety_words - - 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 shop_data_mapping: description: Shop record fields and matching text fields that are installation-/genre-specific. - paths: + value_paths: + - configuration_values.shop_data_mapping.custom_fields + - configuration_values.shop_data_mapping.text + - configuration_values.shop_data_mapping.role_guard + - configuration_values.shop_data_mapping.commerce_connection + review_paths: - shop_matching.custom_fields - shop_matching.text.custom_field_join_separator - shop_matching.text.primary_secondary_separator @@ -176,12 +130,11 @@ parameters: - commerce.max_shop_results governance_and_regression: description: Guardrails and regression expectations that intentionally protect the active genre. - paths: - - governance.regression_baseline.protected_short_model_tokens - - governance.regression_baseline.protected_measurement_values - - governance.regression_baseline.protected_technical_prompt_keywords - - governance.regression_baseline.protected_accessory_prompt_keywords - - governance.vocabulary + value_paths: + - configuration_values.governance_and_regression.regression_baseline + - configuration_values.governance_and_regression.vocabulary_guardrails + - configuration_values.governance_and_regression.core_pattern_audit + review_paths: - governance.core_pattern_audit configuration_values: product_roles: diff --git a/RETRIEX_PATCH_44_RUNTIME_ANSWER_GUARD_README.md b/patch_history/RETRIEX_PATCH_44_RUNTIME_ANSWER_GUARD_README.md similarity index 100% rename from RETRIEX_PATCH_44_RUNTIME_ANSWER_GUARD_README.md rename to patch_history/RETRIEX_PATCH_44_RUNTIME_ANSWER_GUARD_README.md diff --git a/RETRIEX_PATCH_53_CONFIG_LAYOUT_CLEANUP_README.md b/patch_history/RETRIEX_PATCH_53_CONFIG_LAYOUT_CLEANUP_README.md similarity index 100% rename from RETRIEX_PATCH_53_CONFIG_LAYOUT_CLEANUP_README.md rename to patch_history/RETRIEX_PATCH_53_CONFIG_LAYOUT_CLEANUP_README.md diff --git a/RETRIEX_PATCH_54_SINGLE_GENRE_CONFIG_SURFACE_README.md b/patch_history/RETRIEX_PATCH_54_SINGLE_GENRE_CONFIG_SURFACE_README.md similarity index 100% rename from RETRIEX_PATCH_54_SINGLE_GENRE_CONFIG_SURFACE_README.md rename to patch_history/RETRIEX_PATCH_54_SINGLE_GENRE_CONFIG_SURFACE_README.md diff --git a/RETRIEX_PATCH_55B_GENRE_CONFIG_VALUES_VALIDATION_HOTFIX_README.md b/patch_history/RETRIEX_PATCH_55B_GENRE_CONFIG_VALUES_VALIDATION_HOTFIX_README.md similarity index 100% rename from RETRIEX_PATCH_55B_GENRE_CONFIG_VALUES_VALIDATION_HOTFIX_README.md rename to patch_history/RETRIEX_PATCH_55B_GENRE_CONFIG_VALUES_VALIDATION_HOTFIX_README.md diff --git a/RETRIEX_PATCH_55_SINGLE_GENRE_CONFIG_VALUES_README.md b/patch_history/RETRIEX_PATCH_55_SINGLE_GENRE_CONFIG_VALUES_README.md similarity index 100% rename from RETRIEX_PATCH_55_SINGLE_GENRE_CONFIG_VALUES_README.md rename to patch_history/RETRIEX_PATCH_55_SINGLE_GENRE_CONFIG_VALUES_README.md diff --git a/RETRIEX_PATCH_56_SINGLE_GENRE_CONFIG_WIRING_README.md b/patch_history/RETRIEX_PATCH_56_SINGLE_GENRE_CONFIG_WIRING_README.md similarity index 100% rename from RETRIEX_PATCH_56_SINGLE_GENRE_CONFIG_WIRING_README.md rename to patch_history/RETRIEX_PATCH_56_SINGLE_GENRE_CONFIG_WIRING_README.md diff --git a/RETRIEX_PATCH_57_SINGLE_GENRE_SOURCE_AUDIT_README.md b/patch_history/RETRIEX_PATCH_57_SINGLE_GENRE_SOURCE_AUDIT_README.md similarity index 100% rename from RETRIEX_PATCH_57_SINGLE_GENRE_SOURCE_AUDIT_README.md rename to patch_history/RETRIEX_PATCH_57_SINGLE_GENRE_SOURCE_AUDIT_README.md diff --git a/RETRIEX_PATCH_58_SINGLE_GENRE_LEGACY_VALUE_REDUCTION_README.md b/patch_history/RETRIEX_PATCH_58_SINGLE_GENRE_LEGACY_VALUE_REDUCTION_README.md similarity index 100% rename from RETRIEX_PATCH_58_SINGLE_GENRE_LEGACY_VALUE_REDUCTION_README.md rename to patch_history/RETRIEX_PATCH_58_SINGLE_GENRE_LEGACY_VALUE_REDUCTION_README.md diff --git a/patch_history/RETRIEX_PATCH_59B_GENRE_ADAPTATION_SURFACE_CLEANUP_README.md b/patch_history/RETRIEX_PATCH_59B_GENRE_ADAPTATION_SURFACE_CLEANUP_README.md new file mode 100644 index 0000000..5b36149 --- /dev/null +++ b/patch_history/RETRIEX_PATCH_59B_GENRE_ADAPTATION_SURFACE_CLEANUP_README.md @@ -0,0 +1,75 @@ +# RetrieX Patch p59B - Genre Adaptation Surface Cleanup + +## Ziel + +p59A hat leere Legacy-`source_paths` aus `genre.configuration_values` entfernt und native Genre-Werte mit `origin: genre_native` markiert. p59B räumt nun die darüber liegende `genre.adaptation_surface` auf. + +Die `adaptation_surface` soll nicht mehr als Sammelliste alter YAML-Pfade verstanden werden. Sie ist jetzt eine Review-/Orientierungsfläche mit zwei klar getrennten Kategorien: + +- `value_paths`: native Pflegepunkte innerhalb von `genre.configuration_values` +- `review_paths`: noch bewusst sichtbare nicht-leere technische, frozen oder runtime-nahe Pfade außerhalb von `genre.configuration_values` + +## Änderungen + +### `config/retriex/genre.yaml` + +- Entfernt das alte generische Feld `adaptation_surface.*.paths` vollständig. +- Entfernt 82 leere Legacy-Inventarpfade aus der `adaptation_surface`. +- Entfernt 20 nicht mehr auflösbare/stale Legacy-Inventarpfade aus der `adaptation_surface`. +- Fügt 47 native `value_paths` hinzu, die direkt auf `configuration_values.*` zeigen. +- Behält 32 nicht-leere technische/frozen/runtime-nahe Pfade als `review_paths`. + +### `src/Config/RetriexEffectiveConfigProvider.php` + +- `validateGenre()` akzeptiert jetzt die neue `adaptation_surface`-Struktur. +- `value_paths` werden gegen `genre.configuration_values` validiert. +- `review_paths` werden gegen die effektive Konfiguration validiert. +- Das alte Feld `paths` bleibt bewusst kompatibel validierbar, ist aber in `genre.yaml` nicht mehr im Einsatz. + +## Nicht geändert + +- Keine Runtime-Logik geändert. +- Keine Retrieval-/Prompt-/Shop-/Scoring-Logik geändert. +- Keine Genre-Werte geändert. +- Keine frozen Source-Path-Hashes geändert. +- Keine `configuration_values.*.source_paths` geändert. + +## Ergebnis der lokalen Prüfungen + +Lokale Prüfungen ohne Projekt-Dependencies: + +- `genre.yaml` ist parsebar. +- PHP-Lint grün für die geänderte Config-Klasse. +- Adaptation-Surface-Simulation: + - 11 Surface-Gruppen + - 47 `value_paths` + - 32 `review_paths` + - 0 alte `paths`-Felder + - 0 unbekannte `value_paths` + - 0 unbekannte `review_paths` +- Source-of-Truth-Simulation weiterhin grün: + - 17 Value-Nodes mit `source_paths` + - 39 deklarierte Source-Pfade + - 37 frozen non-empty Legacy-Pfade + - 2 runtime-resolved Pfade + - 0 Fehler + +Symfony-Checks konnten lokal nicht ausgeführt werden, weil die ZIP kein `vendor/` enthält. + +## Empfohlene Projektchecks nach Einspielen + +```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 +``` + +## Folgepatch-Idee + +p59C kann die 32 verbliebenen `review_paths` klassifizieren: + +- echte technische Config, die nicht nach `genre.yaml` gehört +- frozen Fallbacks, die nach weiterem Rewiring entfernt werden können +- runtime-resolved Werte, die bewusst außerhalb der Genre-Pflege bleiben + diff --git a/RETRIEX_PATCH_59_COMPLETE_GENRE_WIRING_README.md b/patch_history/RETRIEX_PATCH_59_COMPLETE_GENRE_WIRING_README.md similarity index 100% rename from RETRIEX_PATCH_59_COMPLETE_GENRE_WIRING_README.md rename to patch_history/RETRIEX_PATCH_59_COMPLETE_GENRE_WIRING_README.md diff --git a/RETRIEX_PATCH_60B_PROMPT_MEASUREMENT_VOCABULARY_VIEW_HOTFIX_README.md b/patch_history/RETRIEX_PATCH_60B_PROMPT_MEASUREMENT_VOCABULARY_VIEW_HOTFIX_README.md similarity index 100% rename from RETRIEX_PATCH_60B_PROMPT_MEASUREMENT_VOCABULARY_VIEW_HOTFIX_README.md rename to patch_history/RETRIEX_PATCH_60B_PROMPT_MEASUREMENT_VOCABULARY_VIEW_HOTFIX_README.md diff --git a/RETRIEX_PATCH_60_LEGACY_VALUE_REDUCTION_FINAL_README.md b/patch_history/RETRIEX_PATCH_60_LEGACY_VALUE_REDUCTION_FINAL_README.md similarity index 100% rename from RETRIEX_PATCH_60_LEGACY_VALUE_REDUCTION_FINAL_README.md rename to patch_history/RETRIEX_PATCH_60_LEGACY_VALUE_REDUCTION_FINAL_README.md diff --git a/RETRIEX_PATCH_61_GENRE_SOURCE_OF_TRUTH_GUARD_README.md b/patch_history/RETRIEX_PATCH_61_GENRE_SOURCE_OF_TRUTH_GUARD_README.md similarity index 100% rename from RETRIEX_PATCH_61_GENRE_SOURCE_OF_TRUTH_GUARD_README.md rename to patch_history/RETRIEX_PATCH_61_GENRE_SOURCE_OF_TRUTH_GUARD_README.md diff --git a/public/assets/styles/base.css b/public/assets/styles/base.css index a28382f..fd5e784 100644 --- a/public/assets/styles/base.css +++ b/public/assets/styles/base.css @@ -58,7 +58,7 @@ input, textarea, select { } .container { - max-width: 1024px; + max-width: 900px; margin: 0 auto; display: flex; flex-direction: column; @@ -84,7 +84,8 @@ input, textarea, select { .chat { flex: 1; overflow-y: auto; - padding: 1rem; + padding-right: 1rem; + padding-bottom: 1rem; /* background: #121a25; border: 1px solid var(--border);*/ border-radius: 6px 6px 0 0; @@ -486,14 +487,15 @@ span.think { } .retriex-chat-options { - display: flex; + display: flex +; flex-wrap: wrap; gap: 0.5rem; - margin: -1px 0 0.75rem; + margin: 1rem 0 0.25rem; color: rgba(248, 249, 250, 0.76); font-size: 0.84rem; - border-radius: 0 0 6px 6px; - background-color: #212b39 !important; + border-radius: 6px; + background-color: transparent !important; } .retriex-option-toggle { diff --git a/src/Config/RetriexEffectiveConfigProvider.php b/src/Config/RetriexEffectiveConfigProvider.php index 150344c..5fc0adc 100644 --- a/src/Config/RetriexEffectiveConfigProvider.php +++ b/src/Config/RetriexEffectiveConfigProvider.php @@ -1121,6 +1121,26 @@ final readonly class RetriexEffectiveConfigProvider $errors[] = 'genre.mode must not be empty.'; } + $configurationValues = $genre['configuration_values'] ?? null; + if (!is_array($configurationValues) || $configurationValues === []) { + $errors[] = 'genre.configuration_values must be a non-empty map.'; + return; + } + + foreach ($configurationValues as $group => $valueDefinition) { + if (!is_string($group) || trim($group) === '') { + $errors[] = 'genre.configuration_values keys must be non-empty strings.'; + continue; + } + + if (!is_array($valueDefinition) || $valueDefinition === []) { + $errors[] = sprintf('genre.configuration_values.%s must be a non-empty map.', $group); + } + } + + $configurationValuePaths = []; + $this->flattenEffectiveConfigPath('configuration_values', $configurationValues, $configurationValuePaths); + $surface = $genre['adaptation_surface'] ?? null; if (!is_array($surface) || $surface === []) { $errors[] = 'genre.adaptation_surface must be a non-empty map.'; @@ -1148,41 +1168,78 @@ final readonly class RetriexEffectiveConfigProvider continue; } - $paths = $definition['paths'] ?? null; - if (!is_array($paths) || $paths === []) { - $errors[] = sprintf('genre.adaptation_surface.%s.paths must be a non-empty list.', $group); + if (!array_key_exists($group, $configurationValues)) { + $warnings[] = sprintf('genre.configuration_values is missing value group for adaptation_surface.%s.', $group); + } + + $valuePaths = $definition['value_paths'] ?? null; + $legacyPaths = $definition['paths'] ?? null; + if ((!is_array($valuePaths) || $valuePaths === []) && (!is_array($legacyPaths) || $legacyPaths === [])) { + $errors[] = sprintf('genre.adaptation_surface.%s.value_paths must be a non-empty list.', $group); continue; } - foreach ($paths as $path) { - if (!is_string($path) || trim($path) === '') { - $errors[] = sprintf('genre.adaptation_surface.%s.paths must contain non-empty strings.', $group); + if (is_array($valuePaths)) { + if ($valuePaths === []) { + $errors[] = sprintf('genre.adaptation_surface.%s.value_paths must be a non-empty list when declared.', $group); + } + + foreach ($valuePaths as $path) { + if (!is_string($path) || trim($path) === '') { + $errors[] = sprintf('genre.adaptation_surface.%s.value_paths must contain non-empty strings.', $group); + continue; + } + + $path = trim($path); + if (!str_starts_with($path, 'configuration_values.' . $group . '.')) { + $warnings[] = sprintf('genre.adaptation_surface.%s.value_paths should reference configuration_values.%s.*: %s.', $group, $group, $path); + } + + if (!isset($configurationValuePaths[$path])) { + $warnings[] = sprintf('genre.adaptation_surface.%s references unknown genre value path: %s.', $group, $path); + } + } + } + + if (is_array($legacyPaths)) { + if ($legacyPaths === []) { + $errors[] = sprintf('genre.adaptation_surface.%s.paths must be a non-empty list when declared.', $group); + } + + foreach ($legacyPaths as $path) { + if (!is_string($path) || trim($path) === '') { + $errors[] = sprintf('genre.adaptation_surface.%s.paths must contain non-empty strings.', $group); + continue; + } + + $path = trim($path); + if (!isset($flattened[$path])) { + $warnings[] = sprintf('genre.adaptation_surface.%s references unknown config path: %s.', $group, $path); + } + } + } + + $reviewPaths = $definition['review_paths'] ?? null; + if (array_key_exists('review_paths', $definition)) { + if (!is_array($reviewPaths) || $reviewPaths === []) { + $errors[] = sprintf('genre.adaptation_surface.%s.review_paths must be a non-empty list when declared.', $group); continue; } - if (!isset($flattened[$path])) { - $warnings[] = sprintf('genre.adaptation_surface.%s references unknown config path: %s.', $group, $path); + foreach ($reviewPaths as $path) { + if (!is_string($path) || trim($path) === '') { + $errors[] = sprintf('genre.adaptation_surface.%s.review_paths must contain non-empty strings.', $group); + continue; + } + + $path = trim($path); + if (!isset($flattened[$path])) { + $warnings[] = sprintf('genre.adaptation_surface.%s references unknown review path: %s.', $group, $path); + } } } } - $configurationValues = $genre['configuration_values'] ?? null; - if (!is_array($configurationValues) || $configurationValues === []) { - $errors[] = 'genre.configuration_values must be a non-empty map.'; - return; - } - - foreach ($configurationValues as $group => $valueDefinition) { - if (!is_string($group) || trim($group) === '') { - $errors[] = 'genre.configuration_values keys must be non-empty strings.'; - continue; - } - - if (!is_array($valueDefinition) || $valueDefinition === []) { - $errors[] = sprintf('genre.configuration_values.%s must be a non-empty map.', $group); - } - } - foreach ($this->collectGenreConfigurationValueSourcePaths($configurationValues) as $valuePath => $sourcePaths) { foreach ($sourcePaths as $sourcePath) { if (!isset($flattened[$sourcePath])) {