)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":14228,"name":"Clif Houck","email":"me@clifhouck.com","username":"clif_h"},"change_message_id":"a5730fba1b356c1f1bb61dc19a3bb7d3a518a48d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"307cb37a_65d78b7f","updated":"2026-01-16 19:25:37.000000000","message":"Getting close but not ready yet","commit_id":"8b84e8894168c1af799910f31f455fe205fa305f"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"cdb6c14416b2e2a847a910335a0ac1c4dcc475cc","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":3,"id":"9372d71f_ae60de3a","updated":"2026-01-21 18:34:59.000000000","message":"Fallback and consistency behaviors can be implemented in a follow-on if desired.","commit_id":"4820c813b9ac7ed9a2656097a24bc2fb5d36f0c8"},{"author":{"_account_id":14228,"name":"Clif Houck","email":"me@clifhouck.com","username":"clif_h"},"change_message_id":"38627386994f22559e397327401a805ab01aa24e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"368c0132_7f405903","updated":"2026-01-28 02:13:42.000000000","message":"These have been addressed in follow-up commits.","commit_id":"4820c813b9ac7ed9a2656097a24bc2fb5d36f0c8"},{"author":{"_account_id":14228,"name":"Clif Houck","email":"me@clifhouck.com","username":"clif_h"},"change_message_id":"38627386994f22559e397327401a805ab01aa24e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"5bac5088_df9ee828","in_reply_to":"9372d71f_ae60de3a","updated":"2026-01-28 02:13:42.000000000","message":"Done","commit_id":"4820c813b9ac7ed9a2656097a24bc2fb5d36f0c8"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"1d489ccb6d3b868513a6f3dd40d8f561c9e47ea4","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"5b8f3863_b2e17a06","updated":"2026-01-28 17:42:38.000000000","message":"Clif promised a follow-up for the docstrings.","commit_id":"9d80c5502e806095601567ff9680da37868fe4fc"}],"ironic/common/trait_based_networking/base.py":[{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"cdb6c14416b2e2a847a910335a0ac1c4dcc475cc","unresolved":true,"context_lines":[{"line_number":277,"context_line":"        return True"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"class Network(object):"},{"line_number":281,"context_line":"    def __init__(self, network_id, name, tags):"},{"line_number":282,"context_line":"        self.id \u003d network_id"},{"line_number":283,"context_line":"        self.name \u003d name"}],"source_content_type":"text/x-python","patch_set":3,"id":"6d361ba8_13bb5051","line":280,"updated":"2026-01-21 18:34:59.000000000","message":"nit (throughout): it\u0027d be nice to have docstrings for all classes","commit_id":"4820c813b9ac7ed9a2656097a24bc2fb5d36f0c8"},{"author":{"_account_id":14228,"name":"Clif Houck","email":"me@clifhouck.com","username":"clif_h"},"change_message_id":"f02913cafbac5f519a7e400e43c27150d425a723","unresolved":false,"context_lines":[{"line_number":277,"context_line":"        return True"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"class Network(object):"},{"line_number":281,"context_line":"    def __init__(self, network_id, name, tags):"},{"line_number":282,"context_line":"        self.id \u003d network_id"},{"line_number":283,"context_line":"        self.name \u003d name"}],"source_content_type":"text/x-python","patch_set":3,"id":"f3160b4d_51212465","line":280,"in_reply_to":"6d361ba8_13bb5051","updated":"2026-01-28 02:13:52.000000000","message":"Acknowledged","commit_id":"4820c813b9ac7ed9a2656097a24bc2fb5d36f0c8"}],"ironic/common/trait_based_networking/plan.py":[{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"cdb6c14416b2e2a847a910335a0ac1c4dcc475cc","unresolved":true,"context_lines":[{"line_number":107,"context_line":"    # TODO(clif): Take cues from get_free_port_like_object where appropriate."},{"line_number":108,"context_line":"    net \u003d base.Network.from_vif_info(vif_info)"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    # TODO(clif): Enforce some type of ordering in traits?"},{"line_number":111,"context_line":"    for trait in traits:"},{"line_number":112,"context_line":"        actions \u003d plan_network("},{"line_number":113,"context_line":"            trait,"}],"source_content_type":"text/x-python","patch_set":3,"id":"c57a03e4_7668c4ef","line":110,"updated":"2026-01-21 18:34:59.000000000","message":"For now, lets pick and document SOMETHING consistent: even if it\u0027s just ABC order of str(trait.name).\n\nIn a follow-up, after we\u0027re done with portgroups, we should revisit and see if having an explicit priority value is worthwhile.","commit_id":"4820c813b9ac7ed9a2656097a24bc2fb5d36f0c8"},{"author":{"_account_id":14228,"name":"Clif Houck","email":"me@clifhouck.com","username":"clif_h"},"change_message_id":"38627386994f22559e397327401a805ab01aa24e","unresolved":false,"context_lines":[{"line_number":107,"context_line":"    # TODO(clif): Take cues from get_free_port_like_object where appropriate."},{"line_number":108,"context_line":"    net \u003d base.Network.from_vif_info(vif_info)"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    # TODO(clif): Enforce some type of ordering in traits?"},{"line_number":111,"context_line":"    for trait in traits:"},{"line_number":112,"context_line":"        actions \u003d plan_network("},{"line_number":113,"context_line":"            trait,"}],"source_content_type":"text/x-python","patch_set":3,"id":"acd6fe01_65e401a4","line":110,"in_reply_to":"c57a03e4_7668c4ef","updated":"2026-01-28 02:13:42.000000000","message":"Done","commit_id":"4820c813b9ac7ed9a2656097a24bc2fb5d36f0c8"}],"ironic/drivers/modules/network/common.py":[{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"cdb6c14416b2e2a847a910335a0ac1c4dcc475cc","unresolved":true,"context_lines":[{"line_number":611,"context_line":"                 network."},{"line_number":612,"context_line":""},{"line_number":613,"context_line":"        \"\"\""},{"line_number":614,"context_line":"        # TODO(clif): What about a default trait if none apply?"},{"line_number":615,"context_line":"        applicable_traits \u003d plan.filter_traits_for_node(task.node,"},{"line_number":616,"context_line":"                                                        task.tbn_traits)"},{"line_number":617,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"661ceea1_e1aadcc5","line":614,"updated":"2026-01-21 18:34:59.000000000","message":"We need to explicitly require/allow a DEFAULT (in lieu of a specific trait): inside the configuration file. We could even ship an \"example\" config with DEFAULT configured to behave as Ironic currently does. If we picked this option, and no DEFAULT section existed, we\u0027d need to fail the deployment in any case where there were no matching TBN configs for node traits.","commit_id":"4820c813b9ac7ed9a2656097a24bc2fb5d36f0c8"},{"author":{"_account_id":14228,"name":"Clif Houck","email":"me@clifhouck.com","username":"clif_h"},"change_message_id":"38627386994f22559e397327401a805ab01aa24e","unresolved":false,"context_lines":[{"line_number":611,"context_line":"                 network."},{"line_number":612,"context_line":""},{"line_number":613,"context_line":"        \"\"\""},{"line_number":614,"context_line":"        # TODO(clif): What about a default trait if none apply?"},{"line_number":615,"context_line":"        applicable_traits \u003d plan.filter_traits_for_node(task.node,"},{"line_number":616,"context_line":"                                                        task.tbn_traits)"},{"line_number":617,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"c0474389_2e3b1d58","line":614,"in_reply_to":"661ceea1_e1aadcc5","updated":"2026-01-28 02:13:42.000000000","message":"Done","commit_id":"4820c813b9ac7ed9a2656097a24bc2fb5d36f0c8"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"cdb6c14416b2e2a847a910335a0ac1c4dcc475cc","unresolved":true,"context_lines":[{"line_number":619,"context_line":""},{"line_number":620,"context_line":"        if len(actions) \u003d\u003d 0 or isinstance(actions[0], tbn_base.NoMatch):"},{"line_number":621,"context_line":"            # TODO(Clif): Raise a more specific exception associated with"},{"line_number":622,"context_line":"            # TBN?"},{"line_number":623,"context_line":"            raise exception.NoFreePhysicalPorts(vif\u003dvif_info[\u0027id\u0027])"},{"line_number":624,"context_line":""},{"line_number":625,"context_line":"        client \u003d neutron.get_client(context\u003dtask.context)"}],"source_content_type":"text/x-python","patch_set":3,"id":"8eb3e03b_3009548e","line":622,"updated":"2026-01-21 18:34:59.000000000","message":"yes please","commit_id":"4820c813b9ac7ed9a2656097a24bc2fb5d36f0c8"},{"author":{"_account_id":14228,"name":"Clif Houck","email":"me@clifhouck.com","username":"clif_h"},"change_message_id":"38627386994f22559e397327401a805ab01aa24e","unresolved":false,"context_lines":[{"line_number":619,"context_line":""},{"line_number":620,"context_line":"        if len(actions) \u003d\u003d 0 or isinstance(actions[0], tbn_base.NoMatch):"},{"line_number":621,"context_line":"            # TODO(Clif): Raise a more specific exception associated with"},{"line_number":622,"context_line":"            # TBN?"},{"line_number":623,"context_line":"            raise exception.NoFreePhysicalPorts(vif\u003dvif_info[\u0027id\u0027])"},{"line_number":624,"context_line":""},{"line_number":625,"context_line":"        client \u003d neutron.get_client(context\u003dtask.context)"}],"source_content_type":"text/x-python","patch_set":3,"id":"416c83f4_cb69602b","line":622,"in_reply_to":"8eb3e03b_3009548e","updated":"2026-01-28 02:13:42.000000000","message":"Done","commit_id":"4820c813b9ac7ed9a2656097a24bc2fb5d36f0c8"}]}
