Skip to content

chore: PEP 440 compliance, mypy --strict cleanliness, lint/format pass#120

Merged
AbdelStark merged 11 commits into
mainfrom
claude/production-ready-codebase-OVqw3
May 21, 2026
Merged

chore: PEP 440 compliance, mypy --strict cleanliness, lint/format pass#120
AbdelStark merged 11 commits into
mainfrom
claude/production-ready-codebase-OVqw3

Conversation

@AbdelStark

Copy link
Copy Markdown
Owner
  • Replace non-PEP-440 0.1.0-draft with 0.1.0.dev0; dynamic
    version sourced from geno_lewm/__init__.py (Hatch).
  • Curate top-level geno_lewm.__all__ so the implemented surface
    (errors, observability, attestation, action specs, decorators)
    is reachable from the package root.
  • Add py.typed marker and tools/__init__.py so downstream type
    checkers and python -m tools.* work as documented.
  • Make tools/api/snapshot.py produce a Python-version-stable enum
    signature; regenerate tests/api/public_surface.json.
  • Tighten pyproject.toml: ruff lint+format with strong rule set,
    mypy strict (now zero errors across geno_lewm/ and tools/),
    pytest strict markers + filterwarnings=error, branch coverage at
    95% gate, optional dep groups split into train/eval/deploy/dev/ docs/all.
  • Resolve every ruff (B, C4, UP, N, RUF, SIM, PIE, PTH, PERF, FURB,
    PLR, LOG, ASYNC) finding across geno_lewm/, tools/, tests/.
  • Resolve every mypy --strict error: TypedDict for histogram
    snapshot, IO[str] stream typing in the verify CLI, Iterator
    return type on ErrorCodeEntry, setattr for method reassignment
    in decorators.
  • Add format-skip directives where deliberate same-line statements
    exercise the per-call-site dedupe in @deprecated.

All 417 tests pass; ruff format/check, mypy --strict,
check_error_codes, check_event_names, check_no_print,
check_network_confined, and the public-API snapshot gate are clean.

claude added 6 commits May 21, 2026 05:37
- Replace non-PEP-440 `0.1.0-draft` with `0.1.0.dev0`; dynamic
  version sourced from `geno_lewm/__init__.py` (Hatch).
- Curate top-level `geno_lewm.__all__` so the implemented surface
  (errors, observability, attestation, action specs, decorators)
  is reachable from the package root.
- Add `py.typed` marker and `tools/__init__.py` so downstream type
  checkers and `python -m tools.*` work as documented.
- Make `tools/api/snapshot.py` produce a Python-version-stable enum
  signature; regenerate `tests/api/public_surface.json`.
- Tighten `pyproject.toml`: ruff lint+format with strong rule set,
  mypy strict (now zero errors across `geno_lewm/` and `tools/`),
  pytest strict markers + filterwarnings=error, branch coverage at
  95% gate, optional dep groups split into `train/eval/deploy/dev/
  docs/all`.
- Resolve every ruff (B, C4, UP, N, RUF, SIM, PIE, PTH, PERF, FURB,
  PLR, LOG, ASYNC) finding across `geno_lewm/`, `tools/`, `tests/`.
- Resolve every mypy `--strict` error: TypedDict for histogram
  snapshot, IO[str] stream typing in the verify CLI, Iterator
  return type on ErrorCodeEntry, `setattr` for method reassignment
  in decorators.
- Add format-skip directives where deliberate same-line statements
  exercise the per-call-site dedupe in `@deprecated`.

All 417 tests pass; ruff format/check, mypy --strict,
check_error_codes, check_event_names, check_no_print,
check_network_confined, and the public-API snapshot gate are clean.
CI/CD pipeline
- .github/workflows/ci.yml: matrix tests on Python 3.10/3.11/3.12/3.13
  across Linux/macOS/Windows, ruff lint+format, mypy --strict, the
  five contract gates (errors / events / surface / print / network),
  build smoke test (sdist+wheel + import sanity), mkdocs --strict
  build, codecov upload, single required-check fan-in.
- .github/workflows/release.yml: tag-driven PyPI publish via OIDC
  trusted publishing (no API tokens), TestPyPI dry-run on manual
  dispatch, GitHub release with extracted changelog notes.
- .github/workflows/codeql.yml: weekly + per-PR static analysis with
  security-extended queries.
- .github/workflows/docs.yml: GitHub Pages deploy.
- Removed legacy .github/workflows/lint-errors.yml (superseded by ci.yml).

Documentation site
- mkdocs.yml with material theme, mkdocstrings, gen-files, literate-nav.
- docs/index.md, docs/quickstart.md: actually-runnable walkthrough
  hitting the implemented surface.
- docs/_gen/ scripts that build the public API reference, the error-code
  table, the log-event table, RFC mirror with rewritten links, and the
  project-root pages (changelog / contributing / security / privacy /
  code-of-conduct) at mkdocs build time so docs cannot drift from the
  runtime registries or the canonical repo sources.
- docs/api/{experimental,metrics}.md hubs.
- docs/release/signing-keys.md trust-anchor placeholder.
- Rewrote all repo-root-relative links across docs/spec/, docs/rfcs/,
  docs/{faq,design-decisions,glossary,maintainers}.md, and the roadmap
  tracker so mkdocs --strict passes with zero warnings.

OSS hygiene
- .pre-commit-config.yaml mirrors every CI gate (large files, line
  endings, ruff, mypy, the five contract linters, snapshot drift).
- .editorconfig, .gitattributes for cross-editor / cross-platform
  consistency.
- .github/CODEOWNERS, .github/FUNDING.yml, .github/dependabot.yml
  (weekly minor/patch + security updates, scoped to pip + actions).
- README badges (CI / CodeQL / Docs / PyPI / Python / License / mypy
  strict / ruff / pre-commit), a sharper "what ships today" table
  for the implemented surface, a real quickstart (EditSpec /
  apply_edit / verify CLI), and a dev-loop block that mirrors the CI
  gates.
- CHANGELOG: full [Unreleased] entry for the packaging /
  tooling / CI / docs / OSS-hygiene work, plus rolled the previously
  separate [Unreleased] block into the [0.1.0-draft] section.
\`make ci\` runs format-check, ruff lint, mypy --strict, every AST
gate, pytest -n auto, and mkdocs --strict — the exact set CI runs.
Individual targets (\`make types\`, \`make docs\`, \`make build-check\`,
…) are available for targeted iteration. \`make snapshot\` is the
documented way to regenerate the public-surface snapshot when an API
change is intentional.
Add tests/unit/test_coverage_extras.py covering the small branches
the per-module suites don't exercise: counter/gauge/histogram reset,
snapshot_all kind tagging, exporter NaN/+Inf/-Inf rendering, default
exporter path env+home fallback, logger level rejection, unknown
event passthrough, pretty stderr formatter (incl. step + error_code
columns), trace-context round-trip, get_logger caching, logged_run's
both-paths exception flushing, shutdown_run sink close, looks_like_sha256
positive/negative branches, redaction_stats helpers, every synthetic
sampler validation branch (negative n, type_mix=0, malformed length_dist,
N-anchor skipping), receipt schema rejections, and to_json timestamp
shape.

Coverage rises from 92.89 % to 96.07 % branch; the 95 % gate now passes
on a clean run. Total tests: 462 (was 417).
Supply-chain
- .github/workflows/scorecard.yml — OpenSSF Scorecard weekly + on
  push to main. SARIF lands in the Security tab; results publish to
  the OpenSSF dashboard for the README badge.
- release.yml now produces a CycloneDX SBOM (cyclonedx-py environment)
  alongside the wheel + sdist, computes SHA256SUMS for the dist
  bundle, and emits a SLSA-3 provenance attestation
  (slsa-framework/slsa-github-generator) so consumers can verify the
  build claim from a single intoto.jsonl.

License header gate
- tools/lint/check_license_headers.py: AST-free linter that requires
  `# SPDX-License-Identifier: Apache-2.0` in the head of every shipped
  .py file under geno_lewm/ and tools/.
- Apply the header to every existing module.
- Wire into Makefile (\`make gates\`), .pre-commit-config.yaml, and CI
  (.github/workflows/ci.yml).

Project hygiene
- .github/labels.yml — declarative label set covering the triage /
  type / area / priority / effort / status taxonomy referenced from
  CONTRIBUTING.md and the issue templates.
- .github/workflows/labels.yml — sync labels on push, prune
  out-of-config entries.
- .github/workflows/stale.yml — 90-day stale / 120-day close cadence
  for issues and PRs. RFCs, "good first issue", "help wanted", any
  "priority:high|medium", and "status:blocked" are exempt so the
  long-tail design work is never pruned.
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

claude added 5 commits May 21, 2026 12:17
Every CI job was failing in ~5 seconds because the previous setup
used \`uv python install\` (which downloads Python into uv's managed
cache without adding it to PATH) followed by \`uv pip install
--system\` (which targets the PATH-discovered interpreter). The two
calls don't compose; uv reported "no system Python found" and the
step exited immediately.

Fix: prepend \`actions/setup-python@v5\` to every job so a Python
interpreter is on PATH, set \`UV_SYSTEM_PYTHON=1\` at the workflow
env level so \`uv pip install\` implicitly targets it, and drop the
now-redundant \`uv python install\` / \`--system\` flag.

Applied to ci.yml (lint, types, gates, tests, build, docs),
docs.yml, and release.yml.
The astral-sh/setup-uv@v3 + uv pip install --system combo was failing
every job in <10s on every runner (Linux/macOS/Windows) regardless of
the PATH-fix attempt. The CI workload is 13 small jobs — pip's speed
is not the bottleneck, and removing uv eliminates a moving piece.

Replace with the boring pattern that always works:
  - actions/setup-python@v5 (cache: pip, cache-dependency-path: pyproject.toml)
  - python -m pip install -e ".[dev]"

Applied uniformly to ci.yml, docs.yml, release.yml.

Local development still uses uv (Makefile, CONTRIBUTING, pyproject
dev extra unchanged).
\`str(Path.home() / \".geno-lewm\" / \"logs\" / \"metrics.prom\")\` produces
backslash-separated output on Windows, so the previous
\`.endswith(\".geno-lewm/logs/metrics.prom\")\` assertion failed there.
Compare path components via \`.parts\` instead; the check is identical
on POSIX and works on Windows.
Windows + pytest-xdist's spawn-based workers re-import the package
per worker, which surfaces flaky failures around the module-level
state in geno_lewm.observability and geno_lewm.metrics. Disable
xdist on Windows only (still -n auto on Linux/macOS, where xdist
uses fork-based workers and the state isn't reimported).

Also upload pytest stdout/stderr as an artifact on failure so the
exact failing test surfaces without needing log-stream access.
The CLI-print allowlist compared paths via
\`str(rel).startswith(str(p) + \"/\")\`. On Windows this never
matched because \`str(rel)\` uses backslashes, so the CLI
allowlist silently failed and every \`print()\` in
\`geno_lewm/cli/verify.py\` was flagged as a violation, breaking
the gates job + two unit tests on every Windows runner.

Switch to component-tuple comparison (\`rel.parts[:n] == p.parts\`)
so the same allowlist matches on POSIX and Windows.

Confirmed by downloading the pytest artifact from the prior
Windows run; both failures (\`test_print_in_cli_dir_is_allowed\` and
\`test_real_package_passes\`) trace to this single AST-linter
regression. Local Linux suite still passes.
@AbdelStark AbdelStark force-pushed the claude/production-ready-codebase-OVqw3 branch from 0d9eaf6 to f840f0c Compare May 21, 2026 12:30
@AbdelStark AbdelStark merged commit a390e1e into main May 21, 2026
14 checks passed
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.

3 participants