FA-9951 / Packaging / Open access
Distribution license policy: Required source offers are missing · case 01
Required source offers are missing.
ROOT CAUSE
The implementation substitutes True for (not source_required or source_offer), so required source offers are missing.
VERIFIED REPAIR
Require source offers precisely when the policy marks them necessary.
Unsuccessful approach: The attempted repair substitutes source_offer. Fixture 13 still yields False instead of True.
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 bool(licenses) and set(licenses) <= set(allowed) and not (set(licenses) & set(forbidden)) and redistribute and True
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 | True | False | Failed |
| 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 / 88aea775466fcefdcf13e62066979bd12aae0e0e148ea4f47d755ae72f55c84f
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 bool(licenses) and set(licenses) <= set(allowed) and not (set(licenses) & set(forbidden)) and redistribute and 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 | False | True | Failed |
| 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 / 2389a42871d94db1bb6f0eda626fb087948834560e93d0d207820a25ca40a8c9
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.592532+00:00.
Case digest / 6ce89de86759ae3d41823fd5f754525d4c5842706b378cb4af5941380ce16c49