FAILURE MAP
← Case archive

FA-9401 / Dependency resolution / Open access

Dependency group activation: Dependencies repeated across groups install repeatedly · case 01

Dependencies repeated across groups install repeatedly.

Verified by executionVariant 1 · 7 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The implementation substitutes sorted(selected) for sorted(set(selected)), so dependencies repeated across groups install repeatedly.

VERIFIED REPAIR

Deduplicate the sorted activated dependency names.

Unsuccessful approach: The attempted repair substitutes list(selected). Fixture 7 still yields ['z', 'a', 'z'] instead of ['a', 'z'].

Case contract

Return sorted unique dependency names from runtime and explicitly enabled optional groups. Exclude inactive markers and disabled entries; a dependency appearing in multiple groups is emitted once.

Why this case matters

An offline model of dependency group activation, 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(rows, enabled):
    selected = []
    for name, group, marker, disabled in rows:
        if group != 'runtime' and group not in enabled: continue
        if not marker: continue
        if disabled: continue
        selected.append(name)
    return sorted(selected)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('fixture 1', solve([], []), [])
check('fixture 2', solve([('a', 'runtime', True, False)], []), ['a'])
check('fixture 3', solve([('a', 'dev', True, False)], []), [])
check('fixture 4', solve([('a', 'dev', True, False)], ['dev']), ['a'])
check('fixture 5', solve([('a', 'runtime', False, False)], []), [])
check('fixture 6', solve([('a', 'runtime', True, True)], []), [])
check('fixture 7', solve([('z', 'runtime', True, False), ('a', 'dev', True, False), ('z', 'dev', True, False)], ['dev']), ['a', 'z'])
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 fixtureActualExpectedOutcome
fixture 1[][]Passed
fixture 2['a']['a']Passed
fixture 3[][]Passed
fixture 4['a']['a']Passed
fixture 5[][]Passed
fixture 6[][]Passed
fixture 7['a', 'z', 'z']['a', 'z']Failed

SHA-256 / ae8b04c7a53243130601e73e9d9366c5aece81f5b4ede615c3cb0a5761cfdf0d

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(rows, enabled):
    selected = []
    for name, group, marker, disabled in rows:
        if group != 'runtime' and group not in enabled: continue
        if not marker: continue
        if disabled: continue
        selected.append(name)
    return list(selected)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('fixture 1', solve([], []), [])
check('fixture 2', solve([('a', 'runtime', True, False)], []), ['a'])
check('fixture 3', solve([('a', 'dev', True, False)], []), [])
check('fixture 4', solve([('a', 'dev', True, False)], ['dev']), ['a'])
check('fixture 5', solve([('a', 'runtime', False, False)], []), [])
check('fixture 6', solve([('a', 'runtime', True, True)], []), [])
check('fixture 7', solve([('z', 'runtime', True, False), ('a', 'dev', True, False), ('z', 'dev', True, False)], ['dev']), ['a', 'z'])
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 fixtureActualExpectedOutcome
fixture 1[][]Passed
fixture 2['a']['a']Passed
fixture 3[][]Passed
fixture 4['a']['a']Passed
fixture 5[][]Passed
fixture 6[][]Passed
fixture 7['z', 'a', 'z']['a', 'z']Failed

SHA-256 / 82362bea5a70af463634e1f80c40ed68b41fea978a2ccd99d18949659e8ae799

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(rows, enabled):
    selected = []
    for name, group, marker, disabled in rows:
        if group != 'runtime' and group not in enabled: continue
        if not marker: continue
        if disabled: continue
        selected.append(name)
    return sorted(set(selected))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('fixture 1', solve([], []), [])
check('fixture 2', solve([('a', 'runtime', True, False)], []), ['a'])
check('fixture 3', solve([('a', 'dev', True, False)], []), [])
check('fixture 4', solve([('a', 'dev', True, False)], ['dev']), ['a'])
check('fixture 5', solve([('a', 'runtime', False, False)], []), [])
check('fixture 6', solve([('a', 'runtime', True, True)], []), [])
check('fixture 7', solve([('z', 'runtime', True, False), ('a', 'dev', True, False), ('z', 'dev', True, False)], ['dev']), ['a', 'z'])
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 fixtureActualExpectedOutcome
fixture 1[][]Passed
fixture 2['a']['a']Passed
fixture 3[][]Passed
fixture 4['a']['a']Passed
fixture 5[][]Passed
fixture 6[][]Passed
fixture 7['a', 'z']['a', 'z']Passed

SHA-256 / 1d8ef41da514736c11f17d6de7c87614627de2794085db73fb84824afa7040f1

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:29.681732+00:00.

Case digest / 49e519a2c3f5de6bb175da1538f6fec610b29c27f5e94374f49aa38f00d7b223