Skip to content

fix(CODEWIKI-005-2): CU-86akbhhru 7 review findings across 4 files - #45

Merged
michaelassraf merged 6 commits into
mainfrom
ai-fix/codewiki-005-2-9f33a9f8-2cc7a212
Sep 8, 2026
Merged

michaelassraf merged 6 commits into
mainfrom
ai-fix/codewiki-005-2-9f33a9f8-2cc7a212

Conversation

@flamingo

@flamingo flamingo Bot commented Sep 7, 2026

Copy link
Copy Markdown

Closes 7 review findings across 4 files.

Draft — this is a starting point, not a finished change. The fix required judgment, so read it before trusting it.

# Fix confidence Finding Location
1 🟡 85 medium Python analyzer builds dot-only component IDs instead of module::ClassName FQDNs codewiki/src/be/dependency_analyzer/analyzers/python.py:73
2 🟢 90 high Missing module-level docstring in python.py analyzer codewiki/src/be/dependency_analyzer/analyzers/python.py:1
3 🟡 85 medium Broad bare except swallows all errors in _get_module_path fallback codewiki/src/be/dependency_analyzer/analyzers/python.py:43
4 🟢 90 high suffix_matches referenced outside its enclosing for-loop scope, possible NameError/UnboundLocalError or stale-value bug FQDN_NORMALIZATION_FIX.py:152
5 🟡 60 medium Standalone proposed-fix module FQDN_NORMALIZATION_FIX.py sits at repo root, unused and undocumented as a scratch file FQDN_NORMALIZATION_FIX.py:1
6 🟡 60 medium verify_fqdn_implementation.py checks for dot-based FQDN construction (f"{namespace}.{original_id}") contradicting the mandated :: separator verify_fqdn_implementation.py:30

What changed — and what was deliberately left — is explained per finding as inline review comments on the lines each finding touched.


Run: https://product-hub.flamingo.so/admin/code-review
Run id: 2cc7a212-e9ac-481a-a76e-5f03d762c00c

Merging this PR is recorded as acceptance of the rule that produced it;
closing it unmerged is recorded as rejection. Both feed rule health, so
closing a wrong suggestion is useful rather than merely tidy.

ClickUp task: CU-86akbhhru CodeWiki backend and CLI review findings (12 PRs)

@flamingo flamingo Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 What this fix changed, finding by finding

6 finding(s) fixed in this draft — 6 explained inline on the diff.

base_classes = [self._extract_base_class_name(base) for base in node.bases]
base_classes = [name for name in base_classes if name is not None]

component_id = f"{self._get_module_path()}.{node.name}"

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🔴 Python analyzer builds dot-only component IDs instead of module::ClassName FQDNs

Changed all dot-only component ID constructions to use '::' as the module/class separator in PythonASTAnalyzer: _get_component_id (line ~66), visit_ClassDef's component_id and base-class callee (lines ~78, ~104), _process_function_node's component_id (line ~119), and visit_Call's caller_id/callee_id construction (lines ~163-170). Intra-module member separators (e.g. ClassName.method) remain dot-separated, only the module::name boundary now uses '::' per CODEWIKI-005-2/008.

🤖 Prompt for AI agents
In codewiki/src/be/dependency_analyzer/analyzers/python.py around line 73, review and complete this code-review fix: Python analyzer builds dot-only component IDs instead of module::ClassName FQDNs.
What the draft fix changed: Changed all dot-only component ID constructions to use '::' as the module/class separator in PythonASTAnalyzer: `_get_component_id` (line ~66), `visit_ClassDef`'s `component_id` and base-class `callee` (lines ~78, ~104), `_process_function_node`'s `component_id` (line ~119), and `visit_Call`'s `caller_id`/`callee_id` construction (lines ~163-170). Intra-module member separators (e.g. `ClassName.method`) remain dot-separated, only the module::name boundary now uses '::' per CODEWIKI-005-2/008.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟡 85 medium — react 👍/👎 to teach the reviewer

clustering system's expected FQDN format.
"""

import ast

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Missing module-level docstring in python.py analyzer

Added a module-level triple-quoted docstring at the top of the file (before imports) describing the analyzer's responsibility, matching the style of the sibling php.py analyzer.

🤖 Prompt for AI agents
In codewiki/src/be/dependency_analyzer/analyzers/python.py around line 1, review and complete this code-review fix: Missing module-level docstring in python.py analyzer.
What the draft fix changed: Added a module-level triple-quoted docstring at the top of the file (before imports) describing the analyzer's responsibility, matching the style of the sibling php.py analyzer.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 90 high — react 👍/👎 to teach the reviewer

Comment on lines 58 to 74
path = path[:-len(ext)]
break
return path.replace('/', '.').replace('\\', '.')
except:
except Exception as e:
logger.debug(f"Falling back to raw file_path for module path: {e}")
return str(self.file_path).replace('/', '.').replace('\\', '.')

def _get_component_id(self, name: str) -> str:
"""Generate dot-separated component ID."""
"""Generate component ID using '::' separator for module::ClassName FQDN format."""
module_path = self._get_module_path()
if self.current_class_name:
return f"{module_path}.{self.current_class_name}.{name}"
return f"{module_path}::{self.current_class_name}.{name}"
else:
return f"{module_path}.{name}"
return f"{module_path}::{name}"

def generic_visit(self, node):
"""Override generic_visit to continue AST traversal."""

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Broad bare except swallows all errors in _get_module_path fallback

Replaced the bare except: in _get_module_path with except Exception as e: and added logger.debug(...) logging of the exception before falling back to the raw file_path computation, matching the logging style used elsewhere in the file.

🤖 Prompt for AI agents
In codewiki/src/be/dependency_analyzer/analyzers/python.py around line 43, review and complete this code-review fix: Broad bare except swallows all errors in _get_module_path fallback.
What the draft fix changed: Replaced the bare `except:` in `_get_module_path` with `except Exception as e:` and added `logger.debug(...)` logging of the exception before falling back to the raw file_path computation, matching the logging style used elsewhere in the file.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟡 85 medium — react 👍/👎 to teach the reviewer

Comment thread FQDN_NORMALIZATION_FIX.py
Comment on lines 135 to 141
# This handles cases where LLM includes partial path
# Example: "deps.openframe-oss-lib.src.main.java.Class"
# should match "openframe-oss-lib.different.path.java.Class"
suffix_matches: List[str] = []
if '.' in comp_id:
# Try matching last 2-4 segments
segments = comp_id.split('.')

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🔴 suffix_matches referenced outside its enclosing for-loop scope, possible NameError/UnboundLocalError or stale-value bug

In normalize_component_ids_enhanced, initialized suffix_matches: List[str] = [] immediately before the if '.' in comp_id: block (Strategy 5), so the variable is always defined before the subsequent if suffix_matches and len(suffix_matches) == 1: check, eliminating the possible NameError/UnboundLocalError and stale-value read when segments has fewer than 2 elements or the for-loop's last iteration produced no matches.

🤖 Prompt for AI agents
In FQDN_NORMALIZATION_FIX.py around line 152, review and complete this code-review fix: suffix_matches referenced outside its enclosing for-loop scope, possible NameError/UnboundLocalError or stale-value bug.
What the draft fix changed: In `normalize_component_ids_enhanced`, initialized `suffix_matches: List[str] = []` immediately before the `if '.' in comp_id:` block (Strategy 5), so the variable is always defined before the subsequent `if suffix_matches and len(suffix_matches) == 1:` check, eliminating the possible NameError/UnboundLocalError and stale-value read when `segments` has fewer than 2 elements or the for-loop's last iteration produced no matches.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 90 high — react 👍/👎 to teach the reviewer

Comment thread FQDN_NORMALIZATION_FIX.py
Comment on lines 8 to 18
4. Partial path matching for complex Java packages

Replace the normalization loop in cluster_modules.py:212-233 with this code.

NOTE: This is a scratch/reference module, not imported anywhere in the
codebase. It documents a proposed patch for cluster_modules.py and should be
merged into that file (or moved to docs/ or a PR description) rather than
kept as standalone code at the repository root.
"""

from typing import Dict, List

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Standalone proposed-fix module FQDN_NORMALIZATION_FIX.py sits at repo root, unused and undocumented as a scratch file

Added a clarifying note to the module docstring at the top of FQDN_NORMALIZATION_FIX.py stating this is a scratch/reference module not imported anywhere and that it should be merged into cluster_modules.py or moved to docs/PR description. This documents the issue in-file but does not remove or relocate the file itself, since deleting it or merging it into cluster_modules.py is out of scope for a single-file fix and risks losing the proposed logic without visibility into the target file's current state — a complete fix requires editing codewiki/src/be/cluster_modules.py (not shown) and then deleting this file, which cannot be safely done here.

🤖 Prompt for AI agents
In FQDN_NORMALIZATION_FIX.py around line 1, review and complete this code-review fix: Standalone proposed-fix module FQDN_NORMALIZATION_FIX.py sits at repo root, unused and undocumented as a scratch file.
What the draft fix changed: Added a clarifying note to the module docstring at the top of `FQDN_NORMALIZATION_FIX.py` stating this is a scratch/reference module not imported anywhere and that it should be merged into `cluster_modules.py` or moved to docs/PR description. This documents the issue in-file but does not remove or relocate the file itself, since deleting it or merging it into `cluster_modules.py` is out of scope for a single-file fix and risks losing the proposed logic without visibility into the target file's current state — a complete fix requires editing `codewiki/src/be/cluster_modules.py` (not shown) and then deleting this file, which cannot be safely done here.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟡 60 medium — react 👍/👎 to teach the reviewer

with open('codewiki/src/be/dependency_analyzer/ast_parser.py', 'r') as f:
content = f.read()

checks = {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🔴 verify_fqdn_implementation.py checks for dot-based FQDN construction (f"{namespace}.{original_id}") contradicting the mandated :: separator

In check_ast_parser(), changed the check key/string from 'fqdn = f"{namespace}.{original_id}"' (dot-separated) to 'fqdn = f"{namespace}::{original_id}"' (double-colon separated) to align the verification script with the CODEWIKI-005-2/008 mandated module.path::ClassName FQDN format. This only fixes the verifier's expectation; it does not change ast_parser.py itself, which is out of scope for this file — if ast_parser.py still builds FQDNs with a dot, this check will now correctly fail, surfacing the mismatch for reconciliation rather than silently validating a non-conformant convention. A complete fix requires confirming/updating the actual separator used in ast_parser.py in a follow-up change.

🤖 Prompt for AI agents
In verify_fqdn_implementation.py around line 30, review and complete this code-review fix: verify_fqdn_implementation.py checks for dot-based FQDN construction (f"{namespace}.{original_id}") contradicting the mandated `::` separator.
What the draft fix changed: In `check_ast_parser()`, changed the check key/string from `'fqdn = f"{namespace}.{original_id}"'` (dot-separated) to `'fqdn = f"{namespace}::{original_id}"'` (double-colon separated) to align the verification script with the CODEWIKI-005-2/008 mandated `module.path::ClassName` FQDN format. This only fixes the verifier's expectation; it does not change `ast_parser.py` itself, which is out of scope for this file — if `ast_parser.py` still builds FQDNs with a dot, this check will now correctly fail, surfacing the mismatch for reconciliation rather than silently validating a non-conformant convention. A complete fix requires confirming/updating the actual separator used in `ast_parser.py` in a follow-up change.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟡 60 medium — react 👍/👎 to teach the reviewer

@flamingo flamingo Bot changed the title fix(CODEWIKI-005-2): 7 review findings across 4 files fix(CODEWIKI-005-2): CU-86akbhhru 7 review findings across 4 files Sep 7, 2026
@michaelassraf

Copy link
Copy Markdown

Blocking — same root cause as #34, which this compounds.

Two problems:

1. python.py changes _get_component_id from . to ::. Combined with ast_parser.py's f"{namespace}::{original_id}", this yields double-:: FQDNs. See #34 for the measurements.

2. extract_module_hint/extract_package_hint now hard-reject FQDNs without ::, returning "unknown"/"core". Against a double-:: FQDN the guard passes but module_part = fqdn.split('::')[0] is just the namespace, so the hints degrade further than #34 alone:

FQDN main this PR
ns::src.main.java.com.openframe.api.controller::DeviceController (openframe-oss-tenant, controller) (openframe-oss-tenant, **core**)

Package hint collapses to core for everything, because Strategy 1 now only searches the namespace segment instead of the whole path.

Also: verify_fqdn_implementation.py is updated to expect fqdn = f"{namespace}::{original_id}" in ast_parser.py, but this PR does not change ast_parser.py — so the verification script fails against its own branch. (#34 is what changes that line.)

The except:except Exception as e: fix in python.py and the suffix_matches initialisation in FQDN_NORMALIZATION_FIX.py are fine and could land separately.

Bring the branch up to date with main (PRs #48, #49, #52, #53, #54, #55).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
michaelassraf added a commit that referenced this pull request Sep 8, 2026
…or change

- generate_sub_module_documentations.py: the branch's
  normalize_component_ids_by_lookup(specs, components, id_to_fqdn) call was a
  three-argument call against a two-argument function, unpacked as a 3-tuple
  from a dict return. #47 has since landed the correct dedupe via
  normalize_component_id_list, so this resolves in favour of main.

- analyzers/c.py: reverted the '.' -> '::' component-id change. Changing the
  separator for C alone is inconsistent with the other seven analyzers, and the
  FQDN format question belongs with #34/#45 where it can be made coherent
  end-to-end. The module docstring is kept.

What remains is worth having:
- deps.py: dict[str, any] -> dict[str, Any]. 'any' is the builtin function, not
  a type, so the old annotation was meaningless.
- agent_orchestrator.__init__: drops a local logger that shadowed the
  module-level one (same logging.getLogger(__name__) object, so no behaviour
  change).
- typescript.py _get_parent_context: returns 'unknown' instead of falling off
  the end as None, honouring its '-> str' annotation. Its one caller stores the
  value and nothing reads it, so this cannot regress.
- The tool description now asks for integer IDs, matching what
  format_potential_core_components actually puts in the prompt.
- Module docstrings throughout, plus from_web_job added to the config.py summary.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
#34 landed the coherent '::' format: '<namespace>.<module.path>::<Name>', with
the namespace still joined by '.' so each FQDN carries exactly one separator.
This branch's verify_fqdn_implementation.py asserted the opposite - that
ast_parser builds f"{namespace}::{original_id}" - which is precisely the
double-separator bug #34 fixed, so the script failed against its own branch.
Restored to expect the '.' join; the script now passes.

python.py's separator change is already on main via #34, so the conflicting
hunk (competing wording on one debug log line) resolves in favour of main.

What remains is this branch's real contribution: extract_module_hint and
extract_package_hint now parse only the module portion before '::' and warn on
an FQDN that lacks one, instead of scanning the whole string. On well-formed
FQDNs the output is identical to main's; a malformed id degrades to
unknown/core with a warning rather than silently yielding a wrong hint.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@michaelassraf
michaelassraf marked this pull request as ready for review September 8, 2026 03:09
@michaelassraf
michaelassraf merged commit 83dd974 into main Sep 8, 2026
@michaelassraf
michaelassraf deleted the ai-fix/codewiki-005-2-9f33a9f8-2cc7a212 branch September 8, 2026 03:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant