Skip to content
Merged
19 changes: 11 additions & 8 deletions .agents/skills/python-codestyle/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Read the repo's `OPERATIONS.md` local-verification commands before substituting
Then read the `pyproject.toml` shape and pick the profile before running Python tooling or tests:

- **build** (Project): `[project]` + `[build-system]` + committed `uv.lock`. Uses `uv run`, pytest,
pyright strict (or mypy where the repo requires it).
and pyright strict, mypy with its strict flags, or both as the CI type checker.
- **lint-only** (Scripts): no `[project]`, no lockfile, no `requirements*.txt` (the hub validator runs
pytest wherever one sits). Uses `uvx` for third-party tools, unittest
for tests, and mypy as the CI gate. Do not run pytest or diagnose its absence as an environment
Expand All @@ -56,11 +56,12 @@ declaration, versioning, VS Code config), see `references/profiles.md`.
| [pytest][docs-link] | test runner (build profile only, lint-only uses `unittest`) | `pyproject.toml` `[tool.pytest.ini_options]` |

**Type checking targets strongly typed, deterministic code.** pyright in strict mode is the
default baseline on first-party code (a repo may instead run mypy in CI and keep pyright
editor-only via Pylance, per the next paragraph): `[tool.pyright]` `strict = ["src"]`, or the
integration package for a Home Assistant repo, with tests run in standard mode. pyright is the
anchor because Pylance embeds it, so the editor and the CLI/CI (`uv run pyright`) run the same
engine and never disagree. The standalone `ms-pyright.pyright` extension stays in
default baseline on first-party code (a repo may instead run mypy with its strict flags in CI
and keep pyright editor-only via Pylance, per the next paragraph): `[tool.pyright]`
`strict = ["src"]`, or the integration package for a Home Assistant repo, with tests run in
standard mode. pyright is the anchor because Pylance embeds it, so where CI runs pyright, the
editor and the CLI/CI (`uv run pyright`) run the same engine and never disagree.
The standalone `ms-pyright.pyright` extension stays in
`unwantedRecommendations` because Pylance covers it. Relax strictness on third-party code only
when a dependency has no usable types and no alternative (e.g. `pandas`): a targeted, commented
`# pyright: ignore[...]` or a scoped `[tool.pyright]` override, never a blanket relaxation.
Comment thread
ptr727 marked this conversation as resolved.
Expand All @@ -72,8 +73,10 @@ than one checker is normal when each serves a purpose (the .NET side pairs CShar
`mypy --strict` because the platinum `strict-typing` quality-scale tier requires it, and a
pydantic-heavy library may opt in for the plugin. When a repo uses mypy it runs in CI and the
editor (the `ms-python.mypy-type-checker` extension) so the two stay consistent, and its mypy
command joins the clean-compile. A repo with no such need stays pyright-only, which is lighter and
inherently consistent.
command joins the clean-compile. mypy may also be a build repo's only CI checker, run with its
strict flags, and Pylance's pyright diagnostics are then advisory, since CI never runs them. A
pyright-only repo is the lightest and is inherently consistent, since the editor and CI run one
engine.

## Local development loop

Expand Down
4 changes: 2 additions & 2 deletions .agents/skills/python-codestyle/references/code-style.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
## Type hints

- **All public APIs are typed.** The repo's configured type checker runs on `src/` (pyright strict
via `[tool.pyright]` `strict = ["src"]`, or mypy where that is the CI checker), and tests run in
the checker's looser/standard mode.
via `[tool.pyright]` `strict = ["src"]`, or mypy's strict flags where mypy is the CI checker),
and tests run in the checker's looser/standard mode.
- **Use modern syntax**: `list[int]` not `List[int]`, `dict[str, X]` not `Dict[str, X]`,
`X | None` not `Optional[X]`, `from __future__ import annotations` only when needed for forward
references.
Expand Down
4 changes: 2 additions & 2 deletions .agents/skills/python-codestyle/references/profiles.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ often differs, and when it does, adapt these fields to match the repo's actual t
than copying verbatim (a verbatim copy that misdescribes the repo is inaccurate and gets rejected
in review). The axes that commonly vary per repo:

- **Type checker in CI**: pyright strict, mypy in CI with pyright editor-only (Pylance), or both.
Whichever runs in CI is the one the clean-compile and the CI gate invoke.
- **Type checker in CI**: pyright strict, mypy with its strict flags in CI and the editor with
pyright editor-only (Pylance), or both. The clean-compile runs every checker CI runs.
- **Dependency declaration**: `[dependency-groups]`, or PEP 621 `[project.optional-dependencies]`
(dev tools installed with `uv sync --extra <group>`).
- **Versioning / publishing**: a published package (`_version.py` plus a version source,
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
258f0a702efc7fb2
f51041024f11173f
19 changes: 11 additions & 8 deletions .claude-plugin/fleet-skills/skills/python-codestyle/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Read the repo's `OPERATIONS.md` local-verification commands before substituting
Then read the `pyproject.toml` shape and pick the profile before running Python tooling or tests:

- **build** (Project): `[project]` + `[build-system]` + committed `uv.lock`. Uses `uv run`, pytest,
pyright strict (or mypy where the repo requires it).
and pyright strict, mypy with its strict flags, or both as the CI type checker.
- **lint-only** (Scripts): no `[project]`, no lockfile, no `requirements*.txt` (the hub validator runs
pytest wherever one sits). Uses `uvx` for third-party tools, unittest
for tests, and mypy as the CI gate. Do not run pytest or diagnose its absence as an environment
Expand All @@ -56,11 +56,12 @@ declaration, versioning, VS Code config), see `references/profiles.md`.
| [pytest][docs-link] | test runner (build profile only, lint-only uses `unittest`) | `pyproject.toml` `[tool.pytest.ini_options]` |

**Type checking targets strongly typed, deterministic code.** pyright in strict mode is the
default baseline on first-party code (a repo may instead run mypy in CI and keep pyright
editor-only via Pylance, per the next paragraph): `[tool.pyright]` `strict = ["src"]`, or the
integration package for a Home Assistant repo, with tests run in standard mode. pyright is the
anchor because Pylance embeds it, so the editor and the CLI/CI (`uv run pyright`) run the same
engine and never disagree. The standalone `ms-pyright.pyright` extension stays in
default baseline on first-party code (a repo may instead run mypy with its strict flags in CI
and keep pyright editor-only via Pylance, per the next paragraph): `[tool.pyright]`
`strict = ["src"]`, or the integration package for a Home Assistant repo, with tests run in
standard mode. pyright is the anchor because Pylance embeds it, so where CI runs pyright, the
editor and the CLI/CI (`uv run pyright`) run the same engine and never disagree.
The standalone `ms-pyright.pyright` extension stays in
`unwantedRecommendations` because Pylance covers it. Relax strictness on third-party code only
when a dependency has no usable types and no alternative (e.g. `pandas`): a targeted, commented
`# pyright: ignore[...]` or a scoped `[tool.pyright]` override, never a blanket relaxation.
Expand All @@ -72,8 +73,10 @@ than one checker is normal when each serves a purpose (the .NET side pairs CShar
`mypy --strict` because the platinum `strict-typing` quality-scale tier requires it, and a
pydantic-heavy library may opt in for the plugin. When a repo uses mypy it runs in CI and the
editor (the `ms-python.mypy-type-checker` extension) so the two stay consistent, and its mypy
command joins the clean-compile. A repo with no such need stays pyright-only, which is lighter and
inherently consistent.
command joins the clean-compile. mypy may also be a build repo's only CI checker, run with its
strict flags, and Pylance's pyright diagnostics are then advisory, since CI never runs them. A
pyright-only repo is the lightest and is inherently consistent, since the editor and CI run one
engine.

## Local development loop

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
## Type hints

- **All public APIs are typed.** The repo's configured type checker runs on `src/` (pyright strict
via `[tool.pyright]` `strict = ["src"]`, or mypy where that is the CI checker), and tests run in
the checker's looser/standard mode.
via `[tool.pyright]` `strict = ["src"]`, or mypy's strict flags where mypy is the CI checker),
and tests run in the checker's looser/standard mode.
- **Use modern syntax**: `list[int]` not `List[int]`, `dict[str, X]` not `Dict[str, X]`,
`X | None` not `Optional[X]`, `from __future__ import annotations` only when needed for forward
references.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ often differs, and when it does, adapt these fields to match the repo's actual t
than copying verbatim (a verbatim copy that misdescribes the repo is inaccurate and gets rejected
in review). The axes that commonly vary per repo:

- **Type checker in CI**: pyright strict, mypy in CI with pyright editor-only (Pylance), or both.
Whichever runs in CI is the one the clean-compile and the CI gate invoke.
- **Type checker in CI**: pyright strict, mypy with its strict flags in CI and the editor with
pyright editor-only (Pylance), or both. The clean-compile runs every checker CI runs.
- **Dependency declaration**: `[dependency-groups]`, or PEP 621 `[project.optional-dependencies]`
(dev tools installed with `uv sync --extra <group>`).
- **Versioning / publishing**: a published package (`_version.py` plus a version source,
Expand Down
19 changes: 11 additions & 8 deletions .github/skills/python-codestyle/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Read the repo's `OPERATIONS.md` local-verification commands before substituting
Then read the `pyproject.toml` shape and pick the profile before running Python tooling or tests:

- **build** (Project): `[project]` + `[build-system]` + committed `uv.lock`. Uses `uv run`, pytest,
pyright strict (or mypy where the repo requires it).
and pyright strict, mypy with its strict flags, or both as the CI type checker.
- **lint-only** (Scripts): no `[project]`, no lockfile, no `requirements*.txt` (the hub validator runs
pytest wherever one sits). Uses `uvx` for third-party tools, unittest
for tests, and mypy as the CI gate. Do not run pytest or diagnose its absence as an environment
Expand All @@ -56,11 +56,12 @@ declaration, versioning, VS Code config), see `references/profiles.md`.
| [pytest][docs-link] | test runner (build profile only, lint-only uses `unittest`) | `pyproject.toml` `[tool.pytest.ini_options]` |

**Type checking targets strongly typed, deterministic code.** pyright in strict mode is the
default baseline on first-party code (a repo may instead run mypy in CI and keep pyright
editor-only via Pylance, per the next paragraph): `[tool.pyright]` `strict = ["src"]`, or the
integration package for a Home Assistant repo, with tests run in standard mode. pyright is the
anchor because Pylance embeds it, so the editor and the CLI/CI (`uv run pyright`) run the same
engine and never disagree. The standalone `ms-pyright.pyright` extension stays in
default baseline on first-party code (a repo may instead run mypy with its strict flags in CI
and keep pyright editor-only via Pylance, per the next paragraph): `[tool.pyright]`
`strict = ["src"]`, or the integration package for a Home Assistant repo, with tests run in
standard mode. pyright is the anchor because Pylance embeds it, so where CI runs pyright, the
editor and the CLI/CI (`uv run pyright`) run the same engine and never disagree.
The standalone `ms-pyright.pyright` extension stays in
`unwantedRecommendations` because Pylance covers it. Relax strictness on third-party code only
when a dependency has no usable types and no alternative (e.g. `pandas`): a targeted, commented
`# pyright: ignore[...]` or a scoped `[tool.pyright]` override, never a blanket relaxation.
Expand All @@ -72,8 +73,10 @@ than one checker is normal when each serves a purpose (the .NET side pairs CShar
`mypy --strict` because the platinum `strict-typing` quality-scale tier requires it, and a
pydantic-heavy library may opt in for the plugin. When a repo uses mypy it runs in CI and the
editor (the `ms-python.mypy-type-checker` extension) so the two stay consistent, and its mypy
command joins the clean-compile. A repo with no such need stays pyright-only, which is lighter and
inherently consistent.
command joins the clean-compile. mypy may also be a build repo's only CI checker, run with its
strict flags, and Pylance's pyright diagnostics are then advisory, since CI never runs them. A
pyright-only repo is the lightest and is inherently consistent, since the editor and CI run one
engine.

## Local development loop

Expand Down
4 changes: 2 additions & 2 deletions .github/skills/python-codestyle/references/code-style.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
## Type hints

- **All public APIs are typed.** The repo's configured type checker runs on `src/` (pyright strict
via `[tool.pyright]` `strict = ["src"]`, or mypy where that is the CI checker), and tests run in
the checker's looser/standard mode.
via `[tool.pyright]` `strict = ["src"]`, or mypy's strict flags where mypy is the CI checker),
and tests run in the checker's looser/standard mode.
- **Use modern syntax**: `list[int]` not `List[int]`, `dict[str, X]` not `Dict[str, X]`,
`X | None` not `Optional[X]`, `from __future__ import annotations` only when needed for forward
references.
Expand Down
4 changes: 2 additions & 2 deletions .github/skills/python-codestyle/references/profiles.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ often differs, and when it does, adapt these fields to match the repo's actual t
than copying verbatim (a verbatim copy that misdescribes the repo is inaccurate and gets rejected
in review). The axes that commonly vary per repo:

- **Type checker in CI**: pyright strict, mypy in CI with pyright editor-only (Pylance), or both.
Whichever runs in CI is the one the clean-compile and the CI gate invoke.
- **Type checker in CI**: pyright strict, mypy with its strict flags in CI and the editor with
pyright editor-only (Pylance), or both. The clean-compile runs every checker CI runs.
- **Dependency declaration**: `[dependency-groups]`, or PEP 621 `[project.optional-dependencies]`
(dev tools installed with `uv sync --extra <group>`).
- **Versioning / publishing**: a published package (`_version.py` plus a version source,
Expand Down
2 changes: 1 addition & 1 deletion AUDIT.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ A check with `intentRef`/`workflowRef` points at the prose section that owns the
- **csharp** - `.editorconfig` carries the shared `[*.cs]` rule block (letter), and analyzer severities are enforced, not relaxed (intent).
- **nuget** - `nuget.publish.oidc` (intent): publish uses OIDC Trusted Publishing with no stored `NUGET_API_KEY` secret, from a job in the publishing repository's own publisher, never inside a build leaf and never in a reusable workflow a different repository hosts, for the reason [`WORKFLOW.md`][workflow] section 3's `Output Seam by Destination` gives for both package registries. `nuget.publish.skipduplicate` (letter): the push carries `--skip-duplicate` and is gated on the publish decision, not on an existence check. `nuget.publish.job` (letter): that publish job declares `id-token: write` and `actions: write`, and consume-then-deletes `nuget-build-<branch>`.
- **pypi** - `pypi.publish.oidc` (intent): OIDC publish with no stored token, from a job in the publishing repository's own publisher under the same seam the **nuget** check names. `pypi.publish.environment` (letter): that job declares `environment: pypi` and `id-token: write`, with `skip-existing: true`.
- **python** - ruff and pyright present (intent), canonical in `pyproject.toml` (letter), and a standalone `.ruff.toml` / `pyrightconfig.json` is a drift finding.
- **python** - ruff and a CI type checker present (intent), strict in a build-profile directory (pyright, mypy, or both), canonical in `pyproject.toml` (letter), and a standalone `.ruff.toml` / `pyrightconfig.json` / `mypy.ini` / `.mypy.ini`, or a `setup.cfg` `[mypy]` section, is a drift finding.
- **dotnet-publish** - `dotnet-publish.smoke.subset` (letter): the smoke runtime matrix is a strict subset of the full set. `dotnet-publish.release.asset` (letter): the per-runtime outputs aggregate to one `release-asset-*`, gated `!smoke`.
- **docker** - registry layer cache (`buildcache-<branch>`, never `type=gha`), the size-limited Docker Hub README is published via the docker-readme task, and the image always re-pushes on publish.
- **hugo** - the build fails on a generator warning, the URL-parity gate asserts a length floor before comparing, the rendered output is untracked, the generator is pinned by version and checksum and declared once, a vendored tree records its upstream ref, and the deploy asserts what the host serves (the release id and the environment). Retention is bounded by a declared count with one side recorded as owning the prune, which is the deploy where its credential can observe the destination and the host where that credential is confined write-only, so grade which shape the repo uses rather than looking for a prune step. Deploy credentials are per-environment, which `spec/secrets.json` cannot express, so a clean **repo-setup** verdict says nothing about whether the environments are configured.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ A human-readable index of the rules agents enforce, implement, and audit. The au

### If a Python Project

- Configure ruff and a type checker in `pyproject.toml`, either pyright strict or mypy in CI with pyright editor-only. Whichever runs in CI is the gate.
- Configure ruff and a type checker in `pyproject.toml`: pyright strict, mypy with its strict flags in CI and the editor with pyright editor-only, or both. Every checker CI runs is a gate.

### If Both C# and Python

Expand Down
Loading
Loading