)]}'
{"keystone/common/sql/expand_repo/versions/073_expand_expiring_group_membership.py":[{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"b2cdc11afd46aa36e3ac3e086d2be91f0cec9095","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"df33271e_14ffb301","line":48,"updated":"2020-03-24 23:15:27.000000000","message":"this needs a test in https://opendev.org/openstack/keystone/src/branch/master/keystone/tests/unit/test_sql_upgrade.py","commit_id":"d663f3061d78e795941648a9aa0cd0659461c9bb"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"2eb5888b48a8cd390c3370debcc583e0df1a4f7f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"df33271e_e208842e","line":48,"in_reply_to":"df33271e_14ffb301","updated":"2020-03-25 14:28:40.000000000","message":"Thanks, will do that this evening.","commit_id":"d663f3061d78e795941648a9aa0cd0659461c9bb"}],"keystone/conf/federation.py":[{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"30f65d9de86a29361b38d1af0c1157a9bcbf7111","unresolved":false,"context_lines":[{"line_number":99,"context_line":"    default\u003d0,"},{"line_number":100,"context_line":"    help\u003dutils.fmt(\"\"\""},{"line_number":101,"context_line":"Default time in minutes for the validity of authorizations carried over from"},{"line_number":102,"context_line":"mappings. Currently used to expire group memberships via mappings. Default is"},{"line_number":103,"context_line":"0, which means disabled."},{"line_number":104,"context_line":"\"\"\"))"},{"line_number":105,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"df33271e_aaec9cf3","line":102,"range":{"start_line":102,"start_character":10,"end_line":102,"end_character":19},"updated":"2020-04-06 23:33:51.000000000","message":"This implies some time in the future this might be used some other way?","commit_id":"b2abae07bd55b1b6c24ef843cf85aefd59b2dfde"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"4d346f231bb9dd506140db3bfeed3aeacc567dfc","unresolved":false,"context_lines":[{"line_number":99,"context_line":"    default\u003d0,"},{"line_number":100,"context_line":"    help\u003dutils.fmt(\"\"\""},{"line_number":101,"context_line":"Default time in minutes for the validity of authorizations carried over from"},{"line_number":102,"context_line":"mappings. Currently used to expire group memberships via mappings. Default is"},{"line_number":103,"context_line":"0, which means disabled."},{"line_number":104,"context_line":"\"\"\"))"},{"line_number":105,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"df33271e_968c5536","line":102,"range":{"start_line":102,"start_character":10,"end_line":102,"end_character":19},"in_reply_to":"df33271e_763551da","updated":"2020-04-07 14:37:34.000000000","message":"I guess my point was I would rather it be definitive, as an operator I don\u0027t want to feel like this is going to change its meaning out from under me. I can\u0027t think of how else this would be used or why we would change it.","commit_id":"b2abae07bd55b1b6c24ef843cf85aefd59b2dfde"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"cfc0057c7c9c97223a5e414dbabe95fb075be1ca","unresolved":false,"context_lines":[{"line_number":99,"context_line":"    default\u003d0,"},{"line_number":100,"context_line":"    help\u003dutils.fmt(\"\"\""},{"line_number":101,"context_line":"Default time in minutes for the validity of authorizations carried over from"},{"line_number":102,"context_line":"mappings. Currently used to expire group memberships via mappings. Default is"},{"line_number":103,"context_line":"0, which means disabled."},{"line_number":104,"context_line":"\"\"\"))"},{"line_number":105,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"df33271e_7159db58","line":102,"range":{"start_line":102,"start_character":10,"end_line":102,"end_character":19},"in_reply_to":"df33271e_968c5536","updated":"2020-04-07 15:01:33.000000000","message":"Makes sense, updating.","commit_id":"b2abae07bd55b1b6c24ef843cf85aefd59b2dfde"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"be61a07043625f739b94b9c026037e7b02633d14","unresolved":false,"context_lines":[{"line_number":99,"context_line":"    default\u003d0,"},{"line_number":100,"context_line":"    help\u003dutils.fmt(\"\"\""},{"line_number":101,"context_line":"Default time in minutes for the validity of authorizations carried over from"},{"line_number":102,"context_line":"mappings. Currently used to expire group memberships via mappings. Default is"},{"line_number":103,"context_line":"0, which means disabled."},{"line_number":104,"context_line":"\"\"\"))"},{"line_number":105,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"df33271e_763551da","line":102,"range":{"start_line":102,"start_character":10,"end_line":102,"end_character":19},"in_reply_to":"df33271e_aaec9cf3","updated":"2020-04-07 14:25:36.000000000","message":"No plans to do yet, but the name is generic enough that it opens the possibility.","commit_id":"b2abae07bd55b1b6c24ef843cf85aefd59b2dfde"}],"keystone/federation/backends/sql.py":[{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"c5c9508555fd27257753105fee98454ca4bfbfff","unresolved":false,"context_lines":[{"line_number":60,"context_line":"    domain_id \u003d sql.Column(sql.String(64), nullable\u003dFalse)"},{"line_number":61,"context_line":"    enabled \u003d sql.Column(sql.Boolean, nullable\u003dFalse)"},{"line_number":62,"context_line":"    description \u003d sql.Column(sql.Text(), nullable\u003dTrue)"},{"line_number":63,"context_line":"    authorization_ttl \u003d sql.Column(sql.Integer, nullable\u003dTrue)"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    remote_ids \u003d orm.relationship(\u0027IdPRemoteIdsModel\u0027,"},{"line_number":66,"context_line":"                                  order_by\u003d\u0027IdPRemoteIdsModel.remote_id\u0027,"}],"source_content_type":"text/x-python","patch_set":9,"id":"df33271e_3d73d44f","line":63,"range":{"start_line":63,"start_character":5,"end_line":63,"end_character":62},"updated":"2020-04-05 10:52:20.000000000","message":"Since this table is updated with a new attribute, dont we need to add this into data migration repo followed by a test case?","commit_id":"639edac7b7278f10fa4654fb985e3c019ded3d75"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"cbe00f63cb3fc114f536ed317fbe8474eb675fef","unresolved":false,"context_lines":[{"line_number":60,"context_line":"    domain_id \u003d sql.Column(sql.String(64), nullable\u003dFalse)"},{"line_number":61,"context_line":"    enabled \u003d sql.Column(sql.Boolean, nullable\u003dFalse)"},{"line_number":62,"context_line":"    description \u003d sql.Column(sql.Text(), nullable\u003dTrue)"},{"line_number":63,"context_line":"    authorization_ttl \u003d sql.Column(sql.Integer, nullable\u003dTrue)"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    remote_ids \u003d orm.relationship(\u0027IdPRemoteIdsModel\u0027,"},{"line_number":66,"context_line":"                                  order_by\u003d\u0027IdPRemoteIdsModel.remote_id\u0027,"}],"source_content_type":"text/x-python","patch_set":9,"id":"df33271e_200e08e5","line":63,"range":{"start_line":63,"start_character":5,"end_line":63,"end_character":62},"in_reply_to":"df33271e_3d73d44f","updated":"2020-04-05 17:23:05.000000000","message":"The data migration repo is used when already existing values need to be updated in some form during the migration. For example moved to a new column, etc. This doesn\u0027t need that, so expanding is enough.\n\nYou are right however about the test case, and I will add a check for this column in test_sql_upgrade.","commit_id":"639edac7b7278f10fa4654fb985e3c019ded3d75"}],"keystone/identity/backends/sql_model.py":[{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"98b815a9cee82bd9d54a6864a84ed157f9a27478","unresolved":false,"context_lines":[{"line_number":390,"context_line":"class ExpiringUserGroupMembership(sql.ModelBase, sql.ModelDictMixin):"},{"line_number":391,"context_line":"    \"\"\"Expiring group membership through federation mapping rules.\"\"\""},{"line_number":392,"context_line":""},{"line_number":393,"context_line":"    _tablename__ \u003d \u0027expiring_user_group_membership\u0027"},{"line_number":394,"context_line":"    user_id \u003d sql.Column(sql.String(64),"},{"line_number":395,"context_line":"                         sql.ForeignKey(\u0027user.id\u0027),"},{"line_number":396,"context_line":"                         primary_key\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":1,"id":"7faddb67_13a39ab3","line":393,"range":{"start_line":393,"start_character":4,"end_line":393,"end_character":5},"updated":"2019-08-23 19:26:27.000000000","message":"gah, I missed one underscore :(","commit_id":"1bd1024e0389d31803d01a35a59a068b2282c84b"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"117d0435d4e3337996bb5eb32567805c33cdd130","unresolved":false,"context_lines":[{"line_number":61,"context_line":"                                     lazy\u003d\u0027joined\u0027,"},{"line_number":62,"context_line":"                                     cascade\u003d\u0027all,delete-orphan\u0027,"},{"line_number":63,"context_line":"                                     backref\u003d\u0027user\u0027)"},{"line_number":64,"context_line":"    expiring_user_group_memberships \u003d orm.relationship("},{"line_number":65,"context_line":"        \u0027ExpiringUserGroupMembership\u0027,"},{"line_number":66,"context_line":"        cascade\u003d\u0027all, delete-orphan\u0027,"},{"line_number":67,"context_line":"        backref\u003d\"user\""},{"line_number":68,"context_line":"    )"},{"line_number":69,"context_line":"    created_at \u003d sql.Column(sql.DateTime, nullable\u003dTrue)"},{"line_number":70,"context_line":"    last_active_at \u003d sql.Column(sql.Date, nullable\u003dTrue)"},{"line_number":71,"context_line":"    # unique constraint needed here to support composite fk constraints"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_3d50f4d4","line":68,"range":{"start_line":64,"start_character":3,"end_line":68,"end_character":5},"updated":"2020-04-05 10:03:20.000000000","message":"Question: Out of curiosity why is the table UserGroupMembership is not added as a relationship to this table whereas table expiring_user_group_memberships is?","commit_id":"d663f3061d78e795941648a9aa0cd0659461c9bb"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"cbe00f63cb3fc114f536ed317fbe8474eb675fef","unresolved":false,"context_lines":[{"line_number":61,"context_line":"                                     lazy\u003d\u0027joined\u0027,"},{"line_number":62,"context_line":"                                     cascade\u003d\u0027all,delete-orphan\u0027,"},{"line_number":63,"context_line":"                                     backref\u003d\u0027user\u0027)"},{"line_number":64,"context_line":"    expiring_user_group_memberships \u003d orm.relationship("},{"line_number":65,"context_line":"        \u0027ExpiringUserGroupMembership\u0027,"},{"line_number":66,"context_line":"        cascade\u003d\u0027all, delete-orphan\u0027,"},{"line_number":67,"context_line":"        backref\u003d\"user\""},{"line_number":68,"context_line":"    )"},{"line_number":69,"context_line":"    created_at \u003d sql.Column(sql.DateTime, nullable\u003dTrue)"},{"line_number":70,"context_line":"    last_active_at \u003d sql.Column(sql.Date, nullable\u003dTrue)"},{"line_number":71,"context_line":"    # unique constraint needed here to support composite fk constraints"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_e00380bd","line":68,"range":{"start_line":64,"start_character":3,"end_line":68,"end_character":5},"in_reply_to":"df33271e_3d50f4d4","updated":"2020-04-05 17:23:05.000000000","message":"What this does, is it adds an attribute called `user` to ExpiringUserGroupMembership objects, so that we can access the  membership\u0027s user by doing `.user`. We haven\u0027t needed to do that for normal group memberships.","commit_id":"d663f3061d78e795941648a9aa0cd0659461c9bb"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"83f47825b21052060b4693bb355c6de2f78a783f","unresolved":false,"context_lines":[{"line_number":61,"context_line":"                                     lazy\u003d\u0027joined\u0027,"},{"line_number":62,"context_line":"                                     cascade\u003d\u0027all,delete-orphan\u0027,"},{"line_number":63,"context_line":"                                     backref\u003d\u0027user\u0027)"},{"line_number":64,"context_line":"    expiring_user_group_memberships \u003d orm.relationship("},{"line_number":65,"context_line":"        \u0027ExpiringUserGroupMembership\u0027,"},{"line_number":66,"context_line":"        cascade\u003d\u0027all, delete-orphan\u0027,"},{"line_number":67,"context_line":"        backref\u003d\"user\""},{"line_number":68,"context_line":"    )"},{"line_number":69,"context_line":"    created_at \u003d sql.Column(sql.DateTime, nullable\u003dTrue)"},{"line_number":70,"context_line":"    last_active_at \u003d sql.Column(sql.Date, nullable\u003dTrue)"},{"line_number":71,"context_line":"    # unique constraint needed here to support composite fk constraints"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_974478b9","line":68,"range":{"start_line":64,"start_character":3,"end_line":68,"end_character":5},"in_reply_to":"df33271e_e00380bd","updated":"2020-04-06 07:30:27.000000000","message":"Thanks for the explanation","commit_id":"d663f3061d78e795941648a9aa0cd0659461c9bb"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"117d0435d4e3337996bb5eb32567805c33cdd130","unresolved":false,"context_lines":[{"line_number":375,"context_line":"    domain_id \u003d sql.Column(sql.String(64), nullable\u003dFalse)"},{"line_number":376,"context_line":"    description \u003d sql.Column(sql.Text())"},{"line_number":377,"context_line":"    extra \u003d sql.Column(sql.JsonBlob())"},{"line_number":378,"context_line":"    expiring_user_group_memberships \u003d orm.relationship("},{"line_number":379,"context_line":"        \u0027ExpiringUserGroupMembership\u0027,"},{"line_number":380,"context_line":"        cascade\u003d\u0027all, delete-orphan\u0027,"},{"line_number":381,"context_line":"        backref\u003d\"group\""},{"line_number":382,"context_line":"    )"},{"line_number":383,"context_line":"    # Unique constraint across two columns to create the separation"},{"line_number":384,"context_line":"    # rather than just only \u0027name\u0027 being unique"},{"line_number":385,"context_line":"    __table_args__ \u003d (sql.UniqueConstraint(\u0027domain_id\u0027, \u0027name\u0027),)"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_9d5e60e7","line":382,"range":{"start_line":378,"start_character":4,"end_line":382,"end_character":5},"updated":"2020-04-05 10:03:20.000000000","message":"Same here?","commit_id":"d663f3061d78e795941648a9aa0cd0659461c9bb"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"b2cdc11afd46aa36e3ac3e086d2be91f0cec9095","unresolved":false,"context_lines":[{"line_number":398,"context_line":""},{"line_number":399,"context_line":""},{"line_number":400,"context_line":"class ExpiringUserGroupMembership(sql.ModelBase, sql.ModelDictMixin):"},{"line_number":401,"context_line":"    \"\"\"Expiring group membership through federation mapping rules.\"\"\""},{"line_number":402,"context_line":""},{"line_number":403,"context_line":"    __tablename__ \u003d \u0027expiring_user_group_membership\u0027"},{"line_number":404,"context_line":"    user_id \u003d sql.Column(sql.String(64),"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_a08842c6","line":401,"updated":"2020-03-24 23:15:27.000000000","message":"remind me why this needed to be a new table instead of new attributes in the UserGroupMembership table?","commit_id":"d663f3061d78e795941648a9aa0cd0659461c9bb"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"5d6d2eaae1f908abb04b8935713fa9580d2af48d","unresolved":false,"context_lines":[{"line_number":398,"context_line":""},{"line_number":399,"context_line":""},{"line_number":400,"context_line":"class ExpiringUserGroupMembership(sql.ModelBase, sql.ModelDictMixin):"},{"line_number":401,"context_line":"    \"\"\"Expiring group membership through federation mapping rules.\"\"\""},{"line_number":402,"context_line":""},{"line_number":403,"context_line":"    __tablename__ \u003d \u0027expiring_user_group_membership\u0027"},{"line_number":404,"context_line":"    user_id \u003d sql.Column(sql.String(64),"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_6773d8b2","line":401,"in_reply_to":"df33271e_821a587a","updated":"2020-03-26 01:40:21.000000000","message":"If we join the tables, identity_provider would have to be part of the composite primary key as well, and any part of a primary key can\u0027t be null. That would mean that a user can\u0027t have group membership from more than one idp, or actual assignment. It\u0027s not possible for a user to have multiple idps for now, but that will change if federated attributes merges in its current form.","commit_id":"d663f3061d78e795941648a9aa0cd0659461c9bb"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"2eb5888b48a8cd390c3370debcc583e0df1a4f7f","unresolved":false,"context_lines":[{"line_number":398,"context_line":""},{"line_number":399,"context_line":""},{"line_number":400,"context_line":"class ExpiringUserGroupMembership(sql.ModelBase, sql.ModelDictMixin):"},{"line_number":401,"context_line":"    \"\"\"Expiring group membership through federation mapping rules.\"\"\""},{"line_number":402,"context_line":""},{"line_number":403,"context_line":"    __tablename__ \u003d \u0027expiring_user_group_membership\u0027"},{"line_number":404,"context_line":"    user_id \u003d sql.Column(sql.String(64),"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_821a587a","line":401,"in_reply_to":"df33271e_a08842c6","updated":"2020-03-25 14:28:40.000000000","message":"My response at the time was that the implementation would be cleaner since idp_id and last_active would not apply to normal groups. But after doing the driver part I\u0027m not so sure of that anymore. I can spend a few hours this evening investigating the same table approach.","commit_id":"d663f3061d78e795941648a9aa0cd0659461c9bb"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"b2cdc11afd46aa36e3ac3e086d2be91f0cec9095","unresolved":false,"context_lines":[{"line_number":408,"context_line":"                          sql.ForeignKey(\u0027group.id\u0027),"},{"line_number":409,"context_line":"                          primary_key\u003dTrue)"},{"line_number":410,"context_line":"    idp_id \u003d sql.Column(sql.String(64),"},{"line_number":411,"context_line":"                        sql.ForeignKey(\u0027identity_provider.id\u0027,"},{"line_number":412,"context_line":"                                       ondelete\u003d\u0027CASCADE\u0027),"},{"line_number":413,"context_line":"                        primary_key\u003dTrue)"},{"line_number":414,"context_line":"    last_verified \u003d sql.Column(sql.DateTime, nullable\u003dFalse)"},{"line_number":415,"context_line":""},{"line_number":416,"context_line":"    @hybrid_property"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_40bdf663","line":413,"range":{"start_line":411,"start_character":24,"end_line":413,"end_character":41},"updated":"2020-03-24 23:15:27.000000000","message":"nope, can\u0027t do this. the federation driver is a separate backend from the identity driver. relationships between the two backends need to be maintained via the manager, not in sql.","commit_id":"d663f3061d78e795941648a9aa0cd0659461c9bb"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"2eb5888b48a8cd390c3370debcc583e0df1a4f7f","unresolved":false,"context_lines":[{"line_number":408,"context_line":"                          sql.ForeignKey(\u0027group.id\u0027),"},{"line_number":409,"context_line":"                          primary_key\u003dTrue)"},{"line_number":410,"context_line":"    idp_id \u003d sql.Column(sql.String(64),"},{"line_number":411,"context_line":"                        sql.ForeignKey(\u0027identity_provider.id\u0027,"},{"line_number":412,"context_line":"                                       ondelete\u003d\u0027CASCADE\u0027),"},{"line_number":413,"context_line":"                        primary_key\u003dTrue)"},{"line_number":414,"context_line":"    last_verified \u003d sql.Column(sql.DateTime, nullable\u003dFalse)"},{"line_number":415,"context_line":""},{"line_number":416,"context_line":"    @hybrid_property"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_829538e7","line":413,"range":{"start_line":411,"start_character":24,"end_line":413,"end_character":41},"in_reply_to":"df33271e_40bdf663","updated":"2020-03-25 14:28:40.000000000","message":"We already have foreign key dependencies to the federation model regardless of this. Line 341 and 348, FederatedUser model.","commit_id":"d663f3061d78e795941648a9aa0cd0659461c9bb"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"af879a56f44e396321a407c102d061709c4244e9","unresolved":false,"context_lines":[{"line_number":408,"context_line":"                          sql.ForeignKey(\u0027group.id\u0027),"},{"line_number":409,"context_line":"                          primary_key\u003dTrue)"},{"line_number":410,"context_line":"    idp_id \u003d sql.Column(sql.String(64),"},{"line_number":411,"context_line":"                        sql.ForeignKey(\u0027identity_provider.id\u0027,"},{"line_number":412,"context_line":"                                       ondelete\u003d\u0027CASCADE\u0027),"},{"line_number":413,"context_line":"                        primary_key\u003dTrue)"},{"line_number":414,"context_line":"    last_verified \u003d sql.Column(sql.DateTime, nullable\u003dFalse)"},{"line_number":415,"context_line":""},{"line_number":416,"context_line":"    @hybrid_property"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_a459f535","line":413,"range":{"start_line":411,"start_character":24,"end_line":413,"end_character":41},"in_reply_to":"df33271e_829538e7","updated":"2020-04-03 18:19:23.000000000","message":"ah okay fair enough","commit_id":"d663f3061d78e795941648a9aa0cd0659461c9bb"}]}
