{"abstract":"Apply redirect interception to the current hop before validating and dispatching the selected target: the follow action only branch emits an incorrect decision.","category":"HTTP redirects","checks":6,"contract":"Apply redirect interception to the current hop before validating and dispatching the selected target. The explicit fixture inputs and outputs define a bounded offline policy; request identity must accompany the decision.","evaluation_group":"s3-http-redirects-interception-contract","failed_approach":"The partial repair uses \"action in ('follow','manual')\" and still fails an explicit boundary or control.","family":"s3-http-redirects-interception-contract-follow-action-only","id":"FA-28201","implementations":{"attempt":{"sha256":"e1d394ea8a899f2914b3c8dc2a494afd964b788b725957c83d10077f33d3fc7c","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nfrom urllib.parse import urlsplit, unquote, quote\nimport posixpath\nimport re\nN = 1\nobservations = []\ndef solve(request, original, current, location, override, action, status, callback_status, headers, synthetic, cached):\n    return {'request': request, 'decision': [location if override is None else override, status, action in ('follow','manual'), current, headers, action == 'follow' and not synthetic, action != 'error', True, urlsplit(location if override is None else override).scheme in ('','http','https'), callback_status if synthetic else None]} \ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncheck('fixture 1', solve('/requests/' + str(N) + '/0', 'https://a/x', 'https://b/y', '/next', 'https://c/z', 'follow', 302, 200, [['X', '1'], ['X', '2']], False, False), {'request': '/requests/' + str(N) + '/0', 'decision': ['https://c/z', 302, True, 'https://b/y', [['X', '1'], ['X', '2']], True, True, True, True, None]})\ncheck('fixture 2', solve('/requests/' + str(N) + '/1', 'https://a/x', 'https://a/x', '/next', None, 'manual', 307, None, [], False, True), {'request': '/requests/' + str(N) + '/1', 'decision': ['/next', 307, False, 'https://a/x', [], False, True, True, True, None]})\ncheck('fixture 3', solve('/requests/' + str(N) + '/2', 'https://a/x', 'https://b/y', '/next', '', 'follow', 303, 204, [['Y', 'v']], True, True), {'request': '/requests/' + str(N) + '/2', 'decision': ['', 303, True, 'https://b/y', [['Y', 'v']], False, True, True, True, 204]})\ncheck('fixture 4', solve('/requests/' + str(N) + '/3', 'https://a/x', 'https://b/y', 'https://safe/x', 'file:/local', 'cancel', 301, 201, [], False, False), {'request': '/requests/' + str(N) + '/3', 'decision': ['file:/local', 301, False, 'https://b/y', [], False, True, True, False, None]})\ncheck('fixture 5', solve('/requests/' + str(N) + '/4', 'https://a/x', 'https://b/y', '/next', None, 'error', 308, None, [['X', '1']], False, True), {'request': '/requests/' + str(N) + '/4', 'decision': ['/next', 308, False, 'https://b/y', [['X', '1']], False, False, True, True, None]})\ncheck('fixture 6', solve('/requests/' + str(N) + '/5', 'https://a/x', 'https://b/y', '/next', '/custom', 'manual', 302, 202, [['Z', '1']], True, False), {'request': '/requests/' + str(N) + '/5', 'decision': ['/custom', 302, False, 'https://b/y', [['Z', '1']], False, True, True, True, 202]})\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"d0174e64173245a89664a2c8bdf61e764c1b3c05f0dbe33b18cc390853e94a5d","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nfrom urllib.parse import urlsplit, unquote, quote\nimport posixpath\nimport re\nN = 1\nobservations = []\ndef solve(request, original, current, location, override, action, status, callback_status, headers, synthetic, cached):\n    return {'request': request, 'decision': [location if override is None else override, status, action != 'cancel', current, headers, action == 'follow' and not synthetic, action != 'error', True, urlsplit(location if override is None else override).scheme in ('','http','https'), callback_status if synthetic else None]} \ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncheck('fixture 1', solve('/requests/' + str(N) + '/0', 'https://a/x', 'https://b/y', '/next', 'https://c/z', 'follow', 302, 200, [['X', '1'], ['X', '2']], False, False), {'request': '/requests/' + str(N) + '/0', 'decision': ['https://c/z', 302, True, 'https://b/y', [['X', '1'], ['X', '2']], True, True, True, True, None]})\ncheck('fixture 2', solve('/requests/' + str(N) + '/1', 'https://a/x', 'https://a/x', '/next', None, 'manual', 307, None, [], False, True), {'request': '/requests/' + str(N) + '/1', 'decision': ['/next', 307, False, 'https://a/x', [], False, True, True, True, None]})\ncheck('fixture 3', solve('/requests/' + str(N) + '/2', 'https://a/x', 'https://b/y', '/next', '', 'follow', 303, 204, [['Y', 'v']], True, True), {'request': '/requests/' + str(N) + '/2', 'decision': ['', 303, True, 'https://b/y', [['Y', 'v']], False, True, True, True, 204]})\ncheck('fixture 4', solve('/requests/' + str(N) + '/3', 'https://a/x', 'https://b/y', 'https://safe/x', 'file:/local', 'cancel', 301, 201, [], False, False), {'request': '/requests/' + str(N) + '/3', 'decision': ['file:/local', 301, False, 'https://b/y', [], False, True, True, False, None]})\ncheck('fixture 5', solve('/requests/' + str(N) + '/4', 'https://a/x', 'https://b/y', '/next', None, 'error', 308, None, [['X', '1']], False, True), {'request': '/requests/' + str(N) + '/4', 'decision': ['/next', 308, False, 'https://b/y', [['X', '1']], False, False, True, True, None]})\ncheck('fixture 6', solve('/requests/' + str(N) + '/5', 'https://a/x', 'https://b/y', '/next', '/custom', 'manual', 302, 202, [['Z', '1']], True, False), {'request': '/requests/' + str(N) + '/5', 'decision': ['/custom', 302, False, 'https://b/y', [['Z', '1']], False, True, True, True, 202]})\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"fixed":{"sha256":"e440e8dbb735e7c049eaa911949b23b67adda4efc9eacfdd4e61174256f30769","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nfrom urllib.parse import urlsplit, unquote, quote\nimport posixpath\nimport re\nN = 1\nobservations = []\ndef solve(request, original, current, location, override, action, status, callback_status, headers, synthetic, cached):\n    return {'request': request, 'decision': [location if override is None else override, status, action == 'follow', current, headers, action == 'follow' and not synthetic, action != 'error', True, urlsplit(location if override is None else override).scheme in ('','http','https'), callback_status if synthetic else None]} \ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncheck('fixture 1', solve('/requests/' + str(N) + '/0', 'https://a/x', 'https://b/y', '/next', 'https://c/z', 'follow', 302, 200, [['X', '1'], ['X', '2']], False, False), {'request': '/requests/' + str(N) + '/0', 'decision': ['https://c/z', 302, True, 'https://b/y', [['X', '1'], ['X', '2']], True, True, True, True, None]})\ncheck('fixture 2', solve('/requests/' + str(N) + '/1', 'https://a/x', 'https://a/x', '/next', None, 'manual', 307, None, [], False, True), {'request': '/requests/' + str(N) + '/1', 'decision': ['/next', 307, False, 'https://a/x', [], False, True, True, True, None]})\ncheck('fixture 3', solve('/requests/' + str(N) + '/2', 'https://a/x', 'https://b/y', '/next', '', 'follow', 303, 204, [['Y', 'v']], True, True), {'request': '/requests/' + str(N) + '/2', 'decision': ['', 303, True, 'https://b/y', [['Y', 'v']], False, True, True, True, 204]})\ncheck('fixture 4', solve('/requests/' + str(N) + '/3', 'https://a/x', 'https://b/y', 'https://safe/x', 'file:/local', 'cancel', 301, 201, [], False, False), {'request': '/requests/' + str(N) + '/3', 'decision': ['file:/local', 301, False, 'https://b/y', [], False, True, True, False, None]})\ncheck('fixture 5', solve('/requests/' + str(N) + '/4', 'https://a/x', 'https://b/y', '/next', None, 'error', 308, None, [['X', '1']], False, True), {'request': '/requests/' + str(N) + '/4', 'decision': ['/next', 308, False, 'https://b/y', [['X', '1']], False, False, True, True, None]})\ncheck('fixture 6', solve('/requests/' + str(N) + '/5', 'https://a/x', 'https://b/y', '/next', '/custom', 'manual', 302, 202, [['Z', '1']], True, False), {'request': '/requests/' + str(N) + '/5', 'decision': ['/custom', 302, False, 'https://b/y', [['Z', '1']], False, True, True, True, 202]})\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"Stipulated offline redirect policy, not a complete HTTP, browser, URL, cache, or security implementation. Numbered variants vary request correlation identity. 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.","method":"Deterministic executable model with adversarial boundary fixtures.","provenance":{"created_by":"Failure Map","dependencies":"Python standard library","family":"s3-http-redirects-interception-contract-follow-action-only","generated_at":"2026-09-29T14:41:31.911599+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Models a redirect controller decision before following a target or exposing a redirect result.","repair":"At this decision use \"action == 'follow'\", preserving the other controller outputs.","root_cause":"The follow-action-only decision uses \"action != 'cancel'\"; this violates the stipulated controller policy.","sha256":"5ca8642e21f0027c871f82dac4ac4caf7fec093bfd1f6392ddde2226a7fdf0d4","title":"Apply redirect interception to the current hop before validating and dispatching the selected target: follow action only · case 01","variant":1,"variant_policy":"N changes request correlation identity. Policy boundary fixtures are reused; numbered variants are not independent examples.","verification":{"attempt":{"elapsed_ms":39.141,"exit_code":1,"observations":[{"actual":{"decision":["https://c/z",302,true,"https://b/y",[["X","1"],["X","2"]],true,true,true,true,null],"request":"/requests/1/0"},"check":"fixture 1","expected":{"decision":["https://c/z",302,true,"https://b/y",[["X","1"],["X","2"]],true,true,true,true,null],"request":"/requests/1/0"},"passed":true},{"actual":{"decision":["/next",307,true,"https://a/x",[],false,true,true,true,null],"request":"/requests/1/1"},"check":"fixture 2","expected":{"decision":["/next",307,false,"https://a/x",[],false,true,true,true,null],"request":"/requests/1/1"},"passed":false},{"actual":{"decision":["",303,true,"https://b/y",[["Y","v"]],false,true,true,true,204],"request":"/requests/1/2"},"check":"fixture 3","expected":{"decision":["",303,true,"https://b/y",[["Y","v"]],false,true,true,true,204],"request":"/requests/1/2"},"passed":true},{"actual":{"decision":["file:/local",301,false,"https://b/y",[],false,true,true,false,null],"request":"/requests/1/3"},"check":"fixture 4","expected":{"decision":["file:/local",301,false,"https://b/y",[],false,true,true,false,null],"request":"/requests/1/3"},"passed":true},{"actual":{"decision":["/next",308,false,"https://b/y",[["X","1"]],false,false,true,true,null],"request":"/requests/1/4"},"check":"fixture 5","expected":{"decision":["/next",308,false,"https://b/y",[["X","1"]],false,false,true,true,null],"request":"/requests/1/4"},"passed":true},{"actual":{"decision":["/custom",302,true,"https://b/y",[["Z","1"]],false,true,true,true,202],"request":"/requests/1/5"},"check":"fixture 6","expected":{"decision":["/custom",302,false,"https://b/y",[["Z","1"]],false,true,true,true,202],"request":"/requests/1/5"},"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"fixture 1\", \"actual\": {\"request\": \"/requests/1/0\", \"decision\": [\"https://c/z\", 302, true, \"https://b/y\", [[\"X\", \"1\"], [\"X\", \"2\"]], true, true, true, true, null]}, \"expected\": {\"request\": \"/requests/1/0\", \"decision\": [\"https://c/z\", 302, true, \"https://b/y\", [[\"X\", \"1\"], [\"X\", \"2\"]], true, true, true, true, null]}, \"passed\": true}, {\"check\": \"fixture 2\", \"actual\": {\"request\": \"/requests/1/1\", \"decision\": [\"/next\", 307, true, \"https://a/x\", [], false, true, true, true, null]}, \"expected\": {\"request\": \"/requests/1/1\", \"decision\": [\"/next\", 307, false, \"https://a/x\", [], false, true, true, true, null]}, \"passed\": false}, {\"check\": \"fixture 3\", \"actual\": {\"request\": \"/requests/1/2\", \"decision\": [\"\", 303, true, \"https://b/y\", [[\"Y\", \"v\"]], false, true, true, true, 204]}, \"expected\": {\"request\": \"/requests/1/2\", \"decision\": [\"\", 303, true, \"https://b/y\", [[\"Y\", \"v\"]], false, true, true, true, 204]}, \"passed\": true}, {\"check\": \"fixture 4\", \"actual\": {\"request\": \"/requests/1/3\", \"decision\": [\"file:/local\", 301, false, \"https://b/y\", [], false, true, true, false, null]}, \"expected\": {\"request\": \"/requests/1/3\", \"decision\": [\"file:/local\", 301, false, \"https://b/y\", [], false, true, true, false, null]}, \"passed\": true}, {\"check\": \"fixture 5\", \"actual\": {\"request\": \"/requests/1/4\", \"decision\": [\"/next\", 308, false, \"https://b/y\", [[\"X\", \"1\"]], false, false, true, true, null]}, \"expected\": {\"request\": \"/requests/1/4\", \"decision\": [\"/next\", 308, false, \"https://b/y\", [[\"X\", \"1\"]], false, false, true, true, null]}, \"passed\": true}, {\"check\": \"fixture 6\", \"actual\": {\"request\": \"/requests/1/5\", \"decision\": [\"/custom\", 302, true, \"https://b/y\", [[\"Z\", \"1\"]], false, true, true, true, 202]}, \"expected\": {\"request\": \"/requests/1/5\", \"decision\": [\"/custom\", 302, false, \"https://b/y\", [[\"Z\", \"1\"]], false, true, true, true, 202]}, \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":39.053,"exit_code":1,"observations":[{"actual":{"decision":["https://c/z",302,true,"https://b/y",[["X","1"],["X","2"]],true,true,true,true,null],"request":"/requests/1/0"},"check":"fixture 1","expected":{"decision":["https://c/z",302,true,"https://b/y",[["X","1"],["X","2"]],true,true,true,true,null],"request":"/requests/1/0"},"passed":true},{"actual":{"decision":["/next",307,true,"https://a/x",[],false,true,true,true,null],"request":"/requests/1/1"},"check":"fixture 2","expected":{"decision":["/next",307,false,"https://a/x",[],false,true,true,true,null],"request":"/requests/1/1"},"passed":false},{"actual":{"decision":["",303,true,"https://b/y",[["Y","v"]],false,true,true,true,204],"request":"/requests/1/2"},"check":"fixture 3","expected":{"decision":["",303,true,"https://b/y",[["Y","v"]],false,true,true,true,204],"request":"/requests/1/2"},"passed":true},{"actual":{"decision":["file:/local",301,false,"https://b/y",[],false,true,true,false,null],"request":"/requests/1/3"},"check":"fixture 4","expected":{"decision":["file:/local",301,false,"https://b/y",[],false,true,true,false,null],"request":"/requests/1/3"},"passed":true},{"actual":{"decision":["/next",308,true,"https://b/y",[["X","1"]],false,false,true,true,null],"request":"/requests/1/4"},"check":"fixture 5","expected":{"decision":["/next",308,false,"https://b/y",[["X","1"]],false,false,true,true,null],"request":"/requests/1/4"},"passed":false},{"actual":{"decision":["/custom",302,true,"https://b/y",[["Z","1"]],false,true,true,true,202],"request":"/requests/1/5"},"check":"fixture 6","expected":{"decision":["/custom",302,false,"https://b/y",[["Z","1"]],false,true,true,true,202],"request":"/requests/1/5"},"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"fixture 1\", \"actual\": {\"request\": \"/requests/1/0\", \"decision\": [\"https://c/z\", 302, true, \"https://b/y\", [[\"X\", \"1\"], [\"X\", \"2\"]], true, true, true, true, null]}, \"expected\": {\"request\": \"/requests/1/0\", \"decision\": [\"https://c/z\", 302, true, \"https://b/y\", [[\"X\", \"1\"], [\"X\", \"2\"]], true, true, true, true, null]}, \"passed\": true}, {\"check\": \"fixture 2\", \"actual\": {\"request\": \"/requests/1/1\", \"decision\": [\"/next\", 307, true, \"https://a/x\", [], false, true, true, true, null]}, \"expected\": {\"request\": \"/requests/1/1\", \"decision\": [\"/next\", 307, false, \"https://a/x\", [], false, true, true, true, null]}, \"passed\": false}, {\"check\": \"fixture 3\", \"actual\": {\"request\": \"/requests/1/2\", \"decision\": [\"\", 303, true, \"https://b/y\", [[\"Y\", \"v\"]], false, true, true, true, 204]}, \"expected\": {\"request\": \"/requests/1/2\", \"decision\": [\"\", 303, true, \"https://b/y\", [[\"Y\", \"v\"]], false, true, true, true, 204]}, \"passed\": true}, {\"check\": \"fixture 4\", \"actual\": {\"request\": \"/requests/1/3\", \"decision\": [\"file:/local\", 301, false, \"https://b/y\", [], false, true, true, false, null]}, \"expected\": {\"request\": \"/requests/1/3\", \"decision\": [\"file:/local\", 301, false, \"https://b/y\", [], false, true, true, false, null]}, \"passed\": true}, {\"check\": \"fixture 5\", \"actual\": {\"request\": \"/requests/1/4\", \"decision\": [\"/next\", 308, true, \"https://b/y\", [[\"X\", \"1\"]], false, false, true, true, null]}, \"expected\": {\"request\": \"/requests/1/4\", \"decision\": [\"/next\", 308, false, \"https://b/y\", [[\"X\", \"1\"]], false, false, true, true, null]}, \"passed\": false}, {\"check\": \"fixture 6\", \"actual\": {\"request\": \"/requests/1/5\", \"decision\": [\"/custom\", 302, true, \"https://b/y\", [[\"Z\", \"1\"]], false, true, true, true, 202]}, \"expected\": {\"request\": \"/requests/1/5\", \"decision\": [\"/custom\", 302, false, \"https://b/y\", [[\"Z\", \"1\"]], false, true, true, true, 202]}, \"passed\": false}], \"passed\": false}\n"},"fixed":{"elapsed_ms":38.02,"exit_code":0,"observations":[{"actual":{"decision":["https://c/z",302,true,"https://b/y",[["X","1"],["X","2"]],true,true,true,true,null],"request":"/requests/1/0"},"check":"fixture 1","expected":{"decision":["https://c/z",302,true,"https://b/y",[["X","1"],["X","2"]],true,true,true,true,null],"request":"/requests/1/0"},"passed":true},{"actual":{"decision":["/next",307,false,"https://a/x",[],false,true,true,true,null],"request":"/requests/1/1"},"check":"fixture 2","expected":{"decision":["/next",307,false,"https://a/x",[],false,true,true,true,null],"request":"/requests/1/1"},"passed":true},{"actual":{"decision":["",303,true,"https://b/y",[["Y","v"]],false,true,true,true,204],"request":"/requests/1/2"},"check":"fixture 3","expected":{"decision":["",303,true,"https://b/y",[["Y","v"]],false,true,true,true,204],"request":"/requests/1/2"},"passed":true},{"actual":{"decision":["file:/local",301,false,"https://b/y",[],false,true,true,false,null],"request":"/requests/1/3"},"check":"fixture 4","expected":{"decision":["file:/local",301,false,"https://b/y",[],false,true,true,false,null],"request":"/requests/1/3"},"passed":true},{"actual":{"decision":["/next",308,false,"https://b/y",[["X","1"]],false,false,true,true,null],"request":"/requests/1/4"},"check":"fixture 5","expected":{"decision":["/next",308,false,"https://b/y",[["X","1"]],false,false,true,true,null],"request":"/requests/1/4"},"passed":true},{"actual":{"decision":["/custom",302,false,"https://b/y",[["Z","1"]],false,true,true,true,202],"request":"/requests/1/5"},"check":"fixture 6","expected":{"decision":["/custom",302,false,"https://b/y",[["Z","1"]],false,true,true,true,202],"request":"/requests/1/5"},"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"fixture 1\", \"actual\": {\"request\": \"/requests/1/0\", \"decision\": [\"https://c/z\", 302, true, \"https://b/y\", [[\"X\", \"1\"], [\"X\", \"2\"]], true, true, true, true, null]}, \"expected\": {\"request\": \"/requests/1/0\", \"decision\": [\"https://c/z\", 302, true, \"https://b/y\", [[\"X\", \"1\"], [\"X\", \"2\"]], true, true, true, true, null]}, \"passed\": true}, {\"check\": \"fixture 2\", \"actual\": {\"request\": \"/requests/1/1\", \"decision\": [\"/next\", 307, false, \"https://a/x\", [], false, true, true, true, null]}, \"expected\": {\"request\": \"/requests/1/1\", \"decision\": [\"/next\", 307, false, \"https://a/x\", [], false, true, true, true, null]}, \"passed\": true}, {\"check\": \"fixture 3\", \"actual\": {\"request\": \"/requests/1/2\", \"decision\": [\"\", 303, true, \"https://b/y\", [[\"Y\", \"v\"]], false, true, true, true, 204]}, \"expected\": {\"request\": \"/requests/1/2\", \"decision\": [\"\", 303, true, \"https://b/y\", [[\"Y\", \"v\"]], false, true, true, true, 204]}, \"passed\": true}, {\"check\": \"fixture 4\", \"actual\": {\"request\": \"/requests/1/3\", \"decision\": [\"file:/local\", 301, false, \"https://b/y\", [], false, true, true, false, null]}, \"expected\": {\"request\": \"/requests/1/3\", \"decision\": [\"file:/local\", 301, false, \"https://b/y\", [], false, true, true, false, null]}, \"passed\": true}, {\"check\": \"fixture 5\", \"actual\": {\"request\": \"/requests/1/4\", \"decision\": [\"/next\", 308, false, \"https://b/y\", [[\"X\", \"1\"]], false, false, true, true, null]}, \"expected\": {\"request\": \"/requests/1/4\", \"decision\": [\"/next\", 308, false, \"https://b/y\", [[\"X\", \"1\"]], false, false, true, true, null]}, \"passed\": true}, {\"check\": \"fixture 6\", \"actual\": {\"request\": \"/requests/1/5\", \"decision\": [\"/custom\", 302, false, \"https://b/y\", [[\"Z\", \"1\"]], false, true, true, true, 202]}, \"expected\": {\"request\": \"/requests/1/5\", \"decision\": [\"/custom\", 302, false, \"https://b/y\", [[\"Z\", \"1\"]], false, true, true, true, 202]}, \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}