Skip to content

fix: declare anthropic and tree-sitter-zig, guard against dep drift#30

Merged
joshbouncesecurity merged 1 commit intomasterfrom
fix/declare-anthropic-and-dep-guard
Apr 19, 2026
Merged

fix: declare anthropic and tree-sitter-zig, guard against dep drift#30
joshbouncesecurity merged 1 commit intomasterfrom
fix/declare-anthropic-and-dep-guard

Conversation

@joshbouncesecurity
Copy link
Copy Markdown
Owner

Summary

  • Re-declare anthropic and add tree-sitter-zig in pyproject.toml so declared deps match actual imports; a clean pip install -e . no longer crashes openant parse at from utilities ....
  • Delete libs/openant-core/requirements.txt and switch CI to pip install -e ".[dev]" — a single source of truth for deps, and the codepath that just broke is now exercised on every CI run.
  • Add tests/test_declared_dependencies.py: a static check that every third-party import under the packaged dirs maps to a declared dependency, plus a smoke test that each packaged top-level module imports cleanly.

Why

PR #25 ("migrate all LLM calls to Claude Agent SDK") dropped anthropic from pyproject.toml but left four files still using it live: utilities/context_enhancer.py (not even mentioned in the PR body), utilities/finding_verifier.py, utilities/agentic_enhancer/agent.py, and report/generator.py — the factory-based create_anthropic_client() callsites were cleaned up, but direct anthropic.Anthropic() fallbacks and except anthropic.RateLimitError handlers were left in place. Because utilities/__init__.py eagerly loads context_enhancer, any clean install blows up at import time.

The bug stayed hidden because CI installed from requirements.txt (which still pinned anthropic==0.75.0), dev venvs already had anthropic from before the migration, and the three manual smoke-tests in #25's own test plan were never checked off. The upstream merge (#29) then added a Zig parser that imports tree_sitter_zig without declaring it — same bug pattern, same reason nobody noticed.

Test plan

  • pytest libs/openant-core/tests/test_declared_dependencies.py passes (8/8).
  • Existing unit tests still pass (test_parser_adapter.py, test_token_tracker.py sampled).
  • Clean pip install -e . into a fresh managed venv (~/.openant/venv/) — import openant, core, utilities, parsers, prompts, context, report all succeed.
  • openant --help (via the Go CLI driving the managed venv) runs.
  • CI green on all three OS legs once this lands.

Follow-ups (not in this PR)

  • Finish the SDK migration properly: replace the remaining anthropic.Anthropic() instantiations and anthropic.*Error catches in the four files above with claude-agent-sdk equivalents. Then anthropic can actually come out of pyproject.toml.

🤖 Generated with Claude Code

PR #25 claimed to remove `anthropic` from pyproject.toml but left four
files still using it (`utilities/context_enhancer.py`,
`utilities/finding_verifier.py`, `utilities/agentic_enhancer/agent.py`,
`report/generator.py`). Every clean install fails at
`from utilities ...` because `utilities/__init__.py` eagerly loads
`context_enhancer`. The upstream merge also added a Zig parser that
imports `tree_sitter_zig` without declaring it.

- Re-declare `anthropic>=0.40.0` and add `tree-sitter-zig>=0.20.0` to
  pyproject.toml so the declared deps match actual imports.
- Delete requirements.txt — it was a hand-maintained duplicate of
  pyproject.toml's deps, and the drift is exactly what let #25 slip
  through CI. Single source of truth now.
- Update CI to install via `pip install -e ".[dev]"` so pyproject.toml
  is exercised on every run.
- Add `tests/test_declared_dependencies.py`: a static check that every
  third-party import under the packaged dirs maps to a declared
  dependency, plus a smoke test that each packaged top-level module
  imports cleanly. Catches the regression class directly.
- Update README install instructions to match.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@joshbouncesecurity joshbouncesecurity merged commit c11cd50 into master Apr 19, 2026
7 checks passed
joshbouncesecurity added a commit that referenced this pull request Apr 19, 2026
Final step of the SDK migration tracked in issue #35. Removes
"anthropic>=0.40.0" from pyproject.toml now that no Python code under
libs/openant-core/ still imports it.

Cleanup alongside the dep drop:

- `utilities/context_enhancer.py`: remove the now-orphaned `import anthropic`.
  PR #34 took it out of `_build_error_info`; PR #36 removed `shared_client`.
  The import line was kept alive across both as a staging measure.

- `openant/cli.py` (cmd_report_data): replace the last `anthropic.Anthropic()`
  instantiation — used for the HTML report's remediation-guidance LLM call —
  with `AnthropicClient(model=MODEL_AUXILIARY).analyze_sync(...)`. Usage
  tracking is now automatic via the global TokenTracker; cost display pulls
  from `client.get_last_call()`. Neither PR #36 nor #37 touched this site
  because it was outside their scope; the dep-drift test (PR #30) surfaced
  it when pyproject.toml's dependency list shrank.

- `utilities/rate_limiter.py`: update the module docstring's example. The
  pre-migration example showed `except anthropic.RateLimitError as e:
  retry_after = e.response.headers.get(...)`. That code path no longer
  exists — rate-limit detection is centralised in `llm_client._run_query`,
  which raises `utilities.sdk_errors.RateLimitError` after notifying the
  global limiter. Example updated to match.

Verification:
- `grep -rn '^import anthropic\|^from anthropic' libs/openant-core/` returns
  zero hits.
- `grep -rn 'anthropic\.' libs/openant-core/` returns only a historical
  docstring reference in `sdk_errors.py`.
- `tests/test_declared_dependencies.py` passes — the regression guard from
  PR #30 now enforces that no undeclared imports exist with anthropic gone.
- `tests/test_sdk_errors.py` (12) + `tests/test_sdk_error_surfacing.py` (9)
  all pass.
- `import openant, core, utilities, parsers, prompts, context, report` all
  succeed.

End state: zero `anthropic` Python dep, all LLM traffic routes through the
Claude Agent SDK via `utilities.llm_client`. Step 8 (end-to-end verification
with a live API key) is the only remaining non-user-action item in the plan.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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