FA-9931 / Packaging / Open access
Distribution license policy: Undeclared licenses pass admission · case 01
Undeclared licenses pass admission.
ROOT CAUSE
The implementation substitutes True for bool(licenses), so undeclared licenses pass admission.
VERIFIED REPAIR
Require at least one declared license in this model.
Unsuccessful approach: The attempted repair substitutes licenses is not None. Fixture 5 still yields True instead of False.
Case contract
Admit only packages with a declared license, every required license permitted, no explicitly forbidden license, redistribution enabled, and source-offer provided when required.
Why this case matters
An offline model of distribution license policy, suitable for testing build and release tooling without external services.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(licenses, allowed, forbidden, redistribute, source_required, source_offer):
return True and set(licenses) <= set(allowed) and not (set(licenses) & set(forbidden)) and redistribute and (not source_required or source_offer)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('fixture 1', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, False), False)
check('fixture 2', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, True), False)
check('fixture 3', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, False), False)
check('fixture 4', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, True), False)
check('fixture 5', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, False), False)
check('fixture 6', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, True), False)
check('fixture 7', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, False), False)
check('fixture 8', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, True), False)
check('fixture 9', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, False), False)
check('fixture 10', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, True), False)
check('fixture 11', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, False), False)
check('fixture 12', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, True), False)
check('fixture 13', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, False), True)
check('fixture 14', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, True), True)
check('fixture 15', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, False), False)
check('fixture 16', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, True), True)
check('fixture 17', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, False), False)
check('fixture 18', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, True), False)
check('fixture 19', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, False), False)
check('fixture 20', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, True), False)
check('fixture 21', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, False), False)
check('fixture 22', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, True), False)
check('fixture 23', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, False), False)
check('fixture 24', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, True), False)
check('fixture 25', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, False), False)
check('fixture 26', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, True), False)
check('fixture 27', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, False), False)
check('fixture 28', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, True), False)
check('fixture 29', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, False), False)
check('fixture 30', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, True), False)
check('fixture 31', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, False), False)
check('fixture 32', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, True), False)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| fixture 1 | False | False | Passed |
| fixture 2 | False | False | Passed |
| fixture 3 | False | False | Passed |
| fixture 4 | False | False | Passed |
| fixture 5 | True | False | Failed |
| fixture 6 | True | False | Failed |
| fixture 7 | False | False | Passed |
| fixture 8 | True | False | Failed |
| fixture 9 | False | False | Passed |
| fixture 10 | False | False | Passed |
| fixture 11 | False | False | Passed |
| fixture 12 | False | False | Passed |
| fixture 13 | True | True | Passed |
| fixture 14 | True | True | Passed |
| fixture 15 | False | False | Passed |
| fixture 16 | True | True | Passed |
| fixture 17 | False | False | Passed |
| fixture 18 | False | False | Passed |
| fixture 19 | False | False | Passed |
| fixture 20 | False | False | Passed |
| fixture 21 | False | False | Passed |
| fixture 22 | False | False | Passed |
| fixture 23 | False | False | Passed |
| fixture 24 | False | False | Passed |
| fixture 25 | False | False | Passed |
| fixture 26 | False | False | Passed |
| fixture 27 | False | False | Passed |
| fixture 28 | False | False | Passed |
| fixture 29 | False | False | Passed |
| fixture 30 | False | False | Passed |
| fixture 31 | False | False | Passed |
| fixture 32 | False | False | Passed |
SHA-256 / 4eca017934d4785eaf64c6644fab05017cb07e4c8dba35be9a78a7a2ccca7532
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(licenses, allowed, forbidden, redistribute, source_required, source_offer):
return licenses is not None and set(licenses) <= set(allowed) and not (set(licenses) & set(forbidden)) and redistribute and (not source_required or source_offer)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('fixture 1', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, False), False)
check('fixture 2', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, True), False)
check('fixture 3', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, False), False)
check('fixture 4', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, True), False)
check('fixture 5', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, False), False)
check('fixture 6', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, True), False)
check('fixture 7', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, False), False)
check('fixture 8', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, True), False)
check('fixture 9', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, False), False)
check('fixture 10', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, True), False)
check('fixture 11', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, False), False)
check('fixture 12', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, True), False)
check('fixture 13', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, False), True)
check('fixture 14', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, True), True)
check('fixture 15', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, False), False)
check('fixture 16', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, True), True)
check('fixture 17', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, False), False)
check('fixture 18', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, True), False)
check('fixture 19', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, False), False)
check('fixture 20', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, True), False)
check('fixture 21', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, False), False)
check('fixture 22', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, True), False)
check('fixture 23', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, False), False)
check('fixture 24', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, True), False)
check('fixture 25', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, False), False)
check('fixture 26', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, True), False)
check('fixture 27', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, False), False)
check('fixture 28', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, True), False)
check('fixture 29', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, False), False)
check('fixture 30', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, True), False)
check('fixture 31', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, False), False)
check('fixture 32', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, True), False)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| fixture 1 | False | False | Passed |
| fixture 2 | False | False | Passed |
| fixture 3 | False | False | Passed |
| fixture 4 | False | False | Passed |
| fixture 5 | True | False | Failed |
| fixture 6 | True | False | Failed |
| fixture 7 | False | False | Passed |
| fixture 8 | True | False | Failed |
| fixture 9 | False | False | Passed |
| fixture 10 | False | False | Passed |
| fixture 11 | False | False | Passed |
| fixture 12 | False | False | Passed |
| fixture 13 | True | True | Passed |
| fixture 14 | True | True | Passed |
| fixture 15 | False | False | Passed |
| fixture 16 | True | True | Passed |
| fixture 17 | False | False | Passed |
| fixture 18 | False | False | Passed |
| fixture 19 | False | False | Passed |
| fixture 20 | False | False | Passed |
| fixture 21 | False | False | Passed |
| fixture 22 | False | False | Passed |
| fixture 23 | False | False | Passed |
| fixture 24 | False | False | Passed |
| fixture 25 | False | False | Passed |
| fixture 26 | False | False | Passed |
| fixture 27 | False | False | Passed |
| fixture 28 | False | False | Passed |
| fixture 29 | False | False | Passed |
| fixture 30 | False | False | Passed |
| fixture 31 | False | False | Passed |
| fixture 32 | False | False | Passed |
SHA-256 / 2da2a667c2ecf513bcdc997d11fa7001f0003952e662d157b27bc349d2716861
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(licenses, allowed, forbidden, redistribute, source_required, source_offer):
return bool(licenses) and set(licenses) <= set(allowed) and not (set(licenses) & set(forbidden)) and redistribute and (not source_required or source_offer)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('fixture 1', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, False), False)
check('fixture 2', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, True), False)
check('fixture 3', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, False), False)
check('fixture 4', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, True), False)
check('fixture 5', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, False), False)
check('fixture 6', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, True), False)
check('fixture 7', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, False), False)
check('fixture 8', solve([], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, True), False)
check('fixture 9', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, False), False)
check('fixture 10', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, True), False)
check('fixture 11', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, False), False)
check('fixture 12', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, True), False)
check('fixture 13', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, False), True)
check('fixture 14', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, True), True)
check('fixture 15', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, False), False)
check('fixture 16', solve(['MIT'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, True), True)
check('fixture 17', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, False), False)
check('fixture 18', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, True), False)
check('fixture 19', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, False), False)
check('fixture 20', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, True), False)
check('fixture 21', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, False), False)
check('fixture 22', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, True), False)
check('fixture 23', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, False), False)
check('fixture 24', solve(['MIT', 'Unknown'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, True), False)
check('fixture 25', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, False), False)
check('fixture 26', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, False, True), False)
check('fixture 27', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, False), False)
check('fixture 28', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], False, True, True), False)
check('fixture 29', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, False), False)
check('fixture 30', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, False, True), False)
check('fixture 31', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, False), False)
check('fixture 32', solve(['Forbidden'], ['MIT', 'Apache', 'Forbidden'], ['Forbidden'], True, True, True), False)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| fixture 1 | False | False | Passed |
| fixture 2 | False | False | Passed |
| fixture 3 | False | False | Passed |
| fixture 4 | False | False | Passed |
| fixture 5 | False | False | Passed |
| fixture 6 | False | False | Passed |
| fixture 7 | False | False | Passed |
| fixture 8 | False | False | Passed |
| fixture 9 | False | False | Passed |
| fixture 10 | False | False | Passed |
| fixture 11 | False | False | Passed |
| fixture 12 | False | False | Passed |
| fixture 13 | True | True | Passed |
| fixture 14 | True | True | Passed |
| fixture 15 | False | False | Passed |
| fixture 16 | True | True | Passed |
| fixture 17 | False | False | Passed |
| fixture 18 | False | False | Passed |
| fixture 19 | False | False | Passed |
| fixture 20 | False | False | Passed |
| fixture 21 | False | False | Passed |
| fixture 22 | False | False | Passed |
| fixture 23 | False | False | Passed |
| fixture 24 | False | False | Passed |
| fixture 25 | False | False | Passed |
| fixture 26 | False | False | Passed |
| fixture 27 | False | False | Passed |
| fixture 28 | False | False | Passed |
| fixture 29 | False | False | Passed |
| fixture 30 | False | False | Passed |
| fixture 31 | False | False | Passed |
| fixture 32 | False | False | Passed |
SHA-256 / a192701c5809fb70f4b86a0c6d43d538f93c3d9d15404282a962c38895226a3a
Verification & scope
This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:38:34.280476+00:00.
Case digest / 92a036e8a630d6dade153f531d21806c70f0be1d5504f7003860a24fa34eef22