diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml new file mode 100644 index 0000000..32cb0cf --- /dev/null +++ b/.github/workflows/scorecard.yml @@ -0,0 +1,62 @@ +# OpenSSF Scorecard — security supply-chain posture for KofTwentyTwo/Jarvis. +# +# Issue #178. Scorecard scores 18 security checks (Branch-Protection, Code-Review, +# Pinned-Dependencies, SAST, Token-Permissions, etc.) and publishes results as +# SARIF to GitHub code-scanning. A weekly schedule keeps the score fresh; we +# also re-run on every push to develop so significant posture regressions show +# up promptly. The badge in README.md links back to the public scorecard page. +# +# Permissions are the canonical Scorecard set: +# - id-token: write OIDC for publish-results +# - contents: read read repo tree +# - security-events: write upload SARIF to code-scanning +# +# This workflow runs on github-hosted ubuntu-latest. Self-hosted Grogu is not +# used here -- Scorecard is short, network-bound, and benefits from a clean +# ephemeral environment. +# +# Workflow consumes no untrusted user inputs (no github.event.* interpolation +# in run: blocks), so it is safe from workflow-injection patterns. + +name: OpenSSF Scorecard + +on: + schedule: + # Mondays at 06:00 UTC. Off-peak relative to weekday push spikes. + - cron: "0 6 * * 1" + push: + branches: [develop] + workflow_dispatch: + +permissions: read-all + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + security-events: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Run Scorecard + uses: ossf/scorecard-action@v2.4.0 + with: + results_file: results.sarif + results_format: sarif + # publish_results: true uploads anonymized scores to the OpenSSF + # public dataset, which is what powers the README badge URL + # (api.scorecard.dev). Safe for a public repo; would need + # reconsidering if the repo were ever made private. + publish_results: true + + - name: Upload SARIF to code-scanning + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: results.sarif diff --git a/README.md b/README.md index b8f0e1b..6ed8b28 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ [![Issues](https://img.shields.io/github/issues/KofTwentyTwo/Jarvis)](https://github.com/KofTwentyTwo/Jarvis/issues) [![Platform: macOS 26](https://img.shields.io/badge/platform-macOS%2026%20Tahoe-blue)](https://www.apple.com/macos/) [![Swift 6](https://img.shields.io/badge/swift-6.0-orange)](https://swift.org) +[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/KofTwentyTwo/Jarvis/badge)](https://scorecard.dev/viewer/?uri=github.com/KofTwentyTwo/Jarvis) Jarvis is a hybrid native + embedded-web macOS app that runs as an ambient menu-bar presence. A Swift host owns the operating system (mic, camera, diff --git a/scripts/build-webview.sh b/scripts/build-webview.sh index 181c8e2..e2bdf13 100755 --- a/scripts/build-webview.sh +++ b/scripts/build-webview.sh @@ -77,6 +77,16 @@ pnpm --filter @jarvis/hud build DEST="$REPO_ROOT/App/Resources/webview" mkdir -p "$DEST" +mkdir -p "$DEST/assets" + +# Issue #46: Vite emits content-hashed asset names (e.g. `index-CXPb0I5z.js`), +# so the active bundle filename changes on every dependency or source edit. +# Without explicit cleanup, stale chunks accumulate in `assets/` because we +# don't pass `--delete` to rsync below. Sweep the asset glob (JS + maps + CSS) +# before the rsync drops the fresh bundle. `bus-harness.html`, `index.html`, +# and the directory's `.gitignore` live one level up (in $DEST), not in +# $DEST/assets, so they are not at risk from this rm. +rm -f "$DEST"/assets/*.js "$DEST"/assets/*.js.map "$DEST"/assets/*.css "$DEST"/assets/*.css.map echo "[build-webview] rsync dist/ -> $DEST" # --exclude bus-harness.html: keep 02-03's committed copy intact (parity @@ -85,6 +95,7 @@ echo "[build-webview] rsync dist/ -> $DEST" # --exclude .gitignore: preserve the App/Resources/webview/.gitignore that # lets index.html stay source-committed while assets/ regenerates. # We do NOT pass --delete: other vendored assets coexist in this dir. +# (The explicit `rm -f` above handles stale `assets/` chunks; see #46.) rsync -a \ --exclude=bus-harness.html \ --exclude=.gitignore \