Skip to content

Commit 2309003

Browse files
hyperpolymathclaude
andcommitted
ci: add 13 standard RSR workflows (copied from rsr-template-repo)
Post-extraction hygiene: estate-standard workflow set for codeql, scorecard, hypatia-scan, quality, mirror, instant-sync, guix-nix-policy, rsr-antipattern, security-policy, wellknown-enforcement, workflow-linter, scorecard-enforcer, secret-scanner. Pre-existing (carried from the subfolder days): npm-bun-blocker, rust-ci, ts-blocker. Total: 16. CI runs gated on GitHub Actions billing per YOUR-ACTIONS §1. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent b22c468 commit 2309003

13 files changed

Lines changed: 1086 additions & 0 deletions

.github/workflows/codeql.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
name: CodeQL Security Analysis
3+
4+
on:
5+
push:
6+
branches: [main, master]
7+
pull_request:
8+
branches: [main, master]
9+
schedule:
10+
- cron: '0 6 * * 1'
11+
12+
permissions:
13+
contents: read
14+
15+
jobs:
16+
analyze:
17+
runs-on: ubuntu-latest
18+
permissions:
19+
contents: read
20+
security-events: write
21+
strategy:
22+
fail-fast: false
23+
matrix:
24+
include:
25+
- language: javascript-typescript
26+
build-mode: none
27+
28+
steps:
29+
- name: Checkout
30+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
31+
32+
- name: Initialize CodeQL
33+
uses: github/codeql-action/init@0d579ffd059c29b07949a3cce3983f0780820c98 # v3.28.1
34+
with:
35+
languages: ${{ matrix.language }}
36+
build-mode: ${{ matrix.build-mode }}
37+
38+
- name: Perform CodeQL Analysis
39+
uses: github/codeql-action/analyze@0d579ffd059c29b07949a3cce3983f0780820c98 # v3.28.1
40+
with:
41+
category: "/language:${{ matrix.language }}"
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
name: Guix/Nix Package Policy
3+
on: [push, pull_request]
4+
5+
permissions:
6+
contents: read
7+
8+
jobs:
9+
check:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
contents: read
13+
steps:
14+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
15+
- name: Enforce Guix primary / Nix fallback
16+
run: |
17+
# Check for package manager files
18+
HAS_GUIX=$(find . -name "*.scm" -o -name ".guix-channel" -o -name "guix.scm" 2>/dev/null | head -1)
19+
HAS_NIX=$(find . -name "*.nix" 2>/dev/null | head -1)
20+
21+
# Block new package-lock.json, yarn.lock, Gemfile.lock, etc.
22+
NEW_LOCKS=$(git diff --name-only --diff-filter=A HEAD~1 2>/dev/null | grep -E 'package-lock\.json|yarn\.lock|Gemfile\.lock|Pipfile\.lock|poetry\.lock|cargo\.lock' || true)
23+
if [ -n "$NEW_LOCKS" ]; then
24+
echo "⚠️ Lock files detected. Prefer Guix manifests for reproducibility."
25+
fi
26+
27+
# Prefer Guix, fallback to Nix
28+
if [ -n "$HAS_GUIX" ]; then
29+
echo "✅ Guix package management detected (primary)"
30+
elif [ -n "$HAS_NIX" ]; then
31+
echo "✅ Nix package management detected (fallback)"
32+
else
33+
echo "ℹ️ Consider adding guix.scm or flake.nix for reproducible builds"
34+
fi
35+
36+
echo "✅ Package policy check passed"

.github/workflows/hypatia-scan.yml

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
# Hypatia Neurosymbolic CI/CD Security Scan
3+
name: Hypatia Security Scan
4+
5+
on:
6+
push:
7+
branches: [ main, master, develop ]
8+
pull_request:
9+
branches: [ main, master ]
10+
schedule:
11+
- cron: '0 0 * * 0' # Weekly on Sunday
12+
workflow_dispatch:
13+
14+
permissions:
15+
contents: read
16+
# security-events: read lets the built-in GITHUB_TOKEN query this
17+
# repo's own Dependabot alerts via the Hypatia DependabotAlerts rule
18+
# (DA001-DA004). Without this, `scan_from_path` gets HTTP 403 and
19+
# the rule silently returns no findings.
20+
# See 007-lang/audits/audit-dependabot-automation-gap-2026-04-17.md.
21+
security-events: read
22+
23+
jobs:
24+
scan:
25+
name: Hypatia Neurosymbolic Analysis
26+
runs-on: ubuntu-latest
27+
28+
steps:
29+
- name: Checkout repository
30+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
31+
with:
32+
fetch-depth: 0 # Full history for better pattern analysis
33+
34+
- name: Setup Elixir for Hypatia scanner
35+
uses: erlef/setup-beam@e6d7c94229049569db56a7ad5a540c051a010af9 # v1.18.2
36+
with:
37+
elixir-version: '1.19.4'
38+
otp-version: '28.3'
39+
40+
- name: Clone Hypatia
41+
run: |
42+
if [ ! -d "$HOME/hypatia" ]; then
43+
git clone https://github.com/hyperpolymath/hypatia.git "$HOME/hypatia"
44+
fi
45+
46+
- name: Build Hypatia scanner (if needed)
47+
run: |
48+
cd "$HOME/hypatia"
49+
if [ ! -f hypatia ]; then
50+
echo "Building hypatia scanner..."
51+
mix deps.get
52+
mix escript.build
53+
fi
54+
55+
- name: Run Hypatia scan
56+
id: scan
57+
env:
58+
# Pass the built-in Actions token through to Hypatia so the
59+
# DependabotAlerts rule can query this repo's own alerts.
60+
# For cross-repo scanning (fleet-coordinator scan-supervised),
61+
# a PAT with `security_events` scope is required instead.
62+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
63+
run: |
64+
echo "Scanning repository: ${{ github.repository }}"
65+
66+
# Run scanner (exits non-zero when findings exist — suppress to continue)
67+
HYPATIA_FORMAT=json "$HOME/hypatia/hypatia-cli.sh" scan . > hypatia-findings.json || true
68+
69+
# Count findings
70+
FINDING_COUNT=$(jq '. | length' hypatia-findings.json 2>/dev/null || echo 0)
71+
echo "findings_count=$FINDING_COUNT" >> $GITHUB_OUTPUT
72+
73+
# Extract severity counts
74+
CRITICAL=$(jq '[.[] | select(.severity == "critical")] | length' hypatia-findings.json)
75+
HIGH=$(jq '[.[] | select(.severity == "high")] | length' hypatia-findings.json)
76+
MEDIUM=$(jq '[.[] | select(.severity == "medium")] | length' hypatia-findings.json)
77+
78+
echo "critical=$CRITICAL" >> $GITHUB_OUTPUT
79+
echo "high=$HIGH" >> $GITHUB_OUTPUT
80+
echo "medium=$MEDIUM" >> $GITHUB_OUTPUT
81+
82+
echo "## Hypatia Scan Results" >> $GITHUB_STEP_SUMMARY
83+
echo "- Total findings: $FINDING_COUNT" >> $GITHUB_STEP_SUMMARY
84+
echo "- Critical: $CRITICAL" >> $GITHUB_STEP_SUMMARY
85+
echo "- High: $HIGH" >> $GITHUB_STEP_SUMMARY
86+
echo "- Medium: $MEDIUM" >> $GITHUB_STEP_SUMMARY
87+
88+
- name: Upload findings artifact
89+
uses: actions/upload-artifact@65c79d7f54e76e4e3c7a8f34db0f4ac8b515c478 # v4
90+
with:
91+
name: hypatia-findings
92+
path: hypatia-findings.json
93+
retention-days: 90
94+
95+
- name: Submit findings to gitbot-fleet (Phase 2)
96+
if: steps.scan.outputs.findings_count > 0
97+
env:
98+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
99+
GITHUB_REPOSITORY: ${{ github.repository }}
100+
GITHUB_SHA: ${{ github.sha }}
101+
run: |
102+
echo "📤 Submitting ${{ steps.scan.outputs.findings_count }} findings to gitbot-fleet..."
103+
104+
# Clone gitbot-fleet to temp directory
105+
FLEET_DIR="/tmp/gitbot-fleet-$$"
106+
git clone https://github.com/hyperpolymath/gitbot-fleet.git "$FLEET_DIR"
107+
108+
# Run submission script
109+
bash "$FLEET_DIR/scripts/submit-finding.sh" hypatia-findings.json
110+
111+
# Cleanup
112+
rm -rf "$FLEET_DIR"
113+
114+
echo "✅ Finding submission complete"
115+
116+
- name: Check for critical issues
117+
if: steps.scan.outputs.critical > 0
118+
run: |
119+
echo "⚠️ Critical security issues found!"
120+
echo "Review hypatia-findings.json for details"
121+
# Don't fail the build yet - just warn
122+
# exit 1
123+
124+
- name: Generate scan report
125+
run: |
126+
cat << EOF > hypatia-report.md
127+
# Hypatia Security Scan Report
128+
129+
**Repository:** ${{ github.repository }}
130+
**Scan Date:** $(date -u +"%Y-%m-%d %H:%M:%S UTC")
131+
**Commit:** ${{ github.sha }}
132+
133+
## Summary
134+
135+
| Severity | Count |
136+
|----------|-------|
137+
| Critical | ${{ steps.scan.outputs.critical }} |
138+
| High | ${{ steps.scan.outputs.high }} |
139+
| Medium | ${{ steps.scan.outputs.medium }} |
140+
| **Total**| ${{ steps.scan.outputs.findings_count }} |
141+
142+
## Next Steps
143+
144+
1. Review findings in the artifact: hypatia-findings.json
145+
2. Auto-fixable issues will be addressed by robot-repo-automaton (Phase 3)
146+
3. Manual review required for complex issues
147+
148+
## Learning
149+
150+
These findings feed Hypatia's learning engine to improve future rules.
151+
152+
---
153+
*Powered by [Hypatia](https://github.com/hyperpolymath/hypatia) - Neurosymbolic CI/CD Intelligence*
154+
EOF
155+
156+
cat hypatia-report.md >> $GITHUB_STEP_SUMMARY
157+
158+
- name: Comment on PR with findings
159+
if: github.event_name == 'pull_request' && steps.scan.outputs.findings_count > 0
160+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v7
161+
with:
162+
script: |
163+
const fs = require('fs');
164+
const findings = JSON.parse(fs.readFileSync('hypatia-findings.json', 'utf8'));
165+
166+
const critical = findings.filter(f => f.severity === 'critical').length;
167+
const high = findings.filter(f => f.severity === 'high').length;
168+
169+
let comment = `## 🔍 Hypatia Security Scan\n\n`;
170+
comment += `**Findings:** ${findings.length} issues detected\n\n`;
171+
comment += `| Severity | Count |\n|----------|-------|\n`;
172+
comment += `| 🔴 Critical | ${critical} |\n`;
173+
comment += `| 🟠 High | ${high} |\n`;
174+
comment += `| 🟡 Medium | ${findings.length - critical - high} |\n\n`;
175+
176+
if (critical > 0) {
177+
comment += `⚠️ **Action Required:** Critical security issues found!\n\n`;
178+
}
179+
180+
comment += `<details><summary>View findings</summary>\n\n`;
181+
comment += `\`\`\`json\n${JSON.stringify(findings.slice(0, 10), null, 2)}\n\`\`\`\n`;
182+
comment += `</details>\n\n`;
183+
comment += `*Powered by Hypatia Neurosymbolic CI/CD Intelligence*`;
184+
185+
github.rest.issues.createComment({
186+
owner: context.repo.owner,
187+
repo: context.repo.repo,
188+
issue_number: context.issue.number,
189+
body: comment
190+
});

.github/workflows/instant-sync.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
# Instant Forge Sync - Triggers propagation to all forges on push/release
3+
name: Instant Sync
4+
5+
on:
6+
push:
7+
branches: [main, master]
8+
release:
9+
types: [published]
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
dispatch:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Trigger Propagation
19+
uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v3
20+
with:
21+
token: ${{ secrets.FARM_DISPATCH_TOKEN }}
22+
repository: hyperpolymath/.git-private-farm
23+
event-type: propagate
24+
client-payload: |-
25+
{
26+
"repo": "${{ github.event.repository.name }}",
27+
"ref": "${{ github.ref }}",
28+
"sha": "${{ github.sha }}",
29+
"forges": ""
30+
}
31+
32+
- name: Confirm
33+
env:
34+
REPO_NAME: ${{ github.event.repository.name }}
35+
run: echo "::notice::Propagation triggered for ${REPO_NAME}"

0 commit comments

Comments
 (0)