FA-74151 / Feature flag rollout bucketing / Open access
Multi-context canonical key: Bare user keys are escaped · case 01
Single-user contexts with ":" in the key no longer match the legacy user key.
ROOT CAUSE
The bare user key is passed through the multi-context escaping.
VERIFIED REPAIR
Return the single user key verbatim.
Unsuccessful approach: Prefixing the kind turns the legacy bare key into a multi-context style key.
Case contract
contexts maps kind -> key. Empty input or any empty key -> None. A context containing only the kind "user" is keyed by the bare user key. Otherwise join, over kinds in sorted order, kind + ":" + escaped key with ":", where escaping replaces "%" by "%25" and then ":" by "%3A".
Why this case matters
Canonical context keys feed bucketing and caches; two spellings of one context split its traffic.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(contexts):
def esc(s):
return s.replace('%', '%25').replace(':', '%3A')
if not contexts or any(k == '' for k in contexts.values()):
return None
if list(contexts) == ['user']:
return esc(contexts['user'])
return ':'.join(kind + ':' + esc(contexts[kind]) for kind in sorted(contexts))
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('percent is escaped before colon', [{'org': 'a:b', 'user': '50%'}], 'org:a%3Ab:user:50%25'),
('already escaped text is escaped again', [{'org': 'x%3Ay', 'user': 'bob'}], 'org:x%253Ay:user:bob'),
('kinds are sorted regardless of insertion', [{'user': 'bob', 'org': 'acme'}], 'org:acme:user:bob'),
('single non-user kind is prefixed', [{'org': 'acme'}], 'org:acme'),
('single user kind stays bare with colon', [{'user': 'a:b'}], 'a:b'),
('context sample 1', [{'device': '50%', 'user': 'z', 'app': 'a:b'}], 'app:a%3Ab:device:50%25:user:z'),
('context sample 2', [{'device': 'acme', 'user': 'z', 'org': 'z'}], 'device:acme:org:z:user:z'),
('context sample 3',
[{'app': 'k:1%', 'user': 'acme', 'device': 'bob'}],
'app:k%3A1%25:device:bob:user:acme')],
[('already escaped text is escaped again', [{'org': 'x%3Ay', 'user': 'bob'}], 'org:x%253Ay:user:bob'),
('kinds are sorted regardless of insertion', [{'user': 'bob', 'org': 'acme'}], 'org:acme:user:bob'),
('single non-user kind is prefixed', [{'org': 'acme'}], 'org:acme'),
('single user kind stays bare with colon', [{'user': 'a:b'}], 'a:b'),
('empty key is invalid', [{'org': 'acme', 'user': ''}], None),
('context sample 6', [{'device': 'bob', 'org': 'a:b'}], 'device:bob:org:a%3Ab'),
('context sample 12', [{'user': 'acme'}], 'acme'),
('context sample 29', [{'user': 'a:b'}], 'a:b')],
[('kinds are sorted regardless of insertion', [{'user': 'bob', 'org': 'acme'}], 'org:acme:user:bob'),
('single non-user kind is prefixed', [{'org': 'acme'}], 'org:acme'),
('single user kind stays bare with colon', [{'user': 'a:b'}], 'a:b'),
('empty key is invalid', [{'org': 'acme', 'user': ''}], None),
('empty mapping is invalid', [{}], None),
('context sample 11', [{'org': 'x%3Ay', 'app': 'a:b', 'device': 'z'}], 'app:a%3Ab:device:z:org:x%253Ay'),
('context sample 18', [{'user': 'x%3Ay'}], 'x%3Ay'),
('context sample 47', [{'user': 'a:b'}], 'a:b')],
[('single non-user kind is prefixed', [{'org': 'acme'}], 'org:acme'),
('single user kind stays bare with colon', [{'user': 'a:b'}], 'a:b'),
('empty key is invalid', [{'org': 'acme', 'user': ''}], None),
('empty mapping is invalid', [{}], None),
('three kinds', [{'device': 'd1', 'app': 'z', 'user': 'bob'}], 'app:z:device:d1:user:bob'),
('context sample 16', [{'org': 'x%3Ay', 'app': 'z'}], 'app:z:org:x%253Ay'),
('context sample 18', [{'user': 'x%3Ay'}], 'x%3Ay'),
('context sample 29', [{'user': 'a:b'}], 'a:b')],
[('percent is escaped before colon', [{'org': 'a:b', 'user': '50%'}], 'org:a%3Ab:user:50%25'),
('single user kind stays bare with colon', [{'user': 'a:b'}], 'a:b'),
('empty key is invalid', [{'org': 'acme', 'user': ''}], None),
('empty mapping is invalid', [{}], None),
('three kinds', [{'device': 'd1', 'app': 'z', 'user': 'bob'}], 'app:z:device:d1:user:bob'),
('context sample 21', [{'org': 'x%3Ay', 'app': 'z'}], 'app:z:org:x%253Ay'),
('context sample 22', [{'org': 'x%3Ay'}], 'org:x%253Ay'),
('context sample 46', [{'user': 'x%3Ay'}], 'x%3Ay')]]
for label, args, expected in fixtures[N - 1]:
check(label, solve(*args), expected)
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 |
|---|---|---|---|
| percent is escaped before colon | org:a%3Ab:user:50%25 | org:a%3Ab:user:50%25 | Passed |
| already escaped text is escaped again | org:x%253Ay:user:bob | org:x%253Ay:user:bob | Passed |
| kinds are sorted regardless of insertion | org:acme:user:bob | org:acme:user:bob | Passed |
| single non-user kind is prefixed | org:acme | org:acme | Passed |
| single user kind stays bare with colon | a%3Ab | a:b | Failed |
| context sample 1 | app:a%3Ab:device:50%25:user:z | app:a%3Ab:device:50%25:user:z | Passed |
| context sample 2 | device:acme:org:z:user:z | device:acme:org:z:user:z | Passed |
| context sample 3 | app:k%3A1%25:device:bob:user:acme | app:k%3A1%25:device:bob:user:acme | Passed |
SHA-256 / db4a48d7b6cdca3d162697b5ae0c12ad6c6f2b3034cfa4e8167761def0b92dc3
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(contexts):
def esc(s):
return s.replace('%', '%25').replace(':', '%3A')
if not contexts or any(k == '' for k in contexts.values()):
return None
if list(contexts) == ['user']:
return 'user:' + contexts['user']
return ':'.join(kind + ':' + esc(contexts[kind]) for kind in sorted(contexts))
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('percent is escaped before colon', [{'org': 'a:b', 'user': '50%'}], 'org:a%3Ab:user:50%25'),
('already escaped text is escaped again', [{'org': 'x%3Ay', 'user': 'bob'}], 'org:x%253Ay:user:bob'),
('kinds are sorted regardless of insertion', [{'user': 'bob', 'org': 'acme'}], 'org:acme:user:bob'),
('single non-user kind is prefixed', [{'org': 'acme'}], 'org:acme'),
('single user kind stays bare with colon', [{'user': 'a:b'}], 'a:b'),
('context sample 1', [{'device': '50%', 'user': 'z', 'app': 'a:b'}], 'app:a%3Ab:device:50%25:user:z'),
('context sample 2', [{'device': 'acme', 'user': 'z', 'org': 'z'}], 'device:acme:org:z:user:z'),
('context sample 3',
[{'app': 'k:1%', 'user': 'acme', 'device': 'bob'}],
'app:k%3A1%25:device:bob:user:acme')],
[('already escaped text is escaped again', [{'org': 'x%3Ay', 'user': 'bob'}], 'org:x%253Ay:user:bob'),
('kinds are sorted regardless of insertion', [{'user': 'bob', 'org': 'acme'}], 'org:acme:user:bob'),
('single non-user kind is prefixed', [{'org': 'acme'}], 'org:acme'),
('single user kind stays bare with colon', [{'user': 'a:b'}], 'a:b'),
('empty key is invalid', [{'org': 'acme', 'user': ''}], None),
('context sample 6', [{'device': 'bob', 'org': 'a:b'}], 'device:bob:org:a%3Ab'),
('context sample 12', [{'user': 'acme'}], 'acme'),
('context sample 29', [{'user': 'a:b'}], 'a:b')],
[('kinds are sorted regardless of insertion', [{'user': 'bob', 'org': 'acme'}], 'org:acme:user:bob'),
('single non-user kind is prefixed', [{'org': 'acme'}], 'org:acme'),
('single user kind stays bare with colon', [{'user': 'a:b'}], 'a:b'),
('empty key is invalid', [{'org': 'acme', 'user': ''}], None),
('empty mapping is invalid', [{}], None),
('context sample 11', [{'org': 'x%3Ay', 'app': 'a:b', 'device': 'z'}], 'app:a%3Ab:device:z:org:x%253Ay'),
('context sample 18', [{'user': 'x%3Ay'}], 'x%3Ay'),
('context sample 47', [{'user': 'a:b'}], 'a:b')],
[('single non-user kind is prefixed', [{'org': 'acme'}], 'org:acme'),
('single user kind stays bare with colon', [{'user': 'a:b'}], 'a:b'),
('empty key is invalid', [{'org': 'acme', 'user': ''}], None),
('empty mapping is invalid', [{}], None),
('three kinds', [{'device': 'd1', 'app': 'z', 'user': 'bob'}], 'app:z:device:d1:user:bob'),
('context sample 16', [{'org': 'x%3Ay', 'app': 'z'}], 'app:z:org:x%253Ay'),
('context sample 18', [{'user': 'x%3Ay'}], 'x%3Ay'),
('context sample 29', [{'user': 'a:b'}], 'a:b')],
[('percent is escaped before colon', [{'org': 'a:b', 'user': '50%'}], 'org:a%3Ab:user:50%25'),
('single user kind stays bare with colon', [{'user': 'a:b'}], 'a:b'),
('empty key is invalid', [{'org': 'acme', 'user': ''}], None),
('empty mapping is invalid', [{}], None),
('three kinds', [{'device': 'd1', 'app': 'z', 'user': 'bob'}], 'app:z:device:d1:user:bob'),
('context sample 21', [{'org': 'x%3Ay', 'app': 'z'}], 'app:z:org:x%253Ay'),
('context sample 22', [{'org': 'x%3Ay'}], 'org:x%253Ay'),
('context sample 46', [{'user': 'x%3Ay'}], 'x%3Ay')]]
for label, args, expected in fixtures[N - 1]:
check(label, solve(*args), expected)
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 |
|---|---|---|---|
| percent is escaped before colon | org:a%3Ab:user:50%25 | org:a%3Ab:user:50%25 | Passed |
| already escaped text is escaped again | org:x%253Ay:user:bob | org:x%253Ay:user:bob | Passed |
| kinds are sorted regardless of insertion | org:acme:user:bob | org:acme:user:bob | Passed |
| single non-user kind is prefixed | org:acme | org:acme | Passed |
| single user kind stays bare with colon | user:a:b | a:b | Failed |
| context sample 1 | app:a%3Ab:device:50%25:user:z | app:a%3Ab:device:50%25:user:z | Passed |
| context sample 2 | device:acme:org:z:user:z | device:acme:org:z:user:z | Passed |
| context sample 3 | app:k%3A1%25:device:bob:user:acme | app:k%3A1%25:device:bob:user:acme | Passed |
SHA-256 / 08e795b8261ec080699d3b6e1f0c44b93a7821de4a1990356dc46f2e38383339
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(contexts):
def esc(s):
return s.replace('%', '%25').replace(':', '%3A')
if not contexts or any(k == '' for k in contexts.values()):
return None
if list(contexts) == ['user']:
return contexts['user']
return ':'.join(kind + ':' + esc(contexts[kind]) for kind in sorted(contexts))
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('percent is escaped before colon', [{'org': 'a:b', 'user': '50%'}], 'org:a%3Ab:user:50%25'),
('already escaped text is escaped again', [{'org': 'x%3Ay', 'user': 'bob'}], 'org:x%253Ay:user:bob'),
('kinds are sorted regardless of insertion', [{'user': 'bob', 'org': 'acme'}], 'org:acme:user:bob'),
('single non-user kind is prefixed', [{'org': 'acme'}], 'org:acme'),
('single user kind stays bare with colon', [{'user': 'a:b'}], 'a:b'),
('context sample 1', [{'device': '50%', 'user': 'z', 'app': 'a:b'}], 'app:a%3Ab:device:50%25:user:z'),
('context sample 2', [{'device': 'acme', 'user': 'z', 'org': 'z'}], 'device:acme:org:z:user:z'),
('context sample 3',
[{'app': 'k:1%', 'user': 'acme', 'device': 'bob'}],
'app:k%3A1%25:device:bob:user:acme')],
[('already escaped text is escaped again', [{'org': 'x%3Ay', 'user': 'bob'}], 'org:x%253Ay:user:bob'),
('kinds are sorted regardless of insertion', [{'user': 'bob', 'org': 'acme'}], 'org:acme:user:bob'),
('single non-user kind is prefixed', [{'org': 'acme'}], 'org:acme'),
('single user kind stays bare with colon', [{'user': 'a:b'}], 'a:b'),
('empty key is invalid', [{'org': 'acme', 'user': ''}], None),
('context sample 6', [{'device': 'bob', 'org': 'a:b'}], 'device:bob:org:a%3Ab'),
('context sample 12', [{'user': 'acme'}], 'acme'),
('context sample 29', [{'user': 'a:b'}], 'a:b')],
[('kinds are sorted regardless of insertion', [{'user': 'bob', 'org': 'acme'}], 'org:acme:user:bob'),
('single non-user kind is prefixed', [{'org': 'acme'}], 'org:acme'),
('single user kind stays bare with colon', [{'user': 'a:b'}], 'a:b'),
('empty key is invalid', [{'org': 'acme', 'user': ''}], None),
('empty mapping is invalid', [{}], None),
('context sample 11', [{'org': 'x%3Ay', 'app': 'a:b', 'device': 'z'}], 'app:a%3Ab:device:z:org:x%253Ay'),
('context sample 18', [{'user': 'x%3Ay'}], 'x%3Ay'),
('context sample 47', [{'user': 'a:b'}], 'a:b')],
[('single non-user kind is prefixed', [{'org': 'acme'}], 'org:acme'),
('single user kind stays bare with colon', [{'user': 'a:b'}], 'a:b'),
('empty key is invalid', [{'org': 'acme', 'user': ''}], None),
('empty mapping is invalid', [{}], None),
('three kinds', [{'device': 'd1', 'app': 'z', 'user': 'bob'}], 'app:z:device:d1:user:bob'),
('context sample 16', [{'org': 'x%3Ay', 'app': 'z'}], 'app:z:org:x%253Ay'),
('context sample 18', [{'user': 'x%3Ay'}], 'x%3Ay'),
('context sample 29', [{'user': 'a:b'}], 'a:b')],
[('percent is escaped before colon', [{'org': 'a:b', 'user': '50%'}], 'org:a%3Ab:user:50%25'),
('single user kind stays bare with colon', [{'user': 'a:b'}], 'a:b'),
('empty key is invalid', [{'org': 'acme', 'user': ''}], None),
('empty mapping is invalid', [{}], None),
('three kinds', [{'device': 'd1', 'app': 'z', 'user': 'bob'}], 'app:z:device:d1:user:bob'),
('context sample 21', [{'org': 'x%3Ay', 'app': 'z'}], 'app:z:org:x%253Ay'),
('context sample 22', [{'org': 'x%3Ay'}], 'org:x%253Ay'),
('context sample 46', [{'user': 'x%3Ay'}], 'x%3Ay')]]
for label, args, expected in fixtures[N - 1]:
check(label, solve(*args), expected)
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 |
|---|---|---|---|
| percent is escaped before colon | org:a%3Ab:user:50%25 | org:a%3Ab:user:50%25 | Passed |
| already escaped text is escaped again | org:x%253Ay:user:bob | org:x%253Ay:user:bob | Passed |
| kinds are sorted regardless of insertion | org:acme:user:bob | org:acme:user:bob | Passed |
| single non-user kind is prefixed | org:acme | org:acme | Passed |
| single user kind stays bare with colon | a:b | a:b | Passed |
| context sample 1 | app:a%3Ab:device:50%25:user:z | app:a%3Ab:device:50%25:user:z | Passed |
| context sample 2 | device:acme:org:z:user:z | device:acme:org:z:user:z | Passed |
| context sample 3 | app:k%3A1%25:device:bob:user:acme | app:k%3A1%25:device:bob:user:acme | Passed |
SHA-256 / e915cd8cbb1e96aa9d43e2fa215faf91ddf29e636de6b1d13f50a37d2586a8b4
Verification & scope
A deterministic toy flag-evaluation model with a stipulated contract; it does not reproduce any vendor SDK byte for byte. 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:48:53.953807+00:00.
Case digest / 3e640b94dce205f0650dde08762a89f96a96c74e3810bca576a53254df4cfa8d