Skip to content

Commit dd4297a

Browse files
authored
Merge pull request #4 from maybebyte/chore/slop-audit-cleanup
Fix tag-frozen generation suite and clean up template config/docs
2 parents 3bf0eec + 3ebd279 commit dd4297a

13 files changed

Lines changed: 105 additions & 21 deletions

AGENTS.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ The maintainer harness is held to the same `recommended` bar the template ships.
2121

2222
```bash
2323
just lint # ruff check . — select=["ALL"] over tests/ (config-derived, audited ignores)
24-
just fmt # ruff format . + ruff check --fix . (apply safe fixes)
24+
just fmt # ruff check --fix . + ruff format . (apply safe fixes)
2525
just fmt-check # ruff format --check . (CI's format gate)
2626
```
2727

@@ -31,12 +31,12 @@ The maintainer harness runs the same full `select=["ALL"]` ruleset the template
3131

3232
1. Add an `enable_*` toggle to `copier.yml`.
3333
2. Add the conditional file(s) under `template/` (file: `{% if flag %}name{% endif %}.jinja`; dir: `{% if flag %}dir{% endif %}/`).
34-
3. Wire it into `template/justfile.jinja` (recipe + `ci` dep). Then, where applicable: a dep in `template/pyproject.toml.jinja` (skip it for `uvx`-run tools like the scanners), a section in `template/AGENTS.md.jinja`, and a CI surface under `template/.github/workflows/` (a conditional step in `scan.yml`, or a dedicated conditional workflow file via the empty-name idiom).
34+
3. Wire it into `template/justfile.jinja` (a recipe; add it as a `ci` dep only for a *gating* layer — out-of-band checks like `scan`/`mutate` ship a recipe but stay off `ci`, and CI-only layers like renovate/sha-pin add no recipe at all). Then, where applicable: a dep in `template/pyproject.toml.jinja` (skip it for `uvx`-run tools like the scanners), a section in `template/AGENTS.md.jinja`, and a CI surface under `template/.github/workflows/` (a conditional step in `scan.yml`, or a dedicated conditional workflow file via the empty-name idiom).
3535
4. Extend `tests/test_generation.py`: assert present-when-on AND absent-when-off, and that the layer's gate passes.
3636

3737
## Release
3838

39-
`copier update` targets the **latest SemVer git tag, not HEAD** — an untagged template makes every downstream update silently pull in-progress commits. The repo carries no tags until the first release is cut, so tag the released commit (on `main`) before announcing it or letting any downstream consume the template:
39+
`copier update` targets the **latest SemVer git tag, not HEAD** — an untagged template makes every downstream update silently pull in-progress commits. Always tag each released commit (on `main`) before announcing it or letting any downstream consume the template (v0.1.0 was the first release):
4040

4141
```bash
4242
git tag -a v0.1.0 -m "v0.1.0" # annotate the released commit

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Changed
11+
12+
- The gitleaks `mise` pin and `scan.yml`'s full-history checkout are now emitted
13+
only when the scanner layer is enabled; projects that enable `scan.yml` through
14+
another layer no longer carry the unused pin or an unbounded `fetch-depth`.
15+
- The `[tool.ruff.lint.mccabe]` block is emitted only under the `all` ruleset,
16+
where `max-complexity` governs a selected rule (C901); the curated ruleset no
17+
longer renders it as dead config.
18+
19+
### Fixed
20+
21+
- `just fmt` runs `ruff check --fix` before `ruff format`, so its own output can
22+
no longer be rejected by `just fmt-check`.
23+
- `just scan` scans committed history (`gitleaks git`) to match the CI gate,
24+
catching secrets that were committed and later deleted from the working tree.
25+
- The mutation workflow no longer sets job-level `continue-on-error`, so genuine
26+
infrastructure failures surface instead of being masked; surviving mutants stay
27+
non-gating via `|| true` on the `mutmut` step.
28+
- `.editorconfig` no longer forces 2-space indentation on `.toml`, which
29+
conflicted with the 4-space arrays in the generated `pyproject.toml`.
30+
- The `ci` recipe comment no longer claims the local gate mirrors everything that
31+
blocks a PR; with scanners enabled it notes they run in CI only (`scan.yml`).
32+
1033
## [0.1.0] - 2026-06-25
1134

1235
### Added

justfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ typecheck:
1616
uv run basedpyright
1717

1818
# Auto-format + apply safe lint fixes to this repo's own tooling (the tests/ harness).
19+
# Lint-fix BEFORE format: ruff's fixes (import sort, SIM/UP/C4 rewrites) can emit
20+
# unformatted code, so the formatter must run last or `fmt-check` may reject `fmt`'s output.
1921
fmt:
20-
uv run ruff format .
2122
uv run ruff check --fix .
23+
uv run ruff format .
2224

2325
# CI's format gate: fail if anything is unformatted.
2426
fmt-check:

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ package = false
1515
[dependency-groups]
1616
dev = [
1717
"copier>=9.6,<10",
18+
# copier drives its _tasks through plumbum; the harness imports `plumbum.local` directly to
19+
# scrub interpreter pins from that channel, so declare it rather than ride copier's transitive pin.
20+
"plumbum>=1.8,<3",
1821
"pytest>=8,<10",
1922
"pyyaml>=6,<7",
2023
"basedpyright>=1.39,<1.40",

template/.editorconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ insert_final_newline = true
77
indent_style = space
88
indent_size = 4
99

10-
[*.{yml,yaml,json,toml}]
10+
[*.{yml,yaml,json}]
1111
indent_size = 2

template/.github/workflows/{% if enable_mutation_tests %}mutation.yml{% endif %}.jinja

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ jobs:
1616
mutation:
1717
runs-on: ubuntu-latest
1818
timeout-minutes: 60
19-
continue-on-error: true
19+
# Survivors stay non-gating via the `|| true` on the mutmut step below; the job is not set
20+
# to ignore failures, so genuine infra breakage (bad lockfile, failed export) still shows red.
2021
steps:
2122
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
2223
with:

template/.github/workflows/{% if enable_scanners or enable_dependency_audit or enable_sha_pin_policy %}scan.yml{% endif %}.jinja

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ jobs:
1919
steps:
2020
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
2121
with:
22-
fetch-depth: 0
22+
# Full history is only needed for secret scanning; other steps read the tree/lockfile.
23+
fetch-depth: {% if enable_scanners %}0{% else %}1{% endif %}
2324
persist-credentials: false
2425
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
2526
with:

template/justfile.jinja

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@ set shell := ["bash", "-eu", "-o", "pipefail", "-c"]
33
default:
44
@just --list
55

6-
# Complete local gate — mirrors what blocks a PR.
6+
# The complete local gate — every PR-blocking check reproducible locally{% if enable_scanners %} (scanners run in CI only; see scan.yml){% endif %}.
77
ci: fmt-check lint typecheck test{% if enable_property_tests %} fuzz{% endif %}{% if enable_policy_tests %} policy{% endif %}{% if enable_dependency_audit %} audit{% endif %}
88
@echo "ci: all gates passed"
99

1010
verify: ci
1111

12+
# Lint-fix BEFORE format: ruff's fixes (import sort, SIM/UP/C4 rewrites) can emit
13+
# unformatted code, so the formatter must run last or `fmt-check` may reject `fmt`'s output.
1214
fmt:
13-
uv run ruff format .
1415
uv run ruff check --fix .
16+
uv run ruff format .
1517

1618
fmt-check:
1719
uv run ruff format --check .
@@ -44,5 +46,6 @@ mutate:
4446
{% endif %}{% if enable_scanners %}
4547
scan:
4648
uvx semgrep@1.167.0 scan --config .semgrep.yml --metrics=off --error .
47-
gitleaks dir . --redact --exit-code 1
49+
# `git` (not `dir`): scan committed history like CI, catching secrets committed then deleted.
50+
gitleaks git . --redact --exit-code 1
4851
{% endif -%}

template/mise.toml.jinja

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,7 @@ python = "{{ python_version }}"
33
uv = "0.11.23"
44
just = "1.50.0"
55
copier = "9.15.2"
6+
{%- if enable_scanners %}
7+
# scanner-only tool; pinned here so Renovate's mise manager keeps it fresh.
68
gitleaks = "8.30.1"
9+
{%- endif %}

template/pyproject.toml.jinja

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,13 @@ ignore = [
6060
select = ["E", "F", "UP", "B", "SIM", "I", "ANN", "S", "C4", "DTZ", "PTH", "RUF", "PL"]
6161
{%- endif %}
6262

63+
{% if ruff_ruleset == "all" -%}
64+
# max-complexity governs C901 (mccabe), active only under select=ALL; the curated
65+
# ruleset omits the C90 prefix, so this block would be dead config there (like pydocstyle).
6366
[tool.ruff.lint.mccabe]
6467
max-complexity = 10
6568

69+
{% endif -%}
6670
[tool.ruff.lint.pylint]
6771
max-args = 8
6872
max-branches = 12

0 commit comments

Comments
 (0)