free-claude-code/CLAUDE.md
Ali Khokhar 85b601884d
Some checks are pending
CI / Ban suppressions and legacy annotations (push) Waiting to run
CI / pytest (push) Waiting to run
CI / ruff-check (push) Waiting to run
CI / ruff-format (push) Waiting to run
CI / ty (push) Waiting to run
Remove legacy future annotation imports (#982)
## Problem

Python 3.14 provides native lazy annotations, but the codebase still
relied on legacy future annotation imports. Those imports also made
type-only import cycles easier to hide instead of fixing ownership
boundaries.

## Changes

| Before | After |
| --- | --- |
| Python files used `from __future__ import annotations`. | Python files
rely on Python 3.14 native lazy annotations. |
| Some runtime modules used `TYPE_CHECKING` or local imports for
required dependencies. | Runtime modules use top-level owner-module
imports with explicit boundaries. |
| Local and GitHub guardrails only rejected type ignore suppressions. |
Local and GitHub guardrails reject type ignore suppressions and legacy
future annotation imports. |
| Agent docs only documented the no-type-ignore rule. | Agent docs
document the Python 3.14 annotation and import-boundary rules. |

<!-- greptile_comment -->

<details open><summary><h3>Greptile Summary</h3></summary>

This PR moves the codebase to Python 3.14 native lazy annotations. The
main changes are:

- Removed legacy `from __future__ import annotations` imports across
Python modules.
- Promoted selected runtime dependencies from `TYPE_CHECKING` or local
imports to explicit owner-module imports.
- Added local, GitHub, and contract-test guardrails to reject legacy
future annotation imports.
- Updated agent docs with the annotation and import-boundary rules.
- Bumped the package patch version for production-file changes.
</details>

<h3>Confidence Score: 5/5</h3>

Safe to merge with low risk.

The changes are mostly mechanical annotation cleanup with matching CI
and contract-test guardrails. Reviewed import-boundary updates did not
show a confirmed runtime cycle or dependency break.

No files require special attention.

<details><summary><h3><a href="https://www.greptile.com/trex"><img
alt="T-Rex"
src="https://greptile-static-assets.s3.amazonaws.com/trex/trex_green.svg"
height="20" align="absmiddle"></a> T-Rex Logs</h3></summary>

**What T-Rex did**
- Performed an end-to-end validation of the guardrail contract suite: an
environment check confirmed uv availability, a guardrail pytest run used
CPython 3.14.0 with 5 passing contract tests, 3 focused CI-script tests
passed, and the direct CI suppressions guardrail command (including the
legacy future-annotations grep) also passed.

<a
href="https://app.greptile.com/trex/runs/13303335/artifacts"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifactsDark.svg?v=4"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifacts.svg?v=4"><img
alt="View all artifacts"
src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifacts.svg?v=4"></picture></a>

<sub><a href="https://www.greptile.com/trex"><img alt="T-Rex"
src="https://greptile-static-assets.s3.amazonaws.com/trex/trex_green.svg"
height="14" align="absmiddle"></a> Ran code and verified through
T-Rex</sub>
</details>

<details open><summary><h3>Important Files Changed</h3></summary>

| Filename | Overview |
|----------|----------|
| api/runtime.py | Moves messaging, CLI manager, session, limiter, and
tree dependencies from local/type-checking imports to explicit top-level
owner-module imports. |
| messaging/platforms/telegram.py | Removes future annotations and
promotes Telegram SDK type imports into the existing availability guard.
|
| messaging/platforms/telegram_inbound.py | Removes future annotations
and imports Telegram SDK types at module scope for inbound
normalization. |
| tests/contracts/test_import_boundaries.py | Adds an AST contract that
rejects legacy future annotation imports across Python files. |
| scripts/ci.sh | Extends the local suppression check to reject legacy
future annotation imports alongside type-ignore suppressions. |
| scripts/ci.ps1 | Mirrors the local PowerShell CI suppression check for
legacy future annotations. |
| .github/workflows/tests.yml | Renames and broadens the GitHub
guardrail job to reject both type suppressions and legacy future
annotations. |
| pyproject.toml | Bumps the patch version for production-file changes.
|

</details>

<details open><summary><h3>Sequence Diagram</h3></summary>

<a href="#gh-light-mode-only">

```mermaid
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Dev as Developer/CI
participant Guard as Suppression guard
participant AST as Import-boundary contract test
participant Py as Python modules

Dev->>Guard: Run local/GitHub suppression check
Guard->>Py: "Scan *.py for type ignores and future annotations"
Guard-->>Dev: Fail if legacy annotation import remains
Dev->>AST: Run pytest contract tests
AST->>Py: Parse imports with ast
AST-->>Dev: Assert no future annotations/import-boundary violations
Py-->>Dev: Use Python 3.14 native lazy annotations
```

</a>
<a href="#gh-dark-mode-only">

```mermaid
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Dev as Developer/CI
participant Guard as Suppression guard
participant AST as Import-boundary contract test
participant Py as Python modules

Dev->>Guard: Run local/GitHub suppression check
Guard->>Py: "Scan *.py for type ignores and future annotations"
Guard-->>Dev: Fail if legacy annotation import remains
Dev->>AST: Run pytest contract tests
AST->>Py: Parse imports with ast
AST-->>Dev: Assert no future annotations/import-boundary violations
Py-->>Dev: Use Python 3.14 native lazy annotations
```

</a>
</details>

<sub>Reviews (2): Last reviewed commit: ["Remove legacy future
annotations
import"](6e6cda69da)
| [Re-trigger
Greptile](https://app.greptile.com/api/retrigger?id=41875785)</sub>

<!-- /greptile_comment -->
2026-07-04 21:41:51 -07:00

7.6 KiB

AGENTIC DIRECTIVE

This file is identical to AGENTS.md. Keep them in sync.

CODING ENVIRONMENT

  • Install astral uv using "curl -LsSf https://astral.sh/uv/install.sh | sh" if not already installed and if already installed then update it to the latest version
  • Install Python 3.14.0 stable using uv python install 3.14.0 if not already installed (requires uv >=0.9; see [tool.uv] required-version in pyproject.toml)
  • Always use uv run to run files instead of the global python command.
  • Current uv ruff formatter is set to py314 which has supports multiple exception types without paranthesis (except TypeError, ValueError:)
  • Read .env.example for environment variables.
  • All CI checks must pass; failing checks block merge.
  • Add tests for new changes (including edge cases).
  • Before pushing, prefer ./scripts/ci.sh (macOS/Linux) or .\scripts\ci.ps1 (Windows) to run the local CI sequence; requires uv on PATH. The local scripts run Ruff in repair mode (ruff format, then ruff check --fix) before type checking and tests.
  • Use --only / --skip (PowerShell: -Only / -Skip) to run a subset when iterating; use --dry-run to print commands without running them.
  • GitHub CI remains check-only for Ruff (ruff format --check, ruff check) so branch protection verifies committed code.
  • Fall back to individual repair commands when debugging local failures: uv run ruff format, uv run ruff check --fix, uv run ty check, uv run pytest -v --tb=short. Use GitHub-style checks only when verifying enforcement locally: uv run ruff format --check, uv run ruff check.
  • Do not add # type: ignore or # ty: ignore; fix the underlying type issue.
  • Do not add from __future__ import annotations; Python 3.14 native lazy annotations are the project standard.
  • All 5 check IDs are represented in scripts/ci.sh / scripts/ci.ps1 and enforced in tests.yml on push/merge (parallel jobs: suppression grep, ruff-format, ruff-check, ty, pytest).
  • GitHub CI runs on push, pull_request, and merge_group so required checks validate merge queue candidates before they land.
  • Repository protection should use rulesets: a non-bypassable main integrity ruleset requires pull requests, merge queue, required checks, and blocks direct/force pushes to main; a separate review ruleset may allow Alishahryar1/admins to bypass review only.
  • Required status checks: set required status checks to all of those statuses (e.g. Ban suppressions and legacy annotations, ruff-format, ruff-check, ty, pytest—use the exact labels GitHub shows, which may be prefixed with CI /). Remove ci from required checks if it was previously added for the old gate job.

IDENTITY & CONTEXT

  • You are an expert Software Architect and Systems Engineer.
  • Goal: Zero-defect, root-cause-oriented engineering for bugs; test-driven engineering for new features. Think carefully; no need to rush.
  • Code: Write the simplest code possible. Keep the codebase minimal and modular.

ARCHITECTURE PRINCIPLES

  • Shared utilities: Put shared Anthropic protocol logic in neutral core/anthropic/ modules. Do not have one provider import from another provider's utils.
  • DRY: Extract shared base classes to eliminate duplication. Prefer composition over copy-paste.
  • Encapsulation: Use accessor methods for internal state (e.g. set_current_task()), not direct _attribute assignment from outside.
  • Provider-specific config: Keep provider-specific fields (e.g. nim_settings) in provider constructors, not in the base ProviderConfig.
  • Dead code: Remove unused code, legacy systems, and hardcoded values. Use settings/config instead of literals (e.g. settings.provider_type not "nvidia_nim").
  • Performance: Use list accumulation for strings (not += in loops), cache env vars at init, prefer iterative over recursive when stack depth matters.
  • Platform-agnostic naming: Use generic names (e.g. PLATFORM_EDIT) not platform-specific ones (e.g. TELEGRAM_EDIT) in shared code.
  • No type ignores: Do not add # type: ignore or # ty: ignore. Fix the underlying type issue.
  • Python 3.14 annotations: Do not use from __future__ import annotations; rely on native lazy annotations and fix circular import boundaries instead of hiding them with annotation stringization.
  • Imports: Prefer top-level imports. Avoid TYPE_CHECKING and local imports for first-party or required dependencies; if a top-level import creates a cycle, move shared types/protocols to a neutral owner.
  • Complete migrations: When moving modules, update imports to the new owner and remove old compatibility shims in the same change unless preserving a published interface is explicitly required.
  • Maximum Test Coverage: There should be maximum test coverage for everything, preferably live smoke test coverage to catch bugs early

COGNITIVE WORKFLOW

  1. ANALYZE: Read relevant files. Do not guess.
  2. PLAN: Map out the logic. Identify root cause or required changes. Order changes by dependency.
  3. EXECUTE: Fix the cause, not the symptom. Execute incrementally with clear commits.
  4. VERIFY: Run ./scripts/ci.sh or .\scripts\ci.ps1, plus relevant smoke tests when needed. Confirm the fix via logs or output.
  5. SPECIFICITY: Do exactly as much as asked; nothing more, nothing less.
  6. PROPAGATION: Changes impact multiple files; propagate updates correctly.
  7. VERSION: If the commit touches production files on main, bump semver in the same commit (see Versioning).

VERSIONING (MAIN)

Every commit on main that changes a production file must include a semver bump in pyproject.toml in the same commit. Do not merge or push prod changes without updating the version.

Production files

These paths count as production (runtime, packaging, or install surface):

  • api/, cli/, config/, core/, messaging/, providers/
  • .env.example
  • pyproject.toml (dependencies, scripts, packaging)
  • scripts/install.sh, scripts/install.ps1, scripts/uninstall.sh, scripts/uninstall.ps1, scripts/ci.sh, scripts/ci.ps1

These do not require a version bump on their own:

  • tests/, smoke/
  • Docs and assets: README.md, assets/, AGENTS.md, CLAUDE.md
  • CI and repo config: .github/, .gitignore

If a single commit mixes production and non-production edits, still bump the version.

Semver rules

Use [project].version as MAJOR.MINOR.PATCH:

  • PATCH (x.y.Z+1): bug fixes, refactors with no user-visible behavior change, dependency updates, packaging/install fixes.
  • MINOR (x.Y+1.0): backward-compatible features—new providers, admin fields, CLI commands, config options, or behavior additions.
  • MAJOR (X+1.0.0): breaking changes—removed or renamed env vars, incompatible API/CLI/default changes, or migrations users must act on.

When unsure between PATCH and MINOR, prefer PATCH for fixes and MINOR for new capability.

Required steps

  1. Classify the change and choose the bump level.
  2. Update version in pyproject.toml.
  3. Run uv lock so uv.lock reflects the new package version.
  4. Include the version and lockfile updates in the same commit as the production change.

Example commit on main after a packaging fix: bump 1.2.381.2.39, run uv lock, commit together with the fix.

SUMMARY STANDARDS

  • Summaries must be technical and granular.
  • Include: [Files Changed], [Logic Altered], [Verification Method], [Residual Risks] (if no residual risks then say none).

TOOLS

  • Prefer built-in tools (grep, read_file, etc.) over manual workflows. Check tool availability before use.