Public record
Software health reportschema 0.26.0 · metrics 1.13.0 · 2026-07-22 10:03 UTC

karsten-s-nielsen / silly-kicks

Maintained fork of socceraction — SPADL event conversion + VAEP action valuation for soccer analytics

PythonMIT★ 1 star⑂ 0 forkssince Apr 2026View on GitHub ↗

karsten-s-nielsen/silly-kicks holds a health index of 62 out of 100, placing it in the Moderate band. It scores highest on Vitality (80/100) and lowest on Community & Adoption (43/100). It was last updated today. A single contributor accounts for most of its recent work.

62
overall / 100
Moderate

Software health index

Metrics are grouped into weighted categories on one standardized 1–100 scale. Overall starts as their weighted mean; when public evidence triggers the High-Risk Jurisdiction Policy, the rating is adjusted and receives an At risk ceiling of 49. AI Readiness sits outside the overall score.

62
Excellent85-100Exemplary; meets essentially all checked criteria
Good70-84Healthy; minor gaps
Moderate50-69Acceptable with notable gaps; review recommended
At risk30-49Significant weaknesses; adoption warrants caution
Critical1-29Severe problems (abandoned, single-maintainer, no hygiene)
VitalityCommunity &AdoptionSustainability &GovernanceEngineeringQualitySecurityAI Readiness

Score profile

Each axis is a category. The shape matters more than the average — a healthy subject fills the whole shape, while a spike-and-crater profile means strength in one dimension is masking risk in another.

Ownership

karsten-s-nielsenOrganization
2 followers11 public repossince Mar 2026

This repository is backed by an organization — shared, accountable stewardship that can outlive any single maintainer.

Package ecosystems

RegistryPackageVersionDownloads / moVersionsLast publishTags
PyPIsilly-kicks4.55.1-1500 days agospadlvaepactionsanalyticsfootballsoccer

Metrics by category

Vitality

Is the project alive — is code being written and are releases shipping?

80Good · 22% of overall
How it's scored
36/36Push recency — last push 0 days ago
9.7/36Commit cadence — 14/52 weeks with commits
18/18Commit volume — 207 commits in the last year
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Inputs used
commits_last_year207
human_commit_share0.96
days_since_last_push0
active_weeks_last_year14
How it's scored
16.2/27Ships releases — 100 version tags (no GitHub releases)
36/36Release recency — latest release 0 days ago
27/27Release cadence — a release every ~0.8 days
0/10OpenSSF Scorecard: Signed-Releases — no data
Inputs used
releases_count100
latest_release_tagv4.55.1
releases_from_tagsyes
days_since_latest_release0
mean_days_between_releases0.8
Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.

Community & Adoption

Does the project have users, downloads, attention, and a welcoming setup for contributors?

43At risk · 18% of overall
How it's scored
0/60Stars — 1 stars
0/25Forks — 0 forks
0/15Watchers — 0 watchers
Inputs used
forks0
stars1
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history

Community health

92Excellent
How it's scored
22.5/22.5README
22.5/22.5License — recognized license (MIT)
18/18CONTRIBUTING guide
13.5/13.5Code of conduct
0/7.2Issue template
6.3/6.3PR template
Inputs used
has_readmeyes
has_licenseyes
has_contributingyes
has_issue_templateno
has_code_of_conductyes
has_pull_request_templateyes

Sustainability & Governance

Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?

52Moderate · 24% of overall
How it's scored
9/54Bus factor — 1 contributor(s) cover half of all commits
0/22.5Commit distribution — top contributor authored 100% of commits
1.4/13.5Contributor breadth — 1 contributors
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Inputs used
bus_factor1
contributors_sampled1
top_contributor_share1
How it's scored
0/46.8Issue resolution — no issues or no data
38.2/38.3PR acceptance — 165/165 decided PRs merged
0/15OpenSSF Scorecard: Code-Review — Found 0/28 approved changesets -- score normalized to 0
Inputs used
merged_prs165
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.
How it's scored
30/30Ownership backing — organization-owned
0/20Verified domain
3.4/25Owner reach — 2 followers of karsten-s-nielsen
8.6/25Track record — 11 public repos, account ~0 yr old
Inputs used
followers2
owner_typeOrganization
is_verified
owner_loginkarsten-s-nielsen
public_repos11
account_age_days141
How it's scored
25/25Published & resolvable — 1 package(s) on pypi
35/35Publish recency — latest publish 0 days ago
20/20Version history — 150 published versions
20/20Not deprecated — active, not deprecated or yanked
Inputs used
packagessilly-kicks
ecosystemspypi
any_deprecatedno
min_days_since_publish0

Engineering Quality

Are baseline engineering and documentation practices in place?

71Good · 20% of overall
How it's scored
24/24CI workflows — 2 workflow(s)
24/24Tests present
0/16Linter config
0/9.6Pre-commit hooks
0/6.4.editorconfig
20/20OpenSSF Scorecard: CI-Tests — 26 out of 26 merged PRs checked by a CI test -- score normalized to 10
Inputs used
has_ciyes
has_testsyes
has_editorconfigno
has_linter_configno
has_precommit_configno
How it's scored
30/30README
25/25Documentation directory
0/15Documentation / homepage site
10/10Repository description
10/10Topics — 10 topics
0/10Wiki
Inputs used
topicsevent-data, opta, pandas, python, soccer-analytics, statsbomb, vaep, wyscout, spadl, football
has_wikino
homepage
has_readmeyes
has_docs_diryes
has_descriptionyes

Security

Are visible security and supply-chain practices strong, without unresolved high-risk jurisdiction exposure?

63Moderate · 16% of overall
How it's scored
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — no data
2.5/2.5CI-Tests — 26 out of 26 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/28 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
10/10Dangerous-Workflow — no dangerous workflow patterns detected
7.5/7.5Dependency-Update-Tool — update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5License — license file detected
7.5/7.5Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
5/5Packaging — packaging workflow detected
1.5/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 3
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
5/5Security-Policy — security policy file detected
0/7.5Signed-Releases — no data
7.5/7.5Token-Permissions — GitHub workflow tokens follow principle of least privilege
0/7.5Vulnerabilities — 29 existing vulnerabilities detected
Inputs used
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate6.3
Excluded from scoring (no data or not applicable): branch_protection, signed_releases. Remaining weights renormalized.

AI Readiness

How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score.

61Moderate · 0% of overall
How it's scored
45/45Agent instructions — CLAUDE.md
0/15Machine-readable docs (llms.txt)
40/40Legible commit history — 96 of 96 human commits state their intent (structured subject or explanatory body)
Inputs used
has_llms_txtno
legible_history_share1
agent_instruction_filesCLAUDE.md
agent_instruction_max_bytes132,634
How it's scored
0/18One-command bootstrap
22/22Automated tests
0/11Lint / format config
0/11Static type checking
10/10Reproducible environment — lockfile
10/10Demonstrated agent practice — 87 of the last 100 commits agent-authored or agent-credited
8/8Automated maintenance — 4 of the last 100 commits are automated dependency updates
3/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 3
Inputs used
has_nixno
has_testsyes
lockfilesuv.lock
has_dockerfileno
typed_languageno
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configs
agent_commit_share0.87
toolchain_manifests
dependency_bot_commit_share0.04
How it's scored
0/45Type-checkable code — Python without a type-check config
54.5/55Manageable file sizes — 7/707 source files over 60KB
Inputs used
primary_languagePython
largest_source_bytes240,290
source_files_sampled707
oversized_source_files7
How it's scored
0/40API schema (OpenAPI/GraphQL/proto)
0/20MCP server
40/40Runnable examples — examples
Inputs used
example_dirsexamples
has_mcp_signalno
api_schema_files

Key facts

1GitHub stars
1contributors
207commits, last 12 months
0days since last push
100releases
1bus factor
0open issues
PyPIpackage ecosystems

Data collection warnings

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository
  • deps.dev does not index pypi:silly-kicks@4.55.1; advisories assessed against the repository dependency graph instead

More detail

OpenSSF Scorecard 6.3 / 10
6.3aggregate

Independent, tool-agnostic security assessment from the open-source OpenSSF Scorecard. Each check rewards a security practice, not a specific vendor's tool. Checks Scorecard could not determine are marked n/a and excluded from the security score (never counted as zero).Scorecard v5.5.0 · 2026-07-22 10:03 UTC

10Binary-Artifactsno binaries found in the repo
n/aBranch-Protectioninternal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
10CI-Tests26 out of 26 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/28 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
10Dangerous-Workflowno dangerous workflow patterns detected
10Dependency-Update-Toolupdate tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
10Packagingpackaging workflow detected
3Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 3
0SASTSAST tool is not run on all commits -- score normalized to 0
10Security-Policysecurity policy file detected
n/aSigned-Releasesno releases found
10Token-PermissionsGitHub workflow tokens follow principle of least privilege
0Vulnerabilities29 existing vulnerabilities detected
Direct dependencies 4
RegistryPackageVersion constraintManifest
PyPIpandas>=2.1.1,!=3.0.4pyproject.toml
PyPInumpy>=1.26.0pyproject.toml
PyPIscikit-learn>=1.3.1pyproject.toml
PyPIscipy>=1.10.0pyproject.toml
All dependencies not collected

The resolved dependency set could not be collected for this report: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Raw JSON report machine-readable
{
  "data": {
    "repo": {
      "topics": [
        "event-data",
        "opta",
        "pandas",
        "python",
        "soccer-analytics",
        "statsbomb",
        "vaep",
        "wyscout",
        "spadl",
        "football"
      ],
      "is_fork": false,
      "size_kb": 150977,
      "has_wiki": false,
      "homepage": null,
      "languages": {
        "Python": 6581315
      },
      "pushed_at": "2026-07-22T10:01:25Z",
      "created_at": "2026-04-06T12:02:43Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-22T05:57:48Z",
      "description": "Maintained fork of socceraction — SPADL event conversion + VAEP action valuation for soccer analytics",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "Python",
      "significant_languages": [
        "Python"
      ]
    },
    "owner": {
      "blog": null,
      "name": null,
      "type": "Organization",
      "login": "karsten-s-nielsen",
      "company": null,
      "location": null,
      "followers": 2,
      "avatar_url": "https://avatars.githubusercontent.com/u/265183875?v=4",
      "created_at": "2026-03-03T04:29:29Z",
      "is_verified": null,
      "public_repos": 11,
      "account_age_days": 141
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v4.55.1",
          "kind": "patch",
          "published_at": "2026-07-22T05:57:32Z"
        },
        {
          "tag": "v4.55.0",
          "kind": "minor",
          "published_at": "2026-07-21T21:08:59Z"
        },
        {
          "tag": "v4.54.0",
          "kind": "minor",
          "published_at": "2026-07-21T10:31:56Z"
        },
        {
          "tag": "v4.53.0",
          "kind": "minor",
          "published_at": "2026-07-19T17:52:34Z"
        },
        {
          "tag": "v4.52.0",
          "kind": "minor",
          "published_at": "2026-07-18T23:52:51Z"
        },
        {
          "tag": "v4.51.0",
          "kind": "minor",
          "published_at": "2026-07-18T02:49:32Z"
        },
        {
          "tag": "v4.50.0",
          "kind": "minor",
          "published_at": "2026-07-17T20:39:27Z"
        },
        {
          "tag": "v4.49.0",
          "kind": "minor",
          "published_at": "2026-07-17T03:57:36Z"
        },
        {
          "tag": "v4.48.1",
          "kind": "patch",
          "published_at": "2026-07-15T19:49:56Z"
        },
        {
          "tag": "v4.48.0",
          "kind": "minor",
          "published_at": "2026-07-15T11:14:37Z"
        },
        {
          "tag": "v4.47.0",
          "kind": "minor",
          "published_at": "2026-07-13T11:37:42Z"
        },
        {
          "tag": "v4.46.0",
          "kind": "minor",
          "published_at": "2026-07-12T16:49:38Z"
        },
        {
          "tag": "v4.45.0",
          "kind": "minor",
          "published_at": "2026-07-12T02:13:23Z"
        },
        {
          "tag": "v4.44.0",
          "kind": "minor",
          "published_at": "2026-07-11T20:10:55Z"
        },
        {
          "tag": "v4.43.0",
          "kind": "minor",
          "published_at": "2026-07-10T23:57:17Z"
        },
        {
          "tag": "v4.42.0",
          "kind": "minor",
          "published_at": "2026-07-10T16:11:12Z"
        },
        {
          "tag": "v4.41.0",
          "kind": "minor",
          "published_at": "2026-07-10T00:01:18Z"
        },
        {
          "tag": "v4.40.0",
          "kind": "minor",
          "published_at": "2026-07-09T17:05:17Z"
        },
        {
          "tag": "v4.39.0",
          "kind": "minor",
          "published_at": "2026-07-01T14:31:41Z"
        },
        {
          "tag": "v4.38.0",
          "kind": "minor",
          "published_at": "2026-07-01T03:36:43Z"
        },
        {
          "tag": "v4.37.0",
          "kind": "minor",
          "published_at": "2026-06-30T13:06:04Z"
        },
        {
          "tag": "v4.36.1",
          "kind": "patch",
          "published_at": "2026-06-29T13:10:05Z"
        },
        {
          "tag": "v4.36.0",
          "kind": "minor",
          "published_at": "2026-06-29T09:12:10Z"
        },
        {
          "tag": "v4.35.1",
          "kind": "patch",
          "published_at": "2026-06-29T08:53:59Z"
        },
        {
          "tag": "v4.35.0",
          "kind": "minor",
          "published_at": "2026-06-27T11:06:21Z"
        },
        {
          "tag": "v4.34.0",
          "kind": "minor",
          "published_at": "2026-06-19T17:01:18Z"
        },
        {
          "tag": "v4.33.0",
          "kind": "minor",
          "published_at": "2026-06-18T19:21:32Z"
        },
        {
          "tag": "v4.32.0",
          "kind": "minor",
          "published_at": "2026-06-17T03:04:20Z"
        },
        {
          "tag": "v4.31.0",
          "kind": "minor",
          "published_at": "2026-06-16T21:24:19Z"
        },
        {
          "tag": "v4.30.0",
          "kind": "minor",
          "published_at": "2026-06-16T19:05:59Z"
        },
        {
          "tag": "v4.29.0",
          "kind": "minor",
          "published_at": "2026-06-16T14:02:53Z"
        },
        {
          "tag": "v4.28.0",
          "kind": "minor",
          "published_at": "2026-06-16T00:16:27Z"
        },
        {
          "tag": "v4.27.1",
          "kind": "patch",
          "published_at": "2026-06-15T16:11:11Z"
        },
        {
          "tag": "v4.27.0",
          "kind": "minor",
          "published_at": "2026-06-13T20:57:45Z"
        },
        {
          "tag": "v4.26.0",
          "kind": "minor",
          "published_at": "2026-06-13T00:35:14Z"
        },
        {
          "tag": "v4.25.0",
          "kind": "minor",
          "published_at": "2026-06-11T22:10:34Z"
        },
        {
          "tag": "v4.24.0",
          "kind": "minor",
          "published_at": "2026-06-11T19:19:29Z"
        },
        {
          "tag": "v4.23.0",
          "kind": "minor",
          "published_at": "2026-06-11T16:59:31Z"
        },
        {
          "tag": "v4.22.2",
          "kind": "patch",
          "published_at": "2026-06-11T14:46:28Z"
        },
        {
          "tag": "v4.22.1",
          "kind": "patch",
          "published_at": "2026-06-11T11:27:29Z"
        },
        {
          "tag": "v4.22.0",
          "kind": "minor",
          "published_at": "2026-06-10T18:48:23Z"
        },
        {
          "tag": "v4.21.4",
          "kind": "patch",
          "published_at": "2026-06-10T15:40:39Z"
        },
        {
          "tag": "v4.21.3",
          "kind": "patch",
          "published_at": "2026-06-10T02:06:58Z"
        },
        {
          "tag": "v4.21.2",
          "kind": "patch",
          "published_at": "2026-06-09T23:55:38Z"
        },
        {
          "tag": "v4.21.1",
          "kind": "patch",
          "published_at": "2026-06-09T21:41:42Z"
        },
        {
          "tag": "v4.21.0",
          "kind": "minor",
          "published_at": "2026-06-09T20:25:04Z"
        },
        {
          "tag": "v4.20.1",
          "kind": "patch",
          "published_at": "2026-06-09T13:07:30Z"
        },
        {
          "tag": "v4.20.0",
          "kind": "minor",
          "published_at": "2026-06-08T22:30:45Z"
        },
        {
          "tag": "v4.19.2",
          "kind": "patch",
          "published_at": "2026-06-08T18:54:38Z"
        },
        {
          "tag": "v4.19.1",
          "kind": "patch",
          "published_at": "2026-06-08T16:24:12Z"
        },
        {
          "tag": "v4.19.0",
          "kind": "minor",
          "published_at": "2026-06-08T15:17:34Z"
        },
        {
          "tag": "v4.18.0",
          "kind": "minor",
          "published_at": "2026-06-08T10:49:43Z"
        },
        {
          "tag": "v4.17.0",
          "kind": "minor",
          "published_at": "2026-06-08T00:32:32Z"
        },
        {
          "tag": "v4.16.1",
          "kind": "patch",
          "published_at": "2026-06-07T19:55:23Z"
        },
        {
          "tag": "v4.16.0",
          "kind": "minor",
          "published_at": "2026-06-07T16:39:13Z"
        },
        {
          "tag": "v4.15.0",
          "kind": "minor",
          "published_at": "2026-06-07T02:36:04Z"
        },
        {
          "tag": "v4.14.0",
          "kind": "minor",
          "published_at": "2026-06-06T12:40:32Z"
        },
        {
          "tag": "v4.13.0",
          "kind": "minor",
          "published_at": "2026-06-04T23:29:53Z"
        },
        {
          "tag": "v4.12.2",
          "kind": "patch",
          "published_at": "2026-06-04T19:57:38Z"
        },
        {
          "tag": "v4.12.1",
          "kind": "patch",
          "published_at": "2026-06-04T18:46:57Z"
        },
        {
          "tag": "v4.12.0",
          "kind": "minor",
          "published_at": "2026-06-04T12:51:37Z"
        },
        {
          "tag": "v4.11.0",
          "kind": "minor",
          "published_at": "2026-06-03T21:45:30Z"
        },
        {
          "tag": "v4.10.0",
          "kind": "minor",
          "published_at": "2026-06-03T20:40:05Z"
        },
        {
          "tag": "v4.9.1",
          "kind": "patch",
          "published_at": "2026-06-03T14:31:54Z"
        },
        {
          "tag": "v4.9.0",
          "kind": "minor",
          "published_at": "2026-06-03T01:25:09Z"
        },
        {
          "tag": "v4.8.0",
          "kind": "minor",
          "published_at": "2026-06-02T19:38:46Z"
        },
        {
          "tag": "v4.7.0",
          "kind": "minor",
          "published_at": "2026-06-02T15:41:37Z"
        },
        {
          "tag": "v4.6.0",
          "kind": "minor",
          "published_at": "2026-06-02T13:24:13Z"
        },
        {
          "tag": "v4.5.0",
          "kind": "minor",
          "published_at": "2026-06-02T11:39:22Z"
        },
        {
          "tag": "v4.4.1",
          "kind": "patch",
          "published_at": "2026-06-02T04:16:04Z"
        },
        {
          "tag": "v4.4.0",
          "kind": "minor",
          "published_at": "2026-06-02T03:24:39Z"
        },
        {
          "tag": "v4.3.0",
          "kind": "minor",
          "published_at": "2026-06-02T01:44:16Z"
        },
        {
          "tag": "v4.2.0",
          "kind": "minor",
          "published_at": "2026-06-01T17:43:08Z"
        },
        {
          "tag": "v4.1.1",
          "kind": "patch",
          "published_at": "2026-06-01T11:24:45Z"
        },
        {
          "tag": "v4.1.0",
          "kind": "minor",
          "published_at": "2026-06-01T03:28:33Z"
        },
        {
          "tag": "v4.0.3",
          "kind": "patch",
          "published_at": "2026-05-31T01:39:07Z"
        },
        {
          "tag": "v4.0.2",
          "kind": "patch",
          "published_at": "2026-05-30T22:38:54Z"
        },
        {
          "tag": "v4.0.1",
          "kind": "patch",
          "published_at": "2026-05-30T21:41:08Z"
        },
        {
          "tag": "v4.0.0",
          "kind": "major",
          "published_at": "2026-05-30T19:44:32Z"
        },
        {
          "tag": "v3.30.0",
          "kind": "minor",
          "published_at": "2026-05-30T15:12:57Z"
        },
        {
          "tag": "v3.29.1",
          "kind": "patch",
          "published_at": "2026-05-30T13:49:20Z"
        },
        {
          "tag": "v3.29.0",
          "kind": "minor",
          "published_at": "2026-05-30T03:00:07Z"
        },
        {
          "tag": "v3.28.0",
          "kind": "minor",
          "published_at": "2026-05-29T21:54:23Z"
        },
        {
          "tag": "v3.27.0",
          "kind": "minor",
          "published_at": "2026-05-29T14:27:30Z"
        },
        {
          "tag": "v3.26.0",
          "kind": "minor",
          "published_at": "2026-05-29T11:14:34Z"
        },
        {
          "tag": "v3.25.1",
          "kind": "patch",
          "published_at": "2026-05-29T03:17:06Z"
        },
        {
          "tag": "v3.25.0",
          "kind": "minor",
          "published_at": "2026-05-28T23:37:21Z"
        },
        {
          "tag": "v3.24.0",
          "kind": "minor",
          "published_at": "2026-05-28T20:26:44Z"
        },
        {
          "tag": "v3.23.0",
          "kind": "minor",
          "published_at": "2026-05-27T15:35:36Z"
        },
        {
          "tag": "v3.22.2",
          "kind": "patch",
          "published_at": "2026-05-27T13:10:04Z"
        },
        {
          "tag": "v3.22.1",
          "kind": "patch",
          "published_at": "2026-05-27T11:50:03Z"
        },
        {
          "tag": "v3.22.0",
          "kind": "minor",
          "published_at": "2026-05-27T03:52:02Z"
        },
        {
          "tag": "v3.21.0",
          "kind": "minor",
          "published_at": "2026-05-27T03:34:50Z"
        },
        {
          "tag": "v3.20.1",
          "kind": "patch",
          "published_at": "2026-05-26T18:09:30Z"
        },
        {
          "tag": "v3.20.0",
          "kind": "minor",
          "published_at": "2026-05-26T15:44:13Z"
        },
        {
          "tag": "v3.19.0",
          "kind": "minor",
          "published_at": "2026-05-26T02:45:56Z"
        },
        {
          "tag": "v3.18.2",
          "kind": "patch",
          "published_at": "2026-05-25T15:18:33Z"
        },
        {
          "tag": "v3.18.1",
          "kind": "patch",
          "published_at": "2026-05-25T03:55:05Z"
        },
        {
          "tag": "v3.18.0",
          "kind": "minor",
          "published_at": "2026-05-24T01:29:27Z"
        },
        {
          "tag": "v3.17.0",
          "kind": "minor",
          "published_at": "2026-05-23T16:30:04Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "a58708beb8cbcd855f6449ba1ff7324cc65f49cc",
          "body": "…mposition + OAuth-native Databricks loader -- silly-kicks 4.55.1 (PR-S123) (#167)\n\nPitchControlSurface.player_share/.player_surface and _gk_influence's\ncompute_gk_influence/compute_zone_closing_times compared a caller-supplied\nplayer_id/gk_player_id scalar against the frame's id column with a raw =\n[…]\n, 0 failed; ruff/format/pyright clean; C4 unchanged (30).\n\nClaude-Session: https://claude.ai/code/session_01GHLeED1UusyqEw5LMpfxHS\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(tracking): ADR-019 dtype-safe id resolution in pitch-control deco…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-22T05:57:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ed20ac708f3ed9494a04527aaa5c27e6a49f2abb",
          "body": "…ction -- silly-kicks 4.55.0 (ADR-045, PR-S122) (#166)\n\nA 180-degree point reflection (ADR-028: x->105-x AND y->68-y for away\nactions) must point-reflect POINTS, negate VECTORS (vx/vy/dx/dy), leave\nMAGNITUDES (speed) unchanged, and swap DIRECTION LABELS. Every reflection\nhelper enumerated an explici\n[…]\nnd the fixture is pinned to match 10502 for determinism.\n\n\nClaude-Session: https://claude.ai/code/session_01GHLeED1UusyqEw5LMpfxHS\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(reflection)!: vector-quantity consistency under coordinate refle…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-21T21:08:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "34bb22f7c0f81f86cc5530e354f9b95fc73e5926",
          "body": "…nly (ADR-044)\n\n4.54.0's parameters-only strip fixed only the headline card claim (:82/:84). The\nserialization-format block and model-files table still described a 170 MB npz storing\n\"leaf assignments, training GK positions\", the variant sizes/counts (12 MB / 887k,\n170 MB) were stale, and the retire\n[…]\n pushed to the recreated\nsilly-kicks/ghost-gk-v1 Hub repo.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01UiMDcUssPB8JKuuuaGVMhY",
          "is_bot": false,
          "headline": "docs(hf): reconcile ghost-gk-v1 model card + org card to parameters-o…",
          "author_name": "Karsten Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-21T12:17:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7b14fc2a9f34e8e241b778da636c22bdc5587ab9",
          "body": "…ublic\") alias fix -- silly-kicks 4.54.0 (ADR-044, PR-S121) (#165)\n\nGhostGkModel.save() no longer persists the three per-sample training arrays (the raw\nper-frame goalkeeper positions of every training sample); distributed model artifacts\nnow carry learned parameters only. RFCDE density estimation n\n[…]\n.\n\nFull non-e2e suite green; pyright clean. See ADR-044.\n\n\nClaude-Session: https://claude.ai/code/session_01UiMDcUssPB8JKuuuaGVMhY\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking)!: ghost-GK parameters-only artifacts + from_variant(\"p…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-21T10:31:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "07f52fe4c6a159626a899837c2f433e70e89c7dc",
          "body": "…ramme -- silly-kicks 4.53.0 (ADR-043, PR-S120) (#162)\n\n* feat(tracking)!: TF-19 PR-3 gkdv physics arms + ADR-019 id-dtype programme -- silly-kicks 4.53.0 (ADR-043, PR-S120)\n\nShips TF-19 PR-3 (the gkdv package) and, alongside it, the ADR-019 id-dtype\nprogramme that PR-3's own review surfaced. Every \n[…]\ne Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GxEgY6oR1XcSMVE4uagitB\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking)!: TF-19 PR-3 gkdv physics arms + ADR-019 id-dtype prog…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-19T17:52:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1b56ad8cac457e469df10e7efe64d7d4d2816395",
          "body": "…est; HF-only is a redistribution limit\n\nThe cards published minutes earlier stated the opposite, under a section titled \"Why this\nvariant did NOT ship\". That was wrong, and it was wrong on a public page.\n\nRoot cause: I read the paired block out of the BUNDLED artifact and assumed it described\nsc_ex\n[…]\nt.\n\nNo version bump: docs-only, zero silly_kicks/ changes.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01HNhThauZPPBgBPakAsuGB5",
          "is_bot": false,
          "headline": "docs(hf): CORRECT the model cards -- sc_extended CLEARED its paired t…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-19T01:19:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "01ab5ea666ff648c129098fc1180fa41f36153e7",
          "body": "…orrect the now-false \"repos do not exist\" claims\n\nThe `sc_extended` -> `from_hub` routing shipped in 4.51.0 but the Hub repos were never\ncreated, so `from_variant(\"sc_extended\")` was unreachable for every consumer. Both repos are\nnow created and populated:\n\n  https://huggingface.co/silly-kicks/xsho\n[…]\nmp: docs-only, zero silly_kicks/ changes, post-4.52.0-tag.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01HNhThauZPPBgBPakAsuGB5",
          "is_bot": false,
          "headline": "docs(hf): publish sc_extended xS/xCross to the Hub -- model cards + c…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-19T01:13:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b88a2f7e6844ae3220e8e5dbc68302b074c83e2c",
          "body": "…5 off-ball run valuation -- silly-kicks 4.52.0 (ADR-041, ADR-042, PR-S119) (#161)\n\nPart A (ADR-041) -- the OBSO family had always multiplied pitch control by a SYNTHETIC\nplaceholder EPV (a linspace(0.01, 0.3) x-ramp). A real ExpectedThreat has shipped since\nSK-xT-1 and was never connected. add_obso\n[…]\nruff format, pyright 0 errors, 5041 passed / 66 skipped.\n\n\nClaude-Session: https://claude.ai/code/session_01HNhThauZPPBgBPakAsuGB5\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking)!: real-xT EPV wiring + five orientation repairs + TF-3…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-18T23:52:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ec543cc4d7c57debb108fc7c4156bd2bb9aa304a",
          "body": "…oad() enforcement + sc_extended HF routing -- silly-kicks 4.51.0 (ADR-040, PR-S118) (#160)\n\n* fix(tracking)!: TF-19 PR-2 -- corrected default weights + chirality load() enforcement + sc_extended HF routing -- silly-kicks 4.51.0 (ADR-040, PR-S118)\n\nThe bundled default xS / xCross / ghost-GK weights \n[…]\ne Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01TqpgWYzVXkRNY8tfTMooAQ\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(tracking)!: TF-19 PR-2 -- corrected default weights + chirality l…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-18T02:49:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a892d004ce0ac209f9f14afbe2d95b34e37d1c99",
          "body": "…-threat + secured reception + net variant -- silly-kicks 4.50.0 (ADR-039, PR-S117) (#159)\n\nShips the coach-facing packing surface over the frozen TF-45 LBS kernel:\nadd_packing (packing_made/net/goal_threat/receiver/secured), packing_xfns\n(numeric-only, opt-in), the public spadl.utils.resolve_next_t\n[…]\n5, 3.0]; dribble in-domain +\nsecured strictly interior).\n\n\nClaude-Session: https://claude.ai/code/session_01DPWWuhfXRqAAm1t4XVXS9V\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): TF-49 packing -- Impect-faithful bypass counts + goal…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-17T20:39:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0d11eed9358b01ceb19356efc7ee0e93c58c538c",
          "body": "…_type_ids, shared derive set untouched -- silly-kicks 4.49.0 (ADR-018 amendment, PR-S116) (#158)\n\nEvery GS OTB+BC carry shipped a placeholder end==start (verified 850/850\nzero-displacement on the live corpus): GS initializes end=start for every\nevent, never runs _add_dribbles, and the shared _DERIV\n[…]\n other seven providers.\nPrecursor to TF-49 packing (PR-S117). Also fixes the stale TODO release\nheader (was 4.47.0 through the 4.48.x releases).\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(spadl): GS dribbles derive real end coordinates -- GS-local extra…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-17T03:57:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "366359f96547d74a3309fa5815b9872901c5304d",
          "body": "…arm unblock -- Soccermatics Pro + Modern Soccer Coach ingestion plan\n\nFull ingestion of both course corpora (all transcripts/PDFs/notebooks) cross-referenced\nagainst 4.48.1, captured as a TODO-ready plan doc + a new flat On-Deck section\n'Course-derived candidates' (no tier -- the old Tiers 1-6 enco\n[…]\nng only). Also\ncommits the prior analysis-session handoff doc the plan supersedes. Planning only -- no\nlibrary code change, no retrain triggers.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(todo): course-derived candidates TF-49..TF-55 + TF-35 valuation-…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-17T01:29:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3930f03d7494626d73d39f35d97889e0c7c8a4eb",
          "body": "…state (\"alive\" not None) -- silly-kicks 4.48.1 (#157)\n\nThe native convert_to_frames builders (ADR-034) set `ball_state = None` for every frame. None is\nnot a valid ball_state (the schema value-set is {\"alive\",\"dead\"}) and makes the strict `== \"alive\"`\ndomain filter in xShotOccurrence (_xshot_occurr\n[…]\nr xS/xCross corpora that include SkillCorner or Metrica.\n\n\nClaude-Session: https://claude.ai/code/session_01TqpgWYzVXkRNY8tfTMooAQ\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(tracking): native SkillCorner/Metrica builders emit a valid ball_…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-15T19:49:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "97c74d5825d60a9d2fc7a4b8cadcd391166d3482",
          "body": "…axonomy + registered expanded-corpus retrain protocol -- silly-kicks 4.48.0 (ADR-038) (#156)\n\nThe pining API's SkillCorner listing grew 10 -> 108 matches. The 98 new ones are\nOWNER-TIER (visibility=\"private\", all Real Madrid LaLiga+UCL) -- they can only\nexpand the owner/full retrain arm (81->179), \n[…]\n `PUBLIC_CORPUS`'s SkillCorner ids to the\nsample loader.\n\n\nClaude-Session: https://claude.ai/code/session_01TqpgWYzVXkRNY8tfTMooAQ\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(skillcorner)!: native tracking route + visibility-keyed corpus t…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-15T11:14:37Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e33fca97b8adab20f9883ec8f0b4e2e2d71cd1f0",
          "body": "…blic causal/ + chirality fingerprints -- silly-kicks 4.47.0 (ADR-037, PR-S114) (#155)\n\nPR-1 of the TF-19 GKDV cycle (spec: docs/superpowers/specs/2026-07-12-tf19-gkdv-regate-and-v1-design.md,\ntriple-reviewed). No weights change here (retrains + load()-enforcement land in PR-2);\nno retrain trigger f\n[…]\nhost-GK save(); probe-sample provenance (provider+match ids) recorded.\n\n\nClaude-Session: https://claude.ai/code/session_01TqpgWYzVXkRNY8tfTMooAQ\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking,causal): TF-19 re-gate code -- registered xS probe + pu…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-13T11:37:42Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3837507dc5cd42d5f6dffa4b6882c419dd45cf0d",
          "body": "…% of its domain at a fabricated zone (ADR-036, PR-S113) (#154)\n\nflat_zones' NaN->0 mapping is a FIT-PATH contract (every fit seam dropna's), but the\nscoring seam _metric.py dropped nothing -- so a NaN coordinate was fabricated into grid\nzone 176 (the own-corner cell) and scored as a real number at \n[…]\n draft compared an all-zero surface to an all-zero surface).\n\nxT-GK v2 re-materialize trigger (opt-in; NOT a forced VAEP retrain).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(xtgk): resolved GK-distribution origins -- v2 no longer scores 24…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-12T16:49:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ca213a4283af3c5532629e5b5583b80c4f84a366",
          "body": "Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6.2.0 to 6.3.0.\n- [Release notes](https://github.com/actions/setup-python/releases)\n- [Commits](https://github.com/actions/setup-python/compare/a309ff8b426b58ec0e2a45f0f869d46889d02405...ece7cb06caefa5fff74198d8649806c4678c61\n[…]\nirect:production\n  update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "build(deps): bump actions/setup-python from 6.2.0 to 6.3.0 (#141)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-12T02:50:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7115949f64a11ded713e18174b52552e88b03ce2",
          "body": "…validated (honest) -- silly-kicks 4.45.0 (ADR-036, PR-S112) (#153)\n\nReplace the mirror geometric turnover proxy with the faithful observed-post-turnover\ncost (Jeff §2.3) and run the full out-of-sample validation of the xT-GK v2 metric.\nGoverned by the §3 honest-reporting guardrail: a-priori params \n[…]\nreads V) untouched, stays GO-leaning.\nC4 count stays 28.\n\n\nClaude-Session: https://claude.ai/code/session_011yincSJTWHYjAXZAQpBQRy\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(xtgk): faithful V_opp + full construct-validity -- xT-GK v2 not …",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-12T02:13:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "104828f129ae4587b59129bb5204f87e2b96d6c3",
          "body": "…er collapse + resolver hardening -- silly-kicks 4.44.0 (ADR-036, PR-S111) (#152)\n\nRetrain the rho retention default on the now-live broadened GK-distribution domain (GS AUC 0.781/\nECE 0.031, n=2923) and bundle a SkillCorner variant -- the broadened domain makes it viable\n(AUC 0.650/ECE 0.020, n=547\n[…]\ncompute_xt_gk_v2 serve output changes (xT-GK v2 opt-in).\n\n\nClaude-Session: https://claude.ai/code/session_011yincSJTWHYjAXZAQpBQRy\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(xtgk): retrain rho on broadened is_gk_distribution domain + load…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-11T20:10:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9afcb35025b6b7778a29c56fd1b384d2ff0b3795",
          "body": "…bution -- silly-kicks 4.43.0 (ADR-036, PR-S110) (#151)\n\nExport the GK-distribution domain as a stable, frame-optional tracking.gk_distribution_mask\n(native/robust lever); frozen v1 _gk_distribution_mask becomes a byte-identical shim over it.\nrho retention loader/trainer drop the shot-scoped gk_was_\n[…]\n read. Additive; no xt_gk/VAEP value change, no retrain.\n\n\nClaude-Session: https://claude.ai/code/session_011yincSJTWHYjAXZAQpBQRy\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): public gk_distribution_mask + rho loader is_gk_distri…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-10T23:57:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5cb35ffa31f8b06e45d9d10503dde4af31d2105d",
          "body": "…tric -- silly-kicks 4.42.0 (ADR-036, PR-S109) (#150)\n\nCompletes xT-GK v2 in one release: the four-term metric compute_xt_gk_v2 over three injected\nports (PossessionValue/RetentionModel/TurnoverCost), the make-or-break gate run on real data,\nand the marts-native rho retention model. v1 tracking/_xt_\n[…]\n4 regenerated. Full suite 4553 passed; pyright 0 errors.\n\n\nClaude-Session: https://claude.ai/code/session_011yincSJTWHYjAXZAQpBQRy\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(xtgk): complete xT-GK v2 -- gate (GO-leaning) + V_opp + rho + me…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-10T16:11:12Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fb90e70f1063824fff770e0ee977b67effb46b10",
          "body": "…ts -- silly-kicks 4.41.0 (ADR-036, PR-S108) (#149)\n\nIncrement on the 4.40.0 xT-GK v2 SP1 possession-value surface, resolving the two owner-only blockers\nagainst the live backend (spec rev 4 §5/§6). Additive; no production/xfn change; Phase 11 still\nwired-but-not-run (blocked on Q4 gate numbers only\n[…]\nill not run). ADR-036 amended. Version 4.40.0 -> 4.41.0.\n\n\nClaude-Session: https://claude.ai/code/session_01HpPkXARbkEQRDssYqvYktA\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(xtgk): G8 frame-aware null-pressure + Q3 reward provenance/repor…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-10T00:01:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b12f711210b0fecc45ed1c23edf1c8e5d4f40cbd",
          "body": "… silly-kicks 4.40.0 (ADR-036, PR-S107) (#148)\n\nNew hexagonal silly_kicks/xtgk/ package: the value function that replaces xT-GK v1's flat,\ndestination-only raw-xT surface. V(z,p) = expected xG the possessing team generates over the\nremainder of the possession, given the ball in 16x12 zone z under pr\n[…]\ntribution: Singh\n2018 (xT lineage), Eyestone (xT-GK v2).\n\n\nClaude-Session: https://claude.ai/code/session_01HpPkXARbkEQRDssYqvYktA\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(xtgk): honest possession-value surface V(z,p) -- xT-GK v2 SP1 --…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-09T17:05:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6ea5637629b9ba43ee2f44b4d96d0fdb53d9ae04",
          "body": "…ror of defending) -- silly-kicks 4.39.0 (TF-13, PR-S106) (#147)\n\nA public composable resolver -- the mirror of defending_gk_from_frames --\nreturning per action the ACTING team's goalkeeper player_id from tracking\nframes. Enables a downstream consumer to override a goal-kick's NULL taker with\nthe ke\n[…]\nng behavior changes; a pure player_id resolver that never\nmutates actions. Deciding WHEN to apply it (the goal-kick actor override) is the\nlakehouse's separate synthesis handoff, scoped to goal-kicks.",
          "is_bot": false,
          "headline": "feat(tracking): acting_gk_from_frames -- acting-team GK resolver (mir…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-01T14:31:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f60bd5d7bcc8bb4147af3931de4123f3fc75dc84",
          "body": "…er, not per-batch derive -- silly-kicks 4.38.0 (ADR-007, PR-S105) (#146)\n\nskillcorner.convert_to_frames discarded the clean native roster is_goalkeeper\nand re-derived it positionally via derive_goalkeepers on every call. Stable on a\nfull match, but on the lakehouse's 250-frame batches a transiently\n[…]\nion unchanged); xt_gk serve output changes for SkillCorner\n-> the lakehouse re-materializes. Follow-up: Metrica (no roster) is contaminated the\nsame way and needs derive-once-per-match, not per batch.",
          "is_bot": false,
          "headline": "fix(tracking): SkillCorner GK identification -- trust the native rost…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-07-01T03:36:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "66b61c440d2d1df15b2ed43fccb3b363c45f22a4",
          "body": "…ust, goal-kicks only) -- silly-kicks 4.37.0 (ADR-024, PR-S104) (#145)\n\nSkillCorner broadcast tracking records a goal-kick's native origin as the\nball-detection ~14-20 m downfield, not the keeper, corrupting xt_gk base/DZV\nand the keeper pressure/PEV. Make native-origin trust provider-aware (fail-sa\n[…]\nn (not a forced VAEP retrain), but the SkillCorner goal-kick serve\noutput changes -> the lakehouse re-materializes those rows. Goal-kick own-box\n57% -> 100% (SD 23.4 -> 0), 100% own-box home AND away.",
          "is_bot": false,
          "headline": "feat(tracking): SkillCorner keeper-origin resolution (broadcast distr…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-30T13:06:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "882eb36ac20301888a14ad76252d6388d51d903b",
          "body": "…duction-amplitude parity (handoff Items 2+4) -- silly-kicks 4.36.1 (PR-S103) (#144)\n\nTests + docs only; no library code change, no behaviour change to any xt_gk_*\nvalue. Released for external visibility.\n\nItem 4 -- golden hand-worked composite (TestGoldenComposite): a fully-controlled\nGK distributi\n[…]\nandoff Item 3's guard-test half remains open (separate).\n\n\nClaude-Session: https://claude.ai/code/session_018vueMBxDts2nTpcyzaeGkE\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(tracking): xT-GK pre-Jeff verification -- golden composite + pro…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-29T13:10:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8d43f145b3b4538a35f89e9798fa9db0ca049972",
          "body": "…s 4.36.0 (ADR-024, PR-S101) (#142)\n\nEmit the EXACT origin/destination coordinates the xT-GK grid lookups used, so\nevery xt_gk row is externally auditable (pre-Jeff-verification handoff,\n2026-06-29). `compute_xt_gk` adds four columns -- xt_gk_origin_x, xt_gk_origin_y,\nxt_gk_dest_x, xt_gk_dest_y -- p\n[…]\ncation. C4 count unchanged (28). Atomic mirror inherits.\n\n\nClaude-Session: https://claude.ai/code/session_018vueMBxDts2nTpcyzaeGkE\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): xT-GK resolved-coordinate audit columns -- silly-kick…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-29T09:12:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cbcec2128e3ef1b1aa07c693a8bff56ff8e54b0e",
          "body": "…y-kicks 4.35.1 (PR-S102) (#143)\n\npandas 3.0.4 segfaults (SIGSEGV / exit 139) in its C take_nd -> maybe_promote\npath when a whole-DataFrame boolean mask carries a datetime64 column. It is hit\non py3.11+ by spadl.orientation.detect_input_convention (the sportec actions\ncarry a datetime column), which\n[…]\nken pandas. To be reported upstream (pandas-dev/pandas).\n\n\nClaude-Session: https://claude.ai/code/session_018vueMBxDts2nTpcyzaeGkE\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(deps): exclude pandas 3.0.4 (C-layer segfault on py3.11+) -- sill…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-29T08:53:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3166cd2fb3b1a8608cd22ab565d6491dbccae64f",
          "body": "Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.3 to 7.0.0.\n- [Release notes](https://github.com/actions/checkout/releases)\n- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/actions/checkout/compare/df4cb1c069e1874edd31b43\n[…]\nirect:production\n  update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "build(deps): bump actions/checkout from 6.0.3 to 7.0.0 (#139)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-27T14:42:51Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f58feaee2d9c48eeb8e7ff8d3ab5838e2e2447fc",
          "body": "…-kicks 4.35.0 (ADR-024, PR-S100) (#140)\n\nBring xT-GK's PEV and DZV terms into fidelity with Eyestone's published\nframework (Q1-Q3 answered 2026-06-27). Option B (base = -xT*(origin), RAV sole\nowner of the destination) is unchanged.\n\nCHANGE 1 -- PEV reads the GK-revalued surface: progress = V_GK*(z'\n[…]\nreport. C4 count unchanged (28). Atomic mirror\ninherits.\n\n\nClaude-Session: https://claude.ai/code/session_018vueMBxDts2nTpcyzaeGkE\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking)!: xT-GK PEV/DZV fidelity fix (Eyestone Q1-Q3) -- silly…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-27T11:06:21Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "bbddb74e62e0e0bb4c2e47516ad777678fde360e",
          "body": "…ag on the native adapters -- silly-kicks 4.34.0 (ADR-035, PR-S99) (#138)\n\ngradientsports + sportec convert_to_frames now self-correct a wrong/absent home_team_start_left_extratime from goalkeeper geometry, via a shared direction.finalize_orientation tail that layers the idempotent orient_frames_to_\n[…]\n=200 chars with a guard test, and bump uv.lock to 4.34.0.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\nClaude-Session: https://claude.ai/code/session_01QFdK9axsg4JmktM4mU7Eze",
          "is_bot": false,
          "headline": "feat(tracking)!: geometric frame-LTR backstop self-corrects the ET fl…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-19T17:01:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cf7b29be68213c85ed5bcdd0d968190eb79c0df9",
          "body": "…urce the coordinate/orientation/clock truth -- silly-kicks 4.33.0 (ADR-034, PR-S98) (#137)\n\nAdds pure, bronze-consuming converters tracking.skillcorner.convert_to_frames /\ntracking.metrica.convert_to_frames (parallel to the native sportec/gradientsports\nadapters) that single-source the SkillCorner/\n[…]\nC4-free (new converters + a geometric orienter, not action-coupled aggregators;\ncount stays 28). Architecture diagram regenerated.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): SkillCorner + Metrica bronze→frame builders single-so…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-18T19:21:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e6db9f17d73a4977bcf9beb107eed3cdc59516f1",
          "body": "…n fix + pitch_control_at_target rename -- silly-kicks 4.32.0 (ADR-033, PR-S97) (#136)\n\nCloses the add_* in-place-mutation class repo-wide with an auto-enumerating\nno-mutation CI gate, fixes the motivating add_gk_distribution_metrics defect,\nrenames pitch_control_at_action -> pitch_control_at_target\n[…]\neaking, window-justified (no released consumer yet).\n\nVAEP/tracking: no retrain (fix is identity/order only; rename is name-only).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking)!: add_* input-purity CI gate + gk_distribution mutatio…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-17T03:04:20Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6df2b6469dbe2650dbb0146f4537726a33fe10f7",
          "body": "…lumn + ADR-028 reprojection -- silly-kicks 4.31.0 (ADR-032, PR-S96) (#135)\n\nThe informationally-dead `pitch_control_at_ball__<method>` (the Spearman PPCF at the ball is\nthe degenerate ~0.5 reaction-time fallback, so the column was ~0.5 for every well-linked\naction) is RETIRED and replaced by a live\n[…]\nolumn-lifecycle migration, atomic with\nthe pin bump (not a currency bump). C4-free (aggregator count stays 28). Decision: ADR-032.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking)!: pitch_control_at_target replaces the dead at-ball co…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-16T21:24:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9b0d37023936a2c81175a9f6bea02a7caf26c6d0",
          "body": "…ec parser -- silly-kicks 4.30.0 (ADR-031, PR-S95) (#134)\n\nNew `silly_kicks/providers/sportec/` package (behind a `[parse-dfl]` extra) single-sources\nthe IDSSE/Sportec DFL parser, eliminating the dev/prod parser drift and retiring the\ny-inverting loader-local kloppy `_kloppy_tracking_to_frames` from\n[…]\nstays 28); new C4 container providers.sportec.\nDecision: ADR-031 (T3). Gate D: the native sportec converter was already y-correct.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(providers)!: DFL parse+shape port single-sources the IDSSE/Sport…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-16T19:05:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "64f6e518f185f71a52b0a3da97147b0a6c468d61",
          "body": "…did not fire for 754d6dd)\n\nNo code change -- the merged tree (754d6dd) is byte-identical to the PR commit\nb470a279, which passed lint + all test legs. This empty commit re-fires the\non:push:main CI workflow, which GitHub did not create for the squash-merge.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: re-trigger main CI for the 4.29.0 merge (squash-merge push event …",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-16T14:13:30Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "754d6dda11093fd647041803f54af017d55774ff",
          "body": "…dinate system (y-inversion fix) -- silly-kicks 4.29.0 (ADR-031) (PR-S94) (#133)\n\nThe kloppy TRACKING gateway emitted frames y-mirrored vs SPADL actions\n(action_y == 68 - frame_y) for SkillCorner / Metrica / IDSSE-dev: the event\ngateway pinned the canonical _SoccerActionCoordinateSystem, the trackin\n[…]\nse-port single-sourcing (T3) follows in PR-S95.\n\nRetrain trigger: VAEP + tracking CALIBRATION consumers for SkillCorner + Metrica.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(tracking,spadl)!: kloppy tracking gateway pins the canonical coor…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-16T14:02:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7734ed46e05a8ecac9bcab3abb6ed90ee67f0cc3",
          "body": "…t+full-corpus-validated lakehouse-PSxG feed -- silly-kicks 4.28.0 (ADR-030) (PR-S93) (#132)\n\nadd_shot_goalmouth derives the goal-plane crossing (y/z), shot kinematics, and\nprovenance from the post-contact ball trajectory in tracking frames, per shot\naction. Pure geometry, no model; the lakehouse sc\n[…]\ny_tracking_y_inverted.md + TODO). TF-48's kernel\nis provider-agnostic: a coordinate-fix smoke-test lifts SC resolution 0.12->0.60.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): TF-48 post-shot goalmouth crossing geometry -- holdou…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-16T00:16:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "53c24fae955511d023b641eea5915295a9b7a9b9",
          "body": "… 4.27.1 (#131)\n\nDocumentation-only release. No library/package code, schema, or behavior\nchange; the silly_kicks package is byte-identical to 4.27.0.\n\nADR reconciliation: verified all 29 ADRs against the current tree (25 clean,\nno behavioral drift). Corrected stale prose in 5 living ADRs:\n- ADR-004\n[…]\nkquote render bug).\n\nVersion bump 4.27.0 -> 4.27.1 across pyproject.toml, silly_kicks/__init__.py,\nCHANGELOG.md, TODO.md, uv.lock.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: ADR-code reconciliation sweep + TODO header trim -- silly-kicks…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-15T16:11:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e261c0d174f8d0ff8d789f4289666ff3dd8e1be5",
          "body": "…tract -- silly-kicks 4.27.0 (ADR-029) (#130)\n\nAdd public silly_kicks.tracking.orient_frames_to_ltr(frames, *, home_team_id,\nhome_team_start_left, home_team_start_left_extratime=None): orients UNLABELED\nabsolute tracking frames into the canonical home-attacks-right (LTR) frame. Pure\ncomposition of c\n[…]\n_left_extratime\nplaceholder bug, not a silly-kicks bug.\n\nDecision: ADR-029. Bumps to 4.27.0; C4 consumer-contracts clause + regen.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): orient_frames_to_ltr single-sources the frame-LTR con…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-13T20:57:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9241c1397ecbfc71617e9cccea61f968792192d1",
          "body": "…ame -- silly-kicks 4.26.0 (ADR-028) (#129)\n\n* fix(tracking)!: emit tracking geometry in the per-action SPADL LTR frame -- silly-kicks 4.26.0 (ADR-028)\n\nSystemic orientation bug (luxury-lakehouse report). SPADL actions are per-acting-team\nLTR (acting team attacks x=105); convert_to_frames is home-at\n[…]\nBOTH 3.10\n(pandas 2.3.3) and 3.12 (pandas 3.0.3).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(tracking)!: emit tracking geometry in the per-action SPADL LTR fr…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-13T00:35:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "40afd4a30d536cdd79923f8f2ea6ff08ec5580bc",
          "body": "…d (was sentinel 0) -- 4.25.0 (ADR-027) (#128)\n\n* fix(spadl)!: GS null-actor duel/foul events emit NaN team_id/player_id (was sentinel 0); fix masked ward NaN-crash + ADR-019 dtype miscompute -- silly-kicks 4.25.0 (ADR-027)\n\nThe Gradient Sports converter emitted the int sentinel 0 as team_id/player_\n[…]\nint leg's ruff format --check failure on PR #128.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(spadl)!: GS null-actor duel/foul events emit NaN team_id/player_i…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-11T22:10:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b2902e9687bf0004a66b8f13f80ab115e9ba296e",
          "body": "…-41 round-2 -- silly-kicks 4.24.0 (#127)\n\nLakehouse round-2 rejection, confirmed algebraically + empirically:\nunder a complementary PC model with a SHARED UNMIRRORED multiplier,\nopp_obso = (1-pc)*M is fully determined by pc*M, so the 4.23.0 opponent\nLOO was the exact pointwise negation of the team \n[…]\nuperseded,\nfinal adoption column list: space_created_m2, space_denied_m2_opponent.\nNot a VAEP retrain trigger (xfns opt-in, in no default list).\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(tracking)!: mirrored opponent OBSO + lean 2-column contract -- TF…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-11T19:19:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0e8e1a6ecc33fc595c7efbba1463973a279af9cc",
          "body": "… full-tree gate -- silly-kicks 4.23.0 (#126)\n\n* feat(tracking): implement space-creation *_opponent triplet + pyright gates tests/+scripts -- silly-kicks 4.23.0\n\nLakehouse REJECTED 4.22.2's removal of the space-creation opponent\ncolumns and mandated implementation (option 1 of the original report).\n[…]\nas complete -- no other locally-installed-but-\nCI-absent package is imported.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): implement space-creation *_opponent triplet + pyright…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-11T16:59:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6078d6b7a44253f812473195f800ba41dfd603d8",
          "body": "… contract -- silly-kicks 4.22.2 (#125)\n\nLakehouse bug report 2026-06-11: space_created_m2_opponent /\nspace_destroyed_m2_opponent / net_space_m2_opponent were hard-coded\nnp.nan on every code path since introduction (3.21.0, PR-S57) --\n100%-NULL across all four tracking providers in production. The T\n[…]\nes change, nothing\n  re-materializes; lakehouse drops the dead bronze columns on adoption.\n  Not a VAEP retrain trigger (xfns output unchanged).\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(tracking): remove dead *_opponent triplet from add_space_creation…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-11T14:46:28Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "343ce80cd1ff06fa3aeb24f1f5c09346e34b5d05",
          "body": "…ompletion-variant alias -- silly-kicks 4.22.1 (#124)\n\nFour fixes from the lakehouse 4.22.0 production report (2026-06-11); the two\nsuspected value bugs (xt_gk_pev ~always 0; obso_peak > obso_optimal) were\nverified by-design and documented instead:\n\n- compute_ghost_gk: clamp served ghost_gk_x/y (goa\n[…]\nominate actual_obso.\n\nVerification: full non-e2e suite 4054 passed / 0 failed; ghost-GK goldens\nbyte-unchanged; ruff + pyright (CI scope) clean.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(tracking): lakehouse-report hardening -- ghost-GK pitch clamp + c…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-11T11:27:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "12491ddb9df3bf5daedf7eed811257f88495bd20",
          "body": "…) -- silly-kicks 4.22.0 (ADR-025) (#123)\n\nadd_restart_coordinates imputes NaN restart coords (goalkick/penalty/corner/throw-in)\nas NEW provenance-tagged columns; canonical start_x/end_x untouched -> no retrain.\nresolve_gk_geometry consolidated to a byte-identical shim over the general engine\nresolv\n[…]\nobe (NaN coords are a GS set-piece phenomenon).\nOwner-gated GS e2e validates real WC2022. Canonical promotion deferred to Phase 2.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(spadl): general restart-coordinate enrichment (Phase 1, additive…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-10T18:48:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7e875c8b4239a40b77d975da912f4f3bad4a1f72",
          "body": "…ks) -- silly-kicks 4.21.4 (ADR-024) (#122)\n\ncompute_xt_gk now serves the per-type calibrated base rate (tagged\nxt_gk_completion_source = \"base_rate\") instead of the geometric model for any\ncompletion sub-domain whose held-out AUC lower-confidence-bound <= 0.5 (or\ndegenerate / below a minimum sample\n[…]\n.dsl/.html regenerated; no new aggregator/model/backend\n(action-coupled aggregator count verified == 27 against tracking.__all__).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): SK-91 xT-GK per-type base-rate serve switch (goal-kic…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-10T15:40:39Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7887639b4d104ef7cfeea5995c46b3c47d2cdaaa",
          "body": "…ligned) -- silly-kicks 4.21.3 (#121)\n\nNative sportec pass/set-piece completion now uses a guarded success-ALLOWLIST\ninstead of an exact `== \"unsuccessful\"` match: `fail` iff the DFL `Evaluation` is\nnon-empty AND not in {successfullyCompleted, successful}. So any unseen reason-coded\nfailure token (e\n[…]\nkloppy gateway), native-shape fixture (not kloppy XML), dependency-light e2e (no\ntracking/xgboost import), red-first TDD ordering.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(spadl): SK-90 sportec play_evaluation success-allowlist (kloppy-a…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-10T02:06:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "204de088ed3f091e2cf793ddccf2e31b322407b9",
          "body": "…ripwire -- silly-kicks 4.21.2 (ADR-021) (#120)\n\nMakes the SK-xT-1 KDE-vs-Singh held-out transition-NLL triangulation a permanent,\nowner-gated @pytest.mark.e2e regression tripwire against the real\nsoccer_analytics.dev_gold.fct_action_values gold mart (the 4.17.0 work ran it as a\nnon-committed one-of\n[…]\ny_kicks/\nwheel is unchanged except __version__. Additive, no behavior change, no retrain trigger.\nTODO SK-xT-1 follow-up; ADR-021.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(xthreat): owner-gated lakehouse-mart KDE-vs-Singh held-out-NLL t…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-09T23:55:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2e913f097f2c1f47e4fe115d1de2cfc451328695",
          "body": "…dapter orientation seams -- silly-kicks 4.21.1 (ADR-019) (#119)\n\nNarrow ALLOW_MODULES from {_id_compat,sportec,gradientsports,kloppy} to {_id_compat}\nso every tracking module -- converter adapters included -- has its id comparisons\nunder the boundary lint. The blanket adapter file-skip is what let \n[…]\n == {_id_compat.py}.\n\nADR-019 amendment. No behavior change, no retrain trigger (BUG-4 fix shipped 4.20.1;\nthis guards the class).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(tracking): SK-89 extend ADR-019 boundary lint to all converter-a…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-09T21:41:42Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3747fb645d951a620b049bd69e53600ce996538d",
          "body": "Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.2 to 6.0.3.\n- [Release notes](https://github.com/actions/checkout/releases)\n- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/actions/checkout/compare/de0fac2e4500dabe0009e67\n[…]\nirect:production\n  update-type: version-update:semver-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "build(deps): bump actions/checkout from 6.0.2 to 6.0.3 (#111)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-09T21:01:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e3d5e9247afc8bb1f8a732544fb577659ce9716b",
          "body": "…letion variant -- silly-kicks 4.21.0 (ADR-024) (#118)\n\n* feat(tracking,spadl): xT-GK (Eyestone) + goal-kick coverage + SkillCorner native-completion variant -- silly-kicks 4.21.0 (ADR-024)\n\nxT-GK (Expected Threat for Goalkeepers, Jeffrey Eyestone, PtP-1) shipped publicly\nwith attribution: a pure pa\n[…]\n Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n* style(tests): ruff format test_gk_completion.py -- CI lint fix\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: xT-GK (Eyestone) + goal-kick coverage + SkillCorner native-comp…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-09T20:25:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c2e9d65b4d6f60cc557da0e20693526f5561c0e9",
          "body": "…ase + goalkick, sportec pass completion, SGM bound -- silly-kicks 4.20.1 (#117)\n\nThree independent data-quality defects found while validating GK-distribution\ncompletion cross-provider (corroborated against the lakehouse bronze). The\nSkillCorner and sportec fixes change VAEP/tracking label distribu\n[…]\n per-provider result models). C4 unaffected (no new aggregator / model / backend).\nFull non-e2e suite green; ruff + pyright clean.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(spadl,tracking): provider data-quality bugs -- SkillCorner time-b…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-09T13:07:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0e9426b0dc021c202096055f94163166c6428eee",
          "body": "…ized gaussian KDE core + pining download caching -- silly-kicks 4.20.0 (PR-S87, ADR-009, ADR-021) (#116)\n\nOptuna sweep over KDEParams.bandwidth x GridSpec resolution x adaptive minimizing K-fold held-out xT transition-NLL; Singh baseline + a reported Spearman-vs-goals cross-check; recommends KDEPar\n[…]\nSingh correlating better with goals at every size (NLL-best != xT-optimal). 4 real multi-provider bugs caught + regression-tested.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(calibration): SK-xT-3 xT bandwidth/resolution NLL sweep + vector…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-08T22:30:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "bfbe5cc8e5153d2a9d40f8123a193ccb627c2f62",
          "body": "… (ADR-023) (#115)\n\n* ci: surface CI test durations to choose the slow-test gating set (measurement push) -- SK CI-1 (spec+plan)\n\nPhase 0 of the CI-time reduction (spec/plan bundled). Adds --durations=0 to the bulk\ntest step so the draft PR's CI run logs the full per-test distribution; the windows-3\n[…]\nM-killed the runners before).\n\nDecision: ADR-023.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: slow-test gating -> primary-leg heavy tests -- silly-kicks 4.19.2…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-08T18:54:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d23a35264491ad1da6d0d45d8610a4ed04df0ae7",
          "body": "… -- silly-kicks 4.19.1 (PR-S86, ADR-007) (#114)\n\nUpgrade derive_goalkeepers SkillCorner validation from Tier-2 (algorithm\nself-consistency) to Tier-1 (external match.json roster ground truth) via an\nowner-runnable e2e: 20/20 team-GKs across the 10 public A-League matches,\nexact-set-equality gate (c\n[…]\nCLAUDE.md record SkillCorner Tier-1; Metrica remains a\ndocumented permanent Tier-2 limitation (anonymized public data, no roster).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(tracking): TF-27 SkillCorner derived-GK Tier-1 roster validation…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-08T16:24:12Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e12d6cbd5fe5184047ab76760ec53afd459b0fa6",
          "body": "…ExpectedThreat, opt-in, atomic mirror) -- silly-kicks 4.19.0 (ADR-022) (#113)\n\nWire a fitted ExpectedThreat into the VAEP feature framework as a frame-free,\nopt-in feature transformer (ADR-005 section 8 <feature>__<method> naming). Standard\n`vaep.features.xt_xfns(*, model)` + atomic mirror `atomic.\n[…]\nguard.\n\nFull non-e2e suite green (3792 passed); ruff + pyright clean. C4 regenerated.\nDecision: ADR-022; attribution Singh (2018).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(vaep): SK-xT-2 xt__<method> VAEP feature factory (caller-frozen …",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-08T15:17:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7f58cbe46ae70bee24e2c89e438f2e2d7c1f55d4",
          "body": "…on harness -- silly-kicks 4.18.0 (PR-S85, ADR-011, ADR-015) (#112)\n\nCloses TF-17 (xCross, GKDV Layer 2) with the PR-B weights cycle and the\nPR-C causal arm, shipped together.\n\nPR-B -- trained weights + GK validation:\n- Bundle the public xCrossAttempt model (skillcorner+idsse), trained on the\n  clea\n[…]\n_data.\n\nMerge origin/main: 4.17.0 (SK-xT-1) + 4.16.1 (sportec play_flat_cross). TODO\ngrooming: drop the now-empty Tier 5 scaffold.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): TF-17 xCrossAttempt trained weights + causal validati…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-08T10:49:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0f5c5dbc2bd41104461d73289015ca15c923b1f9",
          "body": "…+ held-out NLL) -- silly-kicks 4.17.0 (ADR-021) (#110)\n\n* feat(xthreat): SK-xT-1 pluggable, evaluatable xT (Singh facade + KDE flavor + held-out NLL) -- silly-kicks 4.17.0 (ADR-021)\n\nRefactor silly_kicks/xthreat.py into a silly_kicks/xthreat/ package with a house-style\npluggable transition family (\n[…]\ns 4.8 (1M context) <noreply@anthropic.com>\n\n* docs(todo): track SK-xT-1 follow-ups + TF-47 KNN/conditional xT (ADR-021)\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(xthreat): SK-xT-1 pluggable, evaluatable xT (Singh facade + KDE …",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-08T00:32:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d12c55254a518e4be5d79bbee125d50df51c537c",
          "body": "… of DFL passes as crosses -- silly-kicks 4.16.1 (#109)\n\nDFL bronze emits the play_flat_cross qualifier as the native string \"true\"/\"false\".\nThe old _opt(\"play_flat_cross\", False).fillna(False).astype(bool) coercion maps any\nnon-empty string -- including the literal \"false\" -- to True, so every pass\n[…]\n) pass-vs-cross labels change for all event data --\na SPADL re-conversion + downstream VAEP retrain trigger for Sportec consumers.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(spadl): Sportec play_flat_cross string qualifier mislabelled ~99%…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-07T19:55:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "da23a3f9487dfc5fd283387906f1f0c03d910a25",
          "body": "…emic xfns dup-action_id fix -- silly-kicks 4.16.0 (ADR-005, ADR-020) (#108)\n\nTF-45 (arXiv:2603.28916, Karakus & Arkadas 2026): per-pass structural primitives\nquantifying how a pass deforms the opponent's defensive structure.\n\n- _structural_pass.py: pure pandas-free _structural_pass_core (LBS = Line\n[…]\nrom tracking.__all__;\naligns ghost-GK with every other tracking feature and corrects the C4\naction-coupled-aggregator count to 25.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): TF-45 structural-pass primitives (LBS/SGM/SDI) + syst…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-07T16:39:13Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "84f6faf529abe5d9fa9fd6cd24c442a829ba7f40",
          "body": "…R-016) (#107)\n\nThe standalone \"Ghost-GK-mode train/serve kde_backend guard\" TODO item is\nobsoleted by ADR-016 (4.14.0): compute_ghost_gk/add_ghost_gk/ghost_gk_xfns\nnow write predict_mean() (the deterministic, kde_backend-free boosted HGBR\nposition) into ghost_gk_x/y, not the KDE mode. The <=6 m NGP\n[…]\nrecord is otherwise left frozen).\n\nTF-16 (xS) and TF-17 (xCross) never bound this guard (both train on the\nresolved/defending GK).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: retire obsolete ghost-GK kde_backend train/serve guard TODO (AD…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-07T04:39:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0b56254ad395f8fcd0b7f60df7c2e7802fe6465d",
          "body": "…_dtypes -- 4.15.0 (ADR-019) (#106)\n\n* feat(tracking): dtype-safe id contract at feature seams + validate_id_dtypes -- silly-kicks 4.15.0 (ADR-019)\n\nTracking-feature consumers compared SPADL-action ids vs frame ids (and the scalar\nhome_team_id) and merged action<->frame on id keys with raw ==/!=. Th\n[…]\nd (bulk) + 20 benchmark measurements; ruff clean.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): dtype-safe id contract at feature seams + validate_id…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-07T02:36:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "576b867fae3985acabc8e051cd61c89c2b7a0d69",
          "body": "…le-free) -- silly-kicks 4.14.0 (PR-S83, ADR-016) (#105)\n\nCloses a pre-existing integrity gap: compute_ghost_gk served the KDE mode\n(~4.65 m held-out MAE) while the model card reported ~1.1 m for predict_mean,\nan estimator that save()/load() discarded (so it was never actually served).\n\nServe the ex\n[…]\n than the mode).\n\nDecision: ADR-016 (numpy reconstruction over skops/treelite/ONNX -- no\nsklearn-at-inference, no new dependency).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): Ghost-GK serves exact boosted HGBR predict_mean (pick…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-06T12:40:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2576b4da2f6458110affe3c7ea86764052eec1f0",
          "body": "PDF + LinkedIn research audit (2026-06-05): record actionable leads and\ntidy attribution. No code, tests, or config changed.\n\n- TODO.md: add TF-45 (structural-pass primitives LBS/SGM/SDI,\n  arXiv:2603.28916, Tier 5); add TF-46 (corner defensive-role inference\n  + role-conditioned ghosting, arXiv:260\n[…]\n + match-grouped CV + HybridVAEP.\n- ADR-011: add a temporal-leakage-discipline validation note\n  (Peters et al. 2026) + reference.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: research-audit TODO/NOTICE/ADR updates (#104)",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-05T21:41:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "110747491ad08e53f1e87845c9f82fce85f49e4a",
          "body": "…xclusion + own-goal VAEP labels -- silly-kicks 4.13.0 (ADR-018) (#103)\n\nCompletes the Gradient Sports / PFF FC goal-capture work begun in 4.12.2 (which removed the false\nshot_outcome_type==\"O\" -> owngoal mapping). Empirically grounded in the full WC2022 catalog (64\nmatches, 144,541 events); owner-g\n[…]\n-06-04-gs-goal-capture-design.md; plan\ndocs/superpowers/plans/2026-06-04-gs-goal-capture.md (two-round cross-session review each).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(spadl,vaep): Gradient Sports own/cross-goal capture + nonEvent e…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-04T23:29:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6c0f654d9a45d0849549b852eafe8e55e69853c0",
          "body": "…illy-kicks 4.12.2 (#102)\n\nThe Gradient Sports / PFF FC converter mapped shot shot_outcome_type == \"O\" to\nthe SPADL `owngoal` result. \"O\" is in fact the OFF-TARGET shot bucket (alongside\nS=saved, B=blocked); the four main shot outcomes are G=goal / S=saved /\nO=off-target / B=blocked, and only \"G\" is\n[…]\nlean.\n\nAlso corrects the converter design spec's shot-result mapping table (the table\nthe converter docstring points to) to match.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(spadl): Gradient Sports shot \"O\" is off-target, not own-goal -- s…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-04T19:57:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "dd685c04a46a291ffae44ad68fa5fc30f540b9b4",
          "body": "… one frame -- silly-kicks 4.12.1 (#101)\n\ncompute_ghost_gk (hence add_ghost_gk / ghost_gk_xfns + atomic mirror) raised\n\"ValueError: Must have equal len keys and value when setting with an iterable\"\nfor any frame with two or more is_goalkeeper=True rows sharing a team_id.\nReported by luxury-lakehouse\n[…]\nlso fixes stale ADR-017 status drift on main (\"pending implementation\" ->\n\"implemented in silly-kicks 4.12.0\", which has shipped).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(tracking): compute_ghost_gk crash on >=2 same-team goalkeepers in…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-04T18:46:57Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "915099b279e463bb01deab0d3e6dfb44d827fcec",
          "body": "…nk-coverage guard -- silly-kicks 4.12.0 (ADR-017) (#100)\n\nDocuments and enforces silly-kicks' canonical period-relative time_seconds\nconvention (resets to 0 each period -- NOT absolute match-clock), and makes a\nlow action-frame link-coverage outcome loud. Resolves the GradientSports\nperiod-2 silent\n[…]\ns Law: warn-by-default changes observable behavior for callers under\n-W error on genuinely-degraded matches (intended shift-left).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): period-relative time_seconds contract + per-period li…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-04T12:51:37Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3decc02dcbe1b3ad95f781f4db22b524347110c4",
          "body": "…) -- silly-kicks 4.11.0 (PR-A) (#99)\n\nGKDV Layer 2 cross analogue of xShotOccurrence (TF-16). A per-frame, STATE-anchored\nsurface = P(the in-possession team attempts a cross within ~1 s), reframed from the\nCao et al. (arXiv:2505.11841) sender-level event treatment. Realizes 7 of the paper's\n8 confo\n[…]\nNOTICE entry for arXiv:2505.11841.\nC4 + CLAUDE.md + TODO updated. Lands on main 4.10.0 (PR-S81 ghost-gk re-fit); bumped to 4.11.0.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): TF-17 xCrossAttempt propensity model (code, untrained…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-03T21:45:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cad9b16b16c3957c095c617c7cc191303d3ff0a6",
          "body": "…po + sdist exclude -- silly-kicks 4.10.0 (#98)\n\nThe 4.10.0 PyPI publish failed: the source distribution (105 MB) exceeded PyPI's 100 MB per-file limit. The ~91 MB `full` Ghost-GK weights were excluded only from the wheel target (each hatch target has its own include/exclude set), and the larger re-\n[…]\nheel exclude. Code unchanged; version stays 4.10.0 (the failed publish never reached PyPI). sdist 105 MB -> 27 MB; wheel 12.65 MB.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(packaging): remove Hub-distributed full/ Ghost-GK weights from re…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-03T20:40:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d96accd5beff1c09ec84b7122b02b25f4ec1e0f1",
          "body": "… 4.7.0 re-fit -- silly-kicks 4.10.0 (PR-S81) (#97)\n\nFix the Ghost-GK serve/train skew: compute_ghost_gk now resolves the ball-carrier on the FULL frames (with the model's recorded carrier_params) so team_in_possession matches training -- previously serve passed no carrier, leaving it hardcoded 0.0 \n[…]\nan CV 1.12 vs 1.14 m) -- shipped for carrier-regime alignment + R3 provenance. KDE golden regenerated for the new bundled default.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(ghost-gk): serve-carrier fix + R3 carrier-param record/consume +…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-03T19:34:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9bb194f801d9851039627986d9754685b743c5c3",
          "body": "…s hardening -- silly-kicks 4.9.1 (#96)\n\nFixes a downstream lakehouse crash (Gradient Sports match 10502): a frame subset with no frame containing both the ball and players collapsed accessible-space to F==0, returning None / tripping a matrix-consistency assertion that was dereferenced unguarded (A\n[…]\nnical _prepare_frames and coerces the pass identifier columns too.\n\n9 regression tests (bite deterministically pre-fix). Version 4.9.1. CI green across lint + 3.10/3.11/3.12 (ubuntu) + 3.12 (windows).",
          "is_bot": false,
          "headline": "fix(tracking): guard DAS/xC zero-frame subset -> NaN + pyarrow-string…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-03T14:31:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "655031479d5eac5553161c22807b25de91654f63",
          "body": "…) -- silly-kicks 4.9.0 (PR-S80) (#95)\n\nTrain + bundle + turn on the xS shot-occurrence model (PR-S75 shipped it untrained).\nTrained on 81 matches (DGX Spark) vs the 4.7.0 carrier defaults; a pre-registered\npublic-vs-full two-candidate test found owner-tier Gradient Sports data degraded\npublic-held-\n[…]\nms/geometry/platform (TF-38 template); load fails\n  closed on pitch-dim mismatch. publish_xshot_occurrence.py; pyarrow in [train].\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): TF-16 xShotOccurrence trained weights (public variant…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-03T01:25:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f6dd43e7e3c9ac21669b041f34f83059f1267b92",
          "body": "…multimodal mode flips vs NGP, tighter raw grid; correct ADR-014 mode-fidelity claim -- silly-kicks 4.8.0 (#94)\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(ghost-gk): add CIC (bilinear) kde_backend=fft-cic -- ~76% fewer …",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-02T19:38:46Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b12b9a1ecf5b31d5e05121d0e4f9a572da26cf7e",
          "body": "…0, gamma 1.0->0.25) -- silly-kicks 4.7.0 (PR-S79) (#93)\n\nApplies the TF-24 calibration. infer_ball_carrier + ball_carrier_at_action defaults:\n  beta  0.5 -> 0.0   (velocity-toward-ball weighting did not help carrier-actor\n                      accuracy; selection is now purely distance-based)\n  gam\n[…]\nggered (no cross-provider aggregation-form signal).\n\nVersion 4.6.0 -> 4.7.0 (minor: carrier behavior change). uv.lock regenerated.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): apply TF-24 calibrated carrier defaults (beta 0.5->0.…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-02T15:41:37Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "37eca041bd0506039857777d5c53fd0e282a9e72",
          "body": "…-- silly-kicks 4.6.0 (#92)\n\nAdds opt-in kde_backend=\"fft\" (NGP binned-convolution, scipy.signal.fftconvolve, O(k + m log m), ~2355x on the full-k regime). Reuses _kde_setup; no new dep; default stays vectorized. Scalar-faithful (mode/mean/spread) but NOT bit-faithful on the raw probabilities grid -> opt-in (raw-grid consumers keep vectorized; TF-19 is the first such consumer). ADR-014 (+ CIC fft-cic escalation note). 3309 non-e2e pass.",
          "is_bot": false,
          "headline": "feat(ghost-gk): fft KDE backend (binned-convolution, ~2000x, opt-in) …",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-02T13:24:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a387bb078837bf69672221ce782cdf9860895485",
          "body": "…ive (~100x sweep) + cacheable infer_ball_carrier -- silly-kicks 4.5.0 (PR-S78) (#91)\n\nThe TF-24 Stage-1 sweep was pandas-bound, not numba-bound: profiling showed\n_pre_index_frames (long-form frames -> dense per-frame numpy arrays) is ~99%\nof carrier-inference cost, and the objective re-ran it (plus\n[…]\nched.\n\nVersion 4.4.1 -> 4.5.0 (minor: additive public kwargs on infer_ball_carrier /\nball_carrier_at_action). uv.lock regenerated.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "perf(calibration): invariant-prepare cache for Stage-1 carrier object…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-02T11:39:22Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5959bcd62a8f0099ae260271380d6da3c4687b66",
          "body": "… did change values -- silly-kicks 4.4.1 (#90)\n\nDAS changed in 4.2.0 (carrier offside-exemption) -- a correctness fix, not a regression; the 4.2.0 'value-neutral' claim was wrong (onside-only test). Test rename + offside-path regression-lock; CHANGELOG [4.4.1]; ADR-012 amended. No runtime change. Downstream: re-baseline DAS goldens frozen under <=4.1.1.",
          "is_bot": false,
          "headline": "fix(das): correct the 4.2.0 \"value-neutral\" record -- DAS offside fix…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-02T04:16:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c1f242de50c812b20aec3cca035eaf8935877473",
          "body": "Updates the requirements on [xgboost](https://github.com/dmlc/xgboost) to permit the latest version.\n- [Release notes](https://github.com/dmlc/xgboost/releases)\n- [Changelog](https://github.com/dmlc/xgboost/blob/master/NEWS.md)\n- [Commits](https://github.com/dmlc/xgboost/compare/v2.0.0...v3.2.0)\n\n--\n[…]\nndency-version: 3.2.0\n  dependency-type: direct:development\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "build(deps-dev): update xgboost requirement (#86)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-02T03:45:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1c380ef849bb673ec006bb5972d8c52dcf68bd3e",
          "body": "…e_id auto-derive -- silly-kicks 4.4.0 (PR-S77) (#89)\n\nThe TF-24 maintainer sweep completed and found tolerance_m pressed to the\nsearch lower bound on BOTH folds. Root cause: CarrierAccuracyObjective was\nprecision-only -- _match_accuracy averaged matched[valid].mean() over only\nthe actions where a c\n[…]\nable\nconverter behavior change, Hyrum-flagged in the CHANGELOG). C4 dsl+html\nregenerated to reflect the kloppy game_id derivation.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(calibration): recall-aware Stage-1 carrier objective + kloppy gam…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-02T03:24:39Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8154d82aa5812cf05b860a264affe04cad1e71de",
          "body": "…-- silly-kicks 4.3.0 (AC-1 hot-path Phase 1) (#88)\n\nBundles Step 1 (closed-form whitening, shared _kde_setup) + Step 2 (serial @njit cpu-numba backend). kde_backend threaded through predict_density/compute_ghost_gk/add_ghost_gk/ghost_gk_xfns. Default vectorized output shifts ~1e-12..1e-9 (within golden tol; golden not regenerated). ADR-013. 3292 non-e2e tests pass.",
          "is_bot": false,
          "headline": "perf(ghost-gk): cpu-numba KDE backend (~10x) + closed-form whitening …",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-02T01:44:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "96d43e56ba8a0568405e88294d68bd1d14c3fcdd",
          "body": "…-kicks 4.2.0 (AC-1 hot-path Phase 0) (#87)\n\n* perf(tracking): vectorize ghost-GK KDE + DAS offside hygiene -- silly-kicks 4.2.0 (AC-1 hot-path Phase 0)\n\nFull-chain profiling found ghost-GK's per-sample scipy.stats.gaussian_kde is ~74% of the\nAC-1 chain (DAS itself ~1%); this attacks it, cheap-wins-\n[…]\ns/);\n  reformatted the files ruff format flagged.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "perf(tracking): vectorize ghost-GK KDE + DAS offside hygiene -- silly…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-01T17:43:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e0bc0f1d214adb47e0cb261f3465e34083b84bef",
          "body": "…silly-kicks 4.1.1 (PR-S76) (#85)\n\n`@njit(cache=True)` resolves a writable cache locator at decoration time (module\nimport). On read-only / ephemeral installs (e.g. Databricks serverless: wheel on a\nread-only ephemeral NFS path) all locators fail and numba raises RuntimeError from\ninside a successfu\n[…]\nuv.lock\nsilly-kicks self-entry, which was stale at 4.0.3.\n\nCaught 2026-06-01 running tracking enrichment on Databricks serverless.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(tracking): make @njit cache robust to read-only install paths -- …",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-01T11:24:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b9532b62614b50fabc0540fc4017f05b9dd3066a",
          "body": "…ly-kicks 4.1.0 (PR-S75) (#84)\n\nTF-16 / GKDV Layer 2: P(a shot is attempted by the in-possession team within ~1s\nof a tracking frame), lifting the xS sub-model of arXiv:2512.00203 (Pipping, Feng\n& Sabin 2026). Distinct from xG: xS models shot-taking, not shot-quality. TF-19\nwill decompose P(shot | a\n[…]\nor train/serve consistency).\n\nDecision: ADR-011 (trained-model feature lifecycle). Attribution: NOTICE entry for\narXiv:2512.00203.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): add xShotOccurrence (xS) shot-occurrence model -- sil…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-06-01T03:28:33Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f3d2b06a51b0028531aad63bada94b3626f3dff2",
          "body": "…er -- silly-kicks 4.0.3 (PR-S74) (#83)\n\nThe pining match loader (scripts/_loader_pining.load_matches) had no retry: a single transient\ndownload/read blip -- an empty/partial S3 fetch surfacing as kloppy InputNotFoundError, or a\nurllib/OSError network hiccup -- crashed the entire fold load. Across t\n[…]\ns/, not in the wheel); silly_kicks byte-identical to 4.0.2 apart from\nthe version string. Bumped to 4.0.3 for per-PR traceability.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(calibration): retry transient match-download failures in the load…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-05-31T01:39:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e6c1eb33237400d943bcb2fe32c7b414497a2716",
          "body": "…tch -- silly-kicks 4.0.2 (PR-S73) (#82)\n\nThe TF-24 calibration loader silently calibrated on two providers instead of three. The Sportec\nkloppy-gateway converter (spadl_kloppy.convert_to_actions) leaves game_id None, while the loader's\nframes carry the DFL match id from kloppy metadata. Every track\n[…]\nhe version string. Bumped to 4.0.2 for per-PR traceability. The lakehouse stamps game_id\nfrom its bronze tables and is unaffected.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(calibration): stamp IDSSE actions game_id so carrier/DAS joins ma…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-05-30T22:38:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "14993e40572de4459147250325f4c660f2e7794e",
          "body": "…rs -- silly-kicks 4.0.1 (PR-S72) (#81)\n\nTwo latent bugs blocked the TF-24 maintainer calibration sweep; both lived in\ncode paths the calibration tests never exercised (Stage-2 CLI wiring + the\nGradient Sports Stage-2 path -- the e2e/unit fixtures cover SkillCorner only).\n\n- Stage-2 xT wiring: main(\n[…]\ne; ADR-004 one row per\n  (period,frame,player) -- otherwise pitch-control/DAS/team-shape silently\n  compute on inflated rows too).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(calibration,tracking): make TF-24 sweep runnable on all 3 provide…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-05-30T21:41:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3a60f512dc53e31b220763f13f2953a551ba2e92",
          "body": "Least-privilege + supply-chain hardening from a ruthless-efficiency cross-repo audit:\n- publish.yml: add top-level 'permissions: contents: read' (build job needs only read; publish job keeps id-token: write and does not check out).\n- ci.yml: add concurrency group with cancel-in-progress so new pushe\n[…]\n the 'v*' tag policy, so only release tags can publish. Item 5 (ruthless-efficiency>=0.2.1 floor) was already satisfied by PR-S68.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: harden PyPI publish + CI workflow security (PR-S71) (#80)",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-05-30T20:15:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3589d7332845fdd1b8c212db6e047b1b574e49e5",
          "body": "…direction -- silly-kicks 4.0.0 (PR-S70) (#79)\n\nBREAKING: Sportec tracking now raises on extra-time without home_team_start_left_extratime (was silent wrong-geometry). All five per-period-absolute converters (Sportec + Metrica + Gradient Sports, tracking and events) route through one public require_\n[…]\ncalibration-only) + TF-24 sweep memory-bound CLI flags (--match-ids / --max-matches-per-provider / --tracking-limit). See ADR-010.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking)!: symmetric fail-loud ET-direction guard + require_et_…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-05-30T19:44:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8747877bf5fb4d29cf5999c7b6719fb95cfba621",
          "body": "…-- silly-kicks 3.30.0 (PR-S69) (#78)\n\nTwo surgical dead-ball-robustness fixes, both surfaced by the luxury-lakehouse\nAC-1 production run on IDSSE dead-ball batches.\n\n1. add_das no longer crashes on all-dead-ball batches. When team_in_possession is\n   all-NaN, _pin_attacking_direction raises the can\n[…]\nent (Bekkers 2024 section 2.4). Missing vx/vy still\n   raises. Happy path bit-identical (golden-master + snapshot). Atomic mirror.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(tracking): graceful dead-ball DAS + bekkers ball-gap degradation …",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-05-30T15:12:57Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f338ed6dd1b6483b9ebb475dfc0e43ac02f71dff",
          "body": "…on manifest -- silly-kicks 3.29.1 (PR-S68) (#77)\n\nBump ruthless-efficiency[optuna] floor 0.2.0 -> 0.2.1 (calibration + dev extras).\n0.2.1 fixes a warm_start off-by-one in OptunaStrategy where a fresh warm-started\nstudy ran n_trials-1 trials (at n_trials=2: only the warm-start baseline, zero\nexplora\n[…]\nmportlib.metadata.version (stale on\nan editable install bumped post-install). Calibration-tooling only; no runtime\nlibrary change.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "build(calibration): require ruthless-efficiency>=0.2.1 + source-versi…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-05-30T13:49:20Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "16ecac7dccf6a857fe45f07743d03a6cd49a0950",
          "body": "…kicks 3.29.0 (PR-S67) (#76)\n\nAdd attacking_direction_col to add_das + _precompute_das_lookup, threaded to\nget_individual_das. When supplied (numeric +/-1, one value per frame), skips\n_pin_attacking_direction and validates fail-loud; the library possession gate\nis untouched. Lets callers bypass per-\n[…]\n all-NaN team_in_possession). attacking_direction_col=None\nis bit-identical to prior behavior. Uncovered by luxury-lakehouse AC-1.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): add_das attacking_direction_col passthrough -- silly-…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-05-30T03:00:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0a76f529fec2f8c67d1eafe36877246bfce0d34f",
          "body": "…28.0 (PR-B) (#75)\n\nAdd silly_kicks.calibration (optional [calibration] extra) + scripts/ CLI for Optuna-TPE\ncalibration of three tracking defaults (infer_ball_carrier tolerance_m/beta/gamma; LinkParams.k3;\noff-ball-run pre_seconds/min_displacement_m) against real multi-provider tracking data via\nru\n[…]\nhe library constants (separate\n\"apply\" PR after the maintainer sweep). ADR-009; C4 diagram updated (+ accessible-space drift fix).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(calibration): TF-24 Optuna calibration harness -- silly-kicks 3.…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-05-29T21:54:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d1f2156d4753a3740a02e4c670117b91aa6459bb",
          "body": "… 3.27.0 (TF-24 PR-A) (#74)\n\nadd_gradientsports_player_ids resolves GS tracking jerseyNum -> events SPADL int\nplayer_id/team_id via the roster (order-safe map, Int64, unmatched->pd.NA never 0),\n+ is_goalkeeper from positionGroupType==\"GK\" + a graceful GradientsportsRosterReport.\nFixes the silent GS \n[…]\ns id); verified on real GS WC2022 via the gated pining-for-the-data API.\nPrecursor to the TF-24 Optuna calibration harness (PR-B).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(tracking): GS jersey->roster player-id resolution -- silly-kicks…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-05-29T14:27:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5bcdbf2cc9c42241e71cefa07272e5ccc74a8ffb",
          "body": "…- silly-kicks 3.26.0 (PR-S66) (#73)\n\ncompute_ghost_gk gains link_frame_ids; extraction walks all frames to preserve the\nper-period goal-mean + cross-period velocity deps but builds rows only for linked\nframes, and the per-sample KDE runs only on them -> byte-identical. add_ghost_gk\nderives the set from its pointers; ghost_gk_xfns from the union of its 3 gamestate\nslots. ~100x faster per fan-out batch (bundled model).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "perf(tracking): restrict ghost_gk KDE + extraction to linked frames -…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-05-29T11:14:34Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "011f1fa7a5afd151939f254d2af974e5b5dc075a",
          "body": "… fixes flaky budget (#72)\n\nThe PR-S65 detailed=False cover-shadows wall-clock perf budget (45ms) flaked on\nshared Windows CI (47.06ms on a byte-identical build). Replaced with a\ntiming-independent structural guard: spy on lane_control and assert it is called\nonce per receiver (n_blocked first loop), not per (blocker, receiver). Stronger\nregression guard, can never flake. Test-only; no source or version change.",
          "is_bot": false,
          "headline": "test(tracking): structural call-count guard for cover_shadows perf --…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-05-29T03:17:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "00e5800cfd46f5b841db6a3e275437d778951854",
          "body": "… -- silly-kicks 3.25.1 (PR-S65) (#71)\n\nHoist the redundant per-defender man-marking re-classification (provably a\nno-op for lane-blocker removals -- removing a non-winner cannot change a\ngreedy nearest-first matching) and compute the leave-one-out as a single\nvectorized masked re-scan. ~4.3x faster\n[…]\netailed=True\npath is unchanged.\n\nGuarded by a Hypothesis property test (no-ripple invariant), an independent\nfrozen-oracle exactness test, n_blocked bit-stability, atomic parity, and a\nCI perf budget.",
          "is_bot": false,
          "headline": "perf(tracking): vectorized leave-one-out for cover_shadows max_single…",
          "author_name": "Karsten S. Nielsen",
          "author_login": "karstenskyt",
          "committed_at": "2026-05-29T02:51:50Z",
          "body_truncated": true,
          "is_coding_agent": false
        }
      ],
      "releases_count": 100,
      "commits_last_year": 207,
      "latest_release_at": "2026-07-22T05:57:32Z",
      "latest_release_tag": "v4.55.1",
      "releases_from_tags": true,
      "days_since_last_push": 0,
      "active_weeks_last_year": 14,
      "days_since_latest_release": 0,
      "mean_days_between_releases": 0.8
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 87,
      "has_issue_template": false,
      "has_code_of_conduct": true,
      "has_pull_request_template": true
    },
    "ecosystem": {
      "packages": [
        {
          "name": "silly-kicks",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "SPADL",
            "VAEP",
            "actions",
            "analytics",
            "football",
            "soccer",
            "Development Status :: 5 - Production/Stable",
            "Intended Audience :: Science/Research",
            "License :: OSI Approved :: MIT License",
            "Programming Language :: Python :: 3",
            "Programming Language :: Python :: 3.10",
            "Programming Language :: Python :: 3.11",
            "Programming Language :: Python :: 3.12",
            "Topic :: Scientific/Engineering"
          ],
          "ecosystem": "pypi",
          "matches_repo": true,
          "registry_url": "https://pypi.org/project/silly-kicks/",
          "is_deprecated": false,
          "latest_version": "4.55.1",
          "repository_url": "https://github.com/karsten-s-nielsen/silly-kicks",
          "versions_count": 150,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": "2026-04-07T17:16:04.838059Z",
          "latest_published_at": "2026-07-22T10:02:21.247663Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 0
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 1,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": null,
      "open_issues_and_prs": 2
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [],
      "largest_source_bytes": 240290,
      "source_files_sampled": 707,
      "oversized_source_files": 7,
      "agent_instruction_files": [
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 132634
    },
    "dependencies": {
      "manifests": [
        "pyproject.toml"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "pypi"
      ],
      "dependencies": [
        {
          "name": "pandas",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=2.1.1,!=3.0.4"
        },
        {
          "name": "numpy",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=1.26.0"
        },
        {
          "name": "scikit-learn",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=1.3.1"
        },
        {
          "name": "scipy",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=1.10.0"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 2,
        "merged_prs": 165,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 1,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "karstenskyt",
          "commits": 200,
          "avatar_url": "https://avatars.githubusercontent.com/u/6483901?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "publish.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "uv.lock"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": null,
            "reason": "internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "26 out of 26 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/28 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 0,
            "reason": "project has 0 contributing companies or organizations -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 10,
            "reason": "update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 3,
            "reason": "dependency not pinned by hash detected -- score normalized to 3",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 10,
            "reason": "security policy file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 10,
            "reason": "GitHub workflow tokens follow principle of least privilege",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 0,
            "reason": "29 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "a58708beb8cbcd855f6449ba1ff7324cc65f49cc",
        "ran_at": "2026-07-22T10:03:04Z",
        "aggregate_score": 6.3,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": true,
      "has_dependabot_config": true
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-22T10:02:26Z",
      "oldest_open_prs": [
        {
          "number": 163,
          "created_at": "2026-07-20T05:17:03Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 164,
          "created_at": "2026-07-20T05:17:07Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-22T05:57:32Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/karsten-s-nielsen/silly-kicks",
    "host": "github.com",
    "name": "silly-kicks",
    "owner": "karsten-s-nielsen"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 62,
      "inputs": {
        "security": 63,
        "vitality": 80,
        "community": 43,
        "governance": 52,
        "engineering": 71
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 80,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 74,
            "inputs": {
              "commits_last_year": 207,
              "human_commit_share": 0.96,
              "days_since_last_push": 0,
              "active_weeks_last_year": 14
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "14/52 weeks with commits",
                "points": 9.7,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 14
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "207 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 207
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 88,
            "inputs": {
              "releases_count": 100,
              "latest_release_tag": "v4.55.1",
              "releases_from_tags": true,
              "days_since_latest_release": 0,
              "mean_days_between_releases": 0.8
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "100 version tags (no GitHub releases)",
                "points": 16.2,
                "status": "partial",
                "details": [
                  {
                    "code": "version_tags_no_releases",
                    "params": {
                      "count": 100
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~0.8 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 0.8
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 43,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 1,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "1 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "excellent",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 92,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": true,
              "has_pull_request_template": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 13.5,
                "status": "met",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 6.3,
                "status": "met",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 52,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 10,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 72,
            "inputs": {
              "merged_prs": 165,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 0
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "165/165 decided PRs merged",
                "points": 38.2,
                "status": "met",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 165,
                      "decided": 165
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/28 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 42,
            "inputs": {
              "followers": 2,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "karsten-s-nielsen",
              "public_repos": 11,
              "account_age_days": 141
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "2 followers of karsten-s-nielsen",
                "points": 3.4,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 2,
                      "login": "karsten-s-nielsen"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "11 public repos, account ~0 yr old",
                "points": 8.6,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 11
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 0
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "silly-kicks"
              ],
              "ecosystems": "pypi",
              "any_deprecated": false,
              "min_days_since_publish": 0
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on pypi",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "pypi"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 0 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "150 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 150
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "good",
        "name": "Engineering Quality",
        "value": 71,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 68,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "2 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "26 out of 26 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "good",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 75,
            "inputs": {
              "topics": [
                "event-data",
                "opta",
                "pandas",
                "python",
                "soccer-analytics",
                "statsbomb",
                "vaep",
                "wyscout",
                "spadl",
                "football"
              ],
              "has_wiki": false,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": "10 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 10
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 63,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "moderate",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Branch-Protection, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "branch_protection",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 63,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 6.3
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "26 out of 26 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/28 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "update tool detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 3",
                "points": 1.5,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "GitHub workflow tokens follow principle of least privilege",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "29 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 1
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 61,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 1,
              "agent_instruction_files": [
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 132634
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "CLAUDE.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "96 of 96 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 96,
                      "sampled": 96
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 53,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "uv.lock"
              ],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0.87,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0.04
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "87 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 87,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "4 of the last 100 commits are automated dependency updates",
                "points": 8,
                "status": "met",
                "details": [
                  {
                    "code": "dependency_bot_commits",
                    "params": {
                      "count": 4,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 3",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "moderate",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 54,
            "inputs": {
              "primary_language": "Python",
              "largest_source_bytes": 240290,
              "source_files_sampled": 707,
              "oversized_source_files": 7
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Python without a type-check config",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_typecheck_config_language",
                    "params": {
                      "language": "Python"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "7/707 source files over 60KB",
                "points": 54.5,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 707,
                      "oversized": 7
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "at_risk",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "example_dirs": [
                "examples"
              ],
              "has_mcp_signal": false,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": "examples",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "examples"
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
    "deps.dev does not index pypi:silly-kicks@4.55.1; advisories assessed against the repository dependency graph instead"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-22T10:03:22.072573Z",
  "schema_version": "0.26.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/k/karsten-s-nielsen/silly-kicks.svg",
  "full_name": "karsten-s-nielsen/silly-kicks",
  "license_state": "standard",
  "license_spdx": "MIT"
}

Scores are signals, not warranties. They reflect publicly visible practices on GitHub — not a code audit, and not a security guarantee.

Missing data is excluded and weights renormalized, never scored as zero. Methodology is versioned and open: metrics v1.13.0, schema v0.26.0 — full methodology · metrics wiki.

How one result sits in the wider record: aggregate statisticsPyPI.