diff --git a/.semgrep.yml b/.semgrep.yml index 22a2c46..dae5ec1 100644 --- a/.semgrep.yml +++ b/.semgrep.yml @@ -1,6 +1,6 @@ rules: - # These three rules preserve the pinned upstream definitions and IDs. The - # pattern-not clauses are the narrow, reviewed exceptions from PR #67. + # These four rules preserve the pinned upstream definitions and IDs. The + # pattern-not clauses are narrow, reviewed exceptions to false positives. - id: python.lang.security.audit.dynamic-urllib-use-detected.dynamic-urllib-use-detected patterns: - pattern-not: urllib.$W("...") @@ -89,3 +89,39 @@ rules: ... - pattern: $CONNECTION.execute($QUERY, ...) - pattern-not: connection.execute(f"ALTER TABLE episodes ADD COLUMN {name} {column_type}") + + - id: html.security.audit.missing-integrity.missing-integrity + patterns: + - pattern-either: + - pattern: + - pattern: + - metavariable-pattern: + metavariable: $...A + patterns: + - pattern-either: + - pattern: src='... :// ...' + - pattern: src="... :// ..." + - pattern: href='... :// ...' + - pattern: href="... :// ..." + - pattern: src='//...' + - pattern: src="//..." + - pattern: href='//...' + - pattern: href="//..." + - pattern-not-regex: (?is).*integrity=.* + - pattern-not-regex: (google-analytics\.com|fonts\.googleapis\.com|fonts\.gstatic\.com|googletagmanager\.com) + - pattern-not-regex: .*rel\s*=\s*['"]?preconnect.* + # Canonical metadata identifies the document; it fetches no resource. + - pattern-not-regex: .*rel\s*=\s*['"]?canonical.* + paths: + include: + - "*.html" + message: >- + This tag is missing an 'integrity' subresource integrity attribute. The + 'integrity' attribute allows for the browser to verify that externally hosted + files (for example from a CDN) are delivered without unexpected manipulation. + Without this attribute, if an attacker can modify the externally hosted resource, + this could lead to XSS and other types of attacks. To prevent this, include the + base64-encoded cryptographic hash of the resource (file) you're telling the + browser to fetch in the 'integrity' attribute for all externally hosted files. + severity: WARNING + languages: [generic] diff --git a/README.md b/README.md index 21ccc07..615885b 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,10 @@ front-office dynasty games. Agents manage a fictional hockey-style league over multiple seasons by making roster, trade, free-agency, draft, and lineup decisions through a JSON-compatible API. +Explore the [live leaderboard](https://nedcut.github.io/gm-bench/), read the +[phase-one findings](docs/blog/sota-v2-findings.md), or download the +[tagged evidence release](https://github.com/nedcut/gm-bench/releases/tag/sota-v2-phase-one-2026-07-19). + ## Phase-one result Eight pre-registered model systems produced strict `sota-v2` rows under one @@ -19,7 +23,7 @@ Read the [phase-one findings](docs/blog/sota-v2-findings.md), inspect the [generated analysis](results/analysis/publication-panel-analysis.json), or follow the [clean-clone reproduction guide](docs/REPRODUCING_SOTA_V2_RELEASE.md). -The MVP includes: +GM-Bench includes: - A seeded league simulator with aging, development, injuries, contracts, salary-cap pressure, free agency, trades, drafts, playoffs, and team standings. diff --git a/scripts/prepare_semgrep_ruleset.py b/scripts/prepare_semgrep_ruleset.py index 183f861..899801b 100644 --- a/scripts/prepare_semgrep_ruleset.py +++ b/scripts/prepare_semgrep_ruleset.py @@ -14,6 +14,7 @@ "python.lang.security.audit.dynamic-urllib-use-detected.dynamic-urllib-use-detected", "python.lang.security.audit.formatted-sql-query.formatted-sql-query", "python.sqlalchemy.security.sqlalchemy-execute-raw-query.sqlalchemy-execute-raw-query", + "html.security.audit.missing-integrity.missing-integrity", } ) diff --git a/tests/test_publication_claims.py b/tests/test_publication_claims.py index a279d63..43e1340 100644 --- a/tests/test_publication_claims.py +++ b/tests/test_publication_claims.py @@ -46,3 +46,18 @@ def test_public_claim_surfaces_use_the_frozen_lane_and_current_gate() -> None: assert "1,024-token safety ceiling" not in blog assert "`publishable_ranking: true`" in readme assert "no ordinal \u201cbest model\u201d claim" in " ".join(readme.split()) + + +def test_employer_facing_site_links_current_evidence_and_metadata() -> None: + hero = Path("web/src/components/Hero.tsx").read_text() + footer = Path("web/src/components/Footer.tsx").read_text() + index = Path("web/index.html").read_text() + + assert "0 beat the scripted bar" in hero + assert "sota-v2-phase-one-2026-07-19" in hero + assert "Built by Ned Cutler" in footer + assert "REPRODUCING_SOTA_V2_RELEASE.md" in footer + assert 'href="%BASE_URL%favicon.svg"' in index + assert 'rel="canonical" href="https://nedcut.github.io/gm-bench/"' in index + assert 'property="og:title"' in index + assert "leaderboard that stays empty" not in index diff --git a/web/index.html b/web/index.html index d6347cd..5eae457 100644 --- a/web/index.html +++ b/web/index.html @@ -2,12 +2,27 @@ - + + + + + + + + + + GM-Bench — Can a language model run a front office? diff --git a/web/src/components/Footer.tsx b/web/src/components/Footer.tsx index 2cbb684..5ec7bf7 100644 --- a/web/src/components/Footer.tsx +++ b/web/src/components/Footer.tsx @@ -5,15 +5,26 @@ export default function Footer({ data }: { data: LeaderboardData }) { return (