Skip to content

docs: add Signed commits section to CONTRIBUTING - #126

Merged
hyperpolymath merged 1 commit into
mainfrom
docs/signing-policy-d218
Oct 1, 2026
Merged

hyperpolymath merged 1 commit into
mainfrom
docs/signing-policy-d218

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Adds a Signed commits section to this repo's CONTRIBUTING, per owner ruling D218. The estate policy is docs/SIGNING-POLICY.adoc in hyperpolymath/standards.

This repo's default branch is covered by the zero-bypass Require-Signed-Commits ruleset, and rebase-merge is off. The section tells contributors what that requires:

  • People and interactive agents sign with an SSH signing key.
  • Apps, bots and workflows write through the API, so GitHub signs their commits.
  • PRs are merged with squash.

If the file already had its own signing section, that section is replaced in place instead of adding a second one. Lines elsewhere that told people to sign with GPG are changed to match the policy (SSH for people).

This is a docs-only change. The commit was created through createCommitOnBranch, so GitHub signs it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WRvDivYwLSeVCJUrfjic3f

Owner ruling D218. See docs/SIGNING-POLICY.adoc in hyperpolymath/standards.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WRvDivYwLSeVCJUrfjic3f
@coderabbitai

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 85d1acf8-c897-455f-9c86-2c92b5864316

📥 Commits

Reviewing files that changed from the base of the PR and between 2813670 and c892c8a.

📒 Files selected for processing (1)
  • .github/CONTRIBUTING.md

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Recent review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
⚠️ CI failures not shown inline (9)

GitHub Actions: Governance / 1_governance _ Guix primary _ Nix fallback policy.txt: docs: add Signed commits section to CONTRIBUTING

Conclusion: failure

View job details

##[group]Run # Move the checker OUT of the scanned tree and delete the standards
 �[36;1m# Move the checker OUT of the scanned tree and delete the standards�[0m
 �[36;1m# checkout before scanning: the gate walks the whole caller tree, so�[0m
 �[36;1m# a packaging file shipped inside .standards-checkout/ would satisfy�[0m
 �[36;1m# the policy on the caller's behalf (same trap as the baseline job).�[0m
 �[36;1mcp .standards-checkout/scripts/check-package-policy.sh "$RUNNER_TEMP/"�[0m
 �[36;1mrm -rf .standards-checkout�[0m
 �[36;1mbash "$RUNNER_TEMP/check-package-policy.sh" .�[0m
 shell: /usr/bin/bash -e {0}
 ##[endgroup]
 ##[error]Package policy violation: no packaging found.

GitHub Actions: Governance / governance _ Guix primary _ Nix fallback policy: docs: add Signed commits section to CONTRIBUTING

Conclusion: failure

View job details

##[group]Run # Move the checker OUT of the scanned tree and delete the standards
 �[36;1m# Move the checker OUT of the scanned tree and delete the standards�[0m
 �[36;1m# checkout before scanning: the gate walks the whole caller tree, so�[0m
 �[36;1m# a packaging file shipped inside .standards-checkout/ would satisfy�[0m
 �[36;1m# the policy on the caller's behalf (same trap as the baseline job).�[0m
 �[36;1mcp .standards-checkout/scripts/check-package-policy.sh "$RUNNER_TEMP/"�[0m
 �[36;1mrm -rf .standards-checkout�[0m
 �[36;1mbash "$RUNNER_TEMP/check-package-policy.sh" .�[0m
 shell: /usr/bin/bash -e {0}
 ##[endgroup]
 ##[error]Package policy violation: no packaging found.

GitHub Actions: Governance / 5_governance _ Well-Known (RFC 9116 + RSR).txt: docs: add Signed commits section to CONTRIBUTING

Conclusion: failure

View job details

##[group]Run SECTXT=""
 �[36;1mSECTXT=""�[0m
 �[36;1m[ -f ".well-known/security.txt" ] && SECTXT=".well-known/security.txt"�[0m
 �[36;1m[ -f "security.txt" ] && SECTXT="security.txt"�[0m
 �[36;1mif [ -z "$SECTXT" ]; then�[0m
 �[36;1m  echo "::warning::No security.txt found."�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1mgrep -q "^Contact:" "$SECTXT" || { echo "::error::Missing Contact field"; exit 1; }�[0m

GitHub Actions: Governance / governance _ Well-Known (RFC 9116 + RSR): docs: add Signed commits section to CONTRIBUTING

Conclusion: failure

View job details

##[group]Run SECTXT=""
 �[36;1mSECTXT=""�[0m
 �[36;1m[ -f ".well-known/security.txt" ] && SECTXT=".well-known/security.txt"�[0m
 �[36;1m[ -f "security.txt" ] && SECTXT="security.txt"�[0m
 �[36;1mif [ -z "$SECTXT" ]; then�[0m
 �[36;1m  echo "::warning::No security.txt found."�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1mgrep -q "^Contact:" "$SECTXT" || { echo "::error::Missing Contact field"; exit 1; }�[0m

GitHub Actions: Governance / governance _ Well-Known (RFC 9116 + RSR): docs: add Signed commits section to CONTRIBUTING

Conclusion: failure

View job details

##[group]Run MIXED=$(grep -rE 'src="http://|href="http://' --include="*.html" --include="*.htm" . 2>/dev/null | grep -vE 'localhost|127\.0\.0\.1|example\.com|lol/|node_modules/|third-party/|vendor/' | head -5 || true)
 �[36;1mMIXED=$(grep -rE 'src="http://|href="http://' --include="*.html" --include="*.htm" . 2>/dev/null | grep -vE 'localhost|127\.0\.0\.1|example\.com|lol/|node_modules/|third-party/|vendor/' | head -5 || true)�[0m
 �[36;1mif [ -n "$MIXED" ]; then�[0m
 �[36;1m  echo "::error::Mixed content (HTTP in HTML)"�[0m

GitHub Actions: Governance / 8_governance _ Security policy checks.txt: docs: add Signed commits section to CONTRIBUTING

Conclusion: failure

View job details

##[group]Run set -uo pipefail
 �[36;1mset -uo pipefail�[0m
 �[36;1mDIR=.github/canonical-references�[0m
 �[36;1mif [ ! -d "$DIR" ]; then�[0m
 �[36;1m  echo "ℹ️  [R5] no $DIR/ — skipped (repo has not opted in)"�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1mif ! command -v python3 >/dev/null 2>&1; then�[0m
 �[36;1m  echo "❌ [R5] python3 missing on runner — required for YAML rule parsing"�[0m
 �[36;1m  exit 2�[0m
 �[36;1mfi�[0m
 �[36;1mpython3 - <<'PY'�[0m
 �[36;1mimport os, sys, glob, subprocess�[0m
 �[36;1mtry:�[0m
 �[36;1m    import yaml�[0m
 �[36;1mexcept ImportError:�[0m
 �[36;1m    sys.exit("❌ [R5] PyYAML not installed on runner; install python3-yaml")�[0m
 �[36;1m�[0m
 �[36;1mdir_ = ".github/canonical-references"�[0m
 �[36;1mfiles = sorted(glob.glob(f"{dir_}/*.yml") + glob.glob(f"{dir_}/*.yaml"))�[0m
 �[36;1mif not files:�[0m
 �[36;1m    print(f"ℹ️  [R5] {dir_}/ has no .yml/.yaml rules — skipped")�[0m
 �[36;1m    sys.exit(0)�[0m
 �[36;1m�[0m
 �[36;1mtotal = 0�[0m
 �[36;1mfor rf in files:�[0m
 �[36;1m    with open(rf, encoding="utf-8") as fh:�[0m
 �[36;1m        cfg = yaml.safe_load(fh)�[0m
 �[36;1m    if not isinstance(cfg, dict):�[0m
 �[36;1m        print(f"❌ [R5] {rf}: top-level must be a mapping"); total += 1; continue�[0m
 �[36;1m    rid  = cfg.get("id", os.path.basename(rf))�[0m
 �[36;1m    desc = cfg.get("description", "")�[0m
 �[36;1m    pats = cfg.get("patterns") or []�[0m
 �[36;1m    canon = cfg.get("canonical_pointer", "")�[0m
 �[36;1m    scope = (cfg.get("scope") or {})�[0m
 �[36;1m    includes = scope.get("include") or []�[0m
 �[36;1m    if not pats or not includes:�[0m
 �[36;1m        print(f"❌ [R5:{rid}] missing patterns or scope.include in {rf}")�[0m
 �[36;1m        total += 1; continue�[0m
 �[36;1m    # exclude self-references�[0m
 �[36;1m    skip = set(["CHANGELOG.md", "CHANGELOG.adoc", rf])�[0m
 �[36;1m    if canon: skip.add(canon)�[0m
 �[36;1m    rule_hits = 0�[0m
 �[36;1m    for f_ in includes:�[0m
 �[36;1m        if f_ in skip or not os...

GitHub Actions: Governance / governance _ Security policy checks: docs: add Signed commits section to CONTRIBUTING

Conclusion: failure

View job details

##[group]Run set -uo pipefail
 �[36;1mset -uo pipefail�[0m
 �[36;1mDIR=.github/canonical-references�[0m
 �[36;1mif [ ! -d "$DIR" ]; then�[0m
 �[36;1m  echo "ℹ️  [R5] no $DIR/ — skipped (repo has not opted in)"�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1mif ! command -v python3 >/dev/null 2>&1; then�[0m
 �[36;1m  echo "❌ [R5] python3 missing on runner — required for YAML rule parsing"�[0m
 �[36;1m  exit 2�[0m
 �[36;1mfi�[0m
 �[36;1mpython3 - <<'PY'�[0m
 �[36;1mimport os, sys, glob, subprocess�[0m
 �[36;1mtry:�[0m
 �[36;1m    import yaml�[0m
 �[36;1mexcept ImportError:�[0m
 �[36;1m    sys.exit("❌ [R5] PyYAML not installed on runner; install python3-yaml")�[0m
 �[36;1m�[0m
 �[36;1mdir_ = ".github/canonical-references"�[0m
 �[36;1mfiles = sorted(glob.glob(f"{dir_}/*.yml") + glob.glob(f"{dir_}/*.yaml"))�[0m
 �[36;1mif not files:�[0m
 �[36;1m    print(f"ℹ️  [R5] {dir_}/ has no .yml/.yaml rules — skipped")�[0m
 �[36;1m    sys.exit(0)�[0m
 �[36;1m�[0m
 �[36;1mtotal = 0�[0m
 �[36;1mfor rf in files:�[0m
 �[36;1m    with open(rf, encoding="utf-8") as fh:�[0m
 �[36;1m        cfg = yaml.safe_load(fh)�[0m
 �[36;1m    if not isinstance(cfg, dict):�[0m
 �[36;1m        print(f"❌ [R5] {rf}: top-level must be a mapping"); total += 1; continue�[0m
 �[36;1m    rid  = cfg.get("id", os.path.basename(rf))�[0m
 �[36;1m    desc = cfg.get("description", "")�[0m
 �[36;1m    pats = cfg.get("patterns") or []�[0m
 �[36;1m    canon = cfg.get("canonical_pointer", "")�[0m
 �[36;1m    scope = (cfg.get("scope") or {})�[0m
 �[36;1m    includes = scope.get("include") or []�[0m
 �[36;1m    if not pats or not includes:�[0m
 �[36;1m        print(f"❌ [R5:{rid}] missing patterns or scope.include in {rf}")�[0m
 �[36;1m        total += 1; continue�[0m
 �[36;1m    # exclude self-references�[0m
 �[36;1m    skip = set(["CHANGELOG.md", "CHANGELOG.adoc", rf])�[0m
 �[36;1m    if canon: skip.add(canon)�[0m
 �[36;1m    rule_hits = 0�[0m
 �[36;1m    for f_ in includes:�[0m
 �[36;1m        if f_ in skip or not os...

GitHub Actions: Governance / 9_governance _ Code quality + docs.txt: docs: add Signed commits section to CONTRIBUTING

Conclusion: failure

View job details

##[group]Run editorconfig-checker/action-editorconfig-checker@840e866d93b8e032123c23bac69dece044d4d84c
 with:
   github-***REDACTED_SECRET_ASSIGNMENT***
   version: latest
 ##[endgroup]
 Find 'latest' release
 ##[error]Error: The binary 'ec-linux-amd64*' not found

GitHub Actions: Governance / governance _ Code quality + docs: docs: add Signed commits section to CONTRIBUTING

Conclusion: failure

View job details

##[group]Run editorconfig-checker/action-editorconfig-checker@840e866d93b8e032123c23bac69dece044d4d84c
 with:
   github-***REDACTED_SECRET_ASSIGNMENT***
   version: latest
 ##[endgroup]
 Find 'latest' release
 ##[error]Error: The binary 'ec-linux-amd64*' not found

📝 Summary

Summary by CodeRabbit

  • Documentation
    • Updated contribution guidance to require signed commits on the default branch; unsigned pushes are rejected.
    • Clarified signing requirements and accepted methods for contributors, apps, bots and workflows.
    • Added guidance to squash-merge pull requests and recreate branches with signed cherry-picks if they contain unsigned commits. Documented that rebase merging is disabled.

Walkthrough

The contribution guide adds commit-signing requirements, procedures for people and automation, and instructions for handling unsigned commits on pull request branches.

Changes

Commit signing guidance

Layer / File(s) Summary
Signing and merge procedures
.github/CONTRIBUTING.md
The guide sets signing requirements for commits reaching the default branch. It distinguishes signing procedures for people and interactive agents from those for apps, bots, and workflows. It also specifies squash merges and steps for branches containing unsigned commits.

Priority: ⬇️ Low

Estimated code review effort: 1 (Trivial) | ~3 minutes

Change: Other

Architecture Summary

Architecture risk: 🔵 Low · up to c892c

The changed surface does not map to a changed system, dependency edge, entrypoint, or external dependency.

Changed systems: None identified.

Architecture concerns
No architecture-level concerns identified.

Review details

Before / after behavior

  • observed — Modified behavior in .github/CONTRIBUTING.md: Adds commit-signing requirements and distinct signing procedures for people and interactive agents versus apps, bots and workflows. Specifies squash merges, explains that unsigned commits anywhere on a PR branch block merging, directs contributors to recreate such branches with signed cherry-picks, and states that rebase-merge is disabled.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the documentation change in CONTRIBUTING.md.
Description check ✅ Passed The description accurately explains the signed-commits documentation change and its policy context.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🛠️ Fix failing CI checks
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit signs a commit with care,
Then checks each branch before the merge.
Signed cherry-picks hop into place,
While squash merges keep a steady pace.
The guide is clear; the burrow cheers.

Comment @coderabbitai help to get the list of available commands.

@hyperpolymath
hyperpolymath merged commit d738e78 into main Oct 1, 2026
34 of 36 checks passed
@coderabbitai

coderabbitai Bot commented Oct 1, 2026

Copy link
Copy Markdown

Autopilot could not be updated. Open Coding to check access and billing.

@hyperpolymath
hyperpolymath deleted the docs/signing-policy-d218 branch October 1, 2026 21:37
@coderabbitai

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

⚠️ Agent ran but produced no code changes.

The CI failures may require manual intervention.

View agent analysis
I haven't changed any files. None of these four failures comes from this PR's change, and the ones I could pin down can only be fixed by adding packaging manifests or changing CI, which I'm not allowed to do.

All four checks come from one shared workflow in another repo. `.github/workflows/governance.yml` just calls `hyperpolymath/standards/.github/workflows/governance-reusable.yml@81dbf2d…`. The PR itself only adds a "Signed commits" section to `.github/CONTRIBUTING.md`, and none of the checks reads that file.

1. **Guix primary / Nix fallback policy:** "Package policy violation: no packaging found." The repo has neither `guix.scm` nor `flake.nix`, so this check fails on any PR, not just this one. Fixing it means writing new Guix and Nix packaging for the project. That's a build manifest and an infrastructure decision, so it's out of scope here and needs its own PR.
2. **Well-Known (RFC 9116 + RSR):** The step shown only warns and exits 0 when there's no `security.txt`, and this repo has neither `security.txt` nor `.well-known/security.txt`. The log is cut off before the step that actually failed, so I can't see the cause. Nothing in this docs change affects it.
3. **Security policy checks:** The step shown is skipped because `.github/canonical-references/` doesn't exist. Again, the log is cut off before whichever step failed, and it isn't related to CONTRIBUTING.
4. **Code quality + docs:** The editorconfig-checker action couldn't download its binary: "The binary 'ec-linux-amd64*' not found" while resolving `version: latest`. That's a problem with the CI action fetching its tool, not with any file in this repo. The fix is to pin a working version in the shared workflow in `hyperpolymath/standards`, or just re-run the job.

**What to do next:**
- Re-run the checks first; at least #4 may be a temporary download failure.
- Track the missing Guix/Nix packaging (#1) as separate work.
- To diagnose #2 and #3, I'd need the full logs for the steps that actually failed.

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