Description
File: src/extensions/score_metamodel/checks/check_options.py, function validate_links()
validate_links validates link targets by stripping a namespace prefix from the target ID and then re.match-ing the remainder against the allowed link-type names. This only works when the type name happens to be a literal prefix of the need ID — which is true for S-CORE's built-in metamodel but not guaranteed for downstream metamodels.
Analysis results
Root Cause — _remove_namespace_prefix_ strips uppercase prefixes:
def _remove_namespace_prefix_(word: str) -> str:
return re.sub(r"^[A-Z]+_", "", word)
This strips leading uppercase letters followed by an underscore:
P_FOO → FOO
BB_EXAMPLE → EXAMPLE
stkh_req__foo → stkh_req__foo (unchanged — starts with lowercase)
Root Cause — the hidden assumption: When a link constraint uses a type-name string like "product", the regex becomes literally product. re.match("product", value) only succeeds if value starts with "product".
For S-CORE's own metamodel, this works because IDs use lowercase prefixes (stkh_req__, etc.) → the prefix stripper leaves them unchanged, and the type name (stkh_req) is a literal prefix of the ID (stkh_req__something).
But this is a coincidence of S-CORE's naming conventions. Any downstream metamodel with different ID conventions breaks:
| Scenario |
ID example |
Type name |
Stripped ID |
Regex |
Match? |
| S-CORE built-in |
stkh_req__foo |
stkh_req |
stkh_req__foo |
stkh_req |
✅ |
| Uppercase prefix |
P_FOO |
product |
FOO |
product |
❌ |
| Different prefix scheme |
my_product__foo |
product |
my_product__foo |
product |
❌ |
Solution
The prefix-stripping step (_remove_namespace_prefix_) should probably be removed — it is unnecessary and causes the mismatch. Instead, when allowed_values contains a plain string (a type name), resolve the target need's actual type/directive field and check membership in the allowed type-name set. Only fall back to regex matching when the constraint is an actual regex pattern (i.e., a dict with mandatory_options.id).
Error Occurrence Rate
Reproducible
How to reproduce
Extend metamodel with uppercase type names.
Supporting Information
No response
Classification
Minor
First Affected Release
not released (main)
Last Affected Release
not released (main)
Expected Fixed Release
before release (main)
Category
Description
File:
src/extensions/score_metamodel/checks/check_options.py, functionvalidate_links()validate_linksvalidates link targets by stripping a namespace prefix from the target ID and thenre.match-ing the remainder against the allowed link-type names. This only works when the type name happens to be a literal prefix of the need ID — which is true for S-CORE's built-in metamodel but not guaranteed for downstream metamodels.Analysis results
Root Cause —
_remove_namespace_prefix_strips uppercase prefixes:This strips leading uppercase letters followed by an underscore:
P_FOO→FOOBB_EXAMPLE→EXAMPLEstkh_req__foo→stkh_req__foo(unchanged — starts with lowercase)Root Cause — the hidden assumption: When a link constraint uses a type-name string like
"product", the regex becomes literallyproduct.re.match("product", value)only succeeds ifvaluestarts with"product".For S-CORE's own metamodel, this works because IDs use lowercase prefixes (
stkh_req__, etc.) → the prefix stripper leaves them unchanged, and the type name (stkh_req) is a literal prefix of the ID (stkh_req__something).But this is a coincidence of S-CORE's naming conventions. Any downstream metamodel with different ID conventions breaks:
stkh_req__foostkh_reqstkh_req__foostkh_reqP_FOOproductFOOproductmy_product__fooproductmy_product__fooproductSolution
The prefix-stripping step (
_remove_namespace_prefix_) should probably be removed — it is unnecessary and causes the mismatch. Instead, whenallowed_valuescontains a plain string (a type name), resolve the target need's actualtype/directivefield and check membership in the allowed type-name set. Only fall back to regex matching when the constraint is an actual regex pattern (i.e., a dict withmandatory_options.id).Error Occurrence Rate
Reproducible
How to reproduce
Extend metamodel with uppercase type names.
Supporting Information
No response
Classification
Minor
First Affected Release
not released (main)
Last Affected Release
not released (main)
Expected Fixed Release
before release (main)
Category