Repository navigation
fix(ci): resolve ruff ANN401 and mypy strict failures - #5
Merged
Merged
Conversation
Ruff ANN401: - base.py: llm: LLMProvider (imported under TYPE_CHECKING from _llm.py) - All 10 agent __init__: llm: Any → llm: LLMProvider - safety_guardrail: opa_client: Any → OPAClient | None - tacit_knowledge_curator: vector_store: Any → _VectorStoreProtocol | None (new local Protocol with .query() signature) - work_order_mes: cmms_client: Any → object | None (no methods called on it) - governance_lineage: openlineage_client → _OpenLineageProtocol | None, _private_key: Any → Ed25519PrivateKey | None, _load_key() → Ed25519PrivateKey | None - metrics.py: 5 Prometheus fields typed via Counter/Histogram under TYPE_CHECKING - tracing.py: get_tracer() → otel_trace.Tracer via TYPE_CHECKING alias - sparkplug_client: _client typed via paho TYPE_CHECKING import; define _MQTTMessage Protocol; on_connect uses typed params (rc: int, client: mqtt.Client) - opcua_client: _client typed via asyncua TYPE_CHECKING import; write_node *args/*kwargs: object; OPCUAReading.value: object Drop ANN401 from global ruff ignore — code fixes make the rule pass cleanly. Also gitignore data/synthetic/*.jsonl and *.meta.json (generated artifacts). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ruff ANN101/ANN102 (self/cls annotations): - Add `self: Self` to every instance method across all 28 src/ modules - Add `cls: type[Self]` to IndustrialMetrics.get() classmethod - Import `Self` from `typing` in each affected module - Fixes ~130 violations without touching ignore configuration Other ruff fixes: - B905: zip(docs, metas, strict=False) in tacit_knowledge_curator - SIM110: requires_hitl() uses any() instead of for-loop in routing_policy - ARG001: prefix unused typer params (_provider, _since, _fmt) in cli.py - ARG002: write_node(*_args, **_kwargs) in opcua_client - S110: log exception instead of bare pass in governance_lineage handle() - S310: add noqa S310 to urllib.request.Request() line in secrets_vault - PT001/PT023: @pytest.fixture() and @pytest.mark.asyncio() in test files Mypy fixes: - sparkplug_client: annotate self._host: str; type: ignore[assignment] on on_message/on_connect callback assignments (paho stubs signature mismatch) - opa_client: type: ignore[no-any-return] on aiohttp resp.json() - _llm.py: resolved: str = provider or os.getenv(...) to prevent union-attr - governance_lineage: type: ignore[assignment] for load_pem_private_key() which returns a broader private-key union than Ed25519PrivateKey - benchmarks/iabench.py: isinstance guard before .payload access on AgentMessage|AgentDecision union; str() cast for dict[str,str|int] values Bandit fix: - secrets_vault: nosec B310 with justification on urlopen (operator- configured Vault URL, not user-supplied input) Infrastructure: - Add .gitattributes (text=auto eol=lf) to normalize line endings Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ruff format (8 files rewritten with Write tool to fix CRLF + code issues): - sparkplug_client.py: fix _on_paho_message params — each on own line with trailing comma (was hybrid one-line-without-comma, rejected by ruff format) - tacit_knowledge_curator.py: add missing blank line after Protocol class (_VectorStoreProtocol needs 2 blank lines before _SYSTEM_PROMPT = ...) - anomaly_root_cause, hitl_supervisor, safety_guardrail, work_order_mes, opa_client: rewrite to eliminate CRLF mixed with LF from Edit-tool edits Mypy fixes (no type: ignore): - sparkplug_client.py:84: str|None -> use explicit None-check ternary so mypy infers str for self._host (a or b gives str|None when a: str|None) - sparkplug_client.py:145: remove unused # type: ignore[assignment] on on_connect assignment (paho v2 callback types are compatible as-is) - _llm.py:28: same fix for resolved: use ternary instead of `or` Bandit B310 (real fix, not suppression): - secrets_vault.py: parse the Vault URL with urlsplit() and raise ValueError if scheme is not http/https before passing to urlopen - Drop the # noqa: S310 (ruff-only) comments; use # nosec B310 only on the urlopen line with "scheme validated above" annotation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Both urllib.request.Request() and urllib.request.urlopen() trigger ruff S310 (mirror of bandit B310). The previous commit added # nosec B310 (bandit syntax) but not # noqa: S310 (ruff syntax). Both suppressions are now present on lines 75 and 79 of secrets_vault.py, following the urlsplit() scheme validation that genuinely justifies the calls. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The ruff format CI check was failing because Windows clones commit files with CRLF line endings while ruff format on the Linux CI runner expects LF. This commit makes the repo enforce LF globally and for each text file type explicitly, so no future Windows edit can reintroduce CRLF. Changes: - Expand .gitattributes: add explicit per-extension LF rules for all text types (*.py, *.toml, *.yaml, *.yml, *.json, *.md, *.cfg, *.ini, *.sh, Makefile, Dockerfile) in addition to the global `* text=auto eol=lf` - Local git config set to core.autocrlf=input, core.eol=lf - git add --renormalize . run to rewrite all text files to LF in the index (no other files changed because earlier commits already normalized them via the initial .gitattributes) After this commit every checkout on every platform will produce LF-ending text files and ruff format on the Linux CI runner will stop complaining. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Apply .gitattributes normalization to every text file in the repo. .gitattributes was added in 82662a3 but git add --renormalize was not run, so existing CRLF files remained. This commit completes the normalization. Root cause: ruff format (run with ruff 0.4.7, exact CI version verified with uvx) had real code-level format differences in addition to CRLF: - datetime method chains collapsed to single lines where they fit <100 chars - opa_client.py async with parenthesized context manager (PEP 617) - legacy/ files reformatted from CRLF to LF Verification against ruff 0.4.7 (exact CI pin): ruff check src/ tests/ benchmarks/ examples/ → All checks passed ruff format --check src/ tests/ benchmarks/ examples/ → 62 files already formatted Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase
Phase 9: CI green-up
Summary
Resolves the ruff lint (ANN401) and mypy
--stricttype-check failures onmainwithout relaxing tooling. Unit tests on 3.11 and 3.12 already pass; this PR brings the Lint & Format and Type Check jobs to green.What changed
Ruff ANN401 — replace explicit
Anywith proper typesbase.py—llm: Any→llm: LLMProvider(imported underTYPE_CHECKINGfrom_llm.py)__init__signatures —llm: Any→llm: LLMProvidersafety_guardrail—opa_client: Any→OPAClient | Nonetacit_knowledge_curator—vector_store: Any→_VectorStoreProtocol | None(new local Protocol with.query()signature)work_order_mes—cmms_client: Any→object | None(no methods called on it)governance_lineage—openlineage_client→_OpenLineageProtocol | None;_private_key: Any→Ed25519PrivateKey | None;_load_key() -> Ed25519PrivateKey | NoneMypy strict — proper typing for third-party surfaces
metrics.py— 5 Prometheus fields typed viaCounter | Histogram | NoneunderTYPE_CHECKINGtracing.py—get_tracer()returnsotel_trace.TracerviaTYPE_CHECKINGaliassparkplug_client.py—_clienttyped via pahoTYPE_CHECKINGimport; new_MQTTMessageProtocol;on_connectparams typed (rc: int,client: mqtt.Client)opcua_client.py—_clienttyped via asyncuaTYPE_CHECKINGimport;write_node(*args: object, **kwargs: object);OPCUAReading.value: objectConfig
ANN401from global ruff ignore — code fixes make the rule pass cleanly.gitignoreupdated fordata/synthetic/*.jsonland*.meta.json(generated artifacts)Acceptance criteria covered
ruff check .passesruff format --check .passesmypy src/(strict) passespytest tests/unit -qstill green# type: ignorebare suppressions addedHow to verify
Out of scope
paho-mqtt,asyncua,openlineageremain handled via[[tool.mypy.overrides]]ignore_missing_imports = trueper spec §2.3 footnote