chore: community health files (CONTRIBUTING, CoC, SECURITY, issue templates)#17
chore: community health files (CONTRIBUTING, CoC, SECURITY, issue templates)#17cmeans-claude-dev[bot] wants to merge 2 commits into
Conversation
…plates)
Ports the standard set of community-health files from cmeans/mcp-clipboard,
adapting each for pypi-winnow-downloads's surface area:
- CONTRIBUTING.md — Apache-2.0 inbound=outbound rule (no CLA, no extra
terms), no-bounties posture, scope-first (open an issue before a
non-trivial PR), test-required-with-PR, dev setup with `uv sync
--extra dev`. Reference deploy + uv tooling instead of clipboard
daemon variants. Two issue templates instead of three (no
platform-test variant since this is a Linux-only LXC service).
- CODE_OF_CONDUCT.md — adopts Contributor Covenant 2.1 verbatim;
routes private reports through a GitHub Private Security Advisory
prefixed `Conduct:` (one-person project, no shared inbox).
- SECURITY.md — supported versions (0.1.x), private vulnerability
reporting via Advisory. Scope rewritten for this project's actual
surface: pypinfo subprocess invocation, badge writer path handling,
shields.io endpoint JSON integrity, GCP credential handling +
XDG_DATA_HOME isolation, supply chain on published wheel/sdist,
systemd hardening regressions, Caddyfile defaults. Out-of-scope:
pypinfo / PyYAML / google-cloud-bigquery / shields.io / BigQuery
dataset itself (route upstream).
- .github/ISSUE_TEMPLATE/{bug_report,feature_request,config}.yml —
ports + adapts the form fields. Bug template asks for
pip-show-version + Python + OS + deployment shape (systemd /
docker / manual) + a config slice + verbose logs. Feature
template's Area dropdown lists collector / badge generation / new
badge variant / config schema / CLI / deploy artifacts / docs / CI
/ other, with a v1-scope-check field that names the hard
exclusions documented in README. config.yml links README#install
and deploy/README.md as alternative entry points.
CHANGELOG entry omitted (community-health files are project
infrastructure, not user-visible product changes).
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
Starting QA round 1 on head 77d5356. Adding QA Active. |
cmeans
left a comment
There was a problem hiding this comment.
QA round 1 — 1 substantive finding.
-
Substantive —
.github/ISSUE_TEMPLATE/feature_request.yml:50-54(Scope-check field) points readers at a section that doesn't have what the form promises. The description says:"v1 deliberately excludes a database, web framework, user-supplied package API, auth, backfill, and a web UI (see the README's Status section)."
But
README.md:77-83(Status section, verbatim):"Alpha. Self-hosted reference deployment running at
pypi-badges.intfar.com, producing daily badges for four target packages (the three seed packages inconfig.example.yamlpluspypi-winnow-downloadsitself for the dogfood badge). Expect rough edges and possible breaking changes in the 0.x series."The exclusions list is real (it's a project decision), but it lives in awareness/internal docs, not in
README.md. A user who follows the pointer won't find the exclusions there. Three reasonable fixes — pick whichever:- (a) Add the exclusions to
README.md's Status section so the pointer pays off. - (b) Drop the parenthetical pointer and let the inline list above it stand on its own.
- (c) Move the exclusions to
CONTRIBUTING.mdand point there instead.
- (a) Add the exclusions to
Verification done in this session (PR head 77d5356):
- All three issue-template YAMLs parse cleanly (
yaml.safe_load). - 56/56 tests pass under
uv run pytest; ruff + ruff-format +mypy src/all clean. - All paths referenced from the new files exist in tree:
LICENSE,CHANGELOG.md,src/pypi_winnow_downloads/collector.py,tests/test_collector.py,deploy/README.md,deploy/systemd/,deploy/docker/,deploy/caddy/,config.example.yaml— all present.
SECURITY.mdscope claims cross-checked against in-tree code — no drift on those:- Atomic
.tmp+os.replacepattern lives atsrc/pypi_winnow_downloads/badge.py:43-45andsrc/pypi_winnow_downloads/collector.py:269-271. XDG_DATA_HOMEisolation lives atsrc/pypi_winnow_downloads/collector.py:131-144(with thepypinfo db.pyfoot-gun comment intact).- Reference systemd unit (
deploy/systemd/pypi-winnow-downloads-collector.service) hasPrivateTmp=true,ProtectSystem=strict, andRestrictAddressFamilies=AF_UNIX AF_INET AF_INET6— the three directivesSECURITY.mdcalls out. - Caddyfile (
deploy/caddy/Caddyfile.example) setsindex offandContent-Type application/json, matching the in-scope claim about default-on directory listings.
- Atomic
bug_report.ymldeployment options (deploy/systemd reference,deploy/docker reference) all map to real subdirectories.- Pre-merge community-profile baseline:
health_percentage: 42, missing CoC / Contributing / Issue templates / PR template / Security. Post-merge this PR should add 4 of those 5 (no PR template, but PR template wasn't in scope).
Test plan items verifiable now:
- Item 5 (cross-file links resolve) ✓ — see verification above.
- Item 6 (
SECURITY.mdscope vs in-tree code, no drift) ✓ — see verification above.
Test plan items 1-4 are post-merge or UI-render checks that can't be exercised on a feature branch before merge:
- 1, 2: Insights → Community Standards green-checkmark page only re-evaluates after merge to default branch.
- 3: Template chooser at
/issues/new/chooserenders from the default branch, not from a PR branch. - 4: Draft-issue form rendering similarly needs the templates on the default branch.
The YAML-parses-cleanly check above is the strongest pre-merge proxy for items 3 and 4; once merged, you can walk 1-4 against the live UI and tick them in the PR (or in a brief follow-up comment).
|
QA round 1 verdict: QA Failed — 1 substantive (feature_request.yml's Scope-check field directs readers to README's Status section for v1 exclusions, but those exclusions don't actually appear there; three fix options offered). Verification this session at head 77d5356: 56/56 tests, ruff + format + mypy clean, all 3 issue-template YAMLs parse cleanly, all referenced in-tree paths exist, SECURITY.md scope cross-checked against badge.py / collector.py / deploy/systemd / deploy/caddy with no drift. Test-plan items 5 + 6 ticked. Items 1-4 are GitHub-UI checks that can only run post-merge — left unticked with a note. Applying QA Failed as the final act. |
QA round 1 substantive finding: feature_request.yml's Scope-check field directed readers to README's Status section for the v1 exclusions list, but those exclusions don't actually live there — they're in the project's awareness entries / handoff doc, not in any in-tree user-facing file. A contributor following the pointer would not find what the form promised. Going with option (b) from the review: drop the parenthetical "(see the README's Status section)" pointer. The inline list of exclusions in the description is itself the source of truth for the form — no external reference needed, and the form is exactly where a contributor needs the list anyway. Options (a) "add the exclusions to README" and (c) "move the list to CONTRIBUTING.md" would each grow the surface area and force the same list to live in two places. Inline-only is the minimum-drift fix.
|
Round 2 ready (commit 19e2c8e). Round 1 finding addressed:
No CHANGELOG churn — internal QA-round wording, not user-visible. Test plan items 1-4 remain post-merge UI checks (see round 1 review note); items 5 and 6 were ticked in round 1. |
|
Starting QA round 2 on head 19e2c8e. Adding QA Active. |
cmeans
left a comment
There was a problem hiding this comment.
QA round 2 — 1 substantive finding (carried-over drift, this time in the PR body itself).
Round-1 form-side finding cleanly resolved. Commit 19e2c8e drops "(see the README's Status section)" from feature_request.yml's Scope-check field; the field now lists the v1 exclusions inline and stops there. No leftover "README" reference in the form file.
But the PR body still has the same drift the form just shed:
-
Substantive — PR body, line 9: the bullet describing
feature_request.ymlreads:"...with a v1-scope-check field that names the hard exclusions from README's Status section (no DB, web framework, user-supplied package API, auth, backfill, web UI)."
That's the same false attribution the round-1 fix removed from the form file. After this PR squash-merges, the PR body becomes the commit body, so the misdescription persists in
git logforever. Suggested edit — drop the stale source pointer, keep the parenthetical list which is the actually-useful part:"...with a v1-scope-check field that names the hard exclusions (no DB, web framework, user-supplied package API, auth, backfill, web UI)."
No code change needed; just edit the PR body via
gh pr edit 17 --body-file ....
Verification done in this session (PR head 19e2c8e):
- 56/56 tests pass; ruff + ruff-format +
mypy src/all clean. - All 3 issue-template YAMLs still parse.
feature_request.yml's Scope-check field grep'd clean — no remaining "README" reference.- All round-1 checks still hold (paths exist, SECURITY.md scope claims still match in-tree code, all CI checks SUCCESS).
This is a one-line PR-body edit, no code or test changes needed.
|
QA round 2 verdict: QA Failed — 1 substantive (PR-body descriptive bullet for feature_request.yml still says "names the hard exclusions from README's Status section", same drift the round-1 fix removed from the form file; matters because PR body becomes the squash-merge commit body). Form-side round-1 fix verified clean at head 19e2c8e: 56/56 tests, ruff + format + mypy clean, all 3 YAMLs parse, no leftover README reference in feature_request.yml. One-line PR-body edit, no code change. Applying QA Failed as the final act. |
|
Round 3 ready (no new commit — PR-body-only fix per the round-2 finding). Round 2 finding addressed:
No code change; PR head is still |
|
Starting QA round 3 on head 19e2c8e (PR-body-only edit, no new commit). Adding QA Active. |
cmeans
left a comment
There was a problem hiding this comment.
QA round 3 — zero findings, ready for signoff. Round-2 PR-body finding cleanly resolved: line 9 now reads "names the hard exclusions inline (no DB, web framework, user-supplied package API, auth, backfill, web UI)" — no more dangling README reference. Only remaining "README" mention in the PR body is line 10's accurate description of config.yml's contact_links, which legitimately point at README#install and deploy/README.md.
Re-verification on unchanged head 19e2c8e: 56/56 tests pass, ruff + ruff-format + mypy clean, all 3 issue-template YAMLs parse. All round-1 and round-2 verifications still hold.
Test-plan items 1-4 remain post-merge UI checks (Insights → Community Standards re-evaluation, template chooser at /issues/new/choose) — left unticked, as called out in round 1.
|
QA round 3 verdict: Ready for QA Signoff. Zero findings. Round-2 PR-body drift cleanly fixed (line 9 now says "inline"). Re-verification at head 19e2c8e: 56/56 tests, ruff + format + mypy clean, all 3 YAMLs parse. Test-plan items 1-4 remain post-merge UI checks. Applying Ready for QA Signoff as the final act. |
|
Closing — CreateEvent leak under v1 bot-push design (first push of Replaced by #20 with the v2 bot-push design active (CreateEvent now attributes to Background: cmeans/claude-dev#4 deployed v2. |
Summary
Ports the standard community-health file set from
cmeans/mcp-clipboard, adapted for this project's surface area. Six new files; no behavior change.CONTRIBUTING.md— Apache-2.0 inbound=outbound rule (no CLA, no extra terms), no-bounties posture, scope-first (open an issue before a non-trivial PR), test-required-with-PR, dev setup withuv sync --extra dev+uv run pytest/ruff/mypy. References this repo's actual structure (src/pypi_winnow_downloads/collector.py→tests/test_collector.py) and the QA-label state machine (Awaiting CI→Ready for QA→QA Approved/QA Failed). Two issue templates instead of three — no platform-test variant since this is a Linux-only LXC service.CODE_OF_CONDUCT.md— adopts Contributor Covenant 2.1 verbatim; routes private reports through a GitHub Private Security Advisory prefixedConduct:(one-person project, no shared inbox).SECURITY.md— supported versions (0.1.x), private vulnerability reporting via Advisory. Scope is rewritten for this project's actual surface:pypinfosubprocess invocation, badge-writer path handling under attacker-controlled package names, shields.io endpoint JSON integrity, GCP credential handling + theXDG_DATA_HOMEisolation that preventspypinfo's persisted-credential TinyDB from beatingGOOGLE_APPLICATION_CREDENTIALS, supply chain on published wheel/sdist, systemd hardening regressions, Caddyfile defaults. Out of scope:pypinfo/PyYAML/google-cloud-bigquery/ shields.io / the BigQuery public dataset itself (route upstream)..github/ISSUE_TEMPLATE/bug_report.yml— pip-show version + Python version + OS + deployment shape (systemd / Docker / manualwinnow-collect) + an optional config slice (yaml-rendered) +--verboselogs..github/ISSUE_TEMPLATE/feature_request.yml— Area dropdown lists collector / badge generation / new badge variant / config schema / CLI / deploy artifacts / docs / CI / other, with a v1-scope-check field that names the hard exclusions inline (no DB, web framework, user-supplied package API, auth, backfill, web UI)..github/ISSUE_TEMPLATE/config.yml—blank_issues_enabled: true; contact_links point atREADME#installanddeploy/README.mdas alternative entry points before filing.CHANGELOG entry intentionally omitted — community-health files are repo infrastructure, not user-visible product changes (consistent with how mcp-clipboard added theirs).
Test plan
CONTRIBUTING.mdandSECURITY.mdrender correctly on the GitHub repo Insights → Community Standards checklist (the green-checkmark page).Insights → Community Standardsreports CoC, Contributing, Security, and Issue templates as present.config.yml.LICENSE,SECURITY.md,../../issues/new?template=...) resolve.run_pypinfo, deploy/systemd hardening directives) — all referenced behaviors are still in tree.