)]}'
{"mistral/engine/engine_server.py":[{"author":{"_account_id":21970,"name":"Andras Kovi","email":"akovi@nokia.com","username":"andras.kovi"},"change_message_id":"914210863a4241cdf8fdada492c5021e8e36533f","unresolved":false,"context_lines":[{"line_number":98,"context_line":"            description,"},{"line_number":99,"context_line":"            params"},{"line_number":100,"context_line":"        )"},{"line_number":101,"context_line":"        from mistral import context"},{"line_number":102,"context_line":"        if isinstance(rpc_ctx, dict):"},{"line_number":103,"context_line":"            context.set_ctx(context.MistralContext(**rpc_ctx))"},{"line_number":104,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":3,"id":"df3967d1_c9a4e3a8","line":101,"range":{"start_line":101,"start_character":7,"end_line":101,"end_character":35},"updated":"2017-08-03 09:17:08.000000000","message":"imports should probably be declared at the top of the file","commit_id":"a09a4e9391452aeedf64d76c991ef9a46f36cda4"},{"author":{"_account_id":7700,"name":"Nikolay Mahotkin","email":"nikolay.makhotkin@gmail.com","username":"nmakhotkin"},"change_message_id":"277e03e9d1e2edb11035fc44be7c599091073577","unresolved":false,"context_lines":[{"line_number":98,"context_line":"            description,"},{"line_number":99,"context_line":"            params"},{"line_number":100,"context_line":"        )"},{"line_number":101,"context_line":"        from mistral import context"},{"line_number":102,"context_line":"        if isinstance(rpc_ctx, dict):"},{"line_number":103,"context_line":"            context.set_ctx(context.MistralContext(**rpc_ctx))"},{"line_number":104,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":3,"id":"df3967d1_b8a9ea24","line":101,"range":{"start_line":101,"start_character":7,"end_line":101,"end_character":35},"in_reply_to":"df3967d1_c9a4e3a8","updated":"2017-08-03 09:59:52.000000000","message":"Sorry, it is debug.","commit_id":"a09a4e9391452aeedf64d76c991ef9a46f36cda4"}],"mistral/engine/workflows.py":[{"author":{"_account_id":8731,"name":"Renat Akhmerov","email":"renat.akhmerov@gmail.com","username":"rakhmerov"},"change_message_id":"6215bfb5f2a849b131924571b2ed12324fde8ef0","unresolved":false,"context_lines":[{"line_number":296,"context_line":"            # lookup cache anymore."},{"line_number":297,"context_line":"            lookup_utils.invalidate_cached_task_executions(self.wf_ex.id)"},{"line_number":298,"context_line":""},{"line_number":299,"context_line":"            if (not self.wf_ex.task_execution_id"},{"line_number":300,"context_line":"                    and need_delete_trust(self.wf_ex)):"},{"line_number":301,"context_line":"                security.try_delete_trust()"},{"line_number":302,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"df3967d1_200002ab","line":299,"range":{"start_line":299,"start_character":16,"end_line":299,"end_character":48},"updated":"2017-08-04 05:02:37.000000000","message":"This part of condition should be in \"need_delete_trust\".","commit_id":"020deab421ceaa0d035dcf7b8150c873dcbceb5b"},{"author":{"_account_id":8731,"name":"Renat Akhmerov","email":"renat.akhmerov@gmail.com","username":"rakhmerov"},"change_message_id":"6215bfb5f2a849b131924571b2ed12324fde8ef0","unresolved":false,"context_lines":[{"line_number":526,"context_line":"    return msg"},{"line_number":527,"context_line":""},{"line_number":528,"context_line":""},{"line_number":529,"context_line":"def need_delete_trust(wf_ex):"},{"line_number":530,"context_line":"    try:"},{"line_number":531,"context_line":"        description \u003d json.loads(wf_ex.description)"},{"line_number":532,"context_line":"    except ValueError as e:"}],"source_content_type":"text/x-python","patch_set":6,"id":"df3967d1_00c4de5d","line":529,"range":{"start_line":529,"start_character":4,"end_line":529,"end_character":21},"updated":"2017-08-04 05:02:37.000000000","message":"I don\u0027t quite like the name of the method and the fact that it\u0027s in this module because trusts, tokens etc. are security concerns and should be handled separately. These modules under \"engine\" are focused on execution mechanics.\n\nMy suggestion is to create the hook method security.on_workflow_complete(wf_ex)  and simply call it on the line 299. The rest will be hidden in \"security\" module including the checks if the trust should be deleted etc. Otherwise, even this module\u0027s awareness of the workflow execution description format seems like a leaking abstraction.","commit_id":"020deab421ceaa0d035dcf7b8150c873dcbceb5b"},{"author":{"_account_id":7700,"name":"Nikolay Mahotkin","email":"nikolay.makhotkin@gmail.com","username":"nmakhotkin"},"change_message_id":"eed64ce350adf5c1164f3500867df9b5bed2796c","unresolved":false,"context_lines":[{"line_number":526,"context_line":"    return msg"},{"line_number":527,"context_line":""},{"line_number":528,"context_line":""},{"line_number":529,"context_line":"def need_delete_trust(wf_ex):"},{"line_number":530,"context_line":"    try:"},{"line_number":531,"context_line":"        description \u003d json.loads(wf_ex.description)"},{"line_number":532,"context_line":"    except ValueError as e:"}],"source_content_type":"text/x-python","patch_set":6,"id":"df3967d1_4ddc5ae3","line":529,"range":{"start_line":529,"start_character":4,"end_line":529,"end_character":21},"in_reply_to":"df3967d1_00c4de5d","updated":"2017-08-04 08:27:17.000000000","message":"ok, agree","commit_id":"020deab421ceaa0d035dcf7b8150c873dcbceb5b"},{"author":{"_account_id":8731,"name":"Renat Akhmerov","email":"renat.akhmerov@gmail.com","username":"rakhmerov"},"change_message_id":"6215bfb5f2a849b131924571b2ed12324fde8ef0","unresolved":false,"context_lines":[{"line_number":536,"context_line":"    if not isinstance(description, dict):"},{"line_number":537,"context_line":"        return"},{"line_number":538,"context_line":""},{"line_number":539,"context_line":"    triggered \u003d description.get(\u0027triggered_by\u0027)"},{"line_number":540,"context_line":"    if not triggered:"},{"line_number":541,"context_line":"        return"},{"line_number":542,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"df3967d1_20c7e266","line":539,"updated":"2017-08-04 05:02:37.000000000","message":"Soft: put a blank line after 539.","commit_id":"020deab421ceaa0d035dcf7b8150c873dcbceb5b"},{"author":{"_account_id":8731,"name":"Renat Akhmerov","email":"renat.akhmerov@gmail.com","username":"rakhmerov"},"change_message_id":"6215bfb5f2a849b131924571b2ed12324fde8ef0","unresolved":false,"context_lines":[{"line_number":544,"context_line":"        if not db_api.load_cron_trigger(triggered[\u0027name\u0027]):"},{"line_number":545,"context_line":"            return True"},{"line_number":546,"context_line":"    elif triggered[\u0027type\u0027] \u003d\u003d \u0027event_trigger\u0027:"},{"line_number":547,"context_line":""},{"line_number":548,"context_line":"        try:"},{"line_number":549,"context_line":"            db_api.get_event_trigger(triggered[\u0027id\u0027], True)"},{"line_number":550,"context_line":"        except exc.DBEntityNotFoundError:"}],"source_content_type":"text/x-python","patch_set":6,"id":"df3967d1_65617c05","line":547,"updated":"2017-08-04 05:02:37.000000000","message":"Soft: redundant empty line","commit_id":"020deab421ceaa0d035dcf7b8150c873dcbceb5b"},{"author":{"_account_id":8731,"name":"Renat Akhmerov","email":"renat.akhmerov@gmail.com","username":"rakhmerov"},"change_message_id":"6215bfb5f2a849b131924571b2ed12324fde8ef0","unresolved":false,"context_lines":[{"line_number":546,"context_line":"    elif triggered[\u0027type\u0027] \u003d\u003d \u0027event_trigger\u0027:"},{"line_number":547,"context_line":""},{"line_number":548,"context_line":"        try:"},{"line_number":549,"context_line":"            db_api.get_event_trigger(triggered[\u0027id\u0027], True)"},{"line_number":550,"context_line":"        except exc.DBEntityNotFoundError:"},{"line_number":551,"context_line":"            return True"},{"line_number":552,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"df3967d1_a53884ed","line":549,"range":{"start_line":549,"start_character":19,"end_line":549,"end_character":36},"updated":"2017-08-04 05:02:37.000000000","message":"We need to create the method load_event_trigger() as for other entities instead of catching exception.","commit_id":"020deab421ceaa0d035dcf7b8150c873dcbceb5b"},{"author":{"_account_id":7700,"name":"Nikolay Mahotkin","email":"nikolay.makhotkin@gmail.com","username":"nmakhotkin"},"change_message_id":"eed64ce350adf5c1164f3500867df9b5bed2796c","unresolved":false,"context_lines":[{"line_number":546,"context_line":"    elif triggered[\u0027type\u0027] \u003d\u003d \u0027event_trigger\u0027:"},{"line_number":547,"context_line":""},{"line_number":548,"context_line":"        try:"},{"line_number":549,"context_line":"            db_api.get_event_trigger(triggered[\u0027id\u0027], True)"},{"line_number":550,"context_line":"        except exc.DBEntityNotFoundError:"},{"line_number":551,"context_line":"            return True"},{"line_number":552,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"df3967d1_2d0c763f","line":549,"range":{"start_line":549,"start_character":19,"end_line":549,"end_character":36},"in_reply_to":"df3967d1_a53884ed","updated":"2017-08-04 08:27:17.000000000","message":"Done","commit_id":"020deab421ceaa0d035dcf7b8150c873dcbceb5b"}],"mistral/services/periodic.py":[{"author":{"_account_id":21970,"name":"Andras Kovi","email":"akovi@nokia.com","username":"andras.kovi"},"change_message_id":"914210863a4241cdf8fdada492c5021e8e36533f","unresolved":false,"context_lines":[{"line_number":75,"context_line":"                    rpc.get_engine_client().start_workflow("},{"line_number":76,"context_line":"                        trigger.workflow.name,"},{"line_number":77,"context_line":"                        trigger.workflow_input,"},{"line_number":78,"context_line":"                        description\u003djson.dumps(description),"},{"line_number":79,"context_line":"                        **trigger.workflow_params"},{"line_number":80,"context_line":"                    )"},{"line_number":81,"context_line":"            except Exception:"}],"source_content_type":"text/x-python","patch_set":3,"id":"df3967d1_4965931d","line":78,"range":{"start_line":78,"start_character":24,"end_line":78,"end_character":59},"updated":"2017-08-03 09:17:08.000000000","message":"I fear changing the description from string to dict may mess up visualizations.","commit_id":"a09a4e9391452aeedf64d76c991ef9a46f36cda4"},{"author":{"_account_id":8731,"name":"Renat Akhmerov","email":"renat.akhmerov@gmail.com","username":"rakhmerov"},"change_message_id":"6215bfb5f2a849b131924571b2ed12324fde8ef0","unresolved":false,"context_lines":[{"line_number":102,"context_line":"            modified_count \u003d triggers.delete_cron_trigger("},{"line_number":103,"context_line":"                t.name,"},{"line_number":104,"context_line":"                trust_id\u003dt.trust_id,"},{"line_number":105,"context_line":"                need_delete_trust\u003dFalse"},{"line_number":106,"context_line":"            )"},{"line_number":107,"context_line":"        else:  # if remaining execution \u003d None or \u003e 0."},{"line_number":108,"context_line":"            next_time \u003d triggers.get_next_execution_time("}],"source_content_type":"text/x-python","patch_set":6,"id":"df3967d1_0045fe42","line":105,"range":{"start_line":105,"start_character":16,"end_line":105,"end_character":33},"updated":"2017-08-04 05:02:37.000000000","message":"I think we can call it just \"delete_trust\".","commit_id":"020deab421ceaa0d035dcf7b8150c873dcbceb5b"},{"author":{"_account_id":7700,"name":"Nikolay Mahotkin","email":"nikolay.makhotkin@gmail.com","username":"nmakhotkin"},"change_message_id":"eed64ce350adf5c1164f3500867df9b5bed2796c","unresolved":false,"context_lines":[{"line_number":102,"context_line":"            modified_count \u003d triggers.delete_cron_trigger("},{"line_number":103,"context_line":"                t.name,"},{"line_number":104,"context_line":"                trust_id\u003dt.trust_id,"},{"line_number":105,"context_line":"                need_delete_trust\u003dFalse"},{"line_number":106,"context_line":"            )"},{"line_number":107,"context_line":"        else:  # if remaining execution \u003d None or \u003e 0."},{"line_number":108,"context_line":"            next_time \u003d triggers.get_next_execution_time("}],"source_content_type":"text/x-python","patch_set":6,"id":"df3967d1_c829588a","line":105,"range":{"start_line":105,"start_character":16,"end_line":105,"end_character":33},"in_reply_to":"df3967d1_0045fe42","updated":"2017-08-04 08:27:17.000000000","message":"Done","commit_id":"020deab421ceaa0d035dcf7b8150c873dcbceb5b"}],"mistral/services/security.py":[{"author":{"_account_id":8731,"name":"Renat Akhmerov","email":"renat.akhmerov@gmail.com","username":"rakhmerov"},"change_message_id":"6215bfb5f2a849b131924571b2ed12324fde8ef0","unresolved":false,"context_lines":[{"line_number":81,"context_line":"    )"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"def try_delete_trust():"},{"line_number":85,"context_line":"    if not auth_ctx.has_ctx():"},{"line_number":86,"context_line":"        return"},{"line_number":87,"context_line":"    ctx \u003d auth_ctx.ctx()"}],"source_content_type":"text/x-python","patch_set":6,"id":"df3967d1_40c42691","line":84,"range":{"start_line":84,"start_character":4,"end_line":84,"end_character":20},"updated":"2017-08-04 05:02:37.000000000","message":"I\u0027m not sure that this method is needed. Can we leave just method delete_trust() but make its parameter \"trust_id\" optional? So that if it\u0027s not set we extract trust_id from the auth context and then delete it.","commit_id":"020deab421ceaa0d035dcf7b8150c873dcbceb5b"},{"author":{"_account_id":7700,"name":"Nikolay Mahotkin","email":"nikolay.makhotkin@gmail.com","username":"nmakhotkin"},"change_message_id":"eed64ce350adf5c1164f3500867df9b5bed2796c","unresolved":false,"context_lines":[{"line_number":81,"context_line":"    )"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"def try_delete_trust():"},{"line_number":85,"context_line":"    if not auth_ctx.has_ctx():"},{"line_number":86,"context_line":"        return"},{"line_number":87,"context_line":"    ctx \u003d auth_ctx.ctx()"}],"source_content_type":"text/x-python","patch_set":6,"id":"df3967d1_881fd059","line":84,"range":{"start_line":84,"start_character":4,"end_line":84,"end_character":20},"in_reply_to":"df3967d1_40c42691","updated":"2017-08-04 08:27:17.000000000","message":"Done","commit_id":"020deab421ceaa0d035dcf7b8150c873dcbceb5b"},{"author":{"_account_id":8731,"name":"Renat Akhmerov","email":"renat.akhmerov@gmail.com","username":"rakhmerov"},"change_message_id":"6215bfb5f2a849b131924571b2ed12324fde8ef0","unresolved":false,"context_lines":[{"line_number":83,"context_line":""},{"line_number":84,"context_line":"def try_delete_trust():"},{"line_number":85,"context_line":"    if not auth_ctx.has_ctx():"},{"line_number":86,"context_line":"        return"},{"line_number":87,"context_line":"    ctx \u003d auth_ctx.ctx()"},{"line_number":88,"context_line":"    delete_trust(ctx.trust_id)"},{"line_number":89,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"df3967d1_c07c9684","line":86,"range":{"start_line":86,"start_character":8,"end_line":86,"end_character":14},"updated":"2017-08-04 05:02:37.000000000","message":"Soft: insert an empty line after 86.","commit_id":"020deab421ceaa0d035dcf7b8150c873dcbceb5b"}],"mistral/services/triggers.py":[{"author":{"_account_id":21970,"name":"Andras Kovi","email":"akovi@nokia.com","username":"andras.kovi"},"change_message_id":"914210863a4241cdf8fdada492c5021e8e36533f","unresolved":false,"context_lines":[{"line_number":130,"context_line":"    return trig"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"def delete_cron_trigger(name, trust_id\u003dNone, need_delete_trust\u003dTrue):"},{"line_number":134,"context_line":"    if not trust_id:"},{"line_number":135,"context_line":"        trigger \u003d db_api.get_cron_trigger(name)"},{"line_number":136,"context_line":"        trust_id \u003d trigger.trust_id"}],"source_content_type":"text/x-python","patch_set":3,"id":"df3967d1_24da764b","line":133,"range":{"start_line":133,"start_character":45,"end_line":133,"end_character":67},"updated":"2017-08-03 09:17:08.000000000","message":"Directly deleting the trigger from API will still result in the original error if there is a running execution (see: mistral/api/controllers/v2/cron_trigger.py:89)","commit_id":"a09a4e9391452aeedf64d76c991ef9a46f36cda4"},{"author":{"_account_id":7700,"name":"Nikolay Mahotkin","email":"nikolay.makhotkin@gmail.com","username":"nmakhotkin"},"change_message_id":"277e03e9d1e2edb11035fc44be7c599091073577","unresolved":false,"context_lines":[{"line_number":130,"context_line":"    return trig"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"def delete_cron_trigger(name, trust_id\u003dNone, need_delete_trust\u003dTrue):"},{"line_number":134,"context_line":"    if not trust_id:"},{"line_number":135,"context_line":"        trigger \u003d db_api.get_cron_trigger(name)"},{"line_number":136,"context_line":"        trust_id \u003d trigger.trust_id"}],"source_content_type":"text/x-python","patch_set":3,"id":"df3967d1_b857aa26","line":133,"range":{"start_line":133,"start_character":45,"end_line":133,"end_character":67},"in_reply_to":"df3967d1_24da764b","updated":"2017-08-03 09:59:52.000000000","message":"Yes, exactly. If we delete cron-trigger via API, then it probably means we don\u0027t want to run its execution anymore.","commit_id":"a09a4e9391452aeedf64d76c991ef9a46f36cda4"},{"author":{"_account_id":8731,"name":"Renat Akhmerov","email":"renat.akhmerov@gmail.com","username":"rakhmerov"},"change_message_id":"6215bfb5f2a849b131924571b2ed12324fde8ef0","unresolved":false,"context_lines":[{"line_number":130,"context_line":"    return trig"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"def delete_cron_trigger(name, trust_id\u003dNone, need_delete_trust\u003dTrue):"},{"line_number":134,"context_line":"    if not trust_id:"},{"line_number":135,"context_line":"        trigger \u003d db_api.get_cron_trigger(name)"},{"line_number":136,"context_line":"        trust_id \u003d trigger.trust_id"}],"source_content_type":"text/x-python","patch_set":6,"id":"df3967d1_c03db68f","line":133,"range":{"start_line":133,"start_character":45,"end_line":133,"end_character":50},"updated":"2017-08-04 05:02:37.000000000","message":"I think we need to call it \"delete_trust\" w/o \"need\".","commit_id":"020deab421ceaa0d035dcf7b8150c873dcbceb5b"},{"author":{"_account_id":7700,"name":"Nikolay Mahotkin","email":"nikolay.makhotkin@gmail.com","username":"nmakhotkin"},"change_message_id":"eed64ce350adf5c1164f3500867df9b5bed2796c","unresolved":false,"context_lines":[{"line_number":130,"context_line":"    return trig"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"def delete_cron_trigger(name, trust_id\u003dNone, need_delete_trust\u003dTrue):"},{"line_number":134,"context_line":"    if not trust_id:"},{"line_number":135,"context_line":"        trigger \u003d db_api.get_cron_trigger(name)"},{"line_number":136,"context_line":"        trust_id \u003d trigger.trust_id"}],"source_content_type":"text/x-python","patch_set":6,"id":"df3967d1_885470ff","line":133,"range":{"start_line":133,"start_character":45,"end_line":133,"end_character":50},"in_reply_to":"df3967d1_c03db68f","updated":"2017-08-04 08:27:17.000000000","message":"Done","commit_id":"020deab421ceaa0d035dcf7b8150c873dcbceb5b"},{"author":{"_account_id":8731,"name":"Renat Akhmerov","email":"renat.akhmerov@gmail.com","username":"rakhmerov"},"change_message_id":"6215bfb5f2a849b131924571b2ed12324fde8ef0","unresolved":false,"context_lines":[{"line_number":135,"context_line":"        trigger \u003d db_api.get_cron_trigger(name)"},{"line_number":136,"context_line":"        trust_id \u003d trigger.trust_id"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"    modified_count \u003d db_api.delete_cron_trigger(name)"},{"line_number":139,"context_line":"    if modified_count and need_delete_trust:"},{"line_number":140,"context_line":"        # Delete trust only together with deleting trigger."},{"line_number":141,"context_line":"        security.delete_trust(trust_id)"}],"source_content_type":"text/x-python","patch_set":6,"id":"df3967d1_00ba9e08","line":138,"updated":"2017-08-04 05:02:37.000000000","message":"Soft: insert a blank line after 138","commit_id":"020deab421ceaa0d035dcf7b8150c873dcbceb5b"}],"mistral/tests/unit/engine/test_cron_trigger.py":[{"author":{"_account_id":21970,"name":"Andras Kovi","email":"akovi@nokia.com","username":"andras.kovi"},"change_message_id":"914210863a4241cdf8fdada492c5021e8e36533f","unresolved":false,"context_lines":[{"line_number":73,"context_line":"        start_workflow_mock \u003d rpc_mock.return_value.start_workflow"},{"line_number":74,"context_line":"        start_workflow_mock.assert_called_once()"},{"line_number":75,"context_line":"        self.assertIn("},{"line_number":76,"context_line":"            t.name,"},{"line_number":77,"context_line":"            start_workflow_mock.mock_calls[0][2][\u0027description\u0027]"},{"line_number":78,"context_line":"        )"},{"line_number":79,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"df3967d1_843362f6","line":76,"range":{"start_line":76,"start_character":12,"end_line":76,"end_character":19},"updated":"2017-08-03 09:17:08.000000000","message":"In https://review.openstack.org/#/c/458384/ we debated that the id should be added to the description. I think it would be better we kept this rule.","commit_id":"a09a4e9391452aeedf64d76c991ef9a46f36cda4"},{"author":{"_account_id":7700,"name":"Nikolay Mahotkin","email":"nikolay.makhotkin@gmail.com","username":"nmakhotkin"},"change_message_id":"277e03e9d1e2edb11035fc44be7c599091073577","unresolved":false,"context_lines":[{"line_number":73,"context_line":"        start_workflow_mock \u003d rpc_mock.return_value.start_workflow"},{"line_number":74,"context_line":"        start_workflow_mock.assert_called_once()"},{"line_number":75,"context_line":"        self.assertIn("},{"line_number":76,"context_line":"            t.name,"},{"line_number":77,"context_line":"            start_workflow_mock.mock_calls[0][2][\u0027description\u0027]"},{"line_number":78,"context_line":"        )"},{"line_number":79,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"df3967d1_38129a63","line":76,"range":{"start_line":76,"start_character":12,"end_line":76,"end_character":19},"in_reply_to":"df3967d1_843362f6","updated":"2017-08-03 09:59:52.000000000","message":"Ok, I\u0027ll deal with it somehow.","commit_id":"a09a4e9391452aeedf64d76c991ef9a46f36cda4"}]}
