GitNexus/gitnexus/src/core/group
luyua9 df2ed009ce
fix(group): detect httpx AsyncClient alias imports (#1687)
* fix(group): detect httpx AsyncClient alias imports

* fix(group): anchor httpx dotted imports and skip shadowed aliases

Addresses Findings 1-3 of the production-readiness review on PR #1687.

- F1: the `(dotted_name (identifier) @module)` capture matches every
  segment of a dotted module path, so `import package.httpx as hx` and
  `from package.httpx import AsyncClient` would falsely populate the
  alias sets. Anchor the check on `moduleNode.parent?.text === 'httpx'`
  so the full dotted_name must equal `httpx`.

- F2: `moduleAliases` and `asyncClientAliases` were file-global and
  unaware of Python scope. A function-local rebind like
  `AsyncClient = lambda: MockClient()` left the alias entry intact and
  any subsequent `client = AsyncClient(); client.get(...)` emitted a
  false-positive consumer contract. Walk every
  `(assignment left: (identifier) @name)` whose name matches an alias,
  record the enclosing function/class scope as poisoned, and skip
  direct- and module-attribute matches when the call site is inside
  that scope chain.

- F3: extend the existing fixture with dotted-package look-alikes and
  three local-shadow cases (`shadow_direct_alias`, `shadow_module_alias`,
  `shadow_direct_context`) and assert the would-be FP contractIds are
  not emitted.

- F6: refresh the module-level docstring to mention the supported
  import-alias forms and the shadow-exclusion behavior.

* refactor(group): tighten httpx alias shadow detection and broaden tests

Follow-up addressing the residual review findings on PR #1687.

- Replace inline scope-key construction in isAliasShadowed with a
  getScopeKey call so the two helpers cannot drift apart (M1).
- Collapse the double tree traversal in collectHttpxAsyncClients: build
  one combined alias set and pass it to a single
  collectAliasShadowScopes call (perf, P2).
- Add a `shadowScopeKey` helper that returns the scope a rebind actually
  shadows under Python LEGB rules: function scope for in-function
  rebinds, 'module' for top-level rebinds, and `null` for class-body
  rebinds (class attributes do not shadow bare-name lookups in methods).
  Removes the previous blanket `scopeKey === 'module'` skip and now
  correctly poisons module-level rebinds (correctness #1).
- Extend `ALIAS_SHADOW_PATTERNS` to cover tuple, list, and pattern_list
  destructuring targets (correctness #2).
- Rename `ALIAS_REBIND_PATTERNS` to `ALIAS_SHADOW_PATTERNS` and update
  the block comment to say "shadowed" rather than "poisoned" (M4).
- Collapse `callScopeKeys` to a single-line return; the dead Set wrap
  was misleading future readers (M2).

Tests:
- New negative fixtures for 3-segment dotted import
  (`import a.b.c.httpx as deep_evil`), relative import
  (`from .httpx import AsyncClient as rel_evil_async`), tuple
  destructuring rebind, and an isolated file exercising the module-level
  rebind path (T1, correctness #2, expanded F2).
- New positive fixture confirming that a class-body assignment of
  `AsyncClient` does NOT poison the surrounding methods.
- Add a positive control assertion for `module_direct_client` so the
  dotted-package negative assertions cannot pass vacuously (T3).

---------

Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
Co-authored-by: Test <test@example.com>
2026-05-21 18:24:27 +01:00
..
extractors fix(group): detect httpx AsyncClient alias imports (#1687) 2026-05-21 18:24:27 +01:00
bridge-db.ts fix(security): log-injection, http-to-file-access, client-side-request-forgery (#1456) 2026-05-09 17:26:32 +01:00
bridge-schema.ts feat(group): bridge.lbug storage + contract matching expansion (1/4 of #606 split) (#795) 2026-04-11 19:46:12 +01:00
config-parser.ts feat: add IncludeExtractor for C++ cross-repo include tracking (group) (#1156) 2026-05-09 09:31:59 +01:00
contract-extractor.ts feat(group): add group infrastructure and contract matching 2026-04-02 00:39:43 +03:00
cross-impact.ts fix(ingestion): close ReDoS in cobol-preprocessor + rust-workspace + resource-exhaustion in cross-impact (U8) (#1331) 2026-05-08 09:10:07 +01:00
group-path-utils.ts feat: cross-repo impact analysis (#794) — @repo MCP routing + group resources (#984) 2026-04-20 11:55:07 +01:00
matching.ts feat: add IncludeExtractor for C++ cross-repo include tracking (group) (#1156) 2026-05-09 09:31:59 +01:00
normalization.ts feat(group): bridge.lbug storage + contract matching expansion (1/4 of #606 split) (#795) 2026-04-11 19:46:12 +01:00
PIPELINE.md feat(group): extractor expansion + manifest extractor (2/4 of #606 split) (#796) 2026-04-13 08:49:30 +01:00
resolve-at-member.ts feat: cross-repo impact analysis (#794) — @repo MCP routing + group resources (#984) 2026-04-20 11:55:07 +01:00
service-boundary-detector.ts fix(group): address 4 HIGH-priority issues from PR #626 review 2026-04-02 12:55:33 +03:00
service.ts fix(ingestion): close ReDoS in cobol-preprocessor + rust-workspace + resource-exhaustion in cross-impact (U8) (#1331) 2026-05-08 09:10:07 +01:00
storage.ts feat: add IncludeExtractor for C++ cross-repo include tracking (group) (#1156) 2026-05-09 09:31:59 +01:00
sync.ts feat: add IncludeExtractor for C++ cross-repo include tracking (group) (#1156) 2026-05-09 09:31:59 +01:00
types.ts feat: add IncludeExtractor for C++ cross-repo include tracking (group) (#1156) 2026-05-09 09:31:59 +01:00