Skip to content

docs: baseline docstring rules and generate llms.txt in CI - #443

Merged
loonghao merged 1 commit into
mainfrom
docs/docstring-baseline-and-llms-txt
Oct 13, 2026
Merged

loonghao merged 1 commit into
mainfrom
docs/docstring-baseline-and-llms-txt

Conversation

@loonghao

Copy link
Copy Markdown
Owner

Summary

Two related changes, both configuration and documentation only. No packaging
changes and no lockfile changes.

  1. Docstring rules are now on, with the existing debt baselined. The deleted
    .flake8 configured flake8-docstrings (google convention), but the plugin
    was never installed in CI, so those rules never actually ran. Ruff's D rules
    are now enabled and every current finding is recorded as a per-directory
    baseline, so CI stays green on the current tree while any new docstring debt
    fails immediately.
  2. llms.txt / llms-full.txt are now generated, not hand-written. A new
    script generates both, and a new CI job runs it ahead of release-please and
    opens a pull request whenever the output differs from what is committed.

Docstring baseline

There were 864 D findings when the rules were switched on. They are
recorded per directory tier in [tool.ruff.lint.per-file-ignores], each with its
finding count:

Directory Findings
photoshop/api/enumerations.py 129
photoshop/api/save_options/** 112
photoshop/api/open_options/** 9
photoshop/api/colors/** 19
photoshop/api/** (the rest) 443
photoshop/** (package root) 8
test/manual_test/** 118
test/** (the rest) 45

The baseline is a ratchet, not a permanent exemption. Verified in both
directions:

  • New debt fails. Adding an undocumented public function to
    photoshop/api/errors.py (a file whose D100/D101 are baselined) produces
    D103, which is not baselined for that tier, and ruff check fails.
  • Fixing a tier shrinks it. Removing a rule from a tier's list makes that tier's
    remaining debt fail until it is fixed.

To clear a tier: fix the findings, delete the corresponding rule from that
tier's list. enumerations.py is the cheapest first target — all 129 are D101
on IntEnum constant tables where a per-class docstring is mostly noise.

llms.txt generation

  • scripts/generate_llms.py writes llms.txt (a ~2.7 KB curated index) and
    llms-full.txt (~58 KB; README, examples, and a module index concatenated).
  • Output is deterministic: newlines are written as LF explicitly, so a
    maintainer on Windows and CI on Linux produce identical bytes.
  • --check exits non-zero when the committed files are stale. Run
    python scripts/generate_llms.py locally to regenerate.
  • The llms-txt job sits in the Release workflow with needs: [preflight], and
    release-please now has needs: [preflight, llms-txt], so generation is
    ordered ahead of the release. release-please keeps if: always(), so a
    failure here reports red but does not block a release.
  • The job opens or updates a pull request on docs/update-llms-txt rather than
    pushing to main, and is a no-op when nothing changed.

The llms.txt quickstart snippet is the example from the photoshop.Session
docstring, not a newly invented one.

Rules that could not be mapped 1:1 from .flake8

Flagged rather than silently dropped:

  1. ignore = BLK100 — BLK100 comes from flake8-black, which is not in
    the dev dependencies and was never installed, so the ignore was inert. Dropped
    as dead configuration. Formatting is already enforced by ruff format in CI.
  2. exclude included test, the ruff port does not. The test directory
    was excluded from flake8 but is linted under ruff. This widens coverage rather
    than narrowing it. Verified safe: E, W, F, Q, I and UP report zero
    findings on test/, so the widening introduces no new failures.
  3. docstring-convention = google was inert for the reason above; it is now
    live as [tool.ruff.lint.pydocstyle] convention = "google" and is what
    produced the 864 baselined findings.
  4. .pylintrc disabled C0103 (invalid-name) and R0903 (too-few-public-methods).
    These are pylint-only and have no ruff equivalent; pylint was never invoked by
    nox, pre-commit, or any workflow, so the file was dead configuration and was
    already deleted in an earlier PR. No ruff rules were added to replace them.

Validation

  • ruff check photoshop (the CI lint command): passes.
  • ruff check . (the full tree): passes.
  • ruff format --check photoshop: 64 files already formatted.
  • ruff check scripts/ and ruff format --check scripts/: clean.
  • python scripts/generate_llms.py then --check: idempotent.
  • pytest test/test_collections.py test/test_imports.py: 18 passed.
  • pytest --collect-only: 169 tests collected.

The remaining tests under test/manual_test/ drive a real Photoshop COM
instance and cannot run in this environment; they were not executed here.

Enable ruff's D rules with the existing docstring debt recorded as a
per-directory baseline, so CI stays green on the current tree while new
docstring debt fails immediately. Each baseline entry records its finding
count; deleting a rule from an entry makes that tier's debt fail until it
is fixed.

Add scripts/generate_llms.py plus an llms-txt job that runs ahead of
release-please and opens a pull request when the generated llms.txt or
llms-full.txt differ from what is committed. The job is non-blocking: a
failure reports red but does not hold the release.

Configuration and documentation only; no packaging or lockfile changes.
@loonghao
loonghao merged commit 2bd71a1 into main Oct 13, 2026
17 checks passed
@loonghao
loonghao deleted the docs/docstring-baseline-and-llms-txt branch October 13, 2026 21:15
loonghao added a commit that referenced this pull request Oct 13, 2026
…der CI lint (#445)

Follow-up to #443, covering three of the four P2 findings from its review.

Correct the docstring baseline comments where they described behaviour that
ruff does not implement: `per-file-ignores` unions every matching pattern
instead of resolving the most specific one, and the "delete a rule from a
tier" ratchet only operates on the widest tier covering a file. The finding
counts in the comments were also wrong in a way that reversed the explanation.
Rules, tiers and counts are unchanged, so CI behaviour is not affected.

Extend the lint scope from `photoshop` to `photoshop test scripts`, which makes
the `test/**` and `test/manual_test/**` baseline tiers reachable from CI for
the first time and puts `scripts/` under the `D` rules with no baseline. Six
files under `test/` are reformatted; all six are AST-identical before and
after, and the repo's pre-commit hook already applied `ruff format` to the
whole tree.

Run `scripts/generate_llms.py --check` in the `Python package` workflow so a
drifted `llms.txt` fails the build instead of only producing a bot pull
request.

Also correct two stale references: the generator's module docstring pointed at
a workflow file that does not exist, and a comment claimed the job stamps the
version about to be released when it actually stamps the last released one.

Configuration, comments and CI wiring only. No packaging or lockfile changes,
and the generated `llms.txt` / `llms-full.txt` are untouched.
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.

1 participant