FA-9686 / Configuration / Open access
Configuration change plan: Removed settings disappear from the plan · case 01
Removed settings disappear from the plan.
ROOT CAUSE
The implementation substitutes removed = set() for removed = set(before) - set(after), so removed settings disappear from the plan.
VERIFIED REPAIR
Compute removals from old minus new keys.
Unsuccessful approach: The attempted repair substitutes removed = set(after) - set(before). Fixture 2 still yields {'added': ['a'], 'removed': ['a'], 'changed': [], 'restart': ['a'], 'unchanged': []} instead of {'added': ['a'], 'removed': [], 'changed': [], 'restart': ['a'], 'unchanged': []}.
Case contract
Produce sorted added, removed, changed, restart-required, and unchanged key lists. Restart applies only to added/removed/changed keys in the restart set.
Why this case matters
An offline model of configuration change plan, 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(before, after, restart):
added = set(after) - set(before)
removed = set()
common = set(before) & set(after)
changed = {k for k in common if before[k] != after[k]}
return {'added': sorted(added), 'removed': sorted(removed), 'changed': sorted(changed), 'restart': sorted((added | removed | changed) & set(restart)), 'unchanged': sorted(common - changed)}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('fixture 1', solve({}, {}, []), {'added': [], 'removed': [], 'changed': [], 'restart': [], 'unchanged': []})
check('fixture 2', solve({}, {'a': 1}, ['a']), {'added': ['a'], 'removed': [], 'changed': [], 'restart': ['a'], 'unchanged': []})
check('fixture 3', solve({'a': 1}, {}, ['a']), {'added': [], 'removed': ['a'], 'changed': [], 'restart': ['a'], 'unchanged': []})
check('fixture 4', solve({'a': 1}, {'a': 2}, ['a']), {'added': [], 'removed': [], 'changed': ['a'], 'restart': ['a'], 'unchanged': []})
check('fixture 5', solve({'a': 1}, {'a': 1}, ['a']), {'added': [], 'removed': [], 'changed': [], 'restart': [], 'unchanged': ['a']})
check('fixture 6', solve({'a': 1}, {'a': 2}, []), {'added': [], 'removed': [], 'changed': ['a'], 'restart': [], 'unchanged': []})
check('fixture 7', solve({'a': 1, 'b': 2}, {'a': 1, 'c': 3}, ['b', 'c']), {'added': ['c'], 'removed': ['b'], 'changed': [], 'restart': ['b', 'c'], 'unchanged': ['a']})
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 | {'added': [], 'changed': [], 'removed': [], 'restart': [], 'unchanged': []} | {'added': [], 'changed': [], 'removed': [], 'restart': [], 'unchanged': []} | Passed |
| fixture 2 | {'added': ['a'], 'changed': [], 'removed': [], 'restart': ['a'], 'unchanged': []} | {'added': ['a'], 'changed': [], 'removed': [], 'restart': ['a'], 'unchanged': []} | Passed |
| fixture 3 | {'added': [], 'changed': [], 'removed': [], 'restart': [], 'unchanged': []} | {'added': [], 'changed': [], 'removed': ['a'], 'restart': ['a'], 'unchanged': []} | Failed |
| fixture 4 | {'added': [], 'changed': ['a'], 'removed': [], 'restart': ['a'], 'unchanged': []} | {'added': [], 'changed': ['a'], 'removed': [], 'restart': ['a'], 'unchanged': []} | Passed |
| fixture 5 | {'added': [], 'changed': [], 'removed': [], 'restart': [], 'unchanged': ['a']} | {'added': [], 'changed': [], 'removed': [], 'restart': [], 'unchanged': ['a']} | Passed |
| fixture 6 | {'added': [], 'changed': ['a'], 'removed': [], 'restart': [], 'unchanged': []} | {'added': [], 'changed': ['a'], 'removed': [], 'restart': [], 'unchanged': []} | Passed |
| fixture 7 | {'added': ['c'], 'changed': [], 'removed': [], 'restart': ['c'], 'unchanged': ['a']} | {'added': ['c'], 'changed': [], 'removed': ['b'], 'restart': ['b', 'c'], 'unchanged': ['a']} | Failed |
SHA-256 / aa91a64a691e0296c2074200dd22ff124da45b3bf7ba0755b8053fdb060d9556
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(before, after, restart):
added = set(after) - set(before)
removed = set(after) - set(before)
common = set(before) & set(after)
changed = {k for k in common if before[k] != after[k]}
return {'added': sorted(added), 'removed': sorted(removed), 'changed': sorted(changed), 'restart': sorted((added | removed | changed) & set(restart)), 'unchanged': sorted(common - changed)}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('fixture 1', solve({}, {}, []), {'added': [], 'removed': [], 'changed': [], 'restart': [], 'unchanged': []})
check('fixture 2', solve({}, {'a': 1}, ['a']), {'added': ['a'], 'removed': [], 'changed': [], 'restart': ['a'], 'unchanged': []})
check('fixture 3', solve({'a': 1}, {}, ['a']), {'added': [], 'removed': ['a'], 'changed': [], 'restart': ['a'], 'unchanged': []})
check('fixture 4', solve({'a': 1}, {'a': 2}, ['a']), {'added': [], 'removed': [], 'changed': ['a'], 'restart': ['a'], 'unchanged': []})
check('fixture 5', solve({'a': 1}, {'a': 1}, ['a']), {'added': [], 'removed': [], 'changed': [], 'restart': [], 'unchanged': ['a']})
check('fixture 6', solve({'a': 1}, {'a': 2}, []), {'added': [], 'removed': [], 'changed': ['a'], 'restart': [], 'unchanged': []})
check('fixture 7', solve({'a': 1, 'b': 2}, {'a': 1, 'c': 3}, ['b', 'c']), {'added': ['c'], 'removed': ['b'], 'changed': [], 'restart': ['b', 'c'], 'unchanged': ['a']})
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 | {'added': [], 'changed': [], 'removed': [], 'restart': [], 'unchanged': []} | {'added': [], 'changed': [], 'removed': [], 'restart': [], 'unchanged': []} | Passed |
| fixture 2 | {'added': ['a'], 'changed': [], 'removed': ['a'], 'restart': ['a'], 'unchanged': []} | {'added': ['a'], 'changed': [], 'removed': [], 'restart': ['a'], 'unchanged': []} | Failed |
| fixture 3 | {'added': [], 'changed': [], 'removed': [], 'restart': [], 'unchanged': []} | {'added': [], 'changed': [], 'removed': ['a'], 'restart': ['a'], 'unchanged': []} | Failed |
| fixture 4 | {'added': [], 'changed': ['a'], 'removed': [], 'restart': ['a'], 'unchanged': []} | {'added': [], 'changed': ['a'], 'removed': [], 'restart': ['a'], 'unchanged': []} | Passed |
| fixture 5 | {'added': [], 'changed': [], 'removed': [], 'restart': [], 'unchanged': ['a']} | {'added': [], 'changed': [], 'removed': [], 'restart': [], 'unchanged': ['a']} | Passed |
| fixture 6 | {'added': [], 'changed': ['a'], 'removed': [], 'restart': [], 'unchanged': []} | {'added': [], 'changed': ['a'], 'removed': [], 'restart': [], 'unchanged': []} | Passed |
| fixture 7 | {'added': ['c'], 'changed': [], 'removed': ['c'], 'restart': ['c'], 'unchanged': ['a']} | {'added': ['c'], 'changed': [], 'removed': ['b'], 'restart': ['b', 'c'], 'unchanged': ['a']} | Failed |
SHA-256 / 5f93489077efe11adc7d3fdd548a881aa7413da559f27cf291094a2ad31ee012
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(before, after, restart):
added = set(after) - set(before)
removed = set(before) - set(after)
common = set(before) & set(after)
changed = {k for k in common if before[k] != after[k]}
return {'added': sorted(added), 'removed': sorted(removed), 'changed': sorted(changed), 'restart': sorted((added | removed | changed) & set(restart)), 'unchanged': sorted(common - changed)}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('fixture 1', solve({}, {}, []), {'added': [], 'removed': [], 'changed': [], 'restart': [], 'unchanged': []})
check('fixture 2', solve({}, {'a': 1}, ['a']), {'added': ['a'], 'removed': [], 'changed': [], 'restart': ['a'], 'unchanged': []})
check('fixture 3', solve({'a': 1}, {}, ['a']), {'added': [], 'removed': ['a'], 'changed': [], 'restart': ['a'], 'unchanged': []})
check('fixture 4', solve({'a': 1}, {'a': 2}, ['a']), {'added': [], 'removed': [], 'changed': ['a'], 'restart': ['a'], 'unchanged': []})
check('fixture 5', solve({'a': 1}, {'a': 1}, ['a']), {'added': [], 'removed': [], 'changed': [], 'restart': [], 'unchanged': ['a']})
check('fixture 6', solve({'a': 1}, {'a': 2}, []), {'added': [], 'removed': [], 'changed': ['a'], 'restart': [], 'unchanged': []})
check('fixture 7', solve({'a': 1, 'b': 2}, {'a': 1, 'c': 3}, ['b', 'c']), {'added': ['c'], 'removed': ['b'], 'changed': [], 'restart': ['b', 'c'], 'unchanged': ['a']})
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 | {'added': [], 'changed': [], 'removed': [], 'restart': [], 'unchanged': []} | {'added': [], 'changed': [], 'removed': [], 'restart': [], 'unchanged': []} | Passed |
| fixture 2 | {'added': ['a'], 'changed': [], 'removed': [], 'restart': ['a'], 'unchanged': []} | {'added': ['a'], 'changed': [], 'removed': [], 'restart': ['a'], 'unchanged': []} | Passed |
| fixture 3 | {'added': [], 'changed': [], 'removed': ['a'], 'restart': ['a'], 'unchanged': []} | {'added': [], 'changed': [], 'removed': ['a'], 'restart': ['a'], 'unchanged': []} | Passed |
| fixture 4 | {'added': [], 'changed': ['a'], 'removed': [], 'restart': ['a'], 'unchanged': []} | {'added': [], 'changed': ['a'], 'removed': [], 'restart': ['a'], 'unchanged': []} | Passed |
| fixture 5 | {'added': [], 'changed': [], 'removed': [], 'restart': [], 'unchanged': ['a']} | {'added': [], 'changed': [], 'removed': [], 'restart': [], 'unchanged': ['a']} | Passed |
| fixture 6 | {'added': [], 'changed': ['a'], 'removed': [], 'restart': [], 'unchanged': []} | {'added': [], 'changed': ['a'], 'removed': [], 'restart': [], 'unchanged': []} | Passed |
| fixture 7 | {'added': ['c'], 'changed': [], 'removed': ['b'], 'restart': ['b', 'c'], 'unchanged': ['a']} | {'added': ['c'], 'changed': [], 'removed': ['b'], 'restart': ['b', 'c'], 'unchanged': ['a']} | Passed |
SHA-256 / df295066bb3e7a8dc9d53e18bcb2192cd2ecdfd9ed537f332fa104397a20b3dd
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:32.242156+00:00.
Case digest / bdcd3b9713d3ca0b90ab3d5fa45851545461129c91281a372924922a7b15a4f0