diff --git a/.github/workflows/scorecard-ci.yml b/.github/workflows/scorecard-ci.yml index 9a4528f7..8871d32a 100644 --- a/.github/workflows/scorecard-ci.yml +++ b/.github/workflows/scorecard-ci.yml @@ -33,8 +33,19 @@ jobs: ENFORCE=false fi - # Run audit in JSON mode - if ! python scripts/scorecard_ci.py . --output json --threshold "$THRESHOLD" --fail-on-drop > scorecard-report.json 2> scorecard-stderr.txt; then + # Run audit in JSON mode. Exit 1 means an advisory threshold drop; + # any other exit code is an execution/contract failure and must stop + # before attempting to parse a possibly empty report. + set +e + python scripts/scorecard_ci.py . --output json --threshold "$THRESHOLD" --fail-on-drop > scorecard-report.json 2> scorecard-stderr.txt + AUDIT_STATUS=$? + set -e + if [ "$AUDIT_STATUS" -ne 0 ] && [ "$AUDIT_STATUS" -ne 1 ]; then + echo "Scorecard audit failed with exit code $AUDIT_STATUS." >&2 + cat scorecard-stderr.txt >&2 + exit "$AUDIT_STATUS" + fi + if [ "$AUDIT_STATUS" -eq 1 ]; then echo "Scorecard is below the canonical-main threshold; continuing to publish the report." fi diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 722e841f..b6cf4899 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -20,8 +20,6 @@ jobs: analysis: name: Scorecard analysis runs-on: ubuntu-latest - security: - permissions: read-all steps: - name: Checkout diff --git a/crates/sl-viewer/src/app.rs b/crates/sl-viewer/src/app.rs index b96b89ce..41ebdcfb 100644 --- a/crates/sl-viewer/src/app.rs +++ b/crates/sl-viewer/src/app.rs @@ -351,8 +351,7 @@ fn icon_svg(tab_icon: &str) -> &'static str { pub fn App() -> Element { #[cfg(feature = "web")] use_effect(|| { - let force_light = query_fixture_active("launch-splash-light"); - let script = if force_light { + let script = if query_fixture_active("launch-splash-light") { r#" document.documentElement.lang = 'en'; document.documentElement.dataset.theme = 'light'; @@ -521,7 +520,9 @@ pub fn App() -> Element { let _ = document::eval(&format!( r#" (function() {{ - const desired = {theme_attr:?}; + const desired = new URLSearchParams(window.location.search).get('fixture') === 'launch-splash-light' + ? 'light' + : {theme_attr:?}; if (desired === 'system') {{ const prefersLight = window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches; @@ -1288,12 +1289,21 @@ pub fn App() -> Element { r#type: "button", "aria-label": "Toggle light and dark theme", onclick: move |_| { + let next_theme = match settings_signal().theme { + Theme::Light => Theme::Dark, + Theme::Dark | Theme::System => Theme::Light, + }; settings_signal.with_mut(|settings| { - settings.theme = match settings.theme { - Theme::Light => Theme::Dark, - Theme::Dark | Theme::System => Theme::Light, - }; + settings.theme = next_theme; }); + let resolved = match next_theme { + Theme::Light => "light", + Theme::Dark => "dark", + Theme::System => "dark", + }; + let _ = document::eval(&format!( + "document.documentElement.dataset.theme = '{resolved}'; window.localStorage.setItem('sl-viewer-theme', '{resolved}');" + )); }, "Theme" } diff --git a/scripts/miri-permutation-check.ps1 b/scripts/miri-permutation-check.ps1 index c1d33334..b4373269 100644 --- a/scripts/miri-permutation-check.ps1 +++ b/scripts/miri-permutation-check.ps1 @@ -49,14 +49,14 @@ function Write-Check { return $Ok } -function Test-DocContains { +function Test-DocContent { param( [Parameter(Mandatory = $true)][string]$Doc, [Parameter(Mandatory = $true)][string]$Needle, [Parameter(Mandatory = $true)][string]$Label, [string]$Context = "docs/ops/concurrency-safety.md" ) - $ok = $Doc.Contains($Needle) + $ok = $Doc.Contains($Needle) [void](Write-Check -Label $Label -Ok $ok) if (-not $ok) { throw "$Context missing required anchor: '$Needle'" @@ -70,7 +70,7 @@ function Test-DocPattern { [Parameter(Mandatory = $true)][string]$Label, [string]$Context = "docs/ops/concurrency-safety.md" ) - $ok = $Doc -match $Pattern + $ok = $Doc -cmatch $Pattern [void](Write-Check -Label $Label -Ok $ok) if (-not $ok) { throw "$Context missing required pattern: '$Pattern'" @@ -96,21 +96,21 @@ $raceModel = Get-Content -LiteralPath $raceModelPath -Raw $cargoToml = Get-Content -LiteralPath $cargoTomlPath -Raw Write-Host "Concurrency safety doc anchors (done vs unpaid):" -Test-DocContains -Doc $doc -Needle "Miri permutation checkers" ` +Test-DocContent -Doc $doc -Needle "Miri permutation checkers" ` -Label "miri permutation section heading" -Test-DocContains -Doc $doc -Needle "scripts/miri-permutation-check.ps1" ` +Test-DocContent -Doc $doc -Needle "scripts/miri-permutation-check.ps1" ` -Label "permutation SelfCheck script reference" -Test-DocPattern -Doc $doc -Pattern "Miri permutation SelfCheck\s+\|\s+\*\*done\*\*" ` +Test-DocPattern -Doc $doc -Pattern "(?m)^\| Miri permutation SelfCheck\s+\|\s+\*\*done\*\*\s+\|" ` -Label "permutation SelfCheck gate marked done" -Test-DocPattern -Doc $doc -Pattern "Miri permutation race_model CI\s+\|\s+\*\*done\*\*" ` +Test-DocPattern -Doc $doc -Pattern "(?m)^\| Miri permutation race_model CI\s+\|\s+\*\*done\*\*\s+\|" ` -Label "permutation race_model CI gate marked done" -Test-DocContains -Doc $doc -Needle "miri-permutation.yml" ` +Test-DocContent -Doc $doc -Needle "miri-permutation.yml" ` -Label "miri-permutation workflow reference" -Test-DocContains -Doc $doc -Needle "miri-smoke.yml" ` +Test-DocContent -Doc $doc -Needle "miri-smoke.yml" ` -Label "miri-smoke soft workflow reference retained" -Test-DocPattern -Doc $doc -Pattern "loom_model under Miri\s+\|\s+\*\*unpaid\*\*" ` +Test-DocPattern -Doc $doc -Pattern "(?m)^\| loom_model under Miri\s+\|\s+\*\*unpaid\*\*\s+\|" ` -Label "loom_model under Miri unpaid gate" -Test-DocContains -Doc $doc -Needle "Full loom / shuttle permutation checkers | **unpaid**" ` +Test-DocContent -Doc $doc -Needle "Full loom / shuttle permutation checkers | **unpaid**" ` -Label "shared loom/shuttle unpaid gate retained" Write-Host "Workflow blocking-gate anchors:"