-
-
Notifications
You must be signed in to change notification settings - Fork 0
ci(rhodibot): switch to the report-only canary (standards#759) #201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,234 +1,94 @@ | ||||||||||||||||||
| # This workflow is managed by gh actions-lock. | ||||||||||||||||||
| # SPDX-License-Identifier: MPL-2.0 | ||||||||||||||||||
| # rhodibot.yml — Automated RSR compliance enforcement | ||||||||||||||||||
| # rhodibot.yml — RSR compliance CANARY (report-only) | ||||||||||||||||||
| # | ||||||||||||||||||
| # Reads root-hygiene rules and auto-fixes what it can: | ||||||||||||||||||
| # - Delete banned files (AI.djot, duplicate CONTRIBUTING.adoc, stale snapshots) | ||||||||||||||||||
| # - Rename misnamed files (AI.a2ml → 0-AI-MANIFEST.a2ml) | ||||||||||||||||||
| # - Fix SPDX headers (AGPL → MPL-2.0 in dotfiles) | ||||||||||||||||||
| # - Create missing required files (SECURITY.md, CONTRIBUTING.md) | ||||||||||||||||||
| # - Report unfixable issues as PR comments | ||||||||||||||||||
| # Rhodibot does NOT mutate this repository. It never deletes, renames, | ||||||||||||||||||
| # rewrites SPDX headers, creates files, or opens PRs. Instead it DETECTS | ||||||||||||||||||
| # what an auto-fixer would have changed and reports it. | ||||||||||||||||||
| # | ||||||||||||||||||
| # Runs weekly and on Hypatia scan completion. | ||||||||||||||||||
|
|
||||||||||||||||||
| name: "🤖 Rhodibot — RSR Auto-Fix" | ||||||||||||||||||
| # Design intent (owner): if rhodibot "feels the desire to edit" — i.e. it | ||||||||||||||||||
| # detects something it considers non-compliant — that is itself a MAJOR | ||||||||||||||||||
| # WARNING. Either the repo has drifted, OR rhodibot's own rules have | ||||||||||||||||||
| # diverged from the normative style it is meant to enforce. Both warrant | ||||||||||||||||||
| # a human look, so the canary FAILS the run when it finds would-mutate | ||||||||||||||||||
| # drift. Dangerous-pattern hits are advisory warnings only. | ||||||||||||||||||
| # | ||||||||||||||||||
| # Licence note: SPDX/licence drift is reported for MANUAL, owner-only | ||||||||||||||||||
| # correction. Rhodibot must never edit a licence header (estate directive). | ||||||||||||||||||
|
|
||||||||||||||||||
| name: "\U0001F916 Rhodibot — RSR Compliance Canary" | ||||||||||||||||||
| on: | ||||||||||||||||||
| schedule: | ||||||||||||||||||
| - cron: '0 6 * * 1' # Every Monday at 06:00 UTC | ||||||||||||||||||
| workflow_dispatch: # Manual trigger | ||||||||||||||||||
| workflow_run: | ||||||||||||||||||
| workflows: ["Hypatia Neurosymbolic Analysis"] | ||||||||||||||||||
| types: [completed] | ||||||||||||||||||
| - cron: '0 6 * * 1' # Every Monday at 06:00 UTC | ||||||||||||||||||
| workflow_dispatch: # Manual trigger | ||||||||||||||||||
|
|
||||||||||||||||||
| permissions: | ||||||||||||||||||
| contents: write | ||||||||||||||||||
| pull-requests: write | ||||||||||||||||||
| concurrency: | ||||||||||||||||||
| group: ${{ github.workflow }}-${{ github.ref }} | ||||||||||||||||||
| cancel-in-progress: true | ||||||||||||||||||
|
|
||||||||||||||||||
| permissions: | ||||||||||||||||||
| contents: read | ||||||||||||||||||
| jobs: | ||||||||||||||||||
| rhodibot: | ||||||||||||||||||
| canary: | ||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||
| timeout-minutes: 15 | ||||||||||||||||||
| steps: | ||||||||||||||||||
| - name: Checkout | ||||||||||||||||||
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v4 | ||||||||||||||||||
| uses: actions/checkout@v7.0.1 | ||||||||||||||||||
| with: | ||||||||||||||||||
| fetch-depth: 1 | ||||||||||||||||||
|
|
||||||||||||||||||
| - name: Rhodibot — Scan and Fix | ||||||||||||||||||
| id: fix | ||||||||||||||||||
| - name: Rhodibot — detect drift (no mutations) | ||||||||||||||||||
| run: | | ||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||
| FIXES="" | ||||||||||||||||||
| ISSUES="" | ||||||||||||||||||
| CHANGED=false | ||||||||||||||||||
| set -uo pipefail | ||||||||||||||||||
| DRIFT=0 | ||||||||||||||||||
| warn() { echo "::warning title=Rhodibot canary::$*"; DRIFT=$((DRIFT+1)); } | ||||||||||||||||||
| note() { echo "::warning title=Rhodibot advisory::$*"; } | ||||||||||||||||||
|
|
||||||||||||||||||
| # --- 1. Delete banned files --- | ||||||||||||||||||
| for pattern in "AI.djot" "NEXT_STEPS.md" "TODO.md" "NOTES.md" "TASKS.md"; do | ||||||||||||||||||
| if [ -f "$pattern" ]; then | ||||||||||||||||||
| rm "$pattern" | ||||||||||||||||||
| FIXES="$FIXES\n- Deleted \`$pattern\` (superseded)" | ||||||||||||||||||
| CHANGED=true | ||||||||||||||||||
| fi | ||||||||||||||||||
| done | ||||||||||||||||||
| echo "## 🤖 Rhodibot canary — report only (no edits made)" >> "$GITHUB_STEP_SUMMARY" | ||||||||||||||||||
|
|
||||||||||||||||||
| # Delete stale snapshot files | ||||||||||||||||||
| # --- would-DELETE: banned files --- | ||||||||||||||||||
| for f in AI.djot NEXT_STEPS.md TODO.md NOTES.md TASKS.md; do | ||||||||||||||||||
| [ -f "$f" ] && warn "banned file present: $f (an auto-fixer would delete it)" | ||||||||||||||||||
| done | ||||||||||||||||||
| # would-DELETE: stale snapshots | ||||||||||||||||||
| for f in *-STATUS-*.md *-COMPLETION-*.md *-COMPLETE.md *-VERIFIED-*.md; do | ||||||||||||||||||
| if [ -f "$f" ]; then | ||||||||||||||||||
| rm "$f" | ||||||||||||||||||
| FIXES="$FIXES\n- Deleted stale snapshot \`$f\`" | ||||||||||||||||||
| CHANGED=true | ||||||||||||||||||
| fi | ||||||||||||||||||
| [ -f "$f" ] && warn "stale snapshot present: $f (would be deleted)" | ||||||||||||||||||
| done | ||||||||||||||||||
|
|
||||||||||||||||||
| # --- 2. Rename misnamed files --- | ||||||||||||||||||
| # would-RENAME: legacy manifest name | ||||||||||||||||||
| if [ -f "AI.a2ml" ] && [ ! -f "0-AI-MANIFEST.a2ml" ]; then | ||||||||||||||||||
| mv AI.a2ml 0-AI-MANIFEST.a2ml | ||||||||||||||||||
| FIXES="$FIXES\n- Renamed \`AI.a2ml\` → \`0-AI-MANIFEST.a2ml\`" | ||||||||||||||||||
| CHANGED=true | ||||||||||||||||||
| warn "AI.a2ml present without 0-AI-MANIFEST.a2ml (would be renamed)" | ||||||||||||||||||
| fi | ||||||||||||||||||
|
|
||||||||||||||||||
| # --- 3. Delete duplicate format files --- | ||||||||||||||||||
| if [ -f "CONTRIBUTING.md" ] && [ -f "CONTRIBUTING.adoc" ]; then | ||||||||||||||||||
| rm CONTRIBUTING.adoc | ||||||||||||||||||
| FIXES="$FIXES\n- Deleted duplicate \`CONTRIBUTING.adoc\` (keeping .md for GitHub)" | ||||||||||||||||||
| CHANGED=true | ||||||||||||||||||
| fi | ||||||||||||||||||
|
|
||||||||||||||||||
| if [ -f "README.md" ] && [ -f "README.adoc" ]; then | ||||||||||||||||||
| # Only delete README.md if it's a stub (<5 lines) | ||||||||||||||||||
| lines=$(wc -l < README.md) | ||||||||||||||||||
| if [ "$lines" -lt 5 ]; then | ||||||||||||||||||
| rm README.md | ||||||||||||||||||
| FIXES="$FIXES\n- Deleted stub \`README.md\` (keeping .adoc)" | ||||||||||||||||||
| CHANGED=true | ||||||||||||||||||
| fi | ||||||||||||||||||
| # would-DELETE: duplicate community files | ||||||||||||||||||
| [ -f "CONTRIBUTING.md" ] && [ -f "CONTRIBUTING.adoc" ] && warn "duplicate CONTRIBUTING.md + CONTRIBUTING.adoc (one would be removed)" | ||||||||||||||||||
| if [ -f "README.md" ] && [ -f "README.adoc" ] && [ "$(wc -l < README.md)" -lt 5 ]; then | ||||||||||||||||||
| warn "stub README.md alongside README.adoc (would be removed)" | ||||||||||||||||||
| fi | ||||||||||||||||||
|
|
||||||||||||||||||
| # --- 4. Fix SPDX headers in dotfiles --- | ||||||||||||||||||
| # SPDX drift — MANUAL owner-only fix, never auto-edited | ||||||||||||||||||
| for dotfile in .gitignore .gitattributes .editorconfig; do | ||||||||||||||||||
| if [ -f "$dotfile" ] && grep -q "AGPL-3.0" "$dotfile" 2>/dev/null; then | ||||||||||||||||||
| sed -i 's/AGPL-3.0-or-later/MPL-2.0/g; s/AGPL-3.0/MPL-2.0/g' "$dotfile" | ||||||||||||||||||
| FIXES="$FIXES\n- Fixed SPDX header in \`$dotfile\` (AGPL → MPL-2.0)" | ||||||||||||||||||
| CHANGED=true | ||||||||||||||||||
| if [ -f "$dotfile" ] && grep "AGPL-3.0" "$dotfile" 2>/dev/null | grep -v "AGPL-3.0-or-later" | grep -q .; then | ||||||||||||||||||
| warn "$dotfile carries an AGPL-3.0 SPDX header; estate policy is MPL-2.0 — fix MANUALLY (owner-only, never auto-edited)" | ||||||||||||||||||
|
Comment on lines
+68
to
+69
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: sed -n '38,75p' .github/workflows/rhodibot.yml
find . -maxdepth 1 -type f -name '.*' -print -exec wc -c {} \; 2>/dev/nullRepository: hyperpolymath/verisimiser Length of output: 2540 🏁 Script executed: #!/bin/bash
set -u
printf '%s\n' '--- workflow ---'
sed -n '40,72p' .github/workflows/rhodibot.yml
printf '%s\n' '--- dotfile inventory and AGPL lines ---'
for f in .gitignore .gitattributes .editorconfig; do
printf '%s: ' "$f"
wc -c < "$f"
grep -n 'AGPL-3.0' "$f" || true
done
printf '%s\n' '--- exact pipeline status on repository dotfiles ---'
for f in .gitignore .gitattributes .editorconfig; do
set +e
bash -euo pipefail -c 'grep "AGPL-3.0" "$1" 2>/dev/null | grep -v "AGPL-3.0-or-later" | grep -q .' _ "$f"
status=$?
set -e
printf '%s status=%s\n' "$f" "$status"
done
printf '%s\n' '--- bounded fixture probe ---'
tmpdir=$(mktemp -d)
trap 'rm -rf "$tmpdir"' EXIT
python3 - "$tmpdir" <<'PY'
from pathlib import Path
import sys
root = Path(sys.argv[1])
# Include one realistic short header and progressively larger files.
for name, size in [('short', 1024), ('medium', 4096), ('pipe-sized', 131072), ('large', 1048576)]:
body = ('SPDX-License-Identifier: AGPL-3.0\\n' * (size // 34 + 1)).encode()[:size]
(root / name).write_bytes(body)
PY
for f in "$tmpdir"/*; do
set +e
bash -euo pipefail -c 'grep "AGPL-3.0" "$1" 2>/dev/null | grep -v "AGPL-3.0-or-later" | grep -q .' _ "$f"
status=$?
set -e
printf '%s bytes=%s status=%s\n' "${f##*/}" "$(wc -c < "$f")" "$status"
doneRepository: hyperpolymath/verisimiser Length of output: 2414 🏁 Script executed: #!/bin/bash
set -u
printf '%s\n' '--- tool contracts ---'
grep --version | head -n 1
getconf PIPE_BUF . 2>/dev/null || true
printf '%s\n' '--- exact pipeline component statuses ---'
tmpdir=$(mktemp -d)
trap 'rm -rf "$tmpdir"' EXIT
python3 - "$tmpdir" <<'PY'
from pathlib import Path
import sys
root = Path(sys.argv[1])
for name, size in [('bounded', 1642), ('large', 1048576), ('very-large', 10485760)]:
line = b'SPDX-License-Identifier: AGPL-3.0\n'
(root / name).write_bytes((line * (size // len(line) + 1))[:size])
PY
for f in "$tmpdir"/*; do
set +e
bash -uo pipefail -c '
grep "AGPL-3.0" "$1" 2>/dev/null |
grep -v "AGPL-3.0-or-later" |
grep -q .
rc=$?
ps=("${PIPESTATUS[@]}")
printf "%s pipeline=%s PIPESTATUS=%s\n" "$1" "$rc" "${ps[*]}"
' _ "$f"
set -e
done
printf '%s\n' '--- direct short-circuit control ---'
set +e
bash -uo pipefail -c '
yes AGPL-3.0 |
grep "AGPL-3.0" |
grep -v "AGPL-3.0-or-later" |
grep -q .
rc=$?
ps=("${PIPESTATUS[@]}")
printf "control pipeline=%s PIPESTATUS=%s\n" "$rc" "${ps[*]}"
'
set -eRepository: hyperpolymath/verisimiser Length of output: 515 Avoid If a scanned dotfile grows large enough, Count the matches instead. 🛠️ Proposed fix- if [ -f "$dotfile" ] && grep "AGPL-3.0" "$dotfile" 2>/dev/null | grep -v "AGPL-3.0-or-later" | grep -q .; then
+ agpl_hits=0
+ if [ -f "$dotfile" ]; then
+ agpl_hits=$(grep "AGPL-3.0" "$dotfile" 2>/dev/null | grep -cv "AGPL-3.0-or-later" || true)
+ fi
+ if [ "${agpl_hits:-0}" -gt 0 ]; then
warn "$dotfile carries an AGPL-3.0 SPDX header; estate policy is MPL-2.0 — fix MANUALLY (owner-only, never auto-edited)"
fi📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
| fi | ||||||||||||||||||
| done | ||||||||||||||||||
|
|
||||||||||||||||||
| # --- 5. Create missing required files --- | ||||||||||||||||||
| if [ ! -f "SECURITY.md" ]; then | ||||||||||||||||||
| cat > SECURITY.md << 'SECEOF' | ||||||||||||||||||
| <!-- SPDX-License-Identifier: MPL-2.0 --> | ||||||||||||||||||
| # Security Policy | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Reporting a Vulnerability | ||||||||||||||||||
|
|
||||||||||||||||||
| **Email:** j.d.a.jewell@open.ac.uk | ||||||||||||||||||
|
|
||||||||||||||||||
| **Response timeline:** | ||||||||||||||||||
| - Acknowledgement within 48 hours | ||||||||||||||||||
| - Initial assessment within 7 days | ||||||||||||||||||
| - Fix or mitigation within 90 days | ||||||||||||||||||
|
|
||||||||||||||||||
| **Safe harbour:** We will not pursue legal action against security researchers who follow responsible disclosure. | ||||||||||||||||||
| SECEOF | ||||||||||||||||||
| FIXES="$FIXES\n- Created missing \`SECURITY.md\`" | ||||||||||||||||||
| CHANGED=true | ||||||||||||||||||
| fi | ||||||||||||||||||
|
|
||||||||||||||||||
| if [ ! -f "CONTRIBUTING.md" ]; then | ||||||||||||||||||
| cat > CONTRIBUTING.md << 'CONTEOF' | ||||||||||||||||||
| <!-- SPDX-License-Identifier: MPL-2.0 --> | ||||||||||||||||||
| # Contributing | ||||||||||||||||||
|
|
||||||||||||||||||
| 1. Fork the repository | ||||||||||||||||||
| 2. Create a feature branch | ||||||||||||||||||
| 3. Ensure SPDX headers on all files | ||||||||||||||||||
| 4. Submit a pull request | ||||||||||||||||||
|
|
||||||||||||||||||
| **Author:** Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk> | ||||||||||||||||||
| CONTEOF | ||||||||||||||||||
| FIXES="$FIXES\n- Created missing \`CONTRIBUTING.md\`" | ||||||||||||||||||
| CHANGED=true | ||||||||||||||||||
| fi | ||||||||||||||||||
|
|
||||||||||||||||||
| # --- 6. Check for issues we can't auto-fix --- | ||||||||||||||||||
| if [ ! -f "0-AI-MANIFEST.a2ml" ] && [ ! -f "AI.a2ml" ]; then | ||||||||||||||||||
| ISSUES="$ISSUES\n- Missing AI manifest (0-AI-MANIFEST.a2ml)" | ||||||||||||||||||
| fi | ||||||||||||||||||
|
|
||||||||||||||||||
| if [ ! -f "LICENSE" ] && [ ! -f "LICENSE.md" ] && [ ! -f "LICENSE.txt" ]; then | ||||||||||||||||||
| ISSUES="$ISSUES\n- Missing LICENSE file" | ||||||||||||||||||
| fi | ||||||||||||||||||
|
|
||||||||||||||||||
| if [ ! -f "README.adoc" ] && [ ! -f "README.md" ]; then | ||||||||||||||||||
| ISSUES="$ISSUES\n- Missing README" | ||||||||||||||||||
| fi | ||||||||||||||||||
|
|
||||||||||||||||||
| # Check for third-party fork (skip SPDX enforcement) | ||||||||||||||||||
| if [ -f "LICENSE" ] && grep -q "multiple licenses\|LGPL\|Apache" LICENSE 2>/dev/null; then | ||||||||||||||||||
| echo "FORK=true" >> $GITHUB_OUTPUT | ||||||||||||||||||
| fi | ||||||||||||||||||
|
|
||||||||||||||||||
| # --- 7. Check dangerous patterns --- | ||||||||||||||||||
| DANGEROUS="" | ||||||||||||||||||
| for pattern in "believe_me" "assert_total" "Admitted" "sorry" "unsafeCoerce" "Obj.magic"; do | ||||||||||||||||||
| count=$(grep -r "$pattern" --include='*.idr' --include='*.v' --include='*.lean' --include='*.hs' --include='*.ml' --include='*.res' . 2>/dev/null | grep -v node_modules | wc -l || echo 0) | ||||||||||||||||||
| if [ "$count" -gt 0 ]; then | ||||||||||||||||||
| DANGEROUS="$DANGEROUS\n- \`$pattern\`: $count occurrences" | ||||||||||||||||||
| fi | ||||||||||||||||||
| # would-CREATE: missing required files | ||||||||||||||||||
| [ -f "SECURITY.md" ] || [ -f ".github/SECURITY.md" ] || warn "no SECURITY.md (would be created)" | ||||||||||||||||||
| [ -f "CONTRIBUTING.md" ] || [ -f ".github/CONTRIBUTING.md" ] || warn "no CONTRIBUTING.md (would be created)" | ||||||||||||||||||
|
|
||||||||||||||||||
| # --- unfixable compliance gaps (also drift) --- | ||||||||||||||||||
| [ -f "0-AI-MANIFEST.a2ml" ] || [ -f "AI.a2ml" ] || warn "missing AI manifest (0-AI-MANIFEST.a2ml)" | ||||||||||||||||||
| [ -f "LICENSE" ] || [ -f "LICENSE.md" ] || [ -f "LICENSE.txt" ] || warn "missing LICENSE file" | ||||||||||||||||||
| [ -f "README.adoc" ] || [ -f "README.md" ] || warn "missing README" | ||||||||||||||||||
|
|
||||||||||||||||||
| # --- advisory only: dangerous verification-bypass patterns --- | ||||||||||||||||||
| for pattern in believe_me assert_total Admitted sorry unsafeCoerce Obj.magic; do | ||||||||||||||||||
| count=$(grep -rl "$pattern" --include='*.idr' --include='*.v' --include='*.lean' --include='*.hs' --include='*.ml' --include='*.res' . 2>/dev/null | grep -v node_modules | wc -l || true) | ||||||||||||||||||
| [ "$count" -gt 0 ] && note "verification-bypass pattern '$pattern' in $count file(s) (advisory)" | ||||||||||||||||||
| done | ||||||||||||||||||
|
|
||||||||||||||||||
| # Output results | ||||||||||||||||||
| echo "CHANGED=$CHANGED" >> $GITHUB_OUTPUT | ||||||||||||||||||
| { | ||||||||||||||||||
| echo "FIXES<<EOF" | ||||||||||||||||||
| echo -e "$FIXES" | ||||||||||||||||||
| echo "EOF" | ||||||||||||||||||
| } >> $GITHUB_OUTPUT | ||||||||||||||||||
| { | ||||||||||||||||||
| echo "ISSUES<<EOF" | ||||||||||||||||||
| echo -e "$ISSUES" | ||||||||||||||||||
| echo "EOF" | ||||||||||||||||||
| } >> $GITHUB_OUTPUT | ||||||||||||||||||
| { | ||||||||||||||||||
| echo "DANGEROUS<<EOF" | ||||||||||||||||||
| echo -e "$DANGEROUS" | ||||||||||||||||||
| echo "EOF" | ||||||||||||||||||
| } >> $GITHUB_OUTPUT | ||||||||||||||||||
|
|
||||||||||||||||||
| - name: Create PR with fixes | ||||||||||||||||||
| if: steps.fix.outputs.CHANGED == 'true' | ||||||||||||||||||
| run: | | ||||||||||||||||||
| git config user.name "rhodibot" | ||||||||||||||||||
| git config user.email "rhodibot@hyperpolymath.dev" | ||||||||||||||||||
| BRANCH="rhodibot/rsr-compliance-$(date +%Y%m%d)" | ||||||||||||||||||
| git checkout -b "$BRANCH" | ||||||||||||||||||
| git add -A | ||||||||||||||||||
| git commit -m "fix(rhodibot): automated RSR compliance fixes | ||||||||||||||||||
|
|
||||||||||||||||||
| ${{ steps.fix.outputs.FIXES }} | ||||||||||||||||||
|
|
||||||||||||||||||
| Co-Authored-By: rhodibot <rhodibot@hyperpolymath.dev>" | ||||||||||||||||||
|
|
||||||||||||||||||
| git push origin "$BRANCH" | ||||||||||||||||||
|
|
||||||||||||||||||
| BODY="## 🤖 Rhodibot — RSR Compliance Fixes | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Changes Made | ||||||||||||||||||
| ${{ steps.fix.outputs.FIXES }} | ||||||||||||||||||
| " | ||||||||||||||||||
|
|
||||||||||||||||||
| if [ -n "${{ steps.fix.outputs.ISSUES }}" ]; then | ||||||||||||||||||
| BODY="$BODY | ||||||||||||||||||
| ### Issues Found (manual fix needed) | ||||||||||||||||||
| ${{ steps.fix.outputs.ISSUES }} | ||||||||||||||||||
| " | ||||||||||||||||||
| fi | ||||||||||||||||||
|
|
||||||||||||||||||
| if [ -n "${{ steps.fix.outputs.DANGEROUS }}" ]; then | ||||||||||||||||||
| BODY="$BODY | ||||||||||||||||||
| ### ⚠️ Dangerous Patterns Detected | ||||||||||||||||||
| ${{ steps.fix.outputs.DANGEROUS }} | ||||||||||||||||||
|
|
||||||||||||||||||
| _These bypass formal verification. See \`proven\` repo for alternatives._ | ||||||||||||||||||
| " | ||||||||||||||||||
| fi | ||||||||||||||||||
|
|
||||||||||||||||||
| gh pr create \ | ||||||||||||||||||
| --title "🤖 Rhodibot: RSR compliance fixes" \ | ||||||||||||||||||
| --body "$BODY" \ | ||||||||||||||||||
| --base main \ | ||||||||||||||||||
| --head "$BRANCH" | ||||||||||||||||||
| env: | ||||||||||||||||||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||||||
|
|
||||||||||||||||||
| - name: Report (no changes needed) | ||||||||||||||||||
| if: steps.fix.outputs.CHANGED != 'true' | ||||||||||||||||||
| run: | | ||||||||||||||||||
| echo "✅ Repository is RSR-compliant. No fixes needed." | ||||||||||||||||||
| if [ -n "${{ steps.fix.outputs.ISSUES }}" ]; then | ||||||||||||||||||
| echo "⚠️ Issues found (manual fix needed):" | ||||||||||||||||||
| echo -e "${{ steps.fix.outputs.ISSUES }}" | ||||||||||||||||||
| fi | ||||||||||||||||||
| if [ -n "${{ steps.fix.outputs.DANGEROUS }}" ]; then | ||||||||||||||||||
| echo "⚠️ Dangerous patterns:" | ||||||||||||||||||
| echo -e "${{ steps.fix.outputs.DANGEROUS }}" | ||||||||||||||||||
| echo "" >> "$GITHUB_STEP_SUMMARY" | ||||||||||||||||||
| if [ "$DRIFT" -gt 0 ]; then | ||||||||||||||||||
| echo "🔴 **Canary tripped: $DRIFT would-mutate finding(s).** Either the repo drifted or rhodibot's rules diverged from the norm — investigate (no edits were made)." >> "$GITHUB_STEP_SUMMARY" | ||||||||||||||||||
| echo "::error title=Rhodibot canary::$DRIFT would-mutate finding(s) detected — rhodibot wants to edit. Investigate; nothing was changed." | ||||||||||||||||||
| exit 1 | ||||||||||||||||||
| fi | ||||||||||||||||||
| echo "✅ Canary clean — rhodibot has no desire to edit. Repository matches the norm." >> "$GITHUB_STEP_SUMMARY" | ||||||||||||||||||
| echo "✅ Rhodibot canary clean — no drift, no mutations." | ||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🛡️ Analyzed with Security Review | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: hyperpolymath/verisimiser
Length of output: 4844
🤖 get_repo_knowledge executed:
get_repo_knowledge hyperpolymath/verisimiser /tmp/coderabbit-repo-knowledge/hyperpolymath-verisimiser-f3e91912/conventionsLength of output: 4376
🏁 Script executed:
Repository: hyperpolymath/verisimiser
Length of output: 6735
Restore the immutable checkout pin and the required lock entry.
rhodibot.ymlis managed bygh actions-lock. The estate enforces.github/workflows/actions.lockby workflow path and rejects workflows that are not listed before any step runs. The lock file is absent, andv7.0.1violates the repository's immutable SHA convention.Regenerate or restore the lock entry and use:
🤖 Prompt for AI Agents