Skip to content

Commit 1759efe

Browse files
committed
fix(security/compliance): standardized TruffleHog and RSR metadata
2 parents 02ee9fc + 10e937c commit 1759efe

44 files changed

Lines changed: 2474 additions & 163 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,5 @@
4646
Cargo.lock linguist-generated=true
4747
package-lock.json linguist-generated=true
4848
mix.lock linguist-generated=true
49+
# Pending estate-wide policy: hide ReScript from primary-language detection.
50+
**/*.res linguist-detectable=false

.github/workflows/casket-pages.yml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,40 @@
11
# SPDX-License-Identifier: MPL-2.0
22
name: GitHub Pages
3+
34
on:
45
push:
56
branches: [main]
67
workflow_dispatch:
8+
79
permissions:
810
contents: read
911
pages: write
1012
id-token: write
13+
1114
concurrency:
1215
group: "pages"
1316
cancel-in-progress: false
17+
1418
jobs:
1519
build:
1620
runs-on: ubuntu-latest
1721
timeout-minutes: 15
1822
steps:
1923
- name: Checkout
2024
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
25+
2126
- name: Checkout casket-ssg
2227
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
2328
with:
2429
repository: hyperpolymath/casket-ssg
2530
path: .casket-ssg
31+
2632
- name: Setup GHCup
2733
uses: haskell-actions/setup@ec49483bfc012387b227434aba94f59a6ecd0900 # v2
2834
with:
2935
ghc-version: '9.8.2'
3036
cabal-version: '3.10'
37+
3138
- name: Cache Cabal
3239
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
3340
with:
@@ -36,9 +43,11 @@ jobs:
3643
~/.cabal/store
3744
.casket-ssg/dist-newstyle
3845
key: ${{ runner.os }}-casket-${{ hashFiles('.casket-ssg/casket-ssg.cabal') }}
46+
3947
- name: Build casket-ssg
4048
working-directory: .casket-ssg
4149
run: cabal build
50+
4251
- name: Build site
4352
run: |
4453
mkdir -p site _site
@@ -69,18 +78,21 @@ jobs:
6978
fi
7079
fi
7180
cd .casket-ssg && cabal run casket-ssg -- build ../site ../_site
81+
7282
- name: Setup Pages
7383
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5
84+
7485
- name: Upload artifact
7586
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
7687
with:
7788
path: '_site'
89+
7890
deploy:
7991
environment:
8092
name: github-pages
8193
url: ${{ steps.deployment.outputs.page_url }}
8294
runs-on: ubuntu-latest
83-
timeout-minutes: 15
95+
timeout-minutes: 10
8496
needs: build
8597
steps:
8698
- name: Deploy to GitHub Pages

.github/workflows/codeql.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,41 @@
11
# SPDX-License-Identifier: MPL-2.0
22
name: CodeQL Security Analysis
3+
34
on:
45
push:
56
branches: [main]
67
pull_request:
78
branches: [main]
89
schedule:
9-
- cron: '0 6 * * 1' # Weekly on Monday
10+
- cron: '0 6 1 * *' # Weekly on Monday
11+
1012
permissions: read-all
13+
1114
jobs:
1215
analyze:
1316
name: CodeQL Analysis
1417
runs-on: ubuntu-latest
15-
timeout-minutes: 15
18+
timeout-minutes: 30
1619
permissions:
1720
security-events: write
1821
contents: read
22+
1923
strategy:
2024
fail-fast: false
2125
matrix:
2226
language: ['javascript-typescript']
27+
2328
steps:
2429
- name: Checkout repository
2530
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
31+
2632
- name: Initialize CodeQL
2733
uses: github/codeql-action/init@662472033e021d55d94146f66f6058822b0b39fd # v3
2834
with:
2935
languages: ${{ matrix.language }}
36+
3037
- name: Autobuild
3138
uses: github/codeql-action/autobuild@662472033e021d55d94146f66f6058822b0b39fd # v3
39+
3240
- name: Perform CodeQL Analysis
3341
uses: github/codeql-action/analyze@662472033e021d55d94146f66f6058822b0b39fd # v3

.github/workflows/hypatia-scan.yml

Lines changed: 96 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
# SPDX-License-Identifier: MPL-2.0
22
# Hypatia Neurosymbolic CI/CD Security Scan
33
name: Hypatia Security Scan
4+
45
on:
56
push:
6-
branches: [main, master, develop]
7+
branches: [ main, master, develop ]
78
pull_request:
8-
branches: [main, master]
9+
branches: [ main, master ]
910
schedule:
10-
- cron: '0 0 * * 0' # Weekly on Sunday
11+
- cron: '0 0 * * 0' # Weekly on Sunday
1112
workflow_dispatch:
1213
# Estate guardrail: cancel superseded runs so re-pushes don't pile up
1314
# queued runs across the estate. Safe here because this workflow only
1415
# performs read-only checks/lint/test/scan with no publish or mutation.
1516
concurrency:
1617
group: ${{ github.workflow }}-${{ github.ref }}
1718
cancel-in-progress: true
19+
1820
permissions:
1921
contents: read
2022
# security-events: write serves two purposes (write implies read):
@@ -36,26 +38,31 @@ permissions:
3638
# "Resource not accessible by integration" and (absent continue-on-error)
3739
# hard-fails the scan — exactly what the gate-decoupling design forbids.
3840
pull-requests: write
41+
3942
jobs:
4043
scan:
4144
name: Hypatia Neurosymbolic Analysis
4245
runs-on: ubuntu-latest
43-
timeout-minutes: 15
46+
timeout-minutes: 20
47+
4448
steps:
4549
- name: Checkout repository
4650
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
4751
with:
48-
fetch-depth: 0 # Full history for better pattern analysis
52+
fetch-depth: 0 # Full history for better pattern analysis
53+
4954
- name: Setup Elixir for Hypatia scanner
5055
uses: erlef/setup-beam@fc68ffb90438ef2936bbb3251622353b3dcb2f93 # v1.18.2
5156
with:
5257
elixir-version: '1.18'
5358
otp-version: '27'
59+
5460
- name: Clone Hypatia
5561
run: |
5662
if [ ! -d "$HOME/hypatia" ]; then
5763
git clone https://github.com/hyperpolymath/hypatia.git "$HOME/hypatia"
5864
fi
65+
5966
- name: Build Hypatia scanner (if needed)
6067
run: |
6168
cd "$HOME/hypatia"
@@ -64,6 +71,7 @@ jobs:
6471
mix deps.get
6572
mix escript.build
6673
fi
74+
6775
- name: Run Hypatia scan
6876
id: scan
6977
env:
@@ -96,12 +104,14 @@ jobs:
96104
echo "- Critical: $CRITICAL" >> $GITHUB_STEP_SUMMARY
97105
echo "- High: $HIGH" >> $GITHUB_STEP_SUMMARY
98106
echo "- Medium: $MEDIUM" >> $GITHUB_STEP_SUMMARY
107+
99108
- name: Upload findings artifact
100109
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
101110
with:
102111
name: hypatia-findings
103112
path: hypatia-findings.json
104113
retention-days: 90
114+
105115
- name: Convert Hypatia findings to SARIF
106116
# Always runs (no findings_count guard): an EMPTY SARIF run is
107117
# valid and intentional — uploading it clears stale Hypatia
@@ -217,6 +227,7 @@ jobs:
217227
console.log(`hypatia.sarif written: ${results.length} result(s).`);
218228
CJS
219229
node "$RUNNER_TEMP/hypatia-sarif.cjs"
230+
220231
- name: Upload SARIF to GitHub code scanning
221232
# Fork PRs get a read-only GITHUB_TOKEN, so security-events:write
222233
# is unavailable and upload-sarif cannot publish — skip there
@@ -228,19 +239,16 @@ jobs:
228239
# exists to end). The empty-SARIF "clear stale alerts" path is
229240
# handled in the converter above and does not error here.
230241
if: >-
231-
always() && (github.event_name != 'pull_request' ||
232-
233-
234-
235-
236-
242+
always() &&
243+
(github.event_name != 'pull_request' ||
237244
github.event.pull_request.head.repo.fork != true)
238245
uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v3.28.1
239246
with:
240247
sarif_file: hypatia.sarif
241248
# Distinct category so Hypatia results coexist with CodeQL's
242249
# (codeql.yml) instead of overwriting them on the same surface.
243250
category: hypatia
251+
244252
- name: Submit findings to gitbot-fleet (Phase 2)
245253
if: steps.scan.outputs.findings_count > 0
246254
# Phase 2 is the collaborative LEARNING side-channel ("bots share
@@ -264,7 +272,52 @@ jobs:
264272
GITHUB_REPOSITORY: ${{ github.repository }}
265273
GITHUB_SHA: ${{ github.sha }}
266274
FINDINGS_COUNT: ${{ steps.scan.outputs.findings_count }}
267-
run: "echo \"\U0001F4E4 Submitting $FINDINGS_COUNT findings to gitbot-fleet...\"\n\n# Clone gitbot-fleet to temp directory. A clone failure (network,\n# repo gone) is non-fatal: learning submission is best-effort.\nFLEET_DIR=\"/tmp/gitbot-fleet-$$\"\nif ! git clone --depth 1 https://github.com/hyperpolymath/gitbot-fleet.git \"$FLEET_DIR\"; then\n echo \"::warning::Could not clone gitbot-fleet — skipping Phase 2 learning submission (non-fatal).\"\n exit 0\nfi\n\n# The submission script's location in gitbot-fleet has drifted\n# before (it was absent from the default branch, which exit-127'd\n# every consuming repo's scan). Probe known locations rather than\n# hard-coding one path, and skip gracefully if none is present.\nSUBMIT_SCRIPT=\"\"\nfor cand in \\\n \"$FLEET_DIR/scripts/submit-finding.sh\" \\\n \"$FLEET_DIR/scripts/submit_finding.sh\" \\\n \"$FLEET_DIR/bin/submit-finding.sh\" \\\n \"$FLEET_DIR/submit-finding.sh\"; do\n if [ -f \"$cand\" ]; then\n SUBMIT_SCRIPT=\"$cand\"\n break\n fi\ndone\n\nif [ -z \"$SUBMIT_SCRIPT\" ]; then\n echo \"::warning::gitbot-fleet submit-finding script not found at any known path — skipping Phase 2 learning submission (non-fatal). Findings are still uploaded as an artifact and gated below.\"\n rm -rf \"$FLEET_DIR\"\n exit 0\nfi\n\n# Run submission script. Pass the findings path as ABSOLUTE —\n# the script cd's into its own working dir before reading the\n# file, so a relative path would resolve to the wrong place.\n# A submission-script failure is logged but non-fatal.\nif bash \"$SUBMIT_SCRIPT\" \"$GITHUB_WORKSPACE/hypatia-findings.json\"; then\n echo \"✅ Finding submission complete\"\nelse\n echo \"::warning::gitbot-fleet submission script exited non-zero — Phase 2 learning submission skipped (non-fatal).\"\nfi\n\n# Cleanup\nrm -rf \"$FLEET_DIR\"\n"
275+
run: |
276+
echo "📤 Submitting $FINDINGS_COUNT findings to gitbot-fleet..."
277+
278+
# Clone gitbot-fleet to temp directory. A clone failure (network,
279+
# repo gone) is non-fatal: learning submission is best-effort.
280+
FLEET_DIR="/tmp/gitbot-fleet-$$"
281+
if ! git clone --depth 1 https://github.com/hyperpolymath/gitbot-fleet.git "$FLEET_DIR"; then
282+
echo "::warning::Could not clone gitbot-fleet — skipping Phase 2 learning submission (non-fatal)."
283+
exit 0
284+
fi
285+
286+
# The submission script's location in gitbot-fleet has drifted
287+
# before (it was absent from the default branch, which exit-127'd
288+
# every consuming repo's scan). Probe known locations rather than
289+
# hard-coding one path, and skip gracefully if none is present.
290+
SUBMIT_SCRIPT=""
291+
for cand in \
292+
"$FLEET_DIR/scripts/submit-finding.sh" \
293+
"$FLEET_DIR/scripts/submit_finding.sh" \
294+
"$FLEET_DIR/bin/submit-finding.sh" \
295+
"$FLEET_DIR/submit-finding.sh"; do
296+
if [ -f "$cand" ]; then
297+
SUBMIT_SCRIPT="$cand"
298+
break
299+
fi
300+
done
301+
302+
if [ -z "$SUBMIT_SCRIPT" ]; then
303+
echo "::warning::gitbot-fleet submit-finding script not found at any known path — skipping Phase 2 learning submission (non-fatal). Findings are still uploaded as an artifact and gated below."
304+
rm -rf "$FLEET_DIR"
305+
exit 0
306+
fi
307+
308+
# Run submission script. Pass the findings path as ABSOLUTE —
309+
# the script cd's into its own working dir before reading the
310+
# file, so a relative path would resolve to the wrong place.
311+
# A submission-script failure is logged but non-fatal.
312+
if bash "$SUBMIT_SCRIPT" "$GITHUB_WORKSPACE/hypatia-findings.json"; then
313+
echo "✅ Finding submission complete"
314+
else
315+
echo "::warning::gitbot-fleet submission script exited non-zero — Phase 2 learning submission skipped (non-fatal)."
316+
fi
317+
318+
# Cleanup
319+
rm -rf "$FLEET_DIR"
320+
268321
- name: Check for critical issues
269322
if: steps.scan.outputs.critical > 0
270323
# GATING POLICY (explicit, by design — not an oversight):
@@ -282,6 +335,7 @@ jobs:
282335
echo "::warning::Hypatia found critical security issue(s) — advisory."
283336
echo "See the Security → Code scanning page (category: hypatia)"
284337
echo "and the hypatia-findings.json artifact for details."
338+
285339
- name: Generate scan report
286340
run: |
287341
cat << EOF > hypatia-report.md
@@ -320,6 +374,7 @@ jobs:
320374
EOF
321375
322376
cat hypatia-report.md >> $GITHUB_STEP_SUMMARY
377+
323378
- name: Comment on PR with findings
324379
if: github.event_name == 'pull_request' && steps.scan.outputs.findings_count > 0
325380
# Advisory only — posting findings as a PR comment must never gate
@@ -329,4 +384,32 @@ jobs:
329384
continue-on-error: true
330385
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v7
331386
with:
332-
script: "const fs = require('fs');\nconst findings = JSON.parse(fs.readFileSync('hypatia-findings.json', 'utf8'));\n\nconst critical = findings.filter(f => f.severity === 'critical').length;\nconst high = findings.filter(f => f.severity === 'high').length;\n\nlet comment = `## \U0001F50D Hypatia Security Scan\\n\\n`;\ncomment += `**Findings:** ${findings.length} issues detected\\n\\n`;\ncomment += `| Severity | Count |\\n|----------|-------|\\n`;\ncomment += `| \U0001F534 Critical | ${critical} |\\n`;\ncomment += `| \U0001F7E0 High | ${high} |\\n`;\ncomment += `| \U0001F7E1 Medium | ${findings.length - critical - high} |\\n\\n`;\n\nif (critical > 0) {\n comment += `⚠️ **Action Required:** Critical security issues found!\\n\\n`;\n}\n\ncomment += `<details><summary>View findings</summary>\\n\\n`;\ncomment += `\\`\\`\\`json\\n${JSON.stringify(findings.slice(0, 10), null, 2)}\\n\\`\\`\\`\\n`;\ncomment += `</details>\\n\\n`;\ncomment += `*Powered by Hypatia Neurosymbolic CI/CD Intelligence*`;\n\ngithub.rest.issues.createComment({\n owner: context.repo.owner,\n repo: context.repo.repo,\n issue_number: context.issue.number,\n body: comment\n});"
387+
script: |
388+
const fs = require('fs');
389+
const findings = JSON.parse(fs.readFileSync('hypatia-findings.json', 'utf8'));
390+
391+
const critical = findings.filter(f => f.severity === 'critical').length;
392+
const high = findings.filter(f => f.severity === 'high').length;
393+
394+
let comment = `## 🔍 Hypatia Security Scan\n\n`;
395+
comment += `**Findings:** ${findings.length} issues detected\n\n`;
396+
comment += `| Severity | Count |\n|----------|-------|\n`;
397+
comment += `| 🔴 Critical | ${critical} |\n`;
398+
comment += `| 🟠 High | ${high} |\n`;
399+
comment += `| 🟡 Medium | ${findings.length - critical - high} |\n\n`;
400+
401+
if (critical > 0) {
402+
comment += `⚠️ **Action Required:** Critical security issues found!\n\n`;
403+
}
404+
405+
comment += `<details><summary>View findings</summary>\n\n`;
406+
comment += `\`\`\`json\n${JSON.stringify(findings.slice(0, 10), null, 2)}\n\`\`\`\n`;
407+
comment += `</details>\n\n`;
408+
comment += `*Powered by Hypatia Neurosymbolic CI/CD Intelligence*`;
409+
410+
github.rest.issues.createComment({
411+
owner: context.repo.owner,
412+
repo: context.repo.repo,
413+
issue_number: context.issue.number,
414+
body: comment
415+
});

.github/workflows/mirror.yml

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,15 @@
11
# SPDX-License-Identifier: MPL-2.0
2-
name: Mirror to GitLab and Bitbucket
2+
name: Mirror to Git Forges
3+
34
on:
45
push:
56
branches: [main]
6-
permissions: read-all
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: read
11+
712
jobs:
813
mirror:
9-
name: Sync to Forges
10-
runs-on: ubuntu-latest
11-
timeout-minutes: 15
12-
if: vars.GITLAB_MIRROR_ENABLED == 'true' || vars.BITBUCKET_MIRROR_ENABLED == 'true'
13-
permissions:
14-
contents: read
15-
steps:
16-
- name: Checkout repository
17-
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
18-
with:
19-
fetch-depth: 0
20-
- name: Mirror to GitLab
21-
if: vars.GITLAB_MIRROR_ENABLED == 'true' && secrets.GITLAB_SSH_KEY != ''
22-
run: |
23-
mkdir -p ~/.ssh
24-
echo "${{ secrets.GITLAB_SSH_KEY }}" > ~/.ssh/id_rsa
25-
chmod 600 ~/.ssh/id_rsa
26-
ssh-keyscan gitlab.com >> ~/.ssh/known_hosts
27-
git remote add gitlab git@gitlab.com:hyperpolymath/error-lang.git || true
28-
git push --mirror gitlab
29-
- name: Mirror to Bitbucket
30-
if: vars.BITBUCKET_MIRROR_ENABLED == 'true' && secrets.BITBUCKET_SSH_KEY != ''
31-
run: |
32-
mkdir -p ~/.ssh
33-
echo "${{ secrets.BITBUCKET_SSH_KEY }}" > ~/.ssh/id_rsa
34-
chmod 600 ~/.ssh/id_rsa
35-
ssh-keyscan bitbucket.org >> ~/.ssh/known_hosts
36-
git remote add bitbucket git@bitbucket.org:hyperpolymath/error-lang.git || true
37-
git push --mirror bitbucket
14+
uses: hyperpolymath/standards/.github/workflows/mirror-reusable.yml@e6b2884722350515934d443daf23442f2195796f
15+
secrets: inherit

0 commit comments

Comments
 (0)