Write down the contribution rules: look for a library before writing one, and the formats data leaves in #653
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#653
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Two rules from the maintainer's list of 2026-10-02 are written nowhere a contributor, or an assistant working from
CLAUDE.md, would read them. The first is about writing code:The second is about formats:
What exists today
CONTRIBUTING.mdsays what will not be merged (payment, a weakened security boundary, something nobody can use::160-179), that a new boundary takes security tests and that "CI audits the dependencies too" (:253-256), and how the lock is kept current (:301-313). A search of it for reuse, hand-written or new dependency finds nothing.CLAUDE.md:1-83has no word on dependencies or formats either; its AI section (:77-83) says to credit a model "the way you would credit a library".documents/formats.py:18-22("The core stays dependency-light"),documents/docx.py:3-6(nopython-docx, which would bringlxml),applications/ical.py:1-6("A dependency would bring the rest of the standard along for nothing"),docs/PLAN.md:133-136(BeautifulSoup and lxml not added). The DAV plugin says the same of vCard and iCalendar (postulo-dav/pyproject.toml:19-22,src/postulo_dav/text.py:1-8).phonenumberslite(Apache-2.0, libphonenumber's metadata as pure Python) for telephone numbers, andsrc/postulo/core/phones.py:29-45says why: the hand-written rule of thumb "was itself producing numbers nobody can dial" and could not tell an unusual number from a mistyped one. The dependency is commented where it is declared (pyproject.toml:55-61). That is the rule applied before it was written; this issue gives it a place.pip-audit --strictover the lock andnpm audit --audit-level=high(.forgejo/workflows/ci.yml:311-320); an advisory is ignored only by name, with a test that expires the ignore (tests/test_security_audit.py:39-54); a monthlyDependenciesworkflow; the image's SBOM (.forgejo/workflows/image.yml:199). Vendored files are held toTHIRD-PARTY.mdbytests/test_trademarks.py, which names a fixed list of directories (#579). Packages from the index are outside that register on purpose (THIRD-PARTY.md:38-40); severalpyproject.tomlentries (httpx, defusedxml, django-cotton) carry a comment saying why they are there..forgejo/holdsworkflows/andzizmor.yml. #351 adds issue forms only. No plugin repository has aCONTRIBUTING.md; Writing a plugin has a Dependencies paragraph (Writing-a-plugin.md:396-400).core/export.py:80), the candidate's record as JSON (format 4,:104), one contact as JSON (#297), the API; ODT is #480, DOCX and text are done (#236); iCalendar is written by hand and never read; vCard exists only in the DAV plugin.Checked against
mainatf09b6010b.Proposal
CONTRIBUTING.mdgets a section, Look for a library before you write one, after House style, saying in the maintainer's terms: before writing code that implements a standard, a format, a data set or a well-known algorithm, look for an open-source library that already does it, and say in the pull request what was found. Take it when: its licence is compatible with AGPL-3.0-or-later; it is maintained;pip-auditornpm audit(or OSV) report no unpatched advisory in the range the lock would hold; its cost is stated (size, a compiled or system dependency, what it brings with it); and it fits the content security policy and makes no request nobody asked for. It is not taken when it has an unpatched severe advisory. Writing it by hand is then right, and the pull request says which advisory.CLAUDE.mdgets two lines in How the code is shaped, pointing at both sections, so an assistant reads them before it starts..forgejo/PULL_REQUEST_TEMPLATE.md) with the same three questions: what library was looked at, whether a licence line is needed (THIRD-PARTY.mdfor files in the tree, a comment inpyproject.tomlfor a package), and whether the advisory check came back clean. The feature form of #351 gets one field: Is there an open-source library or a standard that already does this?CONTRIBUTING.md.django-cities-xtdbelongs to #700 (maps) anddjango-schedulerto #661 (calendar).seleniumwas not weighed in #36, which built the browser suite on Playwright because it was already an optional dependency. The checks run on 2026-10-02: django-cities-xtd 0.7.1 (2026-01-08, MIT, no advisory in OSV); django-scheduler 0.12.0 (2026-02-15, BSD-3-Clause, none); selenium 4.50.0 (2026-09-30, Apache-2.0, two advisories, both fixed in 4.0.0 and 4.14.0). The browser suite is Playwright (1.62.0 inuv.lock, 1.63.0 the latest release; Apache-2.0, no advisory). The rule asks for the check; it does not say the alternative wins.Decisions
ical.py,docx.py, the DAV parser, the SVG sanitiser); or apply the rule to new code and to code a commit touches. Recommended: from now on, and when touched. Working code is not rewritten for a rule that arrived later; #660 and #661 touch the two files that matter and carry the prior art.python-docxandlxmlwould still be refused and a pure-Python library with no new dependency would not be. The comments are reworded when their files are next touched.pyproject.toml; one whose fix cannot be taken yet is ignored by name with a test that expires the ignore, as oauthlib's is (#323,tests/test_security_audit.py). The library is still taken.applications/views.py:1181) and the spreadsheet import (core/csv_import.py) are CSV because employment offices and spreadsheets are. Recommended: the formats rule governs what Postulo offers first; CSV stays where a spreadsheet is the other end.Needed by
#654, #659, #660 and #661 each record a library check against this rule.
Builds on
Issues #579 (the register and its test), #351 (the forms), #107 (marks), #279 (vendored notices), #480 and #236 (document formats).
Done when
CONTRIBUTING.mdcarries both sections,CLAUDE.mdpoints at them, Writing a plugin says the rule binds plugins, and the pull request template exists with the three questions. The feature form of #351 carries its field.tests/test_trademarks.py, holds the prose to the tree: the template exists and the headingsCONTRIBUTING.mdlinks to are there.tests/test_wiki_surface.pyare unaffected.From the list of improvements of 2026-10-02.