Skip to content

Contributors and coding agents have one written style guide, and CONTRIBUTING sends style questions to it - #982

Merged
jmrplens merged 1 commit into
fix/names-records-and-axesfrom
docs/contributor-style-guide
Oct 21, 2026
Merged

jmrplens merged 1 commit into
fix/names-records-and-axesfrom
docs/contributor-style-guide

Conversation

@jmrplens

@jmrplens jmrplens commented Oct 17, 2026 •

Copy link
Copy Markdown
Owner

phonometry now has a written style guide in docs/contributing/: an index and seven pages (naming, API shape, docstrings and comments, numbers and data, tests, documentation and figures, prose, commits and pull requests) holding 235 rules. Every rule has an identifier a review can cite (N7, F35), says what went wrong without it, shows one example to follow and one to avoid, and names the check that enforces it or says that review does. CONTRIBUTING.md keeps the process and sends every style question to the guide, AGENTS.md sends coding agents there before anything else, and the review bot cites the rule identifiers.

What a contributor gets

Read the index, then the page for the area you are changing. The index lists every rule with its one-line statement and its check, in page order, and closes with the 62 rules no script checks yet, each with the idea of the check that would. It also says what to do where the code around a change breaks a rule: the rule wins, the majority form is not copied, and a rule that looks wrong is raised rather than worked around.

The guide lives only in the repository: English, no site page, no Spanish twin. The style sections of CONTRIBUTING (subscripts, language, style defaults, long numbers, printed limits, arrays, notebook display, code fences, naming, the three verbs of a judgment, module length, deprecations) moved into it, brought up to the final 4.0 names, and every docstring, guard message and workflow comment that pointed at one of them now points at its rule. CONTRIBUTING gains what it was missing as process: the editable install the gates need, what make api-docs and make llms regenerate and that CI fails on their drift, and the bullets an errata entry carries.

The Tests page also holds the two rules every workflow follows: zizmor finds nothing under .github/ (T22, held by the Audit the workflows with zizmor step of CI), and every action is pinned to a release tag, never a branch or a commit SHA (T23, held by tests/test_repository_config.py::test_every_action_is_pinned_to_a_release_tag, with zizmor refusing an action used with no ref at all).

What a coding agent gets

AGENTS.md is one screen: the layout, the setup, the gates as CI runs them (zizmor included), and the reading order (the index, the page for the area, then CONTRIBUTING). It states no rule of its own, and a test keeps it that way. The other agent entry file at the root is one line that imports it, and .coderabbit.yaml asks the review bot to check src, tests, scripts and docs against the guide and cite the rule, with the contributor guide itself exempt from the docs twin rule it states.

How the guide stays true

tests/test_contributing_guide.py holds the guide to itself: every page is well formed (an anchor per rule, one statement, one Enforced by line, a Don't example that can never run), the index and the pages agree rule by rule, every enforcer the guide names exists (a script, a test, a Makefile target, a selected ruff code, a CI job or one of its steps), every link into the guide resolves, and nothing sends a reader to a CONTRIBUTING section the guide absorbed. The guide's Do examples run with every other documentation snippet, and that CI job now installs the pinned pytest its examples of tests need.

Before the pages existed:

FAILED tests/test_contributing_guide.py::test_every_page_is_well_formed[api.md]
FAILED tests/test_contributing_guide.py::test_index_matches_the_pages - FileNotFoundError
FAILED tests/test_contributing_guide.py::test_every_enforcer_exists - FileNotFoundError
FAILED tests/test_contributing_guide.py::test_no_reference_to_a_moved_section
E       AssertionError: these sections moved to docs/contributing/ and must leave CONTRIBUTING.md
E         Left contains 15 more items, first extra item: 'Setting a subscript'
10 failed, 8 passed in 0.58s

And with one index row reworded by hand:

E           AssertionError: N16
E             - Put a unit in a name wherever two customary units compete for the quantity
E             + Put a unit in a name exactly where two customary units compete for the quantity
1 failed, 18 deselected in 0.10s

And with T22 citing the zizmor step before the check read the name of a step:

E         Left contains 2 more items, first extra item: "T22: no CI job named 'Audit the workflows with zizmor'"
1 failed, 18 deselected in 0.29s

On this branch: 20 passed.

What writing the rules down turned up

Every rule was checked against the tree. Where a rule claimed more than was decided or than its check holds, the rule now says what is decided and its Enforced by line says what the check covers. Where the tree broke a rule that is not in question, it is fixed here:

  • environment.sound_pressure_level_history and environment.impulsive_sound_adjustment refuse a stereo signal instead of reading it as one channel twice as long (X8).
  • The layered-absorber and slit-resonator plots keep their octave labels; drawing the reflection factor had reset the axis to 10^2 and 10^3, and the one guide figure that relabeled it after the call no longer needs to (F35). The figure is byte-identical.
  • Eight .plot() methods take language by name instead of only through **kwargs, and building.SoundReductionResult.report() takes metadata and language (A28, A29). Seven of them, the laboratory, intensity and survey insulation results, hand it to the rating plot they draw, and a new test draws each one in Spanish and reads its frequency axis back.
  • The tests of the API reference check put their fake packages on the import path with monkeypatch, so the path is restored by pytest rather than by hand.
  • Eleven docstrings open with a noun phrase rather than "Return" or "Get", and the last :type, :rtype and :returns: fields are gone (D8, D4).
  • 52 noqa comments in scripts and tests carried their reason after the codes; the reasons moved to the line above (C4).
  • The errata registers write their powers of ten in LaTeX and put their three one-line display formulas on lines of their own (F58, F14).
  • room.enclosed_space_reverberation no longer copies a frequency axis its record copies anyway (X11).

Four guards close the class behind those fixes, each seen failing first:

test_no_suppression_comment_hides_its_reason_from_the_parser: 52 directives in scripts/ and tests/ (it read src only)
check_markdown_hazards.py: docs/ERRATA.md:9868 '$$u_{L_\mathrm{c}} = ...' puts the formula on the opening '$$' (and five more)
test_a_published_type_variable_or_protocol_is_reported: assert [] == ["fake_typing_domain.__all__ lists 'Proto', a Protocol", ...]
test_every_plot_takes_ax_first_and_the_rest_by_name: ...IntensityReductionResult.plot: takes no 'language' (and seven more)

All four pass on this branch, as do the content test of the absorber plot and the two new stereo refusals, which fail on the code before the fix.

Where the tree breaks a rule and the fix would change the 4.0 API or needs a decision of its own (str-typed choices, a few defaulted unit-named arguments still positional, two records that still unpack like the tuples they replaced), the rule stays as decided and the break is not written into it as an exception.

Gates

ruff check . and ruff format --check . clean; mypy src scripts stub/src tests/static_typing no issues in 706 files; bandit -q -r src clean. Every scripts/check_*.py that runs without a full figure render passes; the three that read the recordings make graphs writes, the clip freshness check (the clips live in their own repository), the two release checks that read a built wheel and the stub metadata check (it needs a built stub) were left to CI. make conformance, make api-docs, make llms and make site-reports leave nothing to commit. The one figure whose renderer changed was regenerated in all four variants and is byte-identical.

Full suite: 29191 passed, 69 skipped. Documentation snippets, the guide's examples included: Documentation snippets pass all checks: 7737 blocks over 740 pages. Site: install, type check, build and html-validate pass.

@jmrplens
jmrplens added this pull request to stack #984 October 17, 2026 17:11
@sourcery-ai

sourcery-ai Bot commented Oct 17, 2026

Copy link
Copy Markdown

Sorry @jmrplens, your pull request is larger than the review limit of 150,000 diff characters

@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 107 files, which is 7 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

⚙️ Run configuration
  • Configuration used: Repository: jmrplens/phonometry/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c4b3a1fa-a148-4c5d-aa67-0bc9e04eb54c
📥 Commits

Reviewing files that changed from the base of the PR and between fa8cf7a and 9015cd5.

📒 Files selected for processing: 107
  • .coderabbit.yaml
  • .github/ISSUE_TEMPLATE/03-new-standard.yml
  • .github/labeler.yml
  • .github/workflows/python-app.yml
  • AGENTS.md
  • CHANGELOG.md
  • CLAUDE.md
  • CONTRIBUTING.md
  • docs/ERRATA.es.md
  • docs/ERRATA.md
  • docs/README.md
  • docs/contributing/api.md
  • docs/contributing/docs-and-figures.md
  • docs/contributing/docstrings.md
  • docs/contributing/index.md
  • docs/contributing/naming.md
  • docs/contributing/numerics.md
  • docs/contributing/prose.md
  • docs/contributing/tests.md
  • scripts/check_api_reference.py
  • scripts/check_control_characters.py
  • scripts/check_em_dashes.py
  • scripts/check_identifier_spelling.py
  • scripts/check_installed_package.py
  • scripts/check_markdown_hazards.py
  • scripts/check_parameter_units.py
  • scripts/check_published_catalogues_reach_the_page.py
  • scripts/check_published_sources.py
  • scripts/check_reports.py
  • scripts/check_spanish_accents.py
  • scripts/check_subscript_slope.py
  • scripts/conformance/domains/in_situ_measurement.py
  • scripts/conformance/domains/induction_loop.py
  • scripts/diagrams/canvas.py
  • scripts/fdtd_gpu_remote.py
  • scripts/figure_annotation_audit.py
  • scripts/figures/materials.py
  • scripts/generate_graphs.py
  • scripts/generate_llms.py
  • scripts/generate_reports.py
  • scripts/job_runner.py
  • scripts/mirror_overviews.py
  • site/src/content/docs/es/reference/errata.md
  • site/src/content/docs/reference/api/aeroacoustics/anp-fleet.md
  • site/src/content/docs/reference/api/building/insulation.md
  • site/src/content/docs/reference/api/building/intensity-insulation.md
  • site/src/content/docs/reference/api/building/laboratory-insulation.md
  • site/src/content/docs/reference/api/building/panel-transmission.md
  • site/src/content/docs/reference/api/building/survey-insulation.md
  • site/src/content/docs/reference/api/building/uncertainty.md
  • site/src/content/docs/reference/api/environment/impulsive-sound.md
  • site/src/content/docs/reference/api/filters/core.md
  • site/src/content/docs/reference/api/filters/frequencies.md
  • site/src/content/docs/reference/api/materials/uncertainty.md
  • site/src/content/docs/reference/api/metrology/calibration.md
  • site/src/content/docs/reference/api/rooms/spatial-decay.md
  • site/src/content/docs/reference/errata.md
  • src/phonometry/_plot/materials.py
  • src/phonometry/_plot/vibration.py
  • src/phonometry/_report/metadata.py
  • src/phonometry/aircraft/anp_fleet.py
  • src/phonometry/building/measurement/intensity_insulation.py
  • src/phonometry/building/measurement/laboratory_insulation.py
  • src/phonometry/building/measurement/survey_insulation.py
  • src/phonometry/building/measurement/uncertainty.py
  • src/phonometry/building/prediction/panel_transmission.py
  • src/phonometry/environment/assessment/impulsive_sound.py
  • src/phonometry/filters/_pinned_log.py
  • src/phonometry/filters/core.py
  • src/phonometry/filters/frequencies.py
  • src/phonometry/materials/absorbers/rating.py
  • src/phonometry/materials/absorbers/uncertainty.py
  • src/phonometry/metrology/calibration.py
  • src/phonometry/room/enclosed_space_absorption.py
  • src/phonometry/room/spatial_decay.py
  • tests/aircraft/test_aircraft_noise_system.py
  • tests/building/measurement/test_insulation_plot_language.py
  • tests/environment/sources/test_cnossos_road.py
  • tests/filters/test_compliance.py
  • tests/filters/test_weighting_design.py
  • tests/fluids/test_fluid_catalogue.py
  • tests/hearing/test_audiometry_plots.py
  • tests/io/test_catalogue_row_contract.py
  • tests/io/test_catalogue_units.py
  • tests/materials/test_materials_result_plots.py
  • tests/psychoacoustics/quality/test_fluctuation_strength_ecma.py
  • tests/signal_contract.py
  • tests/stored_verdicts.py
  • tests/test_check_api_reference.py
  • tests/test_check_control_characters.py
  • tests/test_check_markdown_hazards.py
  • tests/test_conformance_badges.py
  • tests/test_contributing_guide.py
  • tests/test_error_kinds.py
  • tests/test_fdtd_gpu_parity.py
  • tests/test_generate_llms.py
  • tests/test_mirror_overviews.py
  • tests/test_multichannel_rejection.py
  • tests/test_package_architecture.py
  • tests/test_packaging.py
  • tests/test_public_vocabulary.py
  • tests/test_report_band_labels.py
  • tests/test_result_plots.py
  • tests/test_scalar_guards.py
  • tests/test_scripts_without_numpy.py
  • tests/test_utils.py
  • tests/test_verdict_shape.py

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Review on demand using usage pricing
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@jmrplens jmrplens changed the title docs/contributor style guide Contributors and coding agents have one written style guide, and CONTRIBUTING sends style questions to it Oct 17, 2026
@jmrplens
jmrplens force-pushed the docs/contributor-style-guide branch from 3dc9b09 to 8bcf21d Compare October 17, 2026 17:12
@github-actions github-actions Bot added documentation Improvements or additions to documentation conformance Standard clause coverage, reference values or errata errata Confirmed defect in a published standard, tracked in docs/ERRATA.md api Public API surface, naming and deprecations figures Generated plots, diagrams and animations reports Accredited-format .report() fiches and their rendering site Documentation website i18n English and Spanish translations ci Workflows, linting and developer tooling area: aircraft Aircraft and rotorcraft noise area: building Sound insulation and building acoustics area: environment Outdoor propagation, environmental sources and noise assessment area: hearing Audiometric thresholds, hearing loss and noise exposure area: materials Absorption, impedance and material properties area: metrology Calibration, uncertainty and measurement quality area: psychoacoustics Loudness, sharpness, roughness and annoyance area: room Room acoustics and reverberation area: core Shared internals and cross-cutting code every domain depends on area: filters Octave filter banks, weightings and instrument class verification labels Oct 17, 2026
@codecov

codecov Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.06%. Comparing base (fa8cf7a) to head (9015cd5).

Additional details and impacted files
@@                      Coverage Diff                       @@
##           fix/names-records-and-axes     #982      +/-   ##
==============================================================
+ Coverage                       92.05%   92.06%   +0.01%     
==============================================================
  Files                             446      446              
  Lines                           91513    91513              
==============================================================
+ Hits                            84242    84253      +11     
+ Misses                           7271     7260      -11     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Numerical conformance

All 1893 conformance checks pass, across 111 domains and 523 standards

1893/1893 checks pass across 111 domains and 523 standards (227 normative designations, 125 further published sources).

Used in the tables below is how much of that clause's published tolerance the deviation consumes: 100 % sits exactly on the limit, 5 % uses a twentieth of the allowance, and a dash means the clause states no two-sided tolerance for the quantity, so there is no budget to spend. It is reported and never used to decide a verdict, which is settled at full precision before any rounding.

Renamed (4)

Standard Base quantity Head quantity
ISO 8297:1994 Table 2 Background correction at differences of 6 to 10 dB and at 12 dB, read through plant_background_correction_db Background correction at differences of 6 to 10 dB and at 12 dB, read through plant_background_correction
Wenz wind noise (rule of fives) Wind spectrum level at 1 kHz, 5 kn (canonical anchor), dB re 1 µPa²/Hz Wind spectrum level at 1 kHz, 5 kt (canonical anchor), dB re 1 µPa²/Hz
JOMOPANS-ECHO ship source level Bulker V=13.5 kn L=211 m band level at 1 kHz (File S1 oracle), dB re 1 µPa m Bulker V=13.5 kt L=211 m band level at 1 kHz (File S1 oracle), dB re 1 µPa m
ISO 10847:1997 6.3.1 The short-distance ratio is strict at 0,1, and the after case needs both of its two inequalities The short-distance ratio is strict at 0,1, the after case needs both of its two inequalities, and a geometry past 0,1 on every ratio is short

Closest to their published limit (top 5)

The rows with the least room left, so the ones a change is most likely to push over.

Standard Quantity Deviation Used
ISO/TR 17534-3:2015 Table 3 Ground-projected path length dp, m 0.005 m 100 %
DIN 4150-2:1999-06 Annex C, Example 5 KB_FTr with hammer b) in the rest hours, Formula (5) -0.005 100 %
DIN 4150-2:1999-06 Annex C, Example 8 KB_FTm over the record with the passage maxima alone -0.0005 100 %
E DIN 4150-2:2023-08 Annex B, Table B.1 KB_FTm,Zug of the metro north by Formula (5) -0.0005 100 %
Jarvis (1996) NPL CIRA(EXT) 010 Appendix B, folio 26 Volume of the coupler of the example, v = pi r^2 L -0.00000000005 m³ 100 %

Pass Tests & coverage: 263403 tests, 0 failures (all green)
Python Version Tests Failures Coverage Status
macos-latest-3.12 29267 0 92.1% Pass Passed
macos-latest-3.13 29267 0 92.1% Pass Passed
macos-latest-3.14 29267 0 92.1% Pass Passed
ubuntu-latest-3.12 29267 0 92.1% Pass Passed
ubuntu-latest-3.13 29267 0 92.1% Pass Passed
ubuntu-latest-3.14 29267 0 92.1% Pass Passed
windows-latest-3.12 29267 0 92.1% Pass Passed
windows-latest-3.13 29267 0 92.1% Pass Passed
windows-latest-3.14 29267 0 92.1% Pass Passed

Full report at this commit: docs/CONFORMANCE.md · docs/conformance.json · full CI artifacts

@jmrplens
jmrplens force-pushed the docs/contributor-style-guide branch from 8bcf21d to ff8be1f Compare October 20, 2026 01:45
@greptile-apps

greptile-apps Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Low impact] The PR appears safe to merge; the two remaining guide-test gaps are non-blocking.

Findings

  1. P2 Disabled Ruff checks look active ▶
  2. P2 Required rule sections go unchecked ▶

Reviews (2) · Last reviewed commit: "Contributors and coding agents have one ..." · Reviewed by Greptile

Comment on lines +201 to +206
config = tomllib.loads((root / "pyproject.toml").read_text(encoding="utf-8"))
selected = config["tool"]["ruff"]["lint"]["select"]
return (
None
if any(code.startswith(prefix) for prefix in selected)
else f"ruff {code} is not selected"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Disabled Ruff checks look active

enforcer_problem reads Ruff's select list but never its ignore list. For example, ruff D205 passes because D2 is selected, even though D205 is explicitly disabled. The guide can therefore name a check that does not run. Check the effective Ruff rules and add a test for an ignored rule.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #992, commit 20b5e69. The ruff check reads ignore as well as select and settles a clash by specificity, so ruff D205 reports 'is ignored' and ruff D212 passes, on the real configuration and on a fake one.

Comment on lines +128 to +138
end = starts[k + 1] if k + 1 < len(starts) else len(prose)
enforced = [
m.group(1) for _, ln in prose[start + 1 : end] if (m := _ENFORCED.match(ln))
]
if len(enforced) != 1:
problems.append(
f"{path.name}:{lineno}: {rule_id} needs exactly one '**Enforced by:**' line, has {len(enforced)}"
)
rules.append(
Rule(rule_id, path.name, statement, enforced[0] if enforced else "")
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Required rule sections go unchecked

read_page checks the anchor and Enforced by line, but never requires Why, Do or Don't. dont_fence_problems also succeeds when those sections are absent. The valid _GOOD_RULE fixture already has no examples. Require these parts and test each missing part so explanations and examples cannot disappear unnoticed.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #992, commit 20b5e69. read_page now requires exactly one Why, one Do and one Don't per rule, a Do or Don't label must be followed by its fence, _GOOD_RULE carries its examples, and a parametrized test removes each part. The 238 rules of the guide pass unchanged.

…RIBUTING sends style questions to it

phonometry now has a written style guide in `docs/contributing/`: an index and seven pages (naming, API shape, docstrings and comments, numbers and data, tests, documentation and figures, prose, commits and pull requests) holding 235 rules. Every rule has an identifier a review can cite (N7, F35), says what went wrong without it, shows one example to follow and one to avoid, and names the check that enforces it or says that review does. CONTRIBUTING.md keeps the process and sends every style question to the guide, `AGENTS.md` sends coding agents there before anything else, and the review bot cites the rule identifiers.

## What a contributor gets

Read the index, then the page for the area you are changing. The index lists every rule with its one-line statement and its check, in page order, and closes with the 62 rules no script checks yet, each with the idea of the check that would. It also says what to do where the code around a change breaks a rule: the rule wins, the majority form is not copied, and a rule that looks wrong is raised rather than worked around.

The guide lives only in the repository: English, no site page, no Spanish twin. The style sections of CONTRIBUTING (subscripts, language, style defaults, long numbers, printed limits, arrays, notebook display, code fences, naming, the three verbs of a judgment, module length, deprecations) moved into it, brought up to the final 4.0 names, and every docstring, guard message and workflow comment that pointed at one of them now points at its rule. CONTRIBUTING gains what it was missing as process: the editable install the gates need, what `make api-docs` and `make llms` regenerate and that CI fails on their drift, and the bullets an errata entry carries.

The Tests page also holds the two rules every workflow follows: zizmor finds nothing under `.github/` (T22, held by the `Audit the workflows with zizmor` step of CI), and every action is pinned to a release tag, never a branch or a commit SHA (T23, held by `tests/test_repository_config.py::test_every_action_is_pinned_to_a_release_tag`, with zizmor refusing an action used with no ref at all).

## What a coding agent gets

`AGENTS.md` is one screen: the layout, the setup, the gates as CI runs them (zizmor included), and the reading order (the index, the page for the area, then CONTRIBUTING). It states no rule of its own, and a test keeps it that way. The other agent entry file at the root is one line that imports it, and `.coderabbit.yaml` asks the review bot to check `src`, `tests`, `scripts` and `docs` against the guide and cite the rule, with the contributor guide itself exempt from the docs twin rule it states.

## How the guide stays true

`tests/test_contributing_guide.py` holds the guide to itself: every page is well formed (an anchor per rule, one statement, one Enforced by line, a Don't example that can never run), the index and the pages agree rule by rule, every enforcer the guide names exists (a script, a test, a Makefile target, a selected ruff code, a CI job or one of its steps), every link into the guide resolves, and nothing sends a reader to a CONTRIBUTING section the guide absorbed. The guide's Do examples run with every other documentation snippet, and that CI job now installs the pinned pytest its examples of tests need.

Before the pages existed:

```
FAILED tests/test_contributing_guide.py::test_every_page_is_well_formed[api.md]
FAILED tests/test_contributing_guide.py::test_index_matches_the_pages - FileNotFoundError
FAILED tests/test_contributing_guide.py::test_every_enforcer_exists - FileNotFoundError
FAILED tests/test_contributing_guide.py::test_no_reference_to_a_moved_section
E       AssertionError: these sections moved to docs/contributing/ and must leave CONTRIBUTING.md
E         Left contains 15 more items, first extra item: 'Setting a subscript'
10 failed, 8 passed in 0.58s
```

And with one index row reworded by hand:

```
E           AssertionError: N16
E             - Put a unit in a name wherever two customary units compete for the quantity
E             + Put a unit in a name exactly where two customary units compete for the quantity
1 failed, 18 deselected in 0.10s
```

And with T22 citing the zizmor step before the check read the name of a step:

```
E         Left contains 2 more items, first extra item: "T22: no CI job named 'Audit the workflows with zizmor'"
1 failed, 18 deselected in 0.29s
```

On this branch: `20 passed`.

## What writing the rules down turned up

Every rule was checked against the tree. Where a rule claimed more than was decided or than its check holds, the rule now says what is decided and its Enforced by line says what the check covers. Where the tree broke a rule that is not in question, it is fixed here:

- `environment.sound_pressure_level_history` and `environment.impulsive_sound_adjustment` refuse a stereo signal instead of reading it as one channel twice as long (X8).
- The layered-absorber and slit-resonator plots keep their octave labels; drawing the reflection factor had reset the axis to 10^2 and 10^3, and the one guide figure that relabeled it after the call no longer needs to (F35). The figure is byte-identical.
- Eight `.plot()` methods take `language` by name instead of only through `**kwargs`, and `building.SoundReductionResult.report()` takes `metadata` and `language` (A28, A29). Seven of them, the laboratory, intensity and survey insulation results, hand it to the rating plot they draw, and a new test draws each one in Spanish and reads its frequency axis back.
- The tests of the API reference check put their fake packages on the import path with `monkeypatch`, so the path is restored by pytest rather than by hand.
- Eleven docstrings open with a noun phrase rather than "Return" or "Get", and the last `:type`, `:rtype` and `:returns:` fields are gone (D8, D4).
- 52 `noqa` comments in `scripts` and `tests` carried their reason after the codes; the reasons moved to the line above (C4).
- The errata registers write their powers of ten in LaTeX and put their three one-line display formulas on lines of their own (F58, F14).
- `room.enclosed_space_reverberation` no longer copies a frequency axis its record copies anyway (X11).

Four guards close the class behind those fixes, each seen failing first:

```
test_no_suppression_comment_hides_its_reason_from_the_parser: 52 directives in scripts/ and tests/ (it read src only)
check_markdown_hazards.py: docs/ERRATA.md:9868 '$$u_{L_\mathrm{c}} = ...' puts the formula on the opening '$$' (and five more)
test_a_published_type_variable_or_protocol_is_reported: assert [] == ["fake_typing_domain.__all__ lists 'Proto', a Protocol", ...]
test_every_plot_takes_ax_first_and_the_rest_by_name: ...IntensityReductionResult.plot: takes no 'language' (and seven more)
```

All four pass on this branch, as do the content test of the absorber plot and the two new stereo refusals, which fail on the code before the fix.

Where the tree breaks a rule and the fix would change the 4.0 API or needs a decision of its own (`str`-typed choices, a few defaulted unit-named arguments still positional, two records that still unpack like the tuples they replaced), the rule stays as decided and the break is not written into it as an exception.

## Gates

`ruff check .` and `ruff format --check .` clean; `mypy src scripts stub/src tests/static_typing` no issues in 706 files; `bandit -q -r src` clean. Every `scripts/check_*.py` that runs without a full figure render passes; the three that read the recordings `make graphs` writes, the clip freshness check (the clips live in their own repository), the two release checks that read a built wheel and the stub metadata check (it needs a built stub) were left to CI. `make conformance`, `make api-docs`, `make llms` and `make site-reports` leave nothing to commit. The one figure whose renderer changed was regenerated in all four variants and is byte-identical.

Full suite: `29191 passed, 69 skipped`. Documentation snippets, the guide's examples included: `Documentation snippets pass all checks: 7737 blocks over 740 pages.` Site: install, type check, build and `html-validate` pass.
@jmrplens
jmrplens force-pushed the docs/contributor-style-guide branch from ff8be1f to 9015cd5 Compare October 20, 2026 08:09
@sonarqubecloud

Copy link
Copy Markdown

@jmrplens
jmrplens merged commit 2046276 into main Oct 21, 2026
61 checks passed
@jmrplens
jmrplens deleted the docs/contributor-style-guide branch October 21, 2026 12:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Public API surface, naming and deprecations area: aircraft Aircraft and rotorcraft noise area: building Sound insulation and building acoustics area: core Shared internals and cross-cutting code every domain depends on area: environment Outdoor propagation, environmental sources and noise assessment area: filters Octave filter banks, weightings and instrument class verification area: hearing Audiometric thresholds, hearing loss and noise exposure area: materials Absorption, impedance and material properties area: metrology Calibration, uncertainty and measurement quality area: psychoacoustics Loudness, sharpness, roughness and annoyance area: room Room acoustics and reverberation ci Workflows, linting and developer tooling conformance Standard clause coverage, reference values or errata documentation Improvements or additions to documentation errata Confirmed defect in a published standard, tracked in docs/ERRATA.md figures Generated plots, diagrams and animations i18n English and Spanish translations reports Accredited-format .report() fiches and their rendering site Documentation website

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant