Öffentliches Register
Software-GesundheitsberichtSchema 0.27.0 · Metriken 2.5.0 · 2026-07-31 00:01 UTC

silvermpx / wse

WSE - Rust-powered WebSocket engine for Python. Up to 5M del/s fan-out, native cluster binary protocol, zero-GIL JWT, E2E encryption

Rust · Python · TypeScriptMIT★ 50 Sterne⑂ 1 Forkseit Feb. 2026Auf GitHub ansehen ↗

silvermpx/wse erreicht einen Gesundheitsindex von 65 von 100 und liegt damit im Bereich Gut. Am stärksten schneidet es bei Vitality (77/100) ab, am schwächsten bei Sustainability & Governance (37/100). Zuletzt heute aktualisiert. Ein einzelner Mitwirkender trägt den Großteil der jüngsten Arbeit.

65
gesamt / 100
Gut

Software-Gesundheitsindex

Metriken werden auf einer standardisierten Skala von 1–100 in gewichtete Kategorien gruppiert. Der Gesamtwert beginnt als ihr gewichtetes Mittel, kalibriert auf die Verteilung des öffentlichen Registers, sodass die Stufen Perzentilbedeutung tragen; sobald öffentliche Evidenz die Richtlinie für Hochrisikojurisdiktionen auslöst, wird die Bewertung angepasst und erhält die Obergrenze Gefährdet von 34.

65
Außergewöhnlich93-100Die Spitzengruppe des Registers (≈ obere 5 %); erfüllt im Wesentlichen alle geprüften Kriterien
Exzellent80-92Durchgehend stark; geringfügige Lücken
Gut65-79Gesund; Lücken sind begrenzt und beherrschbar
Mittel50-64Akzeptabel mit deutlichen Lücken; Überprüfung empfohlen
Schwach35-49Wesentliche Schwächen in mehreren Bereichen
Gefährdet20-34Erhebliche Schwächen; eine Übernahme erfordert Vorsicht
Kritisch1-19Schwerwiegende Probleme (aufgegeben, nur ein Maintainer, keine Hygiene)
VitalitätCommunity &VerbreitungNachhaltigkeit &GovernanceEngineering-QualitätSicherheitAI Readiness

Bewertungsprofil

Jede Achse ist eine Kategorie. Die Form zählt mehr als der Durchschnitt — ein gesundes Projekt füllt die gesamte Fläche, während ein Profil aus Spitzen und Kratern bedeutet, dass Stärke in einer Dimension Risiken in einer anderen verdeckt.

Der gewichtete Gesamtwert 60 wird auf der veröffentlichten Indexskala auf 65 kalibriert (Register-Kalibrierung 2026-08-02).

Eigentümerschaft

silvermpxPersönliches Konto
7 Follower3 öffentliche Reposseit Aug. 2018

Dieses Repository gehört einem persönlichen Konto. Ein Projekt mit nur einem Eigentümer trägt ein höheres Kontinuitätsrisiko als ein organisationsgetragenes.

Paket-Ökosysteme

RegistryPaketVersionDownloads / MonatVersionenZuletzt veröffentlichtTags
npmwse-client2.4.127642vor 18 Tagenwebsocketreacthooksreal-timeeventspubsubencryptionrustzustand
PyPIwse-server2.4.1-39vor 18 Tagenwebsocketenginereal-timepubsubclusterencryptedrust
PyPIwse-client2.4.1-25vor 18 Tagenevent-streamingreal-timewebsocketwse

Metriken nach Kategorie

Vitalität

Lebt das Projekt — wird Code geschrieben und werden Releases ausgeliefert?

77Gut · 21 % des Gesamtindex
Wie die Bewertung erfolgt
36/36Push-Aktualität — letzter Push vor 0 Tagen
4.8/36Commit-Rhythmus — 7/52 Wochen mit Commits
18/18Commit-Volumen — 264 Commits im letzten Jahr
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Verwendete Eingangsdaten
commits_last_year264
human_commit_share0,92
days_since_last_push0
active_weeks_last_year7
Wie die Bewertung erfolgt
27/27Liefert Releases aus — 39 Releases veröffentlicht
36/36Release-Aktualität — letztes Release vor 18 Tagen
27/27Release-Rhythmus — ein Release etwa alle 14,8 Tage
0/10OpenSSF Scorecard: Signed-Releases — Project has not signed or included provenance with any releases.
Verwendete Eingangsdaten
releases_count39
latest_release_tagv2.4.1
releases_from_tagsnein
days_since_latest_release18
mean_days_between_releases14,8

Community & Verbreitung

Hat das Projekt Nutzer, Downloads, Aufmerksamkeit und ein einladendes Umfeld für Beitragende?

46Schwach · 17 % des Gesamtindex
Wie die Bewertung erfolgt
27.4/60Stars — 50 Stars
0/25Forks — 1 Forks
1.7/15Watcher — 3 Watcher
Verwendete Eingangsdaten
forks1
stars50
watchers3
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Wie die Bewertung erfolgt
22.5/22.5README
22.5/22.5Lizenz — anerkannte Lizenz (MIT)
18/18CONTRIBUTING-Leitfaden
0/13.5Verhaltenskodex
0/7.2Issue-Vorlage
0/6.3PR-Vorlage
Verwendete Eingangsdaten
has_readmeja
has_licenseja
readme_badges
has_contributingja
has_issue_templatenein
has_code_of_conductnein
readme_badge_services
has_pull_request_templatenein
Wie die Bewertung erfolgt
32.6/80Downloads pro Monat — 276 Downloads/Monat über npm, pypi
0/20Abhängige in der Registry — von diesem Ökosystem nicht ausgewiesen
Verwendete Eingangsdaten
packageswse-client, wse-server, wse-client
dependents
ecosystemsnpm, pypi
total_downloads
monthly_downloads276
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Abhängige in der Registry. Die verbleibenden Gewichte wurden renormalisiert.

Nachhaltigkeit & Governance

Überdauert das Projekt die Menschen, die es tragen — Bus-Faktor, Reaktionsfähigkeit, Trägerschaft und Paketpflege?

37Schwach · 23 % des Gesamtindex
Wie die Bewertung erfolgt
9/54Bus-Faktor — 1 Beitragende decken die Hälfte aller Commits ab
0/22.5Commit-Verteilung — wichtigste beitragende Person verfasste 100 % der Commits
1.4/13.5Breite der Beitragenden — 1 Beitragende
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Verwendete Eingangsdaten
bus_factor1
contributors_sampled1
top_contributor_share1
Wie die Bewertung erfolgt
0/42Issue-Lösungsquote — keine Issues oder keine Daten
7.1/30PR-Annahme — 10/42 entschiedene PRs gemergt
0/13Newcomer PR acceptance — kein PR eines Erstbeitragenden in 30 Tagen entschieden
0/15OpenSSF Scorecard: Code-Review — Found 0/22 approved changesets -- score normalized to 0
Verwendete Eingangsdaten
merged_prs10
open_issues0
closed_issues0
prs_merged_7d
prs_decided_7d
prs_merged_30d
prs_decided_30d
issue_closed_ratio
closed_unmerged_prs32
first_time_authors_30d
first_time_prs_merged_30d
first_time_prs_decided_30d
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Issue-Lösungsquote, newcomer_pr_acceptance. Die verbleibenden Gewichte wurden renormalisiert.
Wie die Bewertung erfolgt
10/30Organisatorische Trägerschaft — persönliches (Nutzer-)Konto
0/20Verifizierte Domain — für Nutzerkonten nicht anwendbar
6.5/25Reichweite des Inhabers — 7 Follower von silvermpx
16.4/25Kontohistorie — 3 öffentliche Repos, Kontoalter ca. 7 Jahre
Verwendete Eingangsdaten
followers7
owner_typeUser
is_verified
owner_loginsilvermpx
public_repos3
account_age_days2.919
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Verifizierte Domain. Die verbleibenden Gewichte wurden renormalisiert.

Paketpflege

100Außergewöhnlich
Wie die Bewertung erfolgt
25/25Veröffentlicht & auflösbar — 3 Paket(e) auf npm, pypi
35/35Veröffentlichungsaktualität — letzte Veröffentlichung vor 18 Tagen
20/20Versionshistorie — 42 veröffentlichte Versionen
20/20Nicht veraltet — aktiv, nicht veraltet oder zurückgezogen
Verwendete Eingangsdaten
packageswse-client, wse-server, wse-client
ecosystemsnpm, pypi
any_deprecatednein
min_days_since_publish18

Engineering-Qualität

Sind grundlegende Engineering- und Dokumentationspraktiken vorhanden?

75Gut · 19 % des Gesamtindex
Wie die Bewertung erfolgt
24/24CI-Workflows — 2 Workflow(s)
24/24Tests vorhanden
0/16Linter-Konfiguration
0/9.6Pre-Commit-Hooks
0/6.4.editorconfig
20/20OpenSSF Scorecard: CI-Tests — 8 out of 8 merged PRs checked by a CI test -- score normalized to 10
Verwendete Eingangsdaten
has_cija
has_testsja
has_editorconfignein
has_linter_confignein
has_precommit_confignein

Dokumentation

85Exzellent
Wie die Bewertung erfolgt
30/30README
25/25Dokumentationsverzeichnis
0/15Dokumentations-/Homepage-Site
10/10Repository-Beschreibung
10/10Topics — 10 Topics
10/10Wiki
Verwendete Eingangsdaten
topicsencryption, high-performance, jwt, pyo3, python, real-time, rust, tokio, websocket, websocket-server
has_wikija
homepage
has_readmeja
has_docs_dirja
has_descriptionja

Sicherheit

Sind die sichtbaren Sicherheits- und Lieferkettenpraktiken belastbar, ohne ungeklärte Exposition gegenüber Hochrisikojurisdiktionen?

70Gut · 16 % des Gesamtindex
Wie die Bewertung erfolgt
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — keine Daten
2.5/2.5CI-Tests — 8 out of 8 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/22 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.5Lizenz — 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
3/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 6
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 — Project has not signed or included provenance with any releases.
7.5/7.5Token-Permissions — GitHub workflow tokens follow principle of least privilege
3/7.5Vulnerabilities — 6 existing vulnerabilities detected
Verwendete Eingangsdaten
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate6,3
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): branch_protection. Die verbleibenden Gewichte wurden renormalisiert.

Abhängigkeits-Advisories

100Außergewöhnlich
Wie die Bewertung erfolgt
35/35Direkte Abhängigkeiten ohne bekannte Advisories — keine direkte Abhängigkeit trägt ein bekanntes Advisory
25/25Indirekte Abhängigkeiten ohne bekannte Advisories — keine indirekte Abhängigkeit trägt ein bekanntes Advisory
0/40Keine offenen Advisories — kein Advisory trägt ein Veröffentlichungsdatum
Verwendete Eingangsdaten
sourceosv
advisories0
affected_packages0
assessed_packages2
unassessed_packages0
affected_by_severitynone
direct_affected_packages0
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Keine offenen Advisories. Die verbleibenden Gewichte wurden renormalisiert. Abgeglichen wurde die Laufzeit-Abhängigkeitshülle von npm:wse-client@2.4.1 — das, was die Installation des veröffentlichten Pakets nach sich zieht — mit 2 Paketen. Erreichbarkeit wird nicht analysiert.

AI Readiness

Wie gut ist das Repository dafür ausgestattet, mit KI-Coding-Agenten entwickelt und gepflegt zu werden? Trägt ein bewusst kleines Gewicht (4 %): Agenten-Tooling ist ein echtes Pflegesignal, doch ein Repository ohne jedes Signal kann weiterhin 100/100 erreichen.

61Mittel · 4 % des Gesamtindex
Wie die Bewertung erfolgt
0/45Agentenanweisungen — keine CLAUDE.md / AGENTS.md / Editor-Regeln
0/15Maschinenlesbare Doku (llms.txt)
40/40Lesbare Commit-Historie — 78 von 92 menschlichen Commits benennen ihre Absicht (strukturierter Betreff oder erläuternder Text)
Verwendete Eingangsdaten
has_llms_txtnein
legible_history_share0,848
agent_instruction_files
agent_instruction_max_bytes
Wie die Bewertung erfolgt
12.6/18Bootstrap mit einem Befehl — benchmarks/rust-bench/Cargo.toml, rust/Cargo.toml (Toolchain-Konvention, kein Task-Runner)
22/22Automatisierte Tests
0/11Lint-/Format-Konfiguration
11/11Statische Typprüfung — benchmarks/ts-bench/tsconfig.json, tsconfig.json, wse_server/py.typed
10/10Reproduzierbare Umgebung — lockfile
0/10Belegte Agentenpraxis — keine von Agenten verfassten Commits unter den letzten 100
8/8Automatisierte Wartung — 8 der letzten 100 Commits sind automatisierte Abhängigkeits-Updates
6/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 6
Verwendete Eingangsdaten
has_nixnein
has_testsja
lockfilesCargo.lock, package-lock.json
has_dockerfilenein
typed_languageja
bootstrap_files
has_devcontainernein
has_linter_confignein
typecheck_configsbenchmarks/ts-bench/tsconfig.json, tsconfig.json, wse_server/py.typed
agent_commit_share0
toolchain_manifestsbenchmarks/rust-bench/Cargo.toml, rust/Cargo.toml
dependency_bot_commit_share0,08
Wie die Bewertung erfolgt
45/45Typprüfbarer Code — Rust (statisch typisiert)
54.2/55Handhabbare Dateigrößen — 2/138 Quelldateien über 60 KB
Verwendete Eingangsdaten
primary_languageRust
largest_source_bytes247.962
source_files_sampled138
oversized_source_files2
Wie die Bewertung erfolgt
0/40API-Schema (OpenAPI/GraphQL/proto)
0/20MCP-Server
40/40Lauffähige Beispiele — examples
Verwendete Eingangsdaten
example_dirsexamples
has_mcp_signalnein
api_schema_files

Eckdaten

50GitHub-Sterne
1Mitwirkende
264Commits, letzte 12 Monate
0Tage seit letztem Push
39Releases
1Bus-Faktor
0offene Issues
crates.io, npm, PyPIPaket-Ökosysteme

Warnungen zur Datenerhebung

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • Could not fetch crates package 'wse-accel' from its registry
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Weitere Details

OpenSSF Scorecard 6.3 / 10
6.3Gesamtwert

Unabhängige, werkzeugneutrale Sicherheitsbewertung durch das quelloffene OpenSSF Scorecard. Jede Prüfung honoriert eine Sicherheits-Praxis, nicht das Werkzeug eines bestimmten Anbieters. Prüfungen, die Scorecard nicht ermitteln konnte, sind mit k. A. markiert und vom Sicherheitswert ausgeschlossen (nie als null gezählt).Scorecard v5.5.0 · 2026-07-31 00:01 UTC

10Binary-Artifactsno binaries found in the repo
k. A.Branch-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-Tests8 out of 8 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/22 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
6Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 6
0SASTSAST tool is not run on all commits -- score normalized to 0
10Security-Policysecurity policy file detected
0Signed-ReleasesProject has not signed or included provenance with any releases.
10Token-PermissionsGitHub workflow tokens follow principle of least privilege
4Vulnerabilities6 existing vulnerabilities detected
Direkte Abhängigkeiten 40
RegistryPaketVersionsvorgabeManifest
npm@msgpack/msgpack^3.0.0package.json
npmpako^2.1.0package.json
PyPIwebsockets>=13.0python-client/pyproject.toml
crates.iopyo30.29rust/Cargo.toml
crates.ioserde1.0.228rust/Cargo.toml
crates.ioserde_json1.0.149rust/Cargo.toml
crates.ioflate21.1.9rust/Cargo.toml
crates.iormp-serde1.3.1rust/Cargo.toml
crates.iormpv1.3.1rust/Cargo.toml
crates.iohmac0.12.1rust/Cargo.toml
crates.iosha20.10.9rust/Cargo.toml
crates.iohex0.4rust/Cargo.toml
crates.ioahash0.8.12rust/Cargo.toml
crates.iodashmap6rust/Cargo.toml
crates.ioaes-gcm0.10rust/Cargo.toml
crates.iop2560.13rust/Cargo.toml
crates.iojsonwebtoken10rust/Cargo.toml
crates.iohkdf0.12rust/Cargo.toml
crates.iouuid1.22.0rust/Cargo.toml
crates.iobase640.22rust/Cargo.toml
crates.iochrono0.4.44rust/Cargo.toml
crates.ioregex1.12.3rust/Cargo.toml
crates.iotokio1.50.0rust/Cargo.toml
crates.iotokio-tungstenite0.29.0rust/Cargo.toml
crates.iofutures-util0.3.32rust/Cargo.toml
crates.iocrossbeam-channel0.5rust/Cargo.toml
crates.iotokio-util0.7rust/Cargo.toml
crates.iosocket20.6rust/Cargo.toml
crates.iobytes1rust/Cargo.toml
crates.iomimalloc0.1rust/Cargo.toml
crates.iotokio-rustls0.26rust/Cargo.toml
crates.iorustls0.23rust/Cargo.toml
crates.iorustls-pki-types1rust/Cargo.toml
crates.iozstd0.13rust/Cargo.toml
crates.ioparking_lot0.12rust/Cargo.toml
crates.ioindexmap2rust/Cargo.toml
crates.iozeroize1rust/Cargo.toml
crates.iotracing0.1rust/Cargo.toml
crates.iotracing-subscriber0.3rust/Cargo.toml
crates.ioarc-swap1rust/Cargo.toml
Alle Abhängigkeiten nicht erhoben

Der aufgelöste Abhängigkeitssatz konnte für diesen Bericht nicht erhoben werden: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Abhängigkeits-Advisories 0

Die Installation von npm:wse-client@2.4.1 zieht 2 Pakete nach sich, direkt und transitiv: 0 tragen bekannte Advisories, davon 0 direkte Abhängigkeiten.

Keine bekannten Advisories betreffen die bewerteten Abhängigkeiten.

Ein Advisory bedeutet, dass die im Abhängigkeitsgraphen erfasste Version in den betroffenen Bereich eines Advisories fällt. Erreichbarkeit wird nicht analysiert, und der Graph enthält Entwicklungs- und Test-Pins — ein Fund kann das Werkzeug betreffen und nicht die ausgelieferte Software.

JSON-Rohbericht maschinenlesbar
{
  "data": {
    "repo": {
      "topics": [
        "encryption",
        "high-performance",
        "jwt",
        "pyo3",
        "python",
        "real-time",
        "rust",
        "tokio",
        "websocket",
        "websocket-server"
      ],
      "is_fork": false,
      "size_kb": 1735,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "Rust": 927723,
        "Python": 364693,
        "TypeScript": 331420
      },
      "pushed_at": "2026-07-31T00:01:07Z",
      "created_at": "2026-02-20T23:23:52Z",
      "owner_type": "User",
      "updated_at": "2026-07-31T00:01:09Z",
      "description": "WSE - Rust-powered WebSocket engine for Python. Up to 5M del/s fan-out, native cluster binary protocol, zero-GIL JWT, E2E encryption",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "Rust",
      "significant_languages": [
        "Rust",
        "Python",
        "TypeScript"
      ]
    },
    "owner": {
      "blog": null,
      "name": null,
      "type": "User",
      "login": "silvermpx",
      "company": null,
      "location": "Germany",
      "followers": 7,
      "avatar_url": "https://avatars.githubusercontent.com/u/42042558?v=4",
      "created_at": "2018-08-02T16:53:38Z",
      "is_verified": null,
      "public_repos": 3,
      "account_age_days": 2919
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v2.4.1",
          "kind": "patch",
          "published_at": "2026-07-12T13:32:32Z"
        },
        {
          "tag": "v2.4.0",
          "kind": "minor",
          "published_at": "2026-06-10T22:30:55Z"
        },
        {
          "tag": "v2.3.2",
          "kind": "patch",
          "published_at": "2026-03-22T21:49:28Z"
        },
        {
          "tag": "v2.3.1",
          "kind": "patch",
          "published_at": "2026-03-08T01:55:17Z"
        },
        {
          "tag": "v2.3.0",
          "kind": "minor",
          "published_at": "2026-03-07T18:57:09Z"
        },
        {
          "tag": "v2.2.1",
          "kind": "patch",
          "published_at": "2026-03-06T23:09:01Z"
        },
        {
          "tag": "v2.2.0",
          "kind": "minor",
          "published_at": "2026-03-06T16:46:59Z"
        },
        {
          "tag": "v2.1.1",
          "kind": "patch",
          "published_at": "2026-03-01T11:06:20Z"
        },
        {
          "tag": "v2.1.0",
          "kind": "minor",
          "published_at": "2026-03-01T04:53:40Z"
        },
        {
          "tag": "v2.0.8",
          "kind": "patch",
          "published_at": "2026-03-01T02:26:00Z"
        },
        {
          "tag": "v2.0.7",
          "kind": "patch",
          "published_at": "2026-02-28T15:47:08Z"
        },
        {
          "tag": "v2.0.6",
          "kind": "patch",
          "published_at": "2026-02-28T15:12:12Z"
        },
        {
          "tag": "v2.0.5",
          "kind": "patch",
          "published_at": "2026-02-28T14:29:44Z"
        },
        {
          "tag": "v2.0.4",
          "kind": "patch",
          "published_at": "2026-02-28T14:21:07Z"
        },
        {
          "tag": "v2.0.3",
          "kind": "patch",
          "published_at": "2026-02-28T14:00:41Z"
        },
        {
          "tag": "v2.0.2",
          "kind": "patch",
          "published_at": "2026-02-28T12:33:13Z"
        },
        {
          "tag": "v2.0.1",
          "kind": "patch",
          "published_at": "2026-02-28T11:55:03Z"
        },
        {
          "tag": "v2.0.0",
          "kind": "major",
          "published_at": "2026-02-28T05:51:34Z"
        },
        {
          "tag": "v1.4.4",
          "kind": "patch",
          "published_at": "2026-02-25T00:56:09Z"
        },
        {
          "tag": "v1.4.3",
          "kind": "patch",
          "published_at": "2026-02-24T22:52:36Z"
        },
        {
          "tag": "v1.4.1",
          "kind": "patch",
          "published_at": "2026-02-24T12:03:07Z"
        },
        {
          "tag": "v1.4.0",
          "kind": "minor",
          "published_at": "2026-02-24T10:06:07Z"
        },
        {
          "tag": "v1.3.9",
          "kind": "patch",
          "published_at": "2026-02-24T05:22:15Z"
        },
        {
          "tag": "v1.3.8",
          "kind": "patch",
          "published_at": "2026-02-23T23:22:19Z"
        },
        {
          "tag": "v1.3.7",
          "kind": "patch",
          "published_at": "2026-02-23T23:18:46Z"
        },
        {
          "tag": "v1.3.6",
          "kind": "patch",
          "published_at": "2026-02-23T08:00:31Z"
        },
        {
          "tag": "v1.3.4",
          "kind": "patch",
          "published_at": "2026-02-23T07:12:40Z"
        },
        {
          "tag": "v1.3.3",
          "kind": "patch",
          "published_at": "2026-02-23T06:56:21Z"
        },
        {
          "tag": "v1.3.2",
          "kind": "patch",
          "published_at": "2026-02-22T21:50:33Z"
        },
        {
          "tag": "v1.3.1",
          "kind": "patch",
          "published_at": "2026-02-22T21:32:15Z"
        },
        {
          "tag": "v1.3.0",
          "kind": "minor",
          "published_at": "2026-02-22T20:35:38Z"
        },
        {
          "tag": "v1.2.2",
          "kind": "patch",
          "published_at": "2026-02-22T16:18:04Z"
        },
        {
          "tag": "v1.2.1",
          "kind": "patch",
          "published_at": "2026-02-22T02:25:05Z"
        },
        {
          "tag": "v1.2.0",
          "kind": "minor",
          "published_at": "2026-02-22T02:12:04Z"
        },
        {
          "tag": "v1.1.1",
          "kind": "patch",
          "published_at": "2026-02-21T19:48:22Z"
        },
        {
          "tag": "v1.1.0",
          "kind": "minor",
          "published_at": "2026-02-21T20:21:53Z"
        },
        {
          "tag": "v1.0.3",
          "kind": "patch",
          "published_at": "2026-02-20T23:43:46Z"
        },
        {
          "tag": "v1.0.2",
          "kind": "patch",
          "published_at": "2026-02-20T23:32:08Z"
        },
        {
          "tag": "v1.0.1",
          "kind": "patch",
          "published_at": "2026-02-20T23:32:02Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "16836ae51c677eef4fa61c1f73c82580b37173b3",
          "body": "Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.0 to 7.0.1.\n- [Release notes](https://github.com/actions/upload-artifact/releases)\n- [Commits](https://github.com/actions/upload-artifact/compare/bbbca2ddaa5d8feaa63e36b76fdaad77386f024f...043fb46d1a93c77aae656e7c1c\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/upload-artifact from 7.0.0 to 7.0.1 (#38)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-31T00:01:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fdbf4f6a49347127d67911b5f9aaf53a41fedac1",
          "body": "Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.6.1 to 3.0.2.\n- [Release notes](https://github.com/softprops/action-gh-release/releases)\n- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)\n- [Commits](https://github.com/so\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 softprops/action-gh-release from 2.6.1 to 3.0.2 (#39)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-31T00:01:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "01d1adf953195f8636f57fda889a801066663638",
          "body": "Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.1.0 to 4.1.10.\n- [Release notes](https://github.com/vitest-dev/vitest/releases)\n- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)\n- [Commits](https://github.com/vitest-dev/vitest/commit\n[…]\nrect:development\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-dev): bump vitest from 4.1.0 to 4.1.10 (#42)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-31T00:00:56Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ef0fd9f161b77610dd0781b797d386c30cd6a89e",
          "body": "Bumps [zustand](https://github.com/pmndrs/zustand) from 5.0.12 to 5.0.14.\n- [Release notes](https://github.com/pmndrs/zustand/releases)\n- [Commits](https://github.com/pmndrs/zustand/compare/v5.0.12...v5.0.14)\n\n---\nupdated-dependencies:\n- dependency-name: zustand\n  dependency-version: 5.0.13\n  depend\n[…]\nrect:development\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-dev): bump zustand from 5.0.12 to 5.0.14 (#43)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-31T00:00:50Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "73a1b1f1e30f1de70df8ebd22f77e38c08f9f352",
          "body": "Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.5.0 to 26.1.2.\n- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)\n- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)\n\n---\nupdated-depe\n[…]\nrect:development\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-dev): bump @types/node from 25.5.0 to 26.1.2 (#44)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-31T00:00:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f3263df3746e8762ef132e9bd32d986dd1409146",
          "body": "Bumps [Swatinem/rust-cache](https://github.com/swatinem/rust-cache) from 23869a5bd66c73db3c0ac40331f3206eb23791dc to c19371144df3bb44fab255c43d04cbc2ab54d1c4.\n- [Release notes](https://github.com/swatinem/rust-cache/releases)\n- [Changelog](https://github.com/Swatinem/rust-cache/blob/master/CHANGELOG\n[…]\nb255c43d04cbc2ab54d1c4\n  dependency-type: direct:production\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": "Bump Swatinem/rust-cache (#25)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-30T23:52:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f62b6128335e6fdd329904a696a7a45bedc7f13f",
          "body": "Bumps [PyO3/maturin-action](https://github.com/pyo3/maturin-action) from c0c6d69dce7c061509f7b0f5ea52050b45080fbc to 04ac600d27cdf7a9a280dadf7147097c42b757ad.\n- [Release notes](https://github.com/pyo3/maturin-action/releases)\n- [Commits](https://github.com/pyo3/maturin-action/compare/c0c6d69dce7c061\n[…]\n80dadf7147097c42b757ad\n  dependency-type: direct:production\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": "Bump PyO3/maturin-action (#26)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-30T23:52:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "178a1b46631c133b7cad4f7d2d6fe01819f5d6de",
          "body": "Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.13.0 to 1.14.0.\n- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)\n- [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e...cef22109\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": "Bump pypa/gh-action-pypi-publish from 1.13.0 to 1.14.0 (#34)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-30T23:52:12Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "868800f28a947665c231147989769bf5a2de0575",
          "body": "The CI installed a floating 'pip install ruff', and ruff 0.16.1\n(released this week) no longer accepts the long-deprecated TCH rule\nselector — it dropped the whole [tool.ruff.lint] select on the floor\nand linted with the 0.16 defaults instead: 66 phantom errors (BLE001,\nS110, FURB, PYI...) from rule\n[…]\nsion the codebase is actually\nclean under, and TCH renamed to its TC alias (valid on both versions)\nso a future unpin does not trip over it again. ruff check + format\nverified clean locally on 0.15.4.",
          "is_bot": false,
          "headline": "ci: pin ruff to 0.15.4 and rename the removed TCH selector to TC",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-07-30T23:47:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "cf553377921e60c712a63ba29b1d8c0ae98e6755",
          "body": null,
          "is_bot": false,
          "headline": "release: v2.4.2 — the ts-client gap-detector resync fix",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-07-30T23:44:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cf33c7ce80c4da33ca397c16b137b313be129f74",
          "body": "… the store\n\nThe subscription_update ACK stored the server-reported positions only\nin the zustand store — the next-subscribe payload — while the\nEventSequencer's own topicPositions map kept the stale offset. After a\nNotRecovered response every later stamped message read 'gap', was\ndropped, and the w\n[…]\nad and the post-subscribe snapshot covers\nthe skipped window's state. (Found by the SQV live-stack sweep\n2026-07-30 S14-P1 — the server half landed in SQV as the\nsubscription_update inbound protocol.)",
          "is_bot": false,
          "headline": "fix(ts-client): a subscription ACK resyncs the gap detector, not just…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-07-30T23:29:51Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e2d22ca4f7c27236cd4ed0b7d7be054a9ca16a3d",
          "body": "…efresh\n\nThe v2.4.1 release run tripped on two independent gates that had drifted\nunder the unchanged rust code: cargo-audit now flags pyo3 0.28.2 (OOB read\nin PyList/PyTuple iterators + missing Sync bound on new_closure), fixed\nupstream in 0.29 - source-compatible for this crate; and stable clippy\n\n[…]\n-D warnings (presence.rs match -> ?).\ncargo update refreshes the remaining lock to latest compatible.\nVerified: fmt + clippy -D warnings on 1.97, maturin develop --release,\n38 integration tests green.",
          "is_bot": false,
          "headline": "build(rust): pyo3 0.29 (RUSTSEC-2026-0176/0177) + clippy 1.97 + dep r…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-07-12T13:24:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0ae8508a7a280a82a6491002d2f8d8f019cfe821",
          "body": "Same dead-end class as the TS 2.4.1 fix, two paths here: an OPEN breaker\nraised WSECircuitBreakerError inside the reconnect task and parked the\nclient in ERROR (the breaker's own half-open probe window was unreachable),\nand a rate-limit close never retried a transient condition. Both stay on\nthe backoff schedule now. Auth failures remain terminal by design - this\nclient has no token-refresh callback. Version 2.4.1 across both clients.",
          "is_bot": false,
          "headline": "fix(python-client): open circuit breaker and rate-limit close must retry",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-07-12T13:05:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "22ab0df9e54285bf524d0cff0892cbbbef26a6c3",
          "body": "…estart\n\nFour dead-end paths parked the client in ERROR until a page reload:\nmaxAttempts -1 (the documented infinite contract and the shipped default)\nsilently clamped to 10 attempts (~105s of backoff - shorter than a normal\nredeploy); an OPEN circuit breaker aborted reconnect() without scheduling\nt\n[…]\nped after logging; a 4429 rate-limit close never retried.\n\nAll paths now stay on the capped-backoff retry loop and -1 is honored as\ntruly infinite. Reconnection after any-length downtime is automatic.",
          "is_bot": false,
          "headline": "fix(ts-client): reconnect must never die permanently after a server r…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-07-12T12:53:17Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f32dbc133db9bafc047d2ebde7950dbe3bdfd3dc",
          "body": "cargo audit (the CI security gate) flagged three advisories in\nrustls-webpki 0.103.10, pulled in transitively via rustls/tokio-rustls\nfor cluster mTLS:\n- RUSTSEC-2026-0098: name constraints for URI names incorrectly accepted\n- RUSTSEC-2026-0099: name constraints accepted for wildcard-name certs\n- RUSTSEC-2026-0104: reachable panic in CRL parsing\n\n0.103.13 fixes all three. Lockfile-only change; verified `cargo check`\nstill builds and `cargo audit` now reports 0 vulnerabilities.",
          "is_bot": false,
          "headline": "deps: bump rustls-webpki 0.103.10 -> 0.103.13 (RUSTSEC fixes)",
          "author_name": "Silver MPX",
          "author_login": null,
          "committed_at": "2026-06-10T22:13:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d9150bfed96c465ba31f5e5164b4928eb45b9a2b",
          "body": "The deeply-nested decrypted-JSON on_message branch pushed the\nspawn_bounded_callback(&callback_sem, &state, move || {...}) call past\nrustfmt's line width, so `cargo fmt --check` (the CI rust-lint gate) failed.\nApply the canonical multi-line form. No behavior change.",
          "is_bot": false,
          "headline": "rustfmt: wrap spawn_bounded_callback call at the decrypted-JSON site",
          "author_name": "Silver MPX",
          "author_login": null,
          "committed_at": "2026-06-10T22:13:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "718009b313f84bf23b3f778635e7746b310644ff",
          "body": "Three version sources were missed in the earlier bump and still read 2.3.2,\nso the built artifacts would have shipped under the wrong version:\n- pyproject.toml [project].version -> the maturin-built `wse-server` wheel\n- wse_server/__init__.py __version__ -> the server package's runtime version\n- package-lock.json (root + self entry) -> the `wse-client` npm lockfile\n\nVerified by rebuild: `maturin develop --release` now produces\nwse_server-2.4.0-cp312-abi3 and `wse_server.__version__ == \"2.4.0\"`.",
          "is_bot": false,
          "headline": "release: bump remaining 2.3.2 version strings to 2.4.0",
          "author_name": "Silver MPX",
          "author_login": null,
          "committed_at": "2026-06-10T21:54:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3acb28d35684115c18079b4c6845d76afa1941e5",
          "body": "Fix module headers that still pointed at the old `client/...` TS path\n(now `ts-client/...`), and drop the removed \"out-of-order buffering\"\ndescription from the event sequencer header. Clarify in WSEEvent that\n`sequence` is the server's global counter (diagnostic only) -- ordering\nand dedup are per-topic via epoch/offset. Comments only; no behavior change.",
          "is_bot": false,
          "headline": "python-client: refresh stale module docstrings",
          "author_name": "Silver MPX",
          "author_login": null,
          "committed_at": "2026-06-10T21:37:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "69d6df48f290e85c40b14e18f82ad38748f7b5f8",
          "body": "Reconcile every user-facing doc with the v2.4.0 code (verified against\nsource), covering both the prior idempotency/hardening work and this\nrelease's additions.\n\nCHANGELOG: add the inbound callback bound, the real IV-reuse guard, and the\nNetworkMonitor/ConnectionPool client fixes to v2.4.0.\n\nPROTOCO\n[…]\n) idempotent dedup;\ndocument the recovery stamp, the hardening limits, the TS NetworkMonitor change\n(no app-layer packet loss), the missing Python constructor params, and add a\nv2.4 migration section.",
          "is_bot": false,
          "headline": "docs: complete the v2.4.0 documentation pass",
          "author_name": "Silver MPX",
          "author_login": null,
          "committed_at": "2026-06-10T21:37:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fa4ad6ed84673368174bc731f9e759590064877e",
          "body": "The exported WSE_VERSION constant still read 2.3.2 while every manifest\n(package.json, constants.ts WS_CLIENT_VERSION, the Rust/Python versions)\nis 2.4.0, so consumers reading WSE_VERSION saw the wrong release.",
          "is_bot": false,
          "headline": "ts-client: fix stale WSE_VERSION export (2.3.2 -> 2.4.0)",
          "author_name": "Silver MPX",
          "author_login": null,
          "committed_at": "2026-06-10T21:36:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "03c39df4a221055f8b3e28db5aaa38a9f0e008d1",
          "body": "NetworkMonitor's analyze()/getLatencyStats() were fed nothing: recordLatency\nwas never called, so latencyHistory stayed empty and the monitor reported a\nconstant EXCELLENT / 0-jitter verdict regardless of the real connection. The\npacket counters were equally inert (recordPacketSent never called), an\n[…]\n-counting scaffolding (and the matching useWSE record calls).\n- Trim the unused INetworkMonitor interface to the surviving methods.\n\nNetworkDiagnostics keeps its shape, so the public API is unchanged.",
          "is_bot": false,
          "headline": "ts-client: make NetworkMonitor report real network quality",
          "author_name": "Silver MPX",
          "author_login": null,
          "committed_at": "2026-06-10T21:04:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b39a1b07192c468038fb827fecc5416f2aaf9939",
          "body": "ConnectionPool carried a private `connectionMetrics` map (and a file-local\nConnectionMetrics interface shadowing the public one in types.ts) that was\nonly ever cleared, never populated -- no call site recorded per-connection\nmessage/byte counts. The pool's live health scoring (recordSuccess/Failure,\nlatency-weighted scores, load balancing) is unaffected. Remove the dead map\nand its local interface; the public types.ts ConnectionMetrics is untouched.",
          "is_bot": false,
          "headline": "ts-client: drop ConnectionPool's dead per-connection metrics map",
          "author_name": "Silver MPX",
          "author_login": null,
          "committed_at": "2026-06-10T20:49:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "866397858fae2b6e2891f8f3b86828732bfc5af6",
          "body": "usedIVs recorded every IV but never CHECKED the set before encrypting, so\nthe reuse guard was write-only -- it could not have prevented anything. IV\nreuse under one key is catastrophic for AES-GCM (it leaks the GHASH auth\nkey), so consult the set before use: redraw on collision (bounded retries)\nand refuse to encrypt rather than reuse an IV. With a CSPRNG the redraw\neffectively never fires, but the guard is now real. Adds IV_REUSE to the\nSecurityError code union.",
          "is_bot": false,
          "headline": "ts-client: make the AES-GCM IV-reuse guard actually guard",
          "author_name": "Silver MPX",
          "author_login": null,
          "committed_at": "2026-06-10T20:46:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5ad67afc06089e81b4dbc1b44db3dd6a3f72c323",
          "body": "Callback-mode on_message previously spawned an unbounded blocking task\nper inbound frame. A client flooding inbound messages could exhaust the\ntokio blocking pool and contend the GIL, starving every other connection.\n\nAdd a per-server semaphore (MAX_INFLIGHT_CALLBACKS = 256) and route all\nsix inboun\n[…]\nh spawn_bounded_callback.\nWhen the bound is reached the inbound work is SHED and counted in\nrate_limited_total rather than spawning. on_connect (once per connection)\nand outbound paths are unaffected.",
          "is_bot": false,
          "headline": "server: bound concurrent on_message callbacks (inbound flood guard)",
          "author_name": "Silver MPX",
          "author_login": null,
          "committed_at": "2026-06-10T20:40:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b2853dea4345bb96ac4af986806db51a9cac2f95",
          "body": "The per-topic (epoch, offset) idempotency replaced seq-based reordering, leaving\nprocess_sequenced_event / processSequencedEvent, record_sequence / recordSequence,\nthe out-of-order buffer and the expected-sequence cursor dead (the server's `seq`\nis a process-global counter, never a per-connection or\n[…]\n fields (current_sequence, duplicate_window_size, topic_positions).\nThe MessageProcessor's diagnostic recordSequence call is gone too.\n\nPython: 119 tests pass, ruff clean. TS: tsc clean, vitest green.",
          "is_bot": false,
          "headline": "chore(clients): remove the dead seq-based reorder machinery",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T20:28:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c45833b9b3f542f0407d8cacaea725008714fa9a",
          "body": "A received DRAIN frame was only logged; the docs promise that peers \"stop\nforwarding to the draining node\". On DRAIN, clear that peer's remote_interest so\nno new messages are routed to it, while keeping the connection open for in-flight\ndelivery and leaving generation / known_peers / presence intact\n[…]\n(it is not a\ndisconnect, and the peer may resume via a later periodic RESYNC). New\nInterestUpdate::Drain variant carries the signal from peer_reader to the manager.\n\ncluster tests green; clippy clean.",
          "is_bot": false,
          "headline": "cluster: act on DRAIN (lame duck) -- stop routing to a draining peer",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T20:20:16Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "db50c1c3ff8304402b39994430fcf6a3dc891d92",
          "body": "SUB/UNSUB interest deltas are fanned out best-effort (try_send drops them under\nback-pressure), and there was no reconciliation -- a single dropped frame left a\npeer's view of our interest permanently wrong (a dropped SUB withholds messages\nfor that topic forever; a dropped UNSUB forwards forever). \n[…]\nwriter\nchannel as PING (inner frame; peer_writer adds the length prefix). Both session\npaths (outbound run_peer_session, inbound handler) pass local_topic_refcount.\n\ncluster tests green; clippy clean.",
          "is_bot": false,
          "headline": "cluster: periodic full RESYNC to self-heal dropped SUB/UNSUB interest",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T20:17:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "aabafdf6080adbbc33ea1625ee82102104afecbd",
          "body": "…rics trait\n\n- BufferedEvent stored a _sequence field that was never read -- the BTreeMap key\n  already carries the sequence. Drop it.\n- FanoutMetrics was a single-impl trait (ClusterMetrics) used only so\n  peer_dispatch_task could call add_delivered/add_dropped; it was never used as a\n  dyn object or generic bound. Fold the two methods into an inherent impl on\n  ClusterMetrics and delete the trait + its import.\n\nNo behavior change; tests green; clippy clean.",
          "is_bot": false,
          "headline": "chore: remove dead BufferedEvent._sequence + fold vestigial FanoutMet…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T19:30:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1ff5aa26e484ae095e4b70b7c1e8bf97d8df373a",
          "body": "The send_event dedup set was keyed by event id alone and shared across all\nconnections, so send_event(conn_B, {\"id\": X}) silently returned 0 (dropped) if\nconn_A had already received id X -- a legitimate distinct delivery to a\ndifferent connection was lost. Key the set by (conn_id, id). This also makes the\ndocs' \"per-connection deduplication\" claim actually true.",
          "is_bot": false,
          "headline": "server: dedup send_event per (connection, id), not globally by id",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T19:26:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "65b83aa9f361678d47683c9665ae9d9b518e7a73",
          "body": "max_connections only counts REGISTERED connections (a connection registers after\nthe WS upgrade + JWT). Without a separate bound, a slowloris that opens sockets\nbut never completes the upgrade -- each held up to the 10s handshake timeout --\nexhausts tasks and file descriptors before any limit fires.\n[…]\ngisters (or on any earlier handshake failure/timeout), so it bounds\nonly not-yet-established connections, not the live total.\n\nTest: HandshakeGuard increments on new, decrements on drop. clippy clean.",
          "is_bot": false,
          "headline": "server: cap concurrent pre-handshake connections (slowloris)",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T19:23:07Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "26580dc0b12902dccc1fb784c46145dd2e59fc54",
          "body": "A client could send client_hello repeatedly; each one with features.encryption\nre-ran derive_connection_key and overwrote the connection's AES cipher. That\nmade any in-flight message encrypted with the previous key undecryptable on the\nclient, and each hello forced a fresh P-256 keygen + ECDH -- a cheap asymmetric-\ncrypto DoS amplifier. Skip the derivation (keep the existing cipher) when the\nconnection already has one.",
          "is_bot": false,
          "headline": "server: client_hello key exchange is once-only (no mid-session re-key)",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T19:16:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "053002a1e5456bab14d5730b55305c2c989822d3",
          "body": "- decrypt_inbound split the 12-byte IV with split_at(12) + try_into().expect()\n  on attacker-controlled bytes. Use split_first_chunk::<12>() so the (unreachable\n  given the >=28 length check) short case is an Err, not a panic on the hot path.\n- The tungstenite accept_hdr callback's #[allow(clippy::result_large_err)] is now\n  #[expect(..., reason = ...)] per project policy (the Err type is fixed by the\n  third-party callback signature and cannot be boxed).",
          "is_bot": false,
          "headline": "server: non-panicking IV split in decrypt + #[expect] over #[allow]",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T19:14:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "27319462147b8b20b2b7395dada15e3c768df258",
          "body": "… interest\n\n- subscribe_connection drops any topic containing an ASCII control character at\n  the single chokepoint where topics enter local interest. The cluster RESYNC\n  wire format newline-delimits topics, so a '\\n' in a topic name was decoded by\n  a peer as two separate interest entries -- corru\n[…]\nT_PER_PEER so\n  a buggy or compromised (but authenticated) peer streaming distinct SUB frames\n  cannot grow it without limit; a re-sub of an existing topic always succeeds.\n\nTests green; clippy clean.",
          "is_bot": false,
          "headline": "cluster: reject control-char topics (RESYNC injection) + cap per-peer…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T19:12:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ea8511354736373c9d4b03700ae7e3eaed163d25",
          "body": "… (DoS)\n\n- encode_presence_update gained the MAX_FRAME_SIZE guard every other encoder\n  already has. presence_max_data_size is operator-configurable; a large presence\n  update could otherwise emit a frame the receiving peer_reader rejects (>1 MB),\n  disconnecting and flapping the peer on ordinary pr\n[…]\nSTER_PEERS, so a declared u16 count (up to 65535) cannot force a large\n  transient allocation and a 1 MB frame of tiny entries cannot expand into a\n  huge addr Vec.\n\ncluster tests green; clippy clean.",
          "is_bot": false,
          "headline": "cluster: frame-size guard on presence updates + bound PeerList decode…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T19:10:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7ed439968fdd37d70c1240c67948cb189b31d156",
          "body": "…READMEs\n\nThe \"Event Sequencing\" sections still described the old seq-based out-of-order\nbuffering, which was replaced by per-topic (epoch, offset) dedup + gap-triggered\nrecovery. Update both client READMEs to the current model: a duplicate (offset\nalready seen on the same epoch) is dropped, an offs\n[…]\nepoch change re-baselines, and positions survive\nreconnects; seq is diagnostic-only. Add the tp/e/o recovery-stamp fields to the\nPython WSEEvent doc and note the stamp in the TS wire-protocol summary.",
          "is_bot": false,
          "headline": "docs(clients): document the tp/e/o idempotent-delivery model in both …",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T19:04:44Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "26acf96668cb037f650559f0512e409e04041644",
          "body": "… to v2.4.0\n\n- PROTOCOL.md: document the per-message recovery stamp (tp = topic, e = epoch\n  8-hex, o = offset) -- the wire fields clients dedupe + recover on -- plus the\n  per-topic dedup / gap / recover logic and the cluster-trailer cross-reference.\n- Fix HKDF parameters across README / PROTOCOL /\n[…]\nmarising the hardening pass. Bump 2.3.2 -> 2.4.0\n  across rust/Cargo.toml, package.json, python-client, ts-client -- the new\n  tp/e/o fields are optional/additive, so a backward-compatible minor bump.",
          "is_bot": false,
          "headline": "docs: document tp/e/o recovery stamp; fix HKDF/epoch/path drift; bump…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T19:01:30Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "deb4c3e7b521a7ae88a8c0a476305265953c71f5",
          "body": "…t guard)\n\nWhen two nodes discover each other they BOTH dial, so two TCP links exist per\npair. Each node deduped locally (connected_instances.entry), and in ~half of\nraces kept opposite links -> both torn down, both reconnect, flapping (wasted\nhandshakes, transient split membership).\n\ncluster_link_s\n[…]\ntimization; correctness is covered here.)\n\nTest: lower-dialer survives, higher yields, equal rejected, and exactly one of\nA->B / B->A survives for any distinct pair. 145 lib tests green; clippy clean.",
          "is_bot": false,
          "headline": "cluster: deterministic duplicate-connection tiebreaker (+ self-connec…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T18:55:59Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0a4d4810e8e9123a8423c86dd4feca1863403bac",
          "body": "…th python)\n\nConsume the server's per-message recovery stamp (tp/e/o) and drive dedup /\nordering / recovery by per-topic (epoch, offset), mirroring the Python client.\n\n- types: WSMessage gains tp/e/o (parsed automatically -- the wire frame is\n  returned verbatim from JSON.parse).\n- EventSequencer: t\n[…]\n- a replayed message keeps its original (old)\n  ts and would otherwise be dropped, silently breaking recovery.\n\nTest: 6 checkTopicStamp cases (vitest) parallel to the Python suite. tsc --noEmit\nclean.",
          "is_bot": false,
          "headline": "client(ts): idempotent (epoch,offset) dedup + gap recovery (parity wi…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T18:06:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "87d777937828c14321c39d4b2fe52f3431281408",
          "body": "…connect\n\nTwo reconnect-robustness bugs:\n\n1. Permanent lockout. store metric reconnectCount gates canReconnect() (blocks at\n   maxReconnectAttempts=10), but it was incremented on every SUCCESSFUL reconnect\n   and never reset -- so a long-lived flaky-network session that reconnected 10\n   times was l\n[…]\nen available for reconnection' every\n   time. The sentinel is now preserved for cookie auth (only a real bearer token\n   is cleared); the HTTP-only cookie is refreshed server-side. tsc --noEmit clean.",
          "is_bot": false,
          "headline": "client(ts): fix reconnect lockout after 10 successes + cookie-auth re…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T18:00:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ad97948fe4e491725b2a599653de32f141ee9d7a",
          "body": "SecurityManager.initialize generated a standalone RANDOM AES key when\nencryption was enabled, and the send path gated on isEncryptionEnabled() (true\nimmediately). So client_hello -- sent before any key exchange -- was encrypted\nwith a key the server never had. The server drops E:-frames with no regi\n[…]\ned; the send path gates on it, so client_hello goes plaintext\n(still carrying the client's ECDH public key via isEncryptionEnabled()) and only\npost-exchange messages are encrypted. tsc --noEmit clean.",
          "is_bot": false,
          "headline": "client(ts): don't encrypt before ECDH -- fixes E2E handshake deadlock",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T17:56:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "dfcb39930352108653f61e99685716097e2c0459",
          "body": "…seq-reorder\n\nConsume the server's new per-message recovery stamp (tp/e/o) and make dedup /\nordering / recovery driven by per-topic (epoch, offset) instead of the global\n`seq`.\n\n- types/protocol: WSEEvent gains topic/epoch/offset; the codec parses tp/e/o\n  (with topic/epoch/offset long-name fallback\n[…]\ntual gap.\n\nTests: 6 check_topic_stamp cases (new/in-order/duplicate/gap-no-advance/epoch-\nreset/full-reset); server_hello test updated to the real nested wire shape. 124\nclient tests pass; ruff clean.",
          "is_bot": false,
          "headline": "client(py): idempotent (epoch,offset) dedup + recovery; drop unsound …",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T17:52:39Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "84a316c96a3fa95d097e872b8854fd682def3a3f",
          "body": "…nent zombie\n\n_heartbeat_loop calls `await self._force_reconnect()` on idle timeout, and\n_force_reconnect cancel-and-awaited self._heartbeat_task -- i.e. the CURRENTLY\nrunning task. Cancelling the current task makes the very next await (the\nasyncio.gather over the cancelled tasks) raise CancelledErr\n[…]\nnd-awaits the others, so the reconnect is\nalways scheduled. Regression test drives _force_reconnect from a task set as the\nheartbeat task and asserts the reconnect is scheduled. 118 client tests pass.",
          "is_bot": false,
          "headline": "client(py): fix idle-timeout reconnect cancelling itself into a perma…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T17:43:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a0a8c07e9b13f5f3c05f0a202c8697c2babfcdb3",
          "body": "…ecovery replay\n\nTwo coupled fixes sharing one root cause -- recovery stored PRE-FRAMED PLAINTEXT\nand framed the message before its offset was known:\n\n1. Idempotency stamping (was absent). Topic broadcasts now carry their recovery\n   coordinates as top-level JSON fields tp (topic), e (epoch, 8-hex),\n[…]\n lands.\n\nTests: push_stamped offset==storage invariant + recover returns stamped bytes;\nstamp_recovery_fields injection / empty-object / quote-escaping / non-object.\n144 lib tests green; clippy clean.",
          "is_bot": false,
          "headline": "wse: per-message (epoch,offset) stamping + per-connection encrypted r…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T17:38:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "60437b78ad96266926f141aac558f338a84a95cc",
          "body": "… leak)\n\nsubscribe_with_recovery called subscribe_connection (which filters the LIVE\nsubscription through the connection's topic ACL) but then ran the recovery loop\nover the ORIGINAL, unfiltered topic list. An authenticated connection scoped to\ne.g. user:SELF:* could pass user:OTHER:private: the liv\n[…]\nred the connection stays unrestricted (the\nfail-open default is tracked as a separate finding). Integration is covered by\nthe pytest suite against the live server; is_allowed has unit tests in jwt.rs.",
          "is_bot": false,
          "headline": "wse: fail-closed topic ACL on the recovery path (cross-tenant history…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T17:24:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "675ae0aced87930e9fe0f0f2eddce3a1d44b1a16",
          "body": "…pped\n\nencode_presence_full drops any frame over MAX_FRAME_SIZE, so a node hosting more\npresence than fits in one frame sent NO initial full-state to a joining peer --\nthat peer only ever learned the node's users from subsequent deltas, never the\npre-existing set.\n\nserialize_full_state_chunked split\n[…]\ns one chunk with all users; a tiny budget yields\nmultiple chunks whose union still covers every user, each independently valid\nJSON. 141 lib tests green; clippy clean. Completes the presence redesign.",
          "is_bot": false,
          "headline": "presence: chunk the full-state sync so a busy node isn't silently ski…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T17:11:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "363750e9374d5355f9b4c67ad57299e3f5924336",
          "body": "…sconnect\n\nThree interlocked cluster-presence correctness bugs:\n\n1. Per-origin sentinels. A remote user was tracked by a single global\n   __remote__{user_id} sentinel, added only when the entry had no connections.\n   If a user was present on two peers only the first created a sentinel, and a\n   leav\n[…]\nections) stay exact across all three paths. Tests:\nper-origin survival, LWW stale-leave ignore, purge removes only that peer's\nghosts, purge keeps a dual-homed user. 140 lib tests green; clippy clean.",
          "is_bot": false,
          "headline": "presence: per-origin sentinels + LWW leave + ghost cleanup on peer di…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T17:05:56Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2e1351cb187f9defb217cc649d92b6caf493b878",
          "body": "The JWT secret was already wrapped in Zeroizing, but symmetric key material was\nleft on the stack to be dropped un-wiped: rust_ecdh_generate_keypair's\nserialized private scalar, rust_ecdh_derive_shared_secret's derived AES-256 key,\nand derive_connection_key's per-connection AES key. Un-wiped key byt\n[…]\nnt `&*` deref in the ECDH\ntest (clippy borrow_deref_ref).\n\n136 lib tests green; clippy clean except the pre-existing cluster.rs:2315\nwarning, which the upcoming presence ghost-cleanup change resolves.",
          "is_bot": false,
          "headline": "security: zeroize derived AES keys and the serialized ECDH scalar",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T16:55:12Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "53686d85a4b3fa4a20cdad91cd9d4eb19716d221",
          "body": "… buffer\n\nRustEventSequencer::cleanup() removed a topic's expected-sequence cursor\n(expected_sequences) whenever its reorder buffer happened to be empty -- which\nis the HEALTHY in-order case, not idleness. Dropping the cursor reset gap\ndetection: the next event was treated as a brand-new topic start\n[…]\nly. reset_sequence clears last_activity too.\n\nTests: an active in-order topic with an empty buffer keeps its cursor; a topic\nidle past the TTL is evicted so the maps stay bounded. 136 lib tests green.",
          "is_bot": false,
          "headline": "sequencer: keep the per-topic ordering cursor across an empty reorder…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T16:48:39Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "810d07b21341356943cd021e6bb7aecf24c13a06",
          "body": "…erflow DoS)\n\nrmpv::decode::read_value is recursive-descent with no depth limit, so a client\non a ?format=msgpack connection could send a ~1MB frame of repeated 0x91\n(fixarray-len-1) markers, drive ~10^6 levels of recursion, and overflow the\nthread stack -> SIGABRT of the whole process (taking every\n[…]\n.rs).\n\nTests: shallow values pass, exactly-64 passes, 65 and a 100k-deep bomb are\nrejected, truncated/reserved/empty are rejected, guarded decode matches raw\nrmpv for valid input. 134 lib tests green.",
          "is_bot": false,
          "headline": "msgpack: reject over-deep inbound frames before rmpv decode (stack-ov…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T16:38:39Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c226a1317bb4afc2756fe0a86514fcb372046404",
          "body": "Two descending sort_unstable_by(|a,b| b.1.cmp(&a.1)) sorts (the Prometheus\ntop-50 per-topic message export and its test) tripped clippy's\nunnecessary_sort_by. Equal message counts have no meaningful order in a\ntop-N export, so the key form is equivalent; Reverse preserves the\ndescending order. No behavior change.",
          "is_bot": false,
          "headline": "clippy: use sort_unstable_by_key(Reverse) for metrics top-N",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T16:30:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e92d66cbc28a069a3f49e1df6d3951d0e3714ac6",
          "body": "…ble OOM\n\npeer_reader decoded every inbound MSG straight onto an UNBOUNDED dispatch\nchannel (mpsc::unbounded_channel) with a non-blocking send. The comment\nclaimed peer channels were \"bounded (10K) ... messages dropped\", but that only\nheld for the outbound writer (peer_write_tx); the inbound data pl\n[…]\n\nsignatures (peer_reader, peer_dispatch_task) move to the bounded channel.\n\nTest: dispatch_channel_is_bounded_and_sheds_when_full pins that try_send fails\npast the cap. cluster 53 / recovery 18 green.",
          "is_bot": false,
          "headline": "cluster: bound the inbound MSG dispatch queue to stop remote-triggera…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-06-10T16:28:16Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "529a08234ed15c7512bb449f69f5e76dde2bd046",
          "body": "Transitive dep via jsonwebtoken. WSE only uses JWT signature\nverification, never RSA decryption. Not exploitable. No upstream fix.",
          "is_bot": false,
          "headline": "CI: ignore RUSTSEC-2023-0071 (rsa Marvin Attack)",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-22T21:38:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5e6efc2c38528cb02269cb6eeff22162ecae5ac3",
          "body": "Rust: tokio-tungstenite 0.28->0.29, cargo update (11 crates)\nnpm: zustand 5.0.12, @types/node 25.5.0, vitest 4.1.0\nCI: all actions bumped to latest node24 versions\nCI: added cargo-audit + npm audit security scan job",
          "is_bot": false,
          "headline": "Update all deps, CI actions to node24, add security audit",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-22T21:32:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b0a353c0d887808bcf990af1862318c35b79f53f",
          "body": "Tests create AsyncWSEClient without calling connect(), so _event_queue\nand _server_ready_event were None after lazy init change.",
          "is_bot": false,
          "headline": "Fix test_client.py: initialize lazy asyncio primitives in test fixture",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-22T21:11:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4d7ee36bdfc9e3cc8b50c54aee673f89c210d76a",
          "body": "Extract RustWSEServer::new body into build() with grouped param structs.\nExtract connect_cluster body into connect_cluster_inner with tuple grouping.\nExtract jwt_decode logic into jwt_decode_with_rotation helper.\n\n3 remaining #[expect(clippy::too_many_arguments)] are all PyO3 boundary\nfunctions where param count = Python API surface. #[expect] documents the\nreason and warns if the lint stops firing.",
          "is_bot": false,
          "headline": "Replace #[allow] with #[expect] for PyO3 boundary functions",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-22T21:07:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "88b0e3b9d18f759dd662969c324a671520e21a45",
          "body": "Only PyO3 boundary functions retain #[allow(clippy::too_many_arguments)]\n(3 remaining, down from 10).",
          "is_bot": false,
          "headline": "Refactor SharedState::new: SharedStateConfig struct replaces 14 args",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-22T18:47:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fbb51d1142550a5ab715fab63435e8dc6e66d64c",
          "body": "All 6 cluster peer functions now take 7 or fewer arguments.\nRemoved all #[allow(clippy::too_many_arguments)] from cluster.rs.\nNet -170 lines.",
          "is_bot": false,
          "headline": "Refactor cluster functions: ClusterContext struct replaces 15+ args",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-22T17:51:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "23f39b2fa5129d33e0ef0de2e1053f0e162bc6ba",
          "body": "Security: fix HKDF salt/IKM swap (RFC 5869), add 10s handshake timeout,\nwarn on plaintext cluster connections, add max_subscriptions_per_connection,\nzeroize JWT secrets on drop.\n\nBugs: fix pending counter underflow (saturating_sub), fix PEER_SESSION_GENERATION\nordering (Relaxed -> AcqRel), fix recov\n[…]\nady\non reconnect.\n\nTS client: per-instance circuit breaker interval, configurable event throttle,\nfix interval leak on unmount-remount.\n\nDead code cleanup: remove all #[allow(dead_code)] suppressions.",
          "is_bot": false,
          "headline": "v2.3.2 -- Security fixes, bug fixes, client hardening",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-22T16:16:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7b87a40ecf27eab1c059e9eaf65da65944556550",
          "body": "…t everywhere",
          "is_bot": false,
          "headline": "Rename client/ to ts-client/, replace TypeScript client with TS clien…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-08T02:12:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f0b1883327b08e3723720580a432ef18240450d6",
          "body": "- Added /// docstrings to all 32 PyO3 methods (IDE hints + help())\n- Added prometheus_metrics() to .pyi type stub\n- Fixed drain_inbound() docstring (missing presence_join/presence_leave)\n- Bumped all packages to 2.3.1 (server, Python client, TS client)",
          "is_bot": false,
          "headline": "v2.3.1 -- PyO3 docstrings, .pyi stub fix, version sync",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-08T01:51:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "453583cc56f4c6271a26c6b36004553dbc3f7c5b",
          "body": null,
          "is_bot": false,
          "headline": "Fix drain() default values in docs (timeout=30, close_reason empty)",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-07T18:55:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6bf42db9d492161c82577c8a95df07fd54c711c6",
          "body": null,
          "is_bot": false,
          "headline": "Fix cargo fmt in drain timeout handler",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-07T18:51:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "92898a07e1c7caa5c378e047175bed87ebe5df84",
          "body": "… cluster topology API\n\nCluster phases:\n- Replicated recovery with crdt-style merge and cross-node RESYNC\n- Topic ACL with glob pattern matching (allow/deny per connection)\n- Graceful drain with close code 4300 and cluster peer notification\n- Queue groups with round-robin dispatch and cluster-aware \n[…]\nonsumer_drops\n\nTesting:\n- 5 new battle tests (queue-groups, topic-acl, drain, metrics, topology)\n- Fixed battle-presence Binary frame handling\n- 128 Rust unit tests passing, 15/15 battle tests passing",
          "is_bot": false,
          "headline": "v2.3.0 -- Queue groups, topic ACL, graceful drain, per-topic metrics,…",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-07T18:47:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bce45678cbd8b4348254f7044c823fb8bd651baf",
          "body": "Test JWT secret was 31 bytes, now 32+ to satisfy RFC 7518 min key check.",
          "is_bot": false,
          "headline": "Fix test secret length for 32-byte HS256 minimum",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-06T23:05:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e48b47213ae64c09ccc5e545401dac507ce4edd3",
          "body": "RS256 + ES256 asymmetric JWT algorithms via jsonwebtoken v10 crate.\nReplaces hand-rolled HMAC crypto. Algorithm confusion prevention,\nkey rotation for all algorithms, kid validation, min key enforcement.\n\nJWT hardening: 8KB token size limit, 30s clock skew, empty sub\nrejection, explicit error mapping for RSA/ECDSA failures, auth\nclose code 4401, eager PEM validation at startup.",
          "is_bot": false,
          "headline": "v2.2.1 -- RS256/ES256 JWT support, JWT hardening, review fixes",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-06T22:58:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f07786b50993dbc15859ff500ff06e4c51c458f2",
          "body": null,
          "is_bot": false,
          "headline": "Suppress result_large_err clippy lint on WS upgrade closure",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-06T16:41:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "67fe1d43609b835e4957384e87b09eedde857fc8",
          "body": "OOM protection: per-connection byte-based backpressure (max_outbound_queue_bytes),\nslow consumer drops counter, two-phase zombie detection with 10s grace.\n\nFan-out rewrite: direct buffer writes (Mutex<BytesMut> + Notify) bypass mpsc\nchannels. Connection handles stored in topic subscriptions (no Hash\n[…]\n.md index, BENCHMARKS_FANOUT.md v2.2.0\nsections, INTEGRATION.md metrics, DEPLOYMENT.md alerts.\n\nDependencies: tokio 1.50, chrono 0.4.44, uuid 1.22, rmpv 1.3.1.\n\n81/81 tests pass, zero clippy warnings.",
          "is_bot": false,
          "headline": "v2.2.0 -- OOM protection, direct buffer fan-out, pre-release hardening",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-06T16:14:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a71780073412d78a2d45fe8fd6676da48d72f0c3",
          "body": "- Move fetch_sub after write completes (not at dequeue) for accurate\n  backpressure accounting, matching NATS/Centrifugo semantics\n- Hoist raw_slices Vec out of write task loop to avoid per-batch alloc\n- Track encrypt_outbound failures in slow_consumer_drops counter\n- Clean stale entries from suspected_slow set on disconnected connections\n- Pre-bake \"c\" field in benchmark to skip inject_category overhead",
          "is_bot": false,
          "headline": "Code review fixes: accurate backpressure, hoist write allocs, cleanup",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-02T21:59:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "27d5ccd232eab3c319c41e164ac86c72547ceba3",
          "body": "The timestamp-based throughput gating (only count messages where ts_us\n>= measurement_start_us) doesn't work with high-rate publishers. At\n400K+ msg/s, the server's per-connection channel builds a backlog\nfaster than the 2s drain warmup can clear. All messages during\nmeasurement end up \"stale\" (time\n[…]\nreal delivery.\n\nKeep timestamp gating only for latency recording: only measure\nlatency for messages published after measurement started, since\nbacklogged messages would show artificially high latency.",
          "is_bot": false,
          "headline": "Revert benchmark timestamp gating -- incompatible with pipeline backlog",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-02T21:04:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "673d0c61859d9e789c84cbb159aeb21e359a8ebf",
          "body": "Convert per-connection backpressure from message-count to byte-count\ntracking (industry standard per NATS/Centrifugo). Add ws_frame_size()\nhelper, rename max_outbound_queue_size -> max_outbound_queue_bytes\n(default 16MB), update all 40+ fetch_add/fetch_sub call sites.\n\nFix benchmark throughput infla\n[…]\n_received/local_bytes\non measurement_start_us timestamp so stale warmup messages aren't\ncounted. Fix cumulative Prometheus drops counter by capturing\nbefore/after delta per tier in all 3 fanout tests.",
          "is_bot": false,
          "headline": "Byte-based OOM protection, fix benchmark measurement accuracy",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-02T20:29:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4dcae55e06615fd9db6889d64c13d9224cd760b4",
          "body": "- Move pending.fetch_add() BEFORE tx.send() at all 17+ call sites\n  to prevent counter underflow when write task drains between send\n  and increment. Decrement on send failure.\n- Add continue after suspected_slow.insert() in zombie detector\n  to avoid sending ping to connections with full queues.\n- \n[…]\ne Vec allocation + N Arc clones in BroadcastText/BroadcastBytes\n  fast path: new fanout_all_connections() does fanout directly from\n  connections map while holding the read lock (send is synchronous).",
          "is_bot": false,
          "headline": "Fix TOCTOU race, zombie detector bug, optimize broadcast hot path",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-02T19:58:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "83645d4100a66f13f39856d46e4e2b731a328315",
          "body": "Bench server exposes Prometheus metrics via HTTP on port+1000.\nRust benchmark queries wse_slow_consumer_drops_total after each tier\nand prints the result. Covers single-node, cluster, and cluster-tls tests.",
          "is_bot": false,
          "headline": "Add slow_consumer_drops query to fanout benchmarks",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-02T18:45:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "29ed04f0a0c9c376cf612789b842bb8729f0340c",
          "body": "Per-connection outbound channels stay unbounded (no semaphore overhead),\nbut each connection tracks pending message count via Arc<AtomicUsize>\nwith Relaxed ordering (~3ns per send vs ~20ns for tokio bounded).\n\nFan-out hot path checks pending >= max_outbound_queue_size before send,\ndrops message if f\n[…]\n\nreconnect gaps.\n\nNew constructor param: max_outbound_queue_size (default 8192)\nNew Prometheus metric: wse_slow_consumer_drops_total\nCluster paths propagate limits through all peer dispatch functions.",
          "is_bot": false,
          "headline": "OOM protection: unbounded channels + AtomicUsize pending counter",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-02T18:35:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9f4693334699ff88f3e577ea48b575ce5e9136d5",
          "body": "Replace 2s sleep warmup with active drain loop that reads and discards\nall buffered messages. Add timestamp gating so only messages published\nafter measurement_start_us count toward latency (stale messages from\ninter-tier publishing still count for throughput).\n\nFixes invalid 37-250s latency numbers in benchmark output.",
          "is_bot": false,
          "headline": "Fix benchmark latency: active drain warmup + timestamp gating",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-02T18:01:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5ddd02724bf0c9fc23aaf60604450d1e75132178",
          "body": "Add constructor parameters for rate_limit_capacity, rate_limit_refill,\nmax_message_size, ping_interval, idle_timeout with sensible defaults.\nRemove hardcoded constants and .min(131072) clamp on inbound queue.",
          "is_bot": false,
          "headline": "Make hardcoded server params configurable",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-02T13:18:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dd053e600884d6c4fc1c97f9115b95c8d09d51f5",
          "body": "- Fix Python client to read c field from JSON (not just wire prefix)\n- Update all docs, examples, tests, benchmarks to use c field format\n- Remove all remaining WSE{ wire prefix usage from non-receive paths",
          "is_bot": false,
          "headline": "v2.1.1 - Fix c field consistency across docs, tests, Python client",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-01T11:04:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c4cf5e7f36b67251fe0812ba667146dfe1a7ffca",
          "body": "- Fix INTEGRATION.md: send/broadcast examples, presence events, wire format table\n- Fix SECURITY.md: add c field to signed message example\n- Fix README.md: wire protocol description\n- Fix integration tests: replace all WSE{ prefix with c field JSON\n- Fix bench_battle_server: replace WSE prefix in send() calls",
          "is_bot": false,
          "headline": "Update remaining docs, tests, benchmarks to use c field format",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-01T10:57:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "774af27ecea21da7a06cfe26be640de8b7f84d1d",
          "body": "- Update all PROTOCOL.md JSON examples from wire prefix to c field format\n- Fix Python client _parsed_to_event to read c field from JSON\n- Add c/v fields to examples/ send() calls (standalone_basic, standalone_recovery)\n- Remove old WSE wire prefix from standalone_recovery send()\n- Update wire protocol descriptions in client and python-client READMEs",
          "is_bot": false,
          "headline": "Update protocol examples and fix Python client c field parsing",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-01T05:21:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fc670107f20bc19bf46c5417019d8862a91cd481",
          "body": null,
          "is_bot": false,
          "headline": "v2.1.0 - Prometheus metrics, wire prefix removal, message category field",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-01T04:49:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "67d588cb2ee9e2dd7042cecd142b24a7ab1062af",
          "body": null,
          "is_bot": false,
          "headline": "v2.1.0 - Prometheus metrics, wire prefix removal, message category field",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-01T04:39:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "03ffbe6506735922b213ad718c9d10873355b496",
          "body": null,
          "is_bot": false,
          "headline": "Update deployment docs with Prometheus, fix missed test prefix strip",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-01T04:37:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1e29aed07610364f6bac1f98996dc6514b4bcc4a",
          "body": "8 new atomic counters (messages in/out, bytes in/out, connections\naccepted/rejected, auth failures, rate limited) plus prometheus_metrics()\nPyO3 method returning text exposition format. 25 metrics total including\nexisting cluster, recovery, and presence stats.",
          "is_bot": false,
          "headline": "Add Prometheus metrics endpoint",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-01T04:31:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ba0d67ce9b6ba17e880d224e460dfad79770a6dc",
          "body": "- Remove WSE{/S{/U{ wire prefix from all outbound messages\n- Add \"c\" field (category) as first field in JSON: {\"c\":\"U\",\"t\":\"bar_update\",...}\n- Field order: c first, t second, v last for DevTools readability\n- All messages now have c field (was missing on non-snapshot events)\n- Rename _msg_cat to c across server, transformer, TS and Python clients\n- Rust auto-injects c for broadcast_local/broadcast/broadcast_all\n- Backwards-compatible: clients still parse incoming wire prefix",
          "is_bot": false,
          "headline": "Replace wire prefix with c field inside JSON",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-01T03:59:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "289e7e3b0042ad10ea22b9b2736d6fbf42891eb3",
          "body": "- Add jwt_cookie_name parameter to RustWSEServer (default: \"access_token\")\n- Use configured cookie name instead of hardcoded value in auth\n- Add TS/React client file structure and provider setup guide\n- Add publishing patterns docs (Pattern A: publisher-based, Pattern B: event sourcing)\n- Update JWT auth docs across PROTOCOL.md, SECURITY.md, INTEGRATION.md, DEPLOYMENT.md",
          "is_bot": false,
          "headline": "v2.0.8 - Configurable JWT cookie name, publishing patterns docs",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-03-01T02:22:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7a645ab391dc9231a8c032befbc1d6ef683e9689",
          "body": "Cluster protocol:\n- Only forward PeerAnnounce for newly discovered peers (dedup)\n- Remove gossip-discovered peers from known_peers on disconnect\n- Guard static peers from known_peers removal (prevent duplicate tasks)",
          "is_bot": false,
          "headline": "v2.0.7 - Fix gossip amplification and known_peers cleanup",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-02-28T15:46:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a3a75a30c884e18187f56b920617c31941e9bcad",
          "body": "Server (Rust):\n- Skip presence events in recovery ring buffer (skip_recovery flag)\n- Fix presence user double-count with remote sentinels\n- Fix sweep_dead_connections race (remove -> remove_if)\n- Fix sweep leaving dead local conns with remote sentinels\n- Fix recovery get() silent drop in release bui\n[…]\nult (300s -> 3600s)\n- Fix record_success(0.0) spurious zero-latency entries\n- Fix send_bytes crash on non-UTF-8 data with E2E encryption\n\nTS client:\n- Fix SEQUENCE_WINDOW_SIZE constant (1000 -> 10000)",
          "is_bot": false,
          "headline": "v2.0.6 - Fix presence recovery, sweep race, client protocol bugs",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-02-28T15:11:51Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "db84958aff20dbec25fbc6be0198337265f03514",
          "body": null,
          "is_bot": false,
          "headline": "Fix ruff formatting",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-02-28T14:35:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1b2ad47eaede74d8ff2ce80a6fdb65d4f72c7f26",
          "body": "Align Python client with TS client:\n- PONG response: server_timestamp + client_timestamp keys\n- Rate limiter: discrete refill with interval snapback\n- ConnectionPool: scaled failure penalty, latency/consistency bonus, time decay\n- Fibonacci reconnect: match TS delay sequence\n\nFix TS SEQUENCE_WINDOW_SIZE constant (1000 -> 10000)",
          "is_bot": false,
          "headline": "v2.0.5 - Sync Python and TS client protocol behavior",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-02-28T14:29:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cfd47d3f6f280caee688c22c82037578f1b86aeb",
          "body": "- Fix change_endpoint() injecting sentinel into message iterator\n- Fix recv-loop exception leaving heartbeat running (double reconnect)\n- Fix offline queue losing message priority on partial flush\n- Fix CLIENT_VERSION constant not matching package version",
          "is_bot": false,
          "headline": "v2.0.4 - Fix Python client reconnect and queue bugs",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-02-28T14:20:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "35257b56d5b549096d128b7829b180fd90ac96ec",
          "body": null,
          "is_bot": false,
          "headline": "Update CHANGELOG for v2.0.3",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-02-28T13:58:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1305901a102856ccb00af67a65bf6ce774e7a8df",
          "body": "- Fix HMAC signing auto-activation when encryption enabled\n- Fix send_bytes() bypassing E2E encryption\n- Fix key rotation not restarting after reconnect\n- Fix offline queue message loss on partial flush failure\n- Fix SyncWSEClient stale error state on retry\n- Fix connection pool active count growing on force-reconnect",
          "is_bot": false,
          "headline": "v2.0.3 - Python client bug fixes",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-02-28T13:53:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6dc4f760ec2ba1cec7be523fe4dda5e6e76a5529",
          "body": null,
          "is_bot": false,
          "headline": "v2.0.2 - Bug fixes and documentation updates",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-02-28T12:30:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b957557b8b5a34b791696307e827ce7dfd92c2f8",
          "body": null,
          "is_bot": false,
          "headline": "Fix import sorting in conftest.py",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-02-28T11:48:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cad6f9ad1c2ed87b87bb8067b5eea9524bdae598",
          "body": null,
          "is_bot": false,
          "headline": "Fix ruff lint and format errors",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-02-28T11:47:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8d7fc15abc2e93889d4c0c43b56f66bc757cdf52",
          "body": null,
          "is_bot": false,
          "headline": "v2.0.1 - Minor fixes",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-02-28T11:43:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7bdcb093ef1693f7aaa64a642cd31cdf1794762d",
          "body": "IDE autocomplete and type hints for all PyO3 bindings:\n7 classes, 14 functions, full signatures and docstrings.\nUpdate pyproject.toml description.",
          "is_bot": false,
          "headline": "Add .pyi type stubs for Rust extension module",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-02-28T11:01:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "39c291ed6af6392a8ac3b8bdf594184a0141e086",
          "body": "- Fan-out standalone: 4.3M -> 5.0M del/s (new test run)\n- Fan-in JSON: 14.2M -> 14.7M msg/s, size matrix updated\n- README, BENCHMARKS.md, FANOUT, RUST_CLIENT tables updated\n- Kept old data for untested tiers (50K+)\n- Changelog date corrected to 2026-02-28\n- Remove em-dashes from TS and Python benchmark docs",
          "is_bot": false,
          "headline": "Update v2.0.0 benchmark numbers, fix changelog date",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-02-28T05:47:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2e39c097773b2087006b1a09f5710977ae1e0258",
          "body": "Fresh run: peak 14.7M msg/s at 500-1000 conns (was 14.2M).\nUpdated throughput matrix across all payload sizes.",
          "is_bot": false,
          "headline": "Update Rust client benchmark numbers",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-02-28T04:32:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d2e312077afc021d164091438761463d7e176530",
          "body": "Removed \"Comparison with Alternatives\" section (throughput + features\ntables referencing Centrifugo, uWebSockets, Socket.IO, ws).",
          "is_bot": false,
          "headline": "Remove competitor comparison tables from benchmarks",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-02-28T04:32:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "950e0960c25b061acb7f66c050da801e76f427f9",
          "body": "Docs:\n- README: full rewrite with 7 feature tables, complete API reference\n- New docs: CONTRIBUTING.md, DEPLOYMENT.md, MIGRATION.md (v1->v2)\n- All docs verified against Rust source in 4 audit passes\n- Fixed health_snapshot field names (cluster_peer_count, all cluster metrics)\n- Fixed server_hello/se\n[…]\nS client: fixed UseWSEReturn.requestSnapshot type signature\n\nTests:\n- Added integration test suite (25 tests)\n- Added battle benchmark tests for presence and recovery\n- Removed /tests/ from .gitignore",
          "is_bot": false,
          "headline": "Comprehensive documentation overhaul, add integration tests",
          "author_name": "silvermpx",
          "author_login": "silvermpx",
          "committed_at": "2026-02-28T04:12:57Z",
          "body_truncated": true,
          "is_coding_agent": false
        }
      ],
      "releases_count": 39,
      "commits_last_year": 264,
      "latest_release_at": "2026-07-12T13:32:32Z",
      "latest_release_tag": "v2.4.1",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 7,
      "days_since_latest_release": 18,
      "mean_days_between_releases": 14.8
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 71,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "wse-client",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "websocket",
            "react",
            "hooks",
            "real-time",
            "events",
            "pubsub",
            "encryption",
            "rust",
            "zustand"
          ],
          "ecosystem": "npm",
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/wse-client",
          "is_deprecated": false,
          "latest_version": "2.4.1",
          "repository_url": "https://github.com/silvermpx/wse",
          "versions_count": 42,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 276,
          "first_published_at": "2026-02-20T17:49:01.355000Z",
          "latest_published_at": "2026-07-12T13:20:02.065000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 18
        },
        {
          "name": "wse-server",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "websocket",
            "engine",
            "real-time",
            "pubsub",
            "cluster",
            "encrypted",
            "rust",
            "Development Status :: 5 - Production/Stable",
            "Intended Audience :: Developers",
            "License :: OSI Approved :: MIT License",
            "Programming Language :: Python :: 3",
            "Programming Language :: Python :: 3.12",
            "Programming Language :: Python :: 3.13",
            "Programming Language :: Python :: 3.14",
            "Programming Language :: Rust",
            "Topic :: Internet :: WWW/HTTP :: HTTP Servers",
            "Topic :: System :: Networking",
            "Typing :: Typed"
          ],
          "ecosystem": "pypi",
          "matches_repo": true,
          "registry_url": "https://pypi.org/project/wse-server/",
          "is_deprecated": false,
          "latest_version": "2.4.1",
          "repository_url": "https://github.com/silvermpx/wse",
          "versions_count": 39,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": "2026-02-20T20:34:37.276477Z",
          "latest_published_at": "2026-07-12T13:19:34.531366Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 18
        },
        {
          "name": "wse-client",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "event-streaming",
            "real-time",
            "websocket",
            "wse",
            "Development Status :: 4 - Beta",
            "Framework :: AsyncIO",
            "Intended Audience :: Developers",
            "License :: OSI Approved :: MIT License",
            "Programming Language :: Python :: 3",
            "Programming Language :: Python :: 3.11",
            "Programming Language :: Python :: 3.12",
            "Programming Language :: Python :: 3.13",
            "Topic :: Internet",
            "Topic :: Software Development :: Libraries",
            "Typing :: Typed"
          ],
          "ecosystem": "pypi",
          "matches_repo": true,
          "registry_url": "https://pypi.org/project/wse-client/",
          "is_deprecated": false,
          "latest_version": "2.4.1",
          "repository_url": "https://github.com/silvermpx/wse",
          "versions_count": 25,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": "2026-02-22T21:36:37.875816Z",
          "latest_published_at": "2026-07-12T13:20:23.230543Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 18
        }
      ]
    },
    "popularity": {
      "forks": 1,
      "stars": 50,
      "watchers": 3,
      "fork_history": {
        "days": [
          {
            "date": "2026-04-07",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 1,
        "total_forks": 1
      },
      "star_history": null,
      "open_issues_and_prs": 4
    },
    "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": [
        "benchmarks/ts-bench/tsconfig.json",
        "tsconfig.json",
        "wse_server/py.typed"
      ],
      "toolchain_manifests": [
        "benchmarks/rust-bench/Cargo.toml",
        "rust/Cargo.toml"
      ],
      "largest_source_bytes": 247962,
      "source_files_sampled": 138,
      "oversized_source_files": 2,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "package.json",
        "pyproject.toml",
        "python-client/pyproject.toml",
        "rust/Cargo.toml"
      ],
      "advisories": {
        "error": null,
        "scope": "published_package",
        "source": "osv",
        "findings": [],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 2,
        "malicious_count": 0,
        "assessed_package": "npm:wse-client@2.4.1",
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "crates",
        "npm",
        "pypi"
      ],
      "dependencies": [
        {
          "name": "@msgpack/msgpack",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^3.0.0"
        },
        {
          "name": "pako",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.1.0"
        },
        {
          "name": "websockets",
          "manifest": "python-client/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=13.0"
        },
        {
          "name": "pyo3",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.29"
        },
        {
          "name": "serde",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1.0.228"
        },
        {
          "name": "serde_json",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1.0.149"
        },
        {
          "name": "flate2",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1.1.9"
        },
        {
          "name": "rmp-serde",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1.3.1"
        },
        {
          "name": "rmpv",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1.3.1"
        },
        {
          "name": "hmac",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.12.1"
        },
        {
          "name": "sha2",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.10.9"
        },
        {
          "name": "hex",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.4"
        },
        {
          "name": "ahash",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.8.12"
        },
        {
          "name": "dashmap",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "6"
        },
        {
          "name": "aes-gcm",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.10"
        },
        {
          "name": "p256",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.13"
        },
        {
          "name": "jsonwebtoken",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "10"
        },
        {
          "name": "hkdf",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.12"
        },
        {
          "name": "uuid",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1.22.0"
        },
        {
          "name": "base64",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.22"
        },
        {
          "name": "chrono",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.4.44"
        },
        {
          "name": "regex",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1.12.3"
        },
        {
          "name": "tokio",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1.50.0"
        },
        {
          "name": "tokio-tungstenite",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.29.0"
        },
        {
          "name": "futures-util",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.3.32"
        },
        {
          "name": "crossbeam-channel",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.5"
        },
        {
          "name": "tokio-util",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.7"
        },
        {
          "name": "socket2",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.6"
        },
        {
          "name": "bytes",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "mimalloc",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.1"
        },
        {
          "name": "tokio-rustls",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.26"
        },
        {
          "name": "rustls",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.23"
        },
        {
          "name": "rustls-pki-types",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "zstd",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.13"
        },
        {
          "name": "parking_lot",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.12"
        },
        {
          "name": "indexmap",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "2"
        },
        {
          "name": "zeroize",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "tracing",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.1"
        },
        {
          "name": "tracing-subscriber",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.3"
        },
        {
          "name": "arc-swap",
          "manifest": "rust/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        }
      ],
      "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": 4,
        "merged_prs": 10,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 32
      },
      "bus_factor": 1,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "silvermpx",
          "commits": 247,
          "avatar_url": "https://avatars.githubusercontent.com/u/42042558?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "release.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "Cargo.lock",
        "package-lock.json"
      ],
      "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": "8 out of 8 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/22 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": 6,
            "reason": "dependency not pinned by hash detected -- score normalized to 6",
            "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": 0,
            "reason": "Project has not signed or included provenance with any releases.",
            "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": 4,
            "reason": "6 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "16836ae51c677eef4fa61c1f73c82580b37173b3",
        "ran_at": "2026-07-31T00:01:25Z",
        "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-31T00:01:12Z",
      "oldest_open_prs": [
        {
          "number": 27,
          "created_at": "2026-03-27T00:10:33Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 32,
          "created_at": "2026-04-03T00:12:17Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 41,
          "created_at": "2026-04-17T00:12:47Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 46,
          "created_at": "2026-07-30T23:53:17Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-31T00:01:05Z",
      "ci_last_conclusion": null,
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/silvermpx/wse",
    "host": "github.com",
    "name": "wse",
    "owner": "silvermpx"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "good",
      "name": "Overall health",
      "note": "The weighted overall 60 is calibrated to 65 on the published index scale (record calibration 2026-08-02).",
      "notes": [
        {
          "code": "overall_calibration",
          "params": {
            "raw": 60,
            "calibrated": 65,
            "calibration": "2026-08-02"
          }
        }
      ],
      "value": 65,
      "inputs": {
        "security": 70,
        "vitality": 77,
        "community": 46,
        "governance": 37,
        "calibration": "2026-08-02",
        "engineering": 75,
        "ai_readiness": 61,
        "weighted_overall_raw": 60
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 77,
        "weight": 0.21,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 69,
            "inputs": {
              "commits_last_year": 264,
              "human_commit_share": 0.92,
              "days_since_last_push": 0,
              "active_weeks_last_year": 7
            },
            "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": "7/52 weeks with commits",
                "points": 4.8,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 7
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "264 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 264
                    }
                  }
                ],
                "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": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "releases_count": 39,
              "latest_release_tag": "v2.4.1",
              "releases_from_tags": false,
              "days_since_latest_release": 18,
              "mean_days_between_releases": 14.8
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "39 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 39
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 18 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 18
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~14.8 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 14.8
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "exceptional",
            "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": "weak",
        "name": "Community & Adoption",
        "value": 46,
        "weight": 0.17,
        "metrics": [
          {
            "key": "popularity",
            "band": "at_risk",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 29,
            "inputs": {
              "forks": 1,
              "stars": 50,
              "watchers": 3,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "50 stars",
                "points": 27.4,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 50
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "1 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "3 watchers",
                "points": 1.7,
                "status": "partial",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "good",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "readme_badges": null,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "readme_badge_services": [],
              "has_pull_request_template": false
            },
            "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": 0,
                "status": "missed",
                "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": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "weak",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 41,
            "inputs": {
              "packages": [
                "wse-client",
                "wse-server",
                "wse-client"
              ],
              "dependents": null,
              "ecosystems": "npm, pypi",
              "total_downloads": null,
              "monthly_downloads": 276
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "276 downloads/month across npm, pypi",
                "points": 32.6,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 276,
                      "ecosystems": "npm, pypi"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "weak",
        "name": "Sustainability & Governance",
        "value": 37,
        "weight": 0.23,
        "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": "critical",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution, Newcomer PR acceptance. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution",
                    "newcomer_pr_acceptance"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 16,
            "inputs": {
              "merged_prs": 10,
              "open_issues": 0,
              "closed_issues": 0,
              "prs_merged_7d": null,
              "prs_decided_7d": null,
              "prs_merged_30d": null,
              "prs_decided_30d": null,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 32,
              "first_time_authors_30d": null,
              "first_time_prs_merged_30d": null,
              "first_time_prs_decided_30d": null
            },
            "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": 42
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "10/42 decided PRs merged",
                "points": 7.1,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 10,
                      "decided": 42
                    }
                  }
                ],
                "max_points": 30
              },
              {
                "key": "newcomer_pr_acceptance",
                "name": "Newcomer PR acceptance",
                "detail": "no first-time contributor's PR decided in 30d",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_newcomer_prs",
                    "params": {
                      "days": 30
                    }
                  }
                ],
                "max_points": 13
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/22 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "weak",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 41,
            "inputs": {
              "followers": 7,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "silvermpx",
              "public_repos": 3,
              "account_age_days": 2919
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "7 followers of silvermpx",
                "points": 6.5,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 7,
                      "login": "silvermpx"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "3 public repos, account ~7 yr old",
                "points": 16.4,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 3
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 7
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "exceptional",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "wse-client",
                "wse-server",
                "wse-client"
              ],
              "ecosystems": "npm, pypi",
              "any_deprecated": false,
              "min_days_since_publish": 18
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "3 package(s) on npm, pypi",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 3,
                      "ecosystems": "npm, pypi"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 18 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 18
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "42 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 42
                    }
                  }
                ],
                "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": 75,
        "weight": 0.19,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "good",
            "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": "8 out of 8 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "excellent",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "topics": [
                "encryption",
                "high-performance",
                "jwt",
                "pyo3",
                "python",
                "real-time",
                "rust",
                "tokio",
                "websocket",
                "websocket-server"
              ],
              "has_wiki": true,
              "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": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "good",
        "name": "Security",
        "value": 70,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "moderate",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Branch-Protection. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "branch_protection"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 63,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 17,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 1,
              "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": "8 out of 8 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/22 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 6",
                "points": 3,
                "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": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "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": "6 existing vulnerabilities detected",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "exceptional",
            "name": "Dependency advisories",
            "note": "Excluded from scoring (no data or not applicable): No advisories left outstanding. Remaining weights renormalized. Matched the npm:wse-client@2.4.1 runtime dependency closure — what installing the published package pulls in — 2 packages. Reachability is not analyzed.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "no_advisories_left_outstanding"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              },
              {
                "code": "advisories_scope_published",
                "params": {
                  "package": "npm:wse-client@2.4.1",
                  "assessed": 2
                }
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "source": "osv",
              "advisories": 0,
              "affected_packages": 0,
              "assessed_packages": 2,
              "unassessed_packages": 0,
              "affected_by_severity": "none",
              "direct_affected_packages": 0
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "no direct dependency carries a known advisory",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "no_direct_advisories",
                    "params": {}
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "no indirect dependency carries a known advisory",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "no_indirect_advisories",
                    "params": {}
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory carries a publication date",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_no_publication_date",
                    "params": {}
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "exceptional",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 2,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "exceptional",
            "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"
              ],
              "commit_weight_rule": {
                "min_commits": 50,
                "min_commit_share": 0.1
              },
              "review_only_matches": 0,
              "below_threshold_exposures": [],
              "assessed_self_published_locations": 2
            },
            "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.04,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "weak",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.848,
              "agent_instruction_files": [],
              "agent_instruction_max_bytes": null
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "no CLAUDE.md / AGENTS.md / editor rules",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_instructions",
                    "params": {}
                  }
                ],
                "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": "78 of 92 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 78,
                      "sampled": 92
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "good",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "Cargo.lock",
                "package-lock.json"
              ],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "benchmarks/ts-bench/tsconfig.json",
                "tsconfig.json",
                "wse_server/py.typed"
              ],
              "agent_commit_share": 0,
              "toolchain_manifests": [
                "benchmarks/rust-bench/Cargo.toml",
                "rust/Cargo.toml"
              ],
              "dependency_bot_commit_share": 0.08
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "benchmarks/rust-bench/Cargo.toml, rust/Cargo.toml (toolchain convention, no task runner)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "toolchain_convention",
                    "params": {
                      "files": "benchmarks/rust-bench/Cargo.toml, rust/Cargo.toml"
                    }
                  }
                ],
                "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": "benchmarks/ts-bench/tsconfig.json, tsconfig.json, wse_server/py.typed",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "benchmarks/ts-bench/tsconfig.json, tsconfig.json, wse_server/py.typed"
                    }
                  }
                ],
                "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": "no agent-authored commits among the last 100",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_authored_commits",
                    "params": {
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "8 of the last 100 commits are automated dependency updates",
                "points": 8,
                "status": "met",
                "details": [
                  {
                    "code": "dependency_bot_commits",
                    "params": {
                      "count": 8,
                      "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 6",
                "points": 6,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "exceptional",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 99,
            "inputs": {
              "primary_language": "Rust",
              "largest_source_bytes": 247962,
              "source_files_sampled": 138,
              "oversized_source_files": 2
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Rust (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Rust"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "2/138 source files over 60KB",
                "points": 54.2,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 138,
                      "oversized": 2
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "weak",
            "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? Carries a deliberately small weight: agent tooling is a real maintenance signal, but its absence must never gate the top of the scale (calibration saturates at raw 91, so 100/100 remains reachable with AI Readiness at zero)."
      }
    ],
    "classification": {
      "top": [
        "library"
      ],
      "labels": [
        "library"
      ],
      "scores": {
        "library": 12
      },
      "primary": "library",
      "evidence": [
        {
          "tier": "distribution",
          "label": "library",
          "source": "registry:npm",
          "weight": 6
        },
        {
          "tier": "distribution",
          "label": "library",
          "source": "registry:pypi",
          "weight": 6
        }
      ],
      "artifacts": [],
      "confidence": "medium",
      "host_extension": false,
      "runs_as_process": false,
      "consumed_by_code": true
    },
    "metrics_version": "2.5.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "Could not fetch crates package 'wse-accel' from its registry",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-31T00:01:33.873611Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/s/silvermpx/wse.svg",
  "full_name": "silvermpx/wse",
  "license_state": "standard",
  "license_spdx": "MIT"
}

Bewertungen sind Signale, keine Garantien. Sie spiegeln öffentlich sichtbare Praxis auf GitHub wider — kein Code-Audit und keine Sicherheitsgarantie.

Fehlende Daten werden ausgeschlossen und die Gewichte neu normiert, nie als null bewertet. Die Methodik ist versioniert und offen: Metriken v2.5.0, Schema v0.27.0 — vollständige Methodik · Metriken-Wiki.

Wie ein einzelnes Ergebnis im Gesamtregister steht: aggregierte Statistikennpm, PyPI.