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

@@ -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 . '.';
}
}