)]}'
{"watcher_dashboard/api/watcher.py":[{"robot_id":"zuul","robot_run_id":"50f3ce190b084af58f6e231bdccf0176","url":"https://zuul.teim.app/t/main/buildset/50f3ce190b084af58f6e231bdccf0176","author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"62220fc313715f3116c4f7538ffb8967318671bc","patch_set":1,"id":"7bd291a7_35cac57a","line":724,"updated":"2026-02-28 12:35:58.000000000","message":"The service layer functions use \u0027cast()\u0027 for return type annotations on get() functions. Consider whether these casts are still necessary given that underlying class methods already have proper type annotations.\n\n**Severity**: SUGGESTION | **Confidence**: 0.7\n\n**Benefit**: Reviewing cast() necessity could simplify code. If underlying class methods have proper return type annotations, cast() calls may be redundant for mypy compliance.\n\n**Recommendation**:\nEvaluate whether cast() calls are truly necessary for mypy compliance. If needed due to untyped openstack_dashboard base classes, consider adding a comment explaining why the cast is preserved.","commit_id":"3219a2b7349bbcd79601d97f79c06595541bdeae"},{"robot_id":"zuul","robot_run_id":"50f3ce190b084af58f6e231bdccf0176","url":"https://zuul.teim.app/t/main/buildset/50f3ce190b084af58f6e231bdccf0176","author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"62220fc313715f3116c4f7538ffb8967318671bc","patch_set":1,"id":"9e2514e5_54bbbe4d","line":907,"updated":"2026-02-28 12:35:58.000000000","message":"The get_strategy_parameters_for_template function has complex nested conditional logic for handling parameters_spec that could benefit from extraction into a helper function.\n\n**Severity**: SUGGESTION | **Confidence**: 0.7\n\n**Benefit**: Extracting the parameters_spec parsing logic into a separate helper function would improve code readability, make the function easier to test in isolation, and follow the single responsibility principle.\n\n**Recommendation**:\nConsider extracting lines 907-916 into a private helper function like \u0027_parse_parameters_spec(parameters_spec: str | dict | None) -\u003e dict[str, object]\u0027 that handles the JSON parsing and dict extraction logic.","commit_id":"3219a2b7349bbcd79601d97f79c06595541bdeae"},{"robot_id":"zuul","robot_run_id":"50f3ce190b084af58f6e231bdccf0176","url":"https://zuul.teim.app/t/main/buildset/50f3ce190b084af58f6e231bdccf0176","author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"62220fc313715f3116c4f7538ffb8967318671bc","patch_set":1,"id":"feaae422_a4204341","line":913,"updated":"2026-02-28 12:35:58.000000000","message":"The ValueError exception in json.loads() is caught with \u0027except ValueError\u0027 which matches the OpenStack H201 rule requirement, but the broader json.JSONDecodeError would be more precise for Python 3.5+\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: ValueError is parent of JSONDecodeError. Using json.JSONDecodeError would be more explicit about the type of parsing error. However, since ValueError correctly catches JSON parsing errors and project targets Python 3.10+, this is a minor stylistic concern.\n\n**Suggestion**:\nConsider changing \u0027except ValueError:\u0027 to \u0027except json.JSONDecodeError:\u0027 for more precise exception handling. However, the current approach is acceptable as ValueError correctly catches JSON parsing errors and maintains compatibility.","commit_id":"3219a2b7349bbcd79601d97f79c06595541bdeae"},{"robot_id":"zuul","robot_run_id":"a171b330dd074c0d9f36e1180cdbe56c","url":"https://zuul.teim.app/t/main/buildset/a171b330dd074c0d9f36e1180cdbe56c","author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"d1f737c81332694ec45b3a54df2fee8438483dde","patch_set":2,"id":"dd2eaf4a_d78efa3b","line":904,"updated":"2026-03-30 16:27:56.000000000","message":"audit_list uses \u0027# type: ignore[arg-type]\u0027 to suppress a mypy error caused by the Audit.list classmethod accepting an explicit api_version parameter not present in the **filters signature of the service function.\n\n**Severity**: WARNING | **Confidence**: 0.9\n\n**Impact**: The type ignore comment suppresses a legitimate type safety issue. If Audit.list is called with keyword arguments that don\u0027t match its signature, mypy will not catch it. However, the underlying class method is correctly typed so the risk is minimal.\n\n**Suggestion**:\nConsider adding an explicit api_version parameter to audit_list (like Audit.list has) to avoid the type ignore. Alternatively, add a comment explaining why the type ignore is necessary: \u0027# type: ignore[arg-type] -- Audit.list has extra api_version param not in **filters\u0027.","commit_id":"3e7884df69fbe726e0a3598f477ff15753fa382b"},{"robot_id":"zuul","robot_run_id":"a171b330dd074c0d9f36e1180cdbe56c","url":"https://zuul.teim.app/t/main/buildset/a171b330dd074c0d9f36e1180cdbe56c","author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"d1f737c81332694ec45b3a54df2fee8438483dde","patch_set":2,"id":"f1f3408d_5bfe19ea","line":971,"updated":"2026-03-30 16:27:56.000000000","message":"get_strategy_parameters_for_template silently swallows JSON parse errors (ValueError) when strategy.parameters_spec is a malformed string, leaving parameters_spec as an empty dict with no indication that parsing failed.\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: If the Watcher API returns a malformed JSON string in parameters_spec, the function will silently return an empty parameters_spec. Callers (forms) will present no parameters to the user with no warning, potentially causing incorrect audit template creation.\n\n**Suggestion**:\nAdd a LOG.warning when ValueError is caught to aid debugging. Example: except (ValueError, json.JSONDecodeError) as e: LOG.warning(\u0027Failed to parse parameters_spec for strategy %s: %s\u0027, strategy.uuid, e); parameters_spec \u003d {}","commit_id":"3e7884df69fbe726e0a3598f477ff15753fa382b"},{"robot_id":"zuul","robot_run_id":"17178e63bf9d43ccadcf0ed08fd2a6a4","url":"https://zuul.teim.app/t/main/buildset/17178e63bf9d43ccadcf0ed08fd2a6a4","author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"003fb7b22af3fcbd857ea354c72bd3364748ba70","patch_set":3,"id":"810c5fc1_43d85284","line":780,"updated":"2026-04-04 02:30:24.000000000","message":"21 of 29 new service-layer functions lack docstrings. Per H404/H405 compliance and the OpenStack style guide, all public functions should have docstrings explaining their purpose, parameters, and return values. Functions like goal_list, audit_delete, strategy_get etc. are public API that callers will use.\n\n**Severity**: WARNING | **Confidence**: 0.9\n\n**Impact**: Callers of these service functions will have no in-source documentation. Future maintainers will need to trace through the delegation to the class method to understand the contract. IDE hover-docs will be empty for these functions.\n\n**Suggestion**:\nAdd docstrings to all public service-layer functions, even if brief. For simple delegators like audit_delete, a one-line docstring is sufficient. For functions with non-trivial logic (get_strategy_parameters_for_template, get_action_plan_for_audit), the existing docstrings are good and should serve as a model.","commit_id":"bb7110c4b2b29016a9e2d31571feddc516de1470"},{"robot_id":"zuul","robot_run_id":"17178e63bf9d43ccadcf0ed08fd2a6a4","url":"https://zuul.teim.app/t/main/buildset/17178e63bf9d43ccadcf0ed08fd2a6a4","author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"003fb7b22af3fcbd857ea354c72bd3364748ba70","patch_set":3,"id":"c3a057bc_93b0a146","line":983,"updated":"2026-04-04 02:30:24.000000000","message":"The getattr() call on line 983 uses dynamic attribute access for \u0027parameters_spec\u0027, but this field IS declared in Strategy._attrs. The previous refactoring commit (A2-1) specifically replaced getattr with direct attribute access for all declared _attrs fields. Using getattr here is inconsistent with that effort.\n\n**Severity**: WARNING | **Confidence**: 0.9\n\n**Impact**: Violates the project convention established in the A2-1 refactoring commit. A project-wide grep for uncommented getattr/hasattr/setattr was intentionally reduced to zero outside tests; this new usage re-introduces an exception without a clear justification comment matching the pattern used in strategies/views.py.\n\n**Suggestion**:\nReplace getattr(strategy, \u0027parameters_spec\u0027, None) with direct attribute access. Check if parameters_spec can be None using a conditional expression. If the field may genuinely be absent from API responses (not just None), add an inline comment matching the project\u0027s established pattern for intentional reflection.","commit_id":"bb7110c4b2b29016a9e2d31571feddc516de1470"}]}
