Skip to content

ci: narrow the email check to the maintainer's address only - #71

Merged
jothimani-rajendran merged 4 commits into
mainfrom
ci/no-email-leaks
Sep 9, 2026
Merged

ci: narrow the email check to the maintainer's address only#71
jothimani-rajendran merged 4 commits into
mainfrom
ci/no-email-leaks

Conversation

@jothimani-rajendran

Copy link
Copy Markdown
Collaborator

Why this exists

#70 merged a version of the email check that rejects every address except a service account. That would block an outside contributor from signing off with their own email — a DCO sign-off is somebody's own attestation, not a leak, and blocking it turns a privacy check into a barrier to contributing. This corrects that; it is live on main right now.

What the rule is now

  1. A sign-off trailer may carry any address. Signed-off-by, Co-Authored-By, Reported-by, Reviewed-by, Tested-by and Acked-by are exempt.
  2. Anywhere else in the message, an address is rejected — pasted from a log line, a stack trace, or a quoted report. That is how one actually arrives by accident.
  3. The maintainer's own personal address is rejected everywhere, sign-off included, matched by SHA-256 digest — writing it into a public workflow file in the clear would publish it far more prominently than the old commits this check exists to stop repeating.

Also in this branch

docs/figures/palette.py now points at the visual standard it implements. VISUAL.md lives in the org's .github repository, but GitHub gives no special treatment to that filename — unlike profile/README.md or the community-health files, nothing surfaces it, and nothing linked to it. The pointer goes where the standard actually gets broken: the top of the file someone editing figures already has open. CONTRIBUTING.md gains a short ## Figures section for readers rather than editors.

Verified

  • Last 60 commits of all four repositories: zero email false positives. A contributor @gmail sign-off passes; dependabot's support@github.com passes — and this repo's recent history contains such commits, so the earlier revision would have failed every dependency PR here.
  • The workflow's own run: block, extracted from the merged tree and executed against four throwaway commits: contributor sign-off passes, dependabot passes, maintainer address fails, pasted user=bob@example.org fails — and neither address is echoed into the log.
  • palette.py stays a formatter fixed point: clean under ruff check and ruff format at 88, 100 and 120. Every generated SVG byte-identical.

Scans only BASE_SHA..HEAD, unchanged — this repo has 83 pre-existing session-link violations on main, so a full-history scan would fail every build from day one.

🤖 Generated with Claude Code


Generated by Claude Code

The previous revision of this branch rejected every address that was not a
service account, which would have blocked an outside contributor from signing
off with their own email. DCO sign-off is somebody's own attestation, so their
address there is their choice rather than a leak.

Three rules now, in place of one blocklist of five consumer domains:

- A sign-off trailer may carry any address. Signed-off-by, Co-Authored-By,
  Reported-by, Reviewed-by, Tested-by and Acked-by are all exempt.
- Anywhere else in the message an address is rejected, because that is how one
  actually arrives by accident -- pasted from a log line, a stack trace, or a
  quoted report.
- The maintainer's own personal address is rejected everywhere, including in a
  sign-off, matched by SHA-256 digest. Writing it into a public workflow file
  in the clear would publish it far more prominently than the old commits this
  check exists to stop repeating.

Validated before pushing rather than after. Against the last 60 commits of all
four repositories there is not one email false positive: dependabot's
support@github.com sign-off passes, version-pinned filenames like
claude_code@2.1.263.json are not treated as addresses, and every remaining
failure is a session identifier this check already caught. Against the full
history of chock-catalog the digest rule flags all 17 commits that really do
carry that address, and no others. The workflow's own run: block was then
executed end to end: a contributor gmail sign-off passes, the maintainer
address and a pasted log line both fail, and neither is echoed into the log.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Claude <noreply@anthropic.com>
VISUAL.md is live in the org's .github repository, but GitHub gives no
special treatment to that filename -- unlike profile/README.md or the
community health files, nothing surfaces it. It sat at a URL that nothing
linked to, which for a standard is close to not existing.

The person who needs it is editing docs/figures/, so the pointer goes at the
top of palette.py, the file they have open. That file is carried
byte-identically by four repositories, so one edit reaches all of them.

CONTRIBUTING gains a short Figures section for someone browsing rather than
editing, which also states the two rules people get wrong: change the shared
files at the source rather than in one copy, and never add a per-repo lint or
format exclude to work around them.

The docstring line stays under 88 characters, so palette.py remains a
formatter fixed point -- verified clean under ruff check and ruff format at
88, 100 and 120. Every generated SVG is byte-identical, verified by
regenerating and diffing in all four repositories.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Claude <noreply@anthropic.com>
actionlint runs shellcheck over every run: block and failed this branch on
SC2018 and SC2019: tr 'A-Z' 'a-z' only folds ASCII, so an address containing
an accented or non-Latin character would not be lowercased before hashing.
tr '[:upper:]' '[:lower:]' handles those, which is the point of the rule
rather than a style preference.

The digest is unchanged for an ASCII address -- verified both forms produce
the same SHA-256 -- so the maintainer-address rule keeps matching exactly what
it matched before.

Found because CI ran a check the local verification did not: a YAML parse
proves the file is well-formed, not that the shell inside it is sound.
shellcheck is available locally and is now run over the extracted block, which
reports all four repositories clean; the old form reproduces SC2018 and SC2019
on demand.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Claude <noreply@anthropic.com>
@jothimani-rajendran
jothimani-rajendran marked this pull request as ready for review September 9, 2026 16:02
@jothimani-rajendran
jothimani-rajendran merged commit d596626 into main Sep 9, 2026
15 checks passed
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.

2 participants