What happened?
When there is no frontmatter license field and no LICENSE file, the license check falls through to SPDX headers in source files. The capture regex is:
SPDX_LICENSE_PATTERN = r"SPDX-License-Identifier:\s*([A-Za-z0-9.\-+]+)"
in constants.py. That character class stops at whitespace, OR, and (.
So:
SPDX-License-Identifier: MIT OR GPL-3.0 becomes MIT
SPDX-License-Identifier: Apache-2.0 AND GPL-3.0 becomes Apache-2.0
MIT / Apache-2.0 are allowed, so the skill passes. The copyleft half of the expression never gets evaluated. The project already depends on license-expression and does not use it here.
Expected: a compound SPDX expression that includes a blocked license should fail the license gate, or at least be parsed as the full expression rather than the first token.
Actual: the check reports Found SPDX header 'MIT' in script.py and License: MIT (ALLOWED - permissive). Exit 0.
Reproduction steps
tmp=$(mktemp -d)
mkdir -p "$tmp/spdx"
cat > "$tmp/spdx/SKILL.md" <<'EOF'
---
name: spdx
description: Skill whose only license signal is an SPDX OR expression.
---
# SPDX OR
EOF
cat > "$tmp/spdx/script.py" <<'EOF'
# SPDX-License-Identifier: MIT OR GPL-3.0
print("hi")
EOF
skillevaluator validate "$tmp/spdx" --checks license --no-dedup -r cli
Observed: License Compliance | PASS, SPDX header recorded as MIT.
The same skill with # SPDX-License-Identifier: GPL-3.0 (no OR) is blocked, so this is specifically the truncated-expression path.
SkillEvaluator version or commit
009aa300be7925c7ba75760592baeb941cc29ba8 (0.2.1)
Environment
- macOS 15, arm64
- Python 3.12.2
uv sync --python 3.12 --all-extras
- No API key
Before submitting
Happy to send a PR that parses the full SPDX expression (the license-expression dependency is already in the tree) if that is the intended contract.
What happened?
When there is no frontmatter
licensefield and no LICENSE file, the license check falls through to SPDX headers in source files. The capture regex is:in
constants.py. That character class stops at whitespace,OR, and(.So:
SPDX-License-Identifier: MIT OR GPL-3.0becomesMITSPDX-License-Identifier: Apache-2.0 AND GPL-3.0becomesApache-2.0MIT/Apache-2.0are allowed, so the skill passes. The copyleft half of the expression never gets evaluated. The project already depends onlicense-expressionand does not use it here.Expected: a compound SPDX expression that includes a blocked license should fail the license gate, or at least be parsed as the full expression rather than the first token.
Actual: the check reports
Found SPDX header 'MIT' in script.pyandLicense: MIT (ALLOWED - permissive). Exit 0.Reproduction steps
Observed:
License Compliance | PASS, SPDX header recorded asMIT.The same skill with
# SPDX-License-Identifier: GPL-3.0(noOR) is blocked, so this is specifically the truncated-expression path.SkillEvaluator version or commit
009aa300be7925c7ba75760592baeb941cc29ba8(0.2.1)Environment
uv sync --python 3.12 --all-extrasBefore submitting
Happy to send a PR that parses the full SPDX expression (the
license-expressiondependency is already in the tree) if that is the intended contract.