Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .agents/skills/dotnet-codestyle/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ All builds must complete without warnings, enforced three ways:
surfaced as a warning fails the build and must be fixed or deliberately suppressed at the
narrowest scope that fits (see Analyzer suppressions below), never left to accumulate.
- **CI lint backstop.** CI runs the clean-compile checks on every PR as the authoritative gate.
Git hooks are optional, and a repo may wire a local runner (Husky.Net, with `dotnet husky run`
as a style step) for pre-commit enforcement, but CI is the gate that matters.
A working local hook is strongly suggested, not optional: wire Husky.Net from the canonical
`catalog/snippets/husky/` config. See GOVERNANCE.md "Running the Linters Locally" for what the
hook must cover and what its absence means.

**A new port is not a license to silence diagnostics.** Brownfield or just-ported status never
justifies relaxing analyzer severities or muting newly surfaced warnings. Fix them. (The only
Expand Down Expand Up @@ -94,8 +95,8 @@ updates, dependency upgrades, benchmarks) on top:
`dotnet format style --verify-no-changes --severity=info --verbosity=detailed`.
- **`dotnet-outdated-tool`** checks for dependency updates, and Nerdbank.GitVersioning owns
version management.
- CI is the authoritative lint backstop. Local pre-commit hooks are optional, wire Husky.Net (or
another runner) if you want local enforcement.
- CI is the authoritative lint backstop. A local pre-commit hook is strongly suggested: wire
Husky.Net from `catalog/snippets/husky/` for local enforcement, including the shared doc gates.
- **Required VS Code extensions**: CSharpier, markdownlint, CSpell. Use the workspace settings
without overrides.

Expand Down
6 changes: 4 additions & 2 deletions .agents/skills/python-codestyle/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,10 @@ The Python clean-compile is `uv run ruff format` + `uv run ruff check` + the rep
both (see Type checking above). Run it, plus `uv run pytest`, before committing. These are
documented commands, and an optional VS Code tasks mirror (all `type: process`, no `&&` shell
chaining, so it runs the same on any task shell) is in the hub `vscode-tasks-python.json` snippet.
CI runs the same clean-compile commands as the authoritative backstop. Git hooks are opt-in, so
wire `pre-commit` for `ruff` and the type checker yourself if you want local enforcement.
CI runs the same clean-compile commands as the authoritative backstop. A working local hook is
strongly suggested, not opt-in: wire the Python `pre-commit` framework from the canonical
`catalog/snippets/pre-commit/.pre-commit-config.yaml`. See GOVERNANCE.md "Running the Linters
Locally" for what the hook must cover and what its absence means.
Comment thread
coderabbitai[bot] marked this conversation as resolved.

A restricted executor gives each task a cache directory under a writable temporary root. Point
`UV_CACHE_DIR`, `RUFF_CACHE_DIR`, `MYPY_CACHE_DIR`, and `COVERAGE_FILE` into that directory before
Expand Down
2 changes: 1 addition & 1 deletion .claude-plugin/fleet-skills/.source-digest
Original file line number Diff line number Diff line change
@@ -1 +1 @@
85b7db1858ecd00a
309580363f245493
9 changes: 5 additions & 4 deletions .claude-plugin/fleet-skills/skills/dotnet-codestyle/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ All builds must complete without warnings, enforced three ways:
surfaced as a warning fails the build and must be fixed or deliberately suppressed at the
narrowest scope that fits (see Analyzer suppressions below), never left to accumulate.
- **CI lint backstop.** CI runs the clean-compile checks on every PR as the authoritative gate.
Git hooks are optional, and a repo may wire a local runner (Husky.Net, with `dotnet husky run`
as a style step) for pre-commit enforcement, but CI is the gate that matters.
A working local hook is strongly suggested, not optional: wire Husky.Net from the canonical
`catalog/snippets/husky/` config. See GOVERNANCE.md "Running the Linters Locally" for what the
hook must cover and what its absence means.

**A new port is not a license to silence diagnostics.** Brownfield or just-ported status never
justifies relaxing analyzer severities or muting newly surfaced warnings. Fix them. (The only
Expand Down Expand Up @@ -94,8 +95,8 @@ updates, dependency upgrades, benchmarks) on top:
`dotnet format style --verify-no-changes --severity=info --verbosity=detailed`.
- **`dotnet-outdated-tool`** checks for dependency updates, and Nerdbank.GitVersioning owns
version management.
- CI is the authoritative lint backstop. Local pre-commit hooks are optional, wire Husky.Net (or
another runner) if you want local enforcement.
- CI is the authoritative lint backstop. A local pre-commit hook is strongly suggested: wire
Husky.Net from `catalog/snippets/husky/` for local enforcement, including the shared doc gates.
- **Required VS Code extensions**: CSharpier, markdownlint, CSpell. Use the workspace settings
without overrides.

Expand Down
6 changes: 4 additions & 2 deletions .claude-plugin/fleet-skills/skills/python-codestyle/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,10 @@ The Python clean-compile is `uv run ruff format` + `uv run ruff check` + the rep
both (see Type checking above). Run it, plus `uv run pytest`, before committing. These are
documented commands, and an optional VS Code tasks mirror (all `type: process`, no `&&` shell
chaining, so it runs the same on any task shell) is in the hub `vscode-tasks-python.json` snippet.
CI runs the same clean-compile commands as the authoritative backstop. Git hooks are opt-in, so
wire `pre-commit` for `ruff` and the type checker yourself if you want local enforcement.
CI runs the same clean-compile commands as the authoritative backstop. A working local hook is
strongly suggested, not opt-in: wire the Python `pre-commit` framework from the canonical
`catalog/snippets/pre-commit/.pre-commit-config.yaml`. See GOVERNANCE.md "Running the Linters
Locally" for what the hook must cover and what its absence means.

A restricted executor gives each task a cache directory under a writable temporary root. Point
`UV_CACHE_DIR`, `RUFF_CACHE_DIR`, `MYPY_CACHE_DIR`, and `COVERAGE_FILE` into that directory before
Expand Down
9 changes: 5 additions & 4 deletions .github/skills/dotnet-codestyle/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ All builds must complete without warnings, enforced three ways:
surfaced as a warning fails the build and must be fixed or deliberately suppressed at the
narrowest scope that fits (see Analyzer suppressions below), never left to accumulate.
- **CI lint backstop.** CI runs the clean-compile checks on every PR as the authoritative gate.
Git hooks are optional, and a repo may wire a local runner (Husky.Net, with `dotnet husky run`
as a style step) for pre-commit enforcement, but CI is the gate that matters.
A working local hook is strongly suggested, not optional: wire Husky.Net from the canonical
`catalog/snippets/husky/` config. See GOVERNANCE.md "Running the Linters Locally" for what the
hook must cover and what its absence means.

**A new port is not a license to silence diagnostics.** Brownfield or just-ported status never
justifies relaxing analyzer severities or muting newly surfaced warnings. Fix them. (The only
Expand Down Expand Up @@ -94,8 +95,8 @@ updates, dependency upgrades, benchmarks) on top:
`dotnet format style --verify-no-changes --severity=info --verbosity=detailed`.
- **`dotnet-outdated-tool`** checks for dependency updates, and Nerdbank.GitVersioning owns
version management.
- CI is the authoritative lint backstop. Local pre-commit hooks are optional, wire Husky.Net (or
another runner) if you want local enforcement.
- CI is the authoritative lint backstop. A local pre-commit hook is strongly suggested: wire
Husky.Net from `catalog/snippets/husky/` for local enforcement, including the shared doc gates.
- **Required VS Code extensions**: CSharpier, markdownlint, CSpell. Use the workspace settings
without overrides.

Expand Down
6 changes: 4 additions & 2 deletions .github/skills/python-codestyle/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,10 @@ The Python clean-compile is `uv run ruff format` + `uv run ruff check` + the rep
both (see Type checking above). Run it, plus `uv run pytest`, before committing. These are
documented commands, and an optional VS Code tasks mirror (all `type: process`, no `&&` shell
chaining, so it runs the same on any task shell) is in the hub `vscode-tasks-python.json` snippet.
CI runs the same clean-compile commands as the authoritative backstop. Git hooks are opt-in, so
wire `pre-commit` for `ruff` and the type checker yourself if you want local enforcement.
CI runs the same clean-compile commands as the authoritative backstop. A working local hook is
strongly suggested, not opt-in: wire the Python `pre-commit` framework from the canonical
`catalog/snippets/pre-commit/.pre-commit-config.yaml`. See GOVERNANCE.md "Running the Linters
Locally" for what the hook must cover and what its absence means.

A restricted executor gives each task a cache directory under a writable temporary root. Point
`UV_CACHE_DIR`, `RUFF_CACHE_DIR`, `MYPY_CACHE_DIR`, and `COVERAGE_FILE` into that directory before
Expand Down
2 changes: 1 addition & 1 deletion AUDIT.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ A check with `intentRef`/`workflowRef` points at the prose section that owns the
- **carried-scope** - the repo carries no file the hub hosts rather than carries. The set is derived, not listed: the hub's git-tracked paths minus the [`spec/files.json`][files] baseline, so a file dropped from the manifest starts being reported on the next run with no retirement list to remember to edit. The remedy is the opposite of every other file finding, a **deletion**, since the repo reaches the hub's copy per [GOVERNANCE.md "Hub-Hosted Tooling"][governance-hub-hosted-tooling]. The match is on path alone, so a hit is a candidate and not a verdict: a repo's own content at a path the hub also uses matches while carrying nothing of the hub's, which the first fleet run showed twice, a KiCad tooling doc at `scripts/README.md` and per-repo formatting hooks at `.husky/pre-commit`. A [`spec/divergences.json`][divergences] `gaps` disposition decides which case a hit is, so only `retire` asserts a deletion, `accepted` closes a collision or a repo-owned file, and an untriaged hit is read before it is acted on.
- **verbatim-tree** - every applicable `trees[]` declaration in [`spec/files.json`][files] owns its target tree. The audit reports missing files as letter findings, stale or modified bytes as drift, and extra files under a pruned target as drift. An unreadable or truncated repository tree is undecided and produces drift rather than a clean result.
- **repo-setup** - every required secret for the repo's publish mechanisms is configured, and no forbidden secret is present (per [`spec/secrets.json`][secrets]).
- **linter-parity** - one config per linter (`.markdownlint-cli2.jsonc`, `cspell.json`, ruff/pyright, editorconfig/csharpier, actionlint) drives the editor extension, the CLI, and CI, and CI runs each.
- **linter-parity** - one config per linter (`.markdownlint-cli2.jsonc`, `cspell.json`, ruff/pyright, editorconfig/csharpier, actionlint) drives the editor extension, the CLI, and CI, and CI runs each. A local hook exists and runs at minimum the diff-scoped prose gate and the eol check (`parity.hooks`, intent). A repo with none wired is a defect, and one mid-convergence on the language-formatting half stays operational.
- **recurring-violations** - comments concise and non-narrative, ASCII only (no em-dash, no smart quotes), US spelling, line endings per `.editorconfig`. These are frequent regressions, so this dimension is high priority and always runs, and each check is grep-able (see below).
- **readme-structure** - the README follows [`spec/readme-structure.md`][readme-structure] (applicable sections, in order). Mechanically checked against the declared model in [`spec/readme-sections.json`][readme-sections]: required sections present, declared sections in their relative order, `License` last, the shields each deliverable implies, the license shield in the closing License section, and the tagline and its mirrors. A heading the model does not name is dropped before the order comparison, so a repo-specific section is never a finding.

Expand Down
2 changes: 1 addition & 1 deletion CODESTYLE.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Each language defines a **clean-compile** verification: the combination of build

- **Run it after every code change, and it is not the whole gate.** The relevant language's clean-compile must pass before you commit. CI runs those same language checks as a backstop **plus everything else its validation workflow runs**, and all of it reports into the one required status, so a green clean-compile does not predict a green CI. That remainder is at least the doc-lint set (markdownlint, cspell, actionlint, `editorconfig-checker`) and whatever spec, config, and script gates the repo carries, so read the workflow for the full list rather than assuming this sentence enumerates it. What has to pass before a push is the repo's **whole** lint gate, per [GOVERNANCE.md "Verification Discipline"][governance-verification-discipline]. Each linter's known-working invocation is in [GOVERNANCE.md "Running the Linters Locally"][governance-running-the-linters-locally].
- **The named task definition is the canonical spec** - its exact command sequence, arguments, and strictness. You may run it through the VS Code task **or** by invoking the equivalent native commands directly, and either is fine **only if the sequence, arguments, and strictness match exactly**. No shortcuts and no more-lenient options (for example, never drop `--verify-no-changes` or loosen a `--severity`).
- **A local commit/pre-commit gate is the repo's choice.** No single hook runner fits every language (a `dotnet`-tool runner like Husky.Net suits .NET but not Python), so none is mandated, but that is **not** a recommendation against commit gates. CI is the authoritative backstop regardless, and a local gate is an additive convenience a repo may wire and keep: Husky.Net (and `dotnet husky run` as a style step) for .NET, `pre-commit` for Python. Keeping a working gate is not drift.
- **A working local commit/pre-commit gate is strongly suggested, not the repo's free choice to skip.** No single hook runner fits every language (a `dotnet`-tool runner like Husky.Net suits .NET but not Python), so the *mechanism* stays the repo's choice: Husky.Net for .NET, `pre-commit` for Python, canonical configs for both in `catalog/snippets/`. What that gate must cover, and what its absence means for the audit, is [GOVERNANCE.md "Running the Linters Locally"][governance-running-the-linters-locally], not restated here. Keeping a working gate is not drift.
Comment thread
coderabbitai[bot] marked this conversation as resolved.

### Analyzer Diagnostics and Suppressions

Expand Down
6 changes: 4 additions & 2 deletions GOVERNANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,10 @@ CI runs the full lint set, but run the linters locally before pushing to catch i
**Each surface runs the lint with the tool that fits it, all from the same config files** (`.markdownlint-cli2.jsonc`, `cspell.json`, `.editorconfig`):

- **CI (authoritative)** runs **markdownlint-cli2**, **cspell**, and **actionlint** as pinned action wrappers (Dependabot bumps them), plus **editorconfig-checker** via Docker `:latest` (its action only installs the CLI, so the Docker one-liner is what actually runs the check), **shellcheck** and **shfmt** the same way for a repo that carries a shell script, and, **for a repo that carries `.ps1` files**, **PSScriptAnalyzer** the same way (none of the three has an action). markdownlint covers all `**/*.md`, and **cspell is scoped to `README.md` + `HISTORY.md`** (see [CODESTYLE.md](./CODESTYLE.md) "Markdown and Spelling" for why), matching the cspell one-liner below. A "shell script" here is a tracked `.sh` file, plus a tracked, extension-less file whose shebang names bash or sh, the shape a script meant to run as a bare command takes: a bare `*.sh` glob misses that second case, so both discovery paths run before either tool does. This whole block is the hub's `validate-task.yml` reusable workflow, so a fleet repo reaches it rather than carrying a copy of these steps.
- **The `.husky/pre-commit` hook** runs **language formatting** and the **diff-scoped doc gates**, never Docker and never a network call, so it stays fast. The formatting half is whatever the repo's own language needs, CSharpier and `dotnet format` for .NET or ruff for Python, via native tooling. A repo adds each half once its tree passes that half, since a gate that fails on the corpus it guards blocks every commit from the moment it lands, so a hook running one half is a repo mid-convergence rather than a repo out of conformance. The doc half runs each gate at the scope that fits it. The prose gate is scoped to what the commit changes rather than swept over the tree, which is the difference between about 2.2 seconds and about 0.13 and is what makes it affordable in a hook at all. A whole-repo check belongs there too when it is already fast and takes no file list, which the line-ending consistency check is, so scope is a property of the gate rather than a rule the hook applies to all of them. `repo_gate.py --check sha-pin` stays out, since it resolves a same-owner pin against the GitHub API and a hook that needs a network fails offline. A repo enables the hook per clone with `git config core.hooksPath .husky`, and CI remains the authoritative run either way.
- **The VS Code Lint tasks** run the full doc-lint set via Docker `:latest` on demand, the local surface for Markdown, spelling, workflow, and EditorConfig checks.
- **A working local hook is strongly suggested fleet-wide, and its absence is a measured audit finding, not an invisible gap.** `spec/project-types.json`'s `parity.hooks` check reads this section for its rationale, judged by hand during an `AUDIT.md` run like every sibling check in its dimension, never mechanized by `spec/audit.py`: a repo with no local hook mechanism wired at all is a `linter-parity` defect, the same severity a missing markdownlint config already gets, while a repo mid-convergence (below) stays operational. CI remains the authoritative run regardless. Two catalog snippets carry the canonical shape, `catalog/snippets/husky/` (Husky.Net, for .NET or any project including Python) and `catalog/snippets/pre-commit/` (the Python `pre-commit` framework, for a repo with no `.husky/` tree), each carrying a copy of `catalog/snippets/hub-fetch-run.py` alongside it.
- **The hook** runs **language formatting** and the **diff-scoped doc gates**, never Docker, so it stays fast. The formatting half is whatever the repo's own language needs, CSharpier and `dotnet format` for .NET or ruff for Python, via native tooling. A repo adds each half once its tree passes that half, since a gate that fails on the corpus it guards blocks every commit from the moment it lands, so a hook running one half is a repo mid-convergence rather than a repo out of conformance. The doc half runs each gate at the scope that fits it. The prose gate is scoped to what the commit changes rather than swept over the tree, which is the difference between about 2.2 seconds and about 0.13 and is what makes it affordable in a hook at all. A whole-repo check belongs there too when it is already fast and takes no file list, which the line-ending consistency check is, so scope is a property of the gate rather than a rule the hook applies to all of them. `repo_gate.py --check sha-pin` stays out of the hook regardless, since it resolves a same-owner pin against the GitHub API.
- **The doc gates reach a downstream repo by fetching `.github/actions/prose-gate/prose_lint.py` and `.github/actions/repo-gate/repo_gate.py` fresh from `ptr727/ProjectTemplate`'s `main` branch, via `hub-fetch-run.py`, never vendored and never pinned.** Pinning anything Dependabot does not maintain goes stale by construction, and CI (this repo's own, and the hub's) is the backstop that catches a change landing broken on `main` before a locally fetched copy does real damage. These are the only network calls the hook makes, one per fetched script, the same category of dependency as the Docker pulls the VS Code Lint tasks already do routinely, not a new one. A fetch failure fails the commit, and it never silently skips the gate. The **hub's own** `.husky/pre-commit` is the one exception, staying local and offline, since it already carries `scripts/prose_lint.py` and `scripts/repo_gate.py` directly and has no hub to reach. A repo enables its hook per clone with `git config core.hooksPath .husky` or `uv run pre-commit install`, and CI remains the authoritative run either way.
- **The VS Code Lint tasks** run the full doc-lint set via Docker `:latest` on demand, the local surface for Markdown, spelling, workflow, and EditorConfig checks, plus `Lint: Prose` and `Lint: EOL`, the same two hook gates in whole-repo mode rather than diff-scoped, for on-demand full-tree validation.

The Docker invocations below run the same tools and configs as the VS Code tasks. Their headless form separates the image pull and minimizes repository exposure for an agent executor.

Expand Down
Loading
Loading