)]}'
{"watcher/api/hooks.py":[{"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":"9cb292308c7cdc866139293638342ee4a0117788","unresolved":false,"context_lines":[{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"class ContextHook(hooks.PecanHook):"},{"line_number":26,"context_line":"    \"\"\"Configures a request context and attaches it to the request."},{"line_number":27,"context_line":"    \"\"\""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"    def before(self, state):"}],"source_content_type":"text/x-python","patch_set":1,"id":"caea0ab2_9f7fbc4f","line":26,"updated":"2026-06-29 17:06:04.000000000","message":"ContextHook docstring now has an empty body (only a blank line) after the per-header documentation was removed, leaving a multi-line docstring that documents nothing.\n\n**Severity**: SUGGESTION | **Confidence**: 0.9\n\n**Benefit**: A one-line summary keeps the docstring meaningful and signals that context construction is now delegated to oslo_context.from_environ.\n\n**Recommendation**:\nCollapse to a single-line docstring or add a brief note: e.g. \u0027Builds the request context from the WSGI environ via oslo_context.from_environ.\u0027","commit_id":"33f401ba53241674995710b51587b11aa2756a4b"},{"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":"9cb292308c7cdc866139293638342ee4a0117788","unresolved":false,"context_lines":[{"line_number":27,"context_line":"    \"\"\""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"    def before(self, state):"},{"line_number":30,"context_line":"        state.request.context \u003d context.RequestContext.from_environ("},{"line_number":31,"context_line":"            state.request.environ,"},{"line_number":32,"context_line":"            auth_token_info\u003dstate.request.environ.get(\u0027keystone.token_info\u0027)"},{"line_number":33,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":1,"id":"82dadbe6_bcdd4aef","line":30,"updated":"2026-06-29 17:06:04.000000000","message":"Lost coverage for ContextHook.before(): TestContextHook (3 tests asserting header-\u003econtext mapping for roles, auth_token, auth_token_info, public_api) was deleted and not replaced. from_environ is now mocked in the base TestCase, so no test exercises the real header-\u003econtext path.\n\n**Severity**: HIGH | **Confidence**: 0.8\n\n**Risk**: A regression in how request headers map to user_id/project_id/roles/show_deleted/auth_token (now handled implicitly by oslo_context.from_environ) would not be caught by tests, including security-sensitive attributes like auth_token and roles.\n\n**Priority**: Before merge\n**Why This Matters**: ContextHook is the API\u0027s trust boundary that translates Keystone-provided HTTP headers into the RequestContext used for authorization. Replacing hand-written parsing with from_environ is reasonable, but removing all behavioural tests leaves this path unverified.\n\n**Recommendation**:\nAdd a new test that does NOT mock RequestContext.from_environ for ContextHook: build a FakeRequestState with realistic headers (X-Auth-Token, X-User-Id, X-Roles, X-Show-Deleted) and environ (keystone.token_info), call ContextHook().before(state), and assert the resulting context attributes match expectations. Keep from_environ mocked only in non-API tests.","commit_id":"33f401ba53241674995710b51587b11aa2756a4b"}],"watcher/common/context.py":[{"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":"9cb292308c7cdc866139293638342ee4a0117788","unresolved":false,"context_lines":[{"line_number":35,"context_line":"        # this for and possibly remove it or document it."},{"line_number":36,"context_line":"        self.auth_token_info \u003d auth_token_info"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    def to_dict(self):"},{"line_number":39,"context_line":"        values \u003d super().to_dict()"},{"line_number":40,"context_line":"        values.update("},{"line_number":41,"context_line":"            {"}],"source_content_type":"text/x-python","patch_set":1,"id":"b39843ce_58e8356c","line":38,"updated":"2026-06-29 17:06:04.000000000","message":"to_dict() no longer emits a \u0027timestamp\u0027 key (the custom timestamp attribute and its isoformat serialization were removed), while make_context/from_dict round-trips still run in the test base. Any consumer that previously read context.timestamp from a serialized dict will now silently get nothing.\n\n**Severity**: SUGGESTION | **Confidence**: 0.7\n\n**Benefit**: Confirms whether timestamp was part of watcher\u0027s contract; if it was unused, a brief note avoids confusion for anyone reading old logs/migration code that referenced it.\n\n**Recommendation**:\nVerify no code or log formatter depends on the \u0027timestamp\u0027 field in the serialized context. If none exists (likely), this is fine as-is; if something does, restore it via to_dict/from_dict.","commit_id":"33f401ba53241674995710b51587b11aa2756a4b"}],"watcher/tests/unit/api/test_hooks.py":[{"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":"9cb292308c7cdc866139293638342ee4a0117788","unresolved":false,"context_lines":[{"line_number":27,"context_line":"from watcher.tests.unit.api import base"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"class FakeRequest:"},{"line_number":31,"context_line":"    def __init__(self, headers, context, environ):"},{"line_number":32,"context_line":"        self.headers \u003d headers"},{"line_number":33,"context_line":"        self.context \u003d context"}],"source_content_type":"text/x-python","patch_set":1,"id":"9b6fc73e_004cd4e1","line":30,"updated":"2026-06-29 17:06:04.000000000","message":"Dead/misleading test helper left behind: FakeRequestState (and FakeRequest) in test_hooks.py are no longer referenced by any test after TestContextHook was removed, and set_context contains the broken from_environ call noted above.\n\n**Severity**: WARNING | **Confidence**: 0.9\n\n**Impact**: Carries broken, undocumented dead code that future contributors may either trust or cargo-cult; increases maintenance noise in a file whose purpose is now only NoExceptionTracebackHook.\n\n**Suggestion**:\nRemove FakeRequest, FakeRequestState and set_context if they have no remaining callers; if retained for future use, fix the from_environ call and add a brief comment explaining what consumes them.","commit_id":"33f401ba53241674995710b51587b11aa2756a4b"},{"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":"9cb292308c7cdc866139293638342ee4a0117788","unresolved":false,"context_lines":[{"line_number":47,"context_line":"        is_admin \u003d ("},{"line_number":48,"context_line":"            \u0027admin\u0027 in roles or \u0027administrator\u0027 in roles"},{"line_number":49,"context_line":"        )"},{"line_number":50,"context_line":"        self.request.context \u003d context.RequestContext.from_environ("},{"line_number":51,"context_line":"            is_admin, self.request.environ)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"8802dc2d_6981acbd","line":50,"updated":"2026-06-29 17:06:04.000000000","message":"Broken call signature in FakeRequestState.set_context(): from_environ(is_admin, self.request.environ) passes the boolean is_admin as the environ positional arg. oslo from_environ(environ, **kwargs) would raise TypeError if this method were ever called.\n\n**Severity**: HIGH | **Confidence**: 0.9\n\n**Risk**: set_context is currently unreferenced after TestContextHook removal, so it fails silently as dead code, but any future use will crash immediately; it also misleads readers about correct from_environ usage.\n\n**Priority**: Before merge\n**Why This Matters**: The intended call is from_environ(self.request.environ, is_admin\u003dis_admin). As written it cannot work and signals the helper was left half-migrated.\n\n**Recommendation**:\nEither delete the now-unused FakeRequestState class and its set_context method entirely (preferred, since no test uses it), or fix the call to context.RequestContext.from_environ(self.request.environ, is_admin\u003dis_admin).","commit_id":"33f401ba53241674995710b51587b11aa2756a4b"}]}
