Skip to content

chore: community health files (CONTRIBUTING, CoC, SECURITY, issue templates)#17

Closed
cmeans-claude-dev[bot] wants to merge 2 commits into
mainfrom
chore/community-health-files
Closed

chore: community health files (CONTRIBUTING, CoC, SECURITY, issue templates)#17
cmeans-claude-dev[bot] wants to merge 2 commits into
mainfrom
chore/community-health-files

Conversation

@cmeans-claude-dev

@cmeans-claude-dev cmeans-claude-dev Bot commented Apr 25, 2026

Copy link
Copy Markdown
Contributor

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 with uv sync --extra dev + uv run pytest / ruff / mypy. References this repo's actual structure (src/pypi_winnow_downloads/collector.pytests/test_collector.py) and the QA-label state machine (Awaiting CIReady for QAQA 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 prefixed Conduct: (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: pypinfo subprocess invocation, badge-writer path handling under attacker-controlled package names, shields.io endpoint JSON integrity, GCP credential handling + the XDG_DATA_HOME isolation that prevents pypinfo's persisted-credential TinyDB from beating GOOGLE_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 / manual winnow-collect) + an optional config slice (yaml-rendered) + --verbose logs.
  • .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.ymlblank_issues_enabled: true; contact_links point at README#install and deploy/README.md as 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.md and SECURITY.md render correctly on the GitHub repo Insights → Community Standards checklist (the green-checkmark page).
  • Insights → Community Standards reports CoC, Contributing, Security, and Issue templates as present.
  • Click "New issue" — the two templates appear in the chooser, plus the two contact links from config.yml.
  • Submit a draft bug-report issue and confirm form fields render as designed; close without saving.
  • All cross-file links from CONTRIBUTING (LICENSE, SECURITY.md, ../../issues/new?template=...) resolve.
  • No drift: scan SECURITY.md scope vs current code (collector subprocess argv handling, badge writer atomic-replace flow, XDG_DATA_HOME isolation in run_pypinfo, deploy/systemd hardening directives) — all referenced behaviors are still in tree.

…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).
@github-actions github-actions Bot added Awaiting CI Dev complete, waiting for CI/Codecov to pass before QA Ready for QA Dev work complete — QA can begin review and removed Awaiting CI Dev complete, waiting for CI/Codecov to pass before QA labels Apr 25, 2026
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@cmeans cmeans added QA Active QA is actively reviewing; Dev should not push changes and removed Ready for QA Dev work complete — QA can begin review labels Apr 25, 2026
@cmeans

cmeans commented Apr 25, 2026

Copy link
Copy Markdown
Owner

Starting QA round 1 on head 77d5356. Adding QA Active.

@cmeans cmeans left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

QA round 1 — 1 substantive finding.

  1. 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 in config.example.yaml plus pypi-winnow-downloads itself 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.md and point there instead.

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.md scope claims cross-checked against in-tree code — no drift on those:
    • Atomic .tmp + os.replace pattern lives at src/pypi_winnow_downloads/badge.py:43-45 and src/pypi_winnow_downloads/collector.py:269-271.
    • XDG_DATA_HOME isolation lives at src/pypi_winnow_downloads/collector.py:131-144 (with the pypinfo db.py foot-gun comment intact).
    • Reference systemd unit (deploy/systemd/pypi-winnow-downloads-collector.service) has PrivateTmp=true, ProtectSystem=strict, and RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 — the three directives SECURITY.md calls out.
    • Caddyfile (deploy/caddy/Caddyfile.example) sets index off and Content-Type application/json, matching the in-scope claim about default-on directory listings.
  • bug_report.yml deployment 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.md scope 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/choose renders 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).

@cmeans

cmeans commented Apr 25, 2026

Copy link
Copy Markdown
Owner

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.

@cmeans cmeans added QA Failed QA found issues — needs dev attention and removed QA Active QA is actively reviewing; Dev should not push changes labels Apr 25, 2026
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.
@github-actions github-actions Bot added Awaiting CI Dev complete, waiting for CI/Codecov to pass before QA and removed QA Failed QA found issues — needs dev attention labels Apr 25, 2026
@cmeans-claude-dev cmeans-claude-dev Bot added the Ready for QA Dev work complete — QA can begin review label Apr 25, 2026
@cmeans-claude-dev

Copy link
Copy Markdown
Contributor Author

Round 2 ready (commit 19e2c8e).

Round 1 finding addressed:

  • .github/ISSUE_TEMPLATE/feature_request.yml Scope-check field — dropped the dangling (see the README's Status section) parenthetical. The inline exclusions list (database, web framework, user-supplied package API, auth, backfill, web UI) now stands on its own as the form's source of truth. Picked option (b) from the review because it doesn't require duplicating the exclusions into README.md or CONTRIBUTING.md and keeps the form self-contained. Options (a) and (c) would each grow the surface area and force the list to live in two places.

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.

@github-actions github-actions Bot removed Awaiting CI Dev complete, waiting for CI/Codecov to pass before QA labels Apr 25, 2026
@cmeans cmeans added QA Active QA is actively reviewing; Dev should not push changes and removed Ready for QA Dev work complete — QA can begin review labels Apr 25, 2026
@cmeans

cmeans commented Apr 25, 2026

Copy link
Copy Markdown
Owner

Starting QA round 2 on head 19e2c8e. Adding QA Active.

@cmeans cmeans left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

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:

  1. Substantive — PR body, line 9: the bullet describing feature_request.yml reads:

    "...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 log forever. 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.

@cmeans

cmeans commented Apr 25, 2026

Copy link
Copy Markdown
Owner

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.

@cmeans cmeans added QA Failed QA found issues — needs dev attention and removed QA Active QA is actively reviewing; Dev should not push changes labels Apr 25, 2026
@cmeans-claude-dev cmeans-claude-dev Bot added Ready for QA Dev work complete — QA can begin review and removed QA Failed QA found issues — needs dev attention labels Apr 25, 2026
@cmeans-claude-dev

Copy link
Copy Markdown
Contributor Author

Round 3 ready (no new commit — PR-body-only fix per the round-2 finding).

Round 2 finding addressed:

  • PR body bullet for feature_request.yml no longer says "names the hard exclusions from README's Status section". Replaced with "names the hard exclusions inline" — matches the round-1 form-file fix and won't carry the false README attribution into the squash-merge commit body / git log.

No code change; PR head is still 19e2c8e. CI status preserved (no re-run triggered).

@cmeans cmeans added QA Active QA is actively reviewing; Dev should not push changes and removed Ready for QA Dev work complete — QA can begin review labels Apr 25, 2026
@cmeans

cmeans commented Apr 25, 2026

Copy link
Copy Markdown
Owner

Starting QA round 3 on head 19e2c8e (PR-body-only edit, no new commit). Adding QA Active.

@cmeans cmeans left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

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.

@cmeans

cmeans commented Apr 25, 2026

Copy link
Copy Markdown
Owner

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.

@cmeans cmeans added Ready for QA Signoff QA passed — ready for maintainer final review and merge and removed QA Active QA is actively reviewing; Dev should not push changes labels Apr 25, 2026

@cmeans cmeans left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

LGTM

@cmeans cmeans added QA Approved Manual QA testing completed and passed and removed Ready for QA Signoff QA passed — ready for maintainer final review and merge labels Apr 25, 2026
@cmeans-claude-dev

Copy link
Copy Markdown
Contributor Author

Closing — CreateEvent leak under v1 bot-push design (first push of chore/community-health-files was attributed to cmeans instead of the bot, which makes require_last_push_approval reject the cmeans approval as self-approval). Force-push does not fix this — CreateEvent actor is immutable.

Replaced by #20 with the v2 bot-push design active (CreateEvent now attributes to cmeans-claude-dev[bot]). Same commits cherry-picked; branch contents identical.

Background: cmeans/claude-dev#4 deployed v2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

QA Approved Manual QA testing completed and passed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants