Öffentliches Register
Software-GesundheitsberichtSchema 0.27.0 · Metriken 1.13.0 · 2026-07-25 03:36 UTC

agora-oss-org / agora-sdk-plus

Additive, Agora-only SDK features with no upstream Replyke counterpart — end-to-end-encrypted Secure Chat (blind MLS / RFC 9420), the Social Graph lenses, and web auth ergonomics that drop into @agora-sdk apps.

TypeScriptApache-2.0★ 0 Sterne⑂ 0 Forksseit Juni 2026Auf GitHub ansehen ↗

agora-oss-org/agora-sdk-plus erreicht einen Gesundheitsindex von 43 von 100 und liegt damit im Bereich Gefährdet. Am stärksten schneidet es bei Vitality (75/100) ab, am schwächsten bei Sustainability & Governance (15/100). Zuletzt vor 5 Tagen aktualisiert. Ein einzelner Mitwirkender trägt den Großteil der jüngsten Arbeit.

43
gesamt / 100
Gefährdet

Software-Gesundheitsindex

Metriken werden auf einer Skala von 1–100 in gewichtete Kategorien gruppiert. Der Gesamtwert beginnt als ihr Mittel; sobald öffentliche Evidenz die Richtlinie für Hochrisikojurisdiktionen auslöst, wird die Bewertung angepasst und erhält die Obergrenze 49 (Gefährdet). AI Readiness liegt außerhalb.

43
Exzellent85-100Vorbildlich; erfüllt im Wesentlichen alle geprüften Kriterien
Gut70-84Gesund; geringfügige Lücken
Mittel50-69Akzeptabel mit deutlichen Lücken; Überprüfung empfohlen
Gefährdet30-49Erhebliche Schwächen; eine Übernahme erfordert Vorsicht
Kritisch1-29Schwerwiegende 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.

Eigentümerschaft

Agora OSS OrgOrganisation
0 Follower5 öffentliche Reposseit Juni 2026

Dieses Repository wird von einer Organisation getragen — geteilte, rechenschaftspflichtige Trägerschaft, die jeden einzelnen Maintainer überdauern kann.

Metriken nach Kategorie

Vitalität

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

75Gut · 22 % des Gesamtindex
Wie die Bewertung erfolgt
36/36Push-Aktualität — letzter Push vor 5 Tagen
4.2/36Commit-Rhythmus — 6/52 Wochen mit Commits
18/18Commit-Volumen — 176 Commits im letzten Jahr
0/10OpenSSF Scorecard: Maintained — project was created within the last 90 days. Please review its contents carefully
Verwendete Eingangsdaten
commits_last_year176
human_commit_share1
days_since_last_push5
active_weeks_last_year6

Release-Disziplin

100Exzellent
Wie die Bewertung erfolgt
27/27Liefert Releases aus — 18 Releases veröffentlicht
36/36Release-Aktualität — letztes Release vor 5 Tagen
27/27Release-Rhythmus — ein Release etwa alle 0 Tage
0/10OpenSSF Scorecard: Signed-Releases — keine Daten
Verwendete Eingangsdaten
releases_count18
latest_release_tagv0.11.0
releases_from_tagsnein
days_since_latest_release5
mean_days_between_releases0
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): OpenSSF Scorecard: Signed-Releases. Die verbleibenden Gewichte wurden renormalisiert.

Community & Verbreitung

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

24Kritisch · 18 % des Gesamtindex
Wie die Bewertung erfolgt
0/60Stars — 0 Stars
0/25Forks — 0 Forks
0/15Watcher — 0 Watcher
Verwendete Eingangsdaten
forks0
stars0
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Wie die Bewertung erfolgt
22.5/22.5README
22.5/22.5Lizenz — anerkannte Lizenz (Apache-2.0)
0/18CONTRIBUTING-Leitfaden
0/13.5Verhaltenskodex
0/7.2Issue-Vorlage
0/6.3PR-Vorlage
Verwendete Eingangsdaten
has_readmeja
has_licenseja
has_contributingnein
has_issue_templatenein
has_code_of_conductnein
has_pull_request_templatenein

Nachhaltigkeit & Governance

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

15Kritisch · 24 % 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/46.8Issue-Lösungsquote — keine Issues oder keine Daten
0/38.3PR-Annahme — keine entschiedenen Pull Requests oder keine Daten
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Verwendete Eingangsdaten
merged_prs0
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Issue-Lösungsquote, PR-Annahme. Die verbleibenden Gewichte wurden renormalisiert.
Wie die Bewertung erfolgt
30/30Organisatorische Trägerschaft — im Besitz einer Organisation
0/20Verifizierte Domain
0/25Reichweite des Inhabers — 0 Follower von agora-oss-org
5.8/25Kontohistorie — 5 öffentliche Repos, Kontoalter ca. 0 Jahre
Verwendete Eingangsdaten
followers0
owner_typeOrganization
is_verified
owner_loginagora-oss-org
public_repos5
account_age_days30

Engineering-Qualität

Sind grundlegende Engineering- und Dokumentationspraktiken vorhanden?

70Gut · 20 % 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
0/20OpenSSF Scorecard: CI-Tests — keine Daten
Verwendete Eingangsdaten
has_cija
has_testsja
has_editorconfignein
has_linter_confignein
has_precommit_confignein
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): OpenSSF Scorecard: CI-Tests. Die verbleibenden Gewichte wurden renormalisiert.

Dokumentation

85Exzellent
Wie die Bewertung erfolgt
30/30README
25/25Dokumentationsverzeichnis
0/15Dokumentations-/Homepage-Site
10/10Repository-Beschreibung
10/10Topics — 16 Topics
10/10Wiki
Verwendete Eingangsdaten
topicsagora, agora-sdk, end-to-end-encryption, expo, mls, oauth, open-source, react, react-native, replyke, sdk, secure-chat, self-hosted, social-graph, social-network, typescript
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?

26Kritisch · 16 % des Gesamtindex

Sicherheitslage

26Kritisch
Wie die Bewertung erfolgt
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — keine Daten
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 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
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Lizenz — license file detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
5/5Packaging — packaging workflow detected
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — no SAST tool detected
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — keine Daten
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0/7.5Vulnerabilities — 26 existing vulnerabilities detected
Verwendete Eingangsdaten
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate2,6
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): ci_tests, signed_releases. Die verbleibenden Gewichte wurden renormalisiert.

AI Readiness

Wie gut ist das Repository dafür ausgestattet, mit KI-Coding-Agenten entwickelt und gepflegt zu werden? Ein unabhängiges, experimentelles Badge — Gewicht 0,0, es wird eigenständig ausgewiesen und verändert den Gesamt-Gesundheitswert nicht.

70Gut · 0 % des Gesamtindex
Wie die Bewertung erfolgt
45/45Agentenanweisungen — CLAUDE.md
0/15Maschinenlesbare Doku (llms.txt)
32.5/40Lesbare Commit-Historie — 61 von 100 menschlichen Commits benennen ihre Absicht (strukturierter Betreff oder erläuternder Text)
Verwendete Eingangsdaten
has_llms_txtnein
legible_history_share0,61
agent_instruction_filesCLAUDE.md
agent_instruction_max_bytes20.141
Wie die Bewertung erfolgt
0/18Bootstrap mit einem Befehl
22/22Automatisierte Tests
0/11Lint-/Format-Konfiguration
11/11Statische Typprüfung — packages/auth/react-js/tsconfig.json, packages/public-read/core/tsconfig.json, packages/public-read/react-js/tsconfig.json, packages/secure-chat/core/tsconfig.json, packages/secure-chat/crypto/tsconfig.json, packages/secure-chat/expo/tsconfig.json, packages/secure-chat/react-js/tsconfig.json, packages/secure-chat/react-native/tsconfig.json, packages/social/core/tsconfig.json, packages/social/expo/tsconfig.json, packages/social/react-js/tsconfig.json, packages/social/react-native/tsconfig.json, tsconfig.json
10/10Reproduzierbare Umgebung — lockfile
10/10Belegte Agentenpraxis — 45 der letzten 100 Commits von Agenten verfasst oder ihnen zugeschrieben
0/8Automatisierte Wartung — keine automatisierten Abhängigkeits-Updates beobachtet
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Verwendete Eingangsdaten
has_nixnein
has_testsja
lockfilespnpm-lock.yaml
has_dockerfilenein
typed_languageja
bootstrap_files
has_devcontainernein
has_linter_confignein
typecheck_configspackages/auth/react-js/tsconfig.json, packages/public-read/core/tsconfig.json, packages/public-read/react-js/tsconfig.json, packages/secure-chat/core/tsconfig.json, packages/secure-chat/crypto/tsconfig.json, packages/secure-chat/expo/tsconfig.json, packages/secure-chat/react-js/tsconfig.json, packages/secure-chat/react-native/tsconfig.json, packages/social/core/tsconfig.json, packages/social/expo/tsconfig.json, packages/social/react-js/tsconfig.json, packages/social/react-native/tsconfig.json, tsconfig.json
agent_commit_share0,45
toolchain_manifests
dependency_bot_commit_share0
Wie die Bewertung erfolgt
45/45Typprüfbarer Code — TypeScript (statisch typisiert)
55/55Handhabbare Dateigrößen — 0/164 Quelldateien über 60 KB
Verwendete Eingangsdaten
primary_languageTypeScript
largest_source_bytes46.446
source_files_sampled164
oversized_source_files0

Eckdaten

0GitHub-Sterne
1Mitwirkende
176Commits, letzte 12 Monate
5Tage seit letztem Push
18Releases
1Bus-Faktor
0offene Issues
npmPaket-Ökosysteme

Warnungen zur Datenerhebung

  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Weitere Details

OpenSSF Scorecard 2.6 / 10
2.6Gesamtwert

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-25 03:36 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
k. A.CI-Testsno pull request found
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
10Packagingpackaging workflow detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTno SAST tool detected
0Security-Policysecurity policy file not detected
k. A.Signed-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
0Vulnerabilities26 existing vulnerabilities detected
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

JSON-Rohbericht maschinenlesbar
{
  "data": {
    "repo": {
      "topics": [
        "agora",
        "agora-sdk",
        "end-to-end-encryption",
        "expo",
        "mls",
        "oauth",
        "open-source",
        "react",
        "react-native",
        "replyke",
        "sdk",
        "secure-chat",
        "self-hosted",
        "social-graph",
        "social-network",
        "typescript"
      ],
      "is_fork": false,
      "size_kb": 1984,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "Shell": 7,
        "JavaScript": 9163,
        "TypeScript": 971894
      },
      "pushed_at": "2026-07-19T06:17:06Z",
      "created_at": "2026-06-07T04:01:17Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-19T06:16:52Z",
      "description": "Additive, Agora-only SDK features with no upstream Replyke counterpart — end-to-end-encrypted Secure Chat (blind MLS / RFC 9420), the Social Graph lenses, and web auth ergonomics that drop into @agora-sdk apps.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "Apache-2.0",
      "default_branch": "root",
      "license_spdx_raw": "Apache-2.0",
      "primary_language": "TypeScript",
      "significant_languages": [
        "TypeScript"
      ]
    },
    "owner": {
      "blog": null,
      "name": "Agora OSS Org",
      "type": "Organization",
      "login": "agora-oss-org",
      "company": null,
      "location": null,
      "followers": 0,
      "avatar_url": "https://avatars.githubusercontent.com/u/296750678?v=4",
      "created_at": "2026-06-25T03:22:31Z",
      "is_verified": null,
      "public_repos": 5,
      "account_age_days": 30
    },
    "license": {
      "state": "standard",
      "spdx_id": "Apache-2.0",
      "raw_spdx": "Apache-2.0",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.11.0",
          "kind": "minor",
          "published_at": "2026-07-19T06:01:33Z"
        },
        {
          "tag": "v0.10.2",
          "kind": "patch",
          "published_at": "2026-07-19T06:04:28Z"
        },
        {
          "tag": "v0.10.1",
          "kind": "patch",
          "published_at": "2026-07-19T06:04:27Z"
        },
        {
          "tag": "v0.10.0",
          "kind": "minor",
          "published_at": "2026-07-19T06:04:26Z"
        },
        {
          "tag": "v0.9.2",
          "kind": "patch",
          "published_at": "2026-07-19T06:03:20Z"
        },
        {
          "tag": "v0.9.1",
          "kind": "patch",
          "published_at": "2026-07-19T06:03:19Z"
        },
        {
          "tag": "v0.9.0",
          "kind": "minor",
          "published_at": "2026-07-19T06:03:17Z"
        },
        {
          "tag": "v0.8.0",
          "kind": "minor",
          "published_at": "2026-06-21T03:02:40Z"
        },
        {
          "tag": "v0.7.0",
          "kind": "minor",
          "published_at": "2026-06-21T00:26:20Z"
        },
        {
          "tag": "v0.6.5",
          "kind": "patch",
          "published_at": "2026-07-19T06:03:16Z"
        },
        {
          "tag": "v0.6.4",
          "kind": "patch",
          "published_at": "2026-06-17T09:30:37Z"
        },
        {
          "tag": "v0.6.3",
          "kind": "patch",
          "published_at": "2026-07-19T06:03:15Z"
        },
        {
          "tag": "v0.6.2",
          "kind": "patch",
          "published_at": "2026-06-17T05:36:50Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2026-07-19T06:03:14Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2026-07-19T06:03:12Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-07-19T06:03:11Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-07-19T06:03:09Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-07-19T06:03:08Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "a37662ccb44c3b391b26099879d3195941c79608",
          "body": null,
          "is_bot": false,
          "headline": "v0.11.1",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-19T06:16:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "89024a1de70a7fea32a6deb1c59b06e9b1038e0c",
          "body": "v0.11.0 shipped \"@agora-server/contract\": \"^0.21.0\", but Entity.public was\ncommitted AFTER the contract's v0.21.0 release tag and first published in\n0.22.0. Verified by unpacking both tarballs: 0.21.0 has no `public: boolean`\non Entity, 0.22.0 does. pnpm resolved the floor exactly, so the entire fea\n[…]\nk incl. e2e clean, 530 unit tests, 9 e2e assertions green.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_013rdhA6XmS5AMV4zMnvpb1s",
          "is_bot": false,
          "headline": "fix(public-read): contract floor ^0.22.0 — 0.21.0 lacks Entity.public",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-19T06:11:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "062a51633ecf69dce62cd5c4461b39da836d0507",
          "body": null,
          "is_bot": false,
          "headline": "v0.11.0",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-19T05:37:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "88c105d7a3fab578f3b58c353b6c63d7eb6ac19e",
          "body": "…trap\n\nBoth TESTING.md files now document the second, independently-gated e2e suite,\nadd public-read-core to the vitest alias table, and extend the env tables and\n.env.example with AGORA_E2E_PUBLIC_PROJECT_ID / _FOREIGN_ID.\n\nRecords a trap worth writing down: the root vitest config doesn't enable\n`g\n[…]\ncts docs/TESTING.md's stale unit count (439/54 -> 530/65).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_013rdhA6XmS5AMV4zMnvpb1s",
          "is_bot": false,
          "headline": "docs(testing): cover the public-read e2e suite and the jsdom cleanup …",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-19T05:34:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6eb329216106903ef44b697a7cb52bd180ebed9e",
          "body": "…ternet\n\nAdds @agora-sdk/public-read-{core,react-js}: a tokenless, read-only client for\nagora-server's anonymous /v7/:projectId/public/* surface, so a third-party blog\nwith no account and no Agora SDK installed can embed a comment thread.\n\nTwo properties are enforced structurally rather than by conv\n[…]\ngreen, plus 9 opt-in\ne2e assertions against a live server.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_013rdhA6XmS5AMV4zMnvpb1s",
          "is_bot": false,
          "headline": "merge: public-read — anonymous entity + comment reads for the open in…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-19T05:26:52Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c168f14b03d72838251886f8398f113760646a99",
          "body": "…ve gate\n\nNine assertions against a locally running agora-server, covering what the\nmocked unit suite structurally cannot: real CORS headers, the ETag -> 304\nround trip, no-store on the gate's 404, live PII redaction, and that the\nwalled surface still 401s the same entity.\n\nResolves the seeded ancho\n[…]\nBLIC_PROJECT_ID; verified not collected by the unit\nsuite.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_013rdhA6XmS5AMV4zMnvpb1s",
          "is_bot": false,
          "headline": "test(public-read): opt-in e2e for CORS, ETag revalidation, and the li…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-19T05:04:12Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "eda5701ddbaac852cc0ba686bbd76b09f4a3e41e",
          "body": "Adds packages/public-read/react-js/README.md and threads the new feature group\nthrough the root README (features table + packages block + the independence\nnote), ARCHITECTURE.md (a subgraph plus a dedicated layers-and-seams diagram),\nSTATUS.md, and CLAUDE.md.\n\nThe architecture section makes the poin\n[…]\nelease scripts cover\ntwelve publishable packages, not ten.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_013rdhA6XmS5AMV4zMnvpb1s",
          "is_bot": false,
          "headline": "docs(public-read): integration guide + repo propagation",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-19T05:01:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cbcb6f1c276f72ee1e7bcfc8bb440d740549b68d",
          "body": "…chat\n\nLine 27 hardcoded packages/secure-chat, so social, auth, and public-read were\nnever checked for extensionless ESM specifiers or a missing CJS type marker —\ndespite CI running verify:dist on every push.\n\nGeneralizing it immediately caught a real shipped defect: @agora-sdk/auth-react-js\nemitted\n[…]\nd.\n\nverify:dist now green across all three feature groups.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_013rdhA6XmS5AMV4zMnvpb1s",
          "is_bot": false,
          "headline": "fix(scripts): verify-dist scans every feature group, not just secure-…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-19T04:59:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3a4660b7dc03a49be29fe95bfe7fda0e8ad53717",
          "body": "Takes entityId OR foreignId. foreignId is the mode an embed actually wants —\nthe uuid is generated per install, so a blog template can't hardcode it — and\nbecause the comment routes are uuid-only, the component owns the two-step\n(resolve anchor, then fetch thread by the returned uuid) so no host has\n[…]\n\n\n20 tests in react-js; full workspace suite green at 530.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_013rdhA6XmS5AMV4zMnvpb1s",
          "is_bot": false,
          "headline": "feat(public-read): PublicComments drop-in with thread and paged modes",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-19T04:54:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f017f7011d3499e5a5479e467477cc27b624f481",
          "body": "Recursive renderer over the server's nested replies[]. ESM-only, matching\nsocial-react-js and secure-chat-react-js.\n\nTombstones are a first-class state, not a defensive branch: the server blanks\nauthor-deleted comments in place (Reddit-style) on both the list and the\nthread rather than omitting them\n[…]\nts. Added it locally with the reason documented.\n\n8 tests.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_013rdhA6XmS5AMV4zMnvpb1s",
          "is_bot": false,
          "headline": "feat(public-read): react-js package + recursive comment node renderer",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-19T04:51:37Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ad0351328629e7ab0ea7ec62aa3231b3674e40c1",
          "body": "One round trip for the whole thread. Exposes the server's replies[] shape\nverbatim — the fork's addCommentsToTree exists only because the walled surface\nserves flat pages, so porting it here would buy nothing and create a drift\nliability against a fork this package doesn't depend on.\n\nhasMore is inf\n[…]\n 43 tests across transport, provider, and\nall three hooks.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_013rdhA6XmS5AMV4zMnvpb1s",
          "is_bot": false,
          "headline": "feat(public-read): usePublicCommentThread over the server-nested route",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-19T04:46:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3e42a971af29b485e190f8525af5cffa5cb79af4",
          "body": "…port\n\nloadMore appends; changing sort resets to page 1, since a page-2 offset into a\nre-sorted list is meaningless. Reply paging is the same hook with parentId set\n— the endpoint and state machine are identical, so a separate hook would be\nduplication.\n\nAccepts a null entityId and no-ops, which is \n[…]\nder \"unavailable\" on a perfectly\nhealthy thread.\n\n9 tests.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_013rdhA6XmS5AMV4zMnvpb1s",
          "is_bot": false,
          "headline": "feat(public-read): usePublicComments with offset paging and reply sup…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-19T04:44:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c9a1897fbc438d65eb00f9ad67a2768aeb2c6279",
          "body": "The resolver for the whole feature. An embed can't hardcode a per-install\nuuid, so it addresses the anchor by the host app's own key — but the comment\nroutes are uuid-only, so this hook returns the resolved entityId alongside the\nentity and callers chain it:\n\n    foreignId -> usePublicEntity -> enti\n[…]\nd. Guard is on `kind === null`, not truthiness.\n\n10 tests.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_013rdhA6XmS5AMV4zMnvpb1s",
          "is_bot": false,
          "headline": "feat(public-read): usePublicEntity resolves by uuid or foreignId",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-19T04:43:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5612f7cb08d1375b018b9c586442733f909859af",
          "body": "Deliberately simpler than SocialProvider: no token prop and no mount-time\nfetch, because the anonymous surface has no transparency/feature-gate endpoint\nto resolve — so there is no loading gate and no all-disabled sentinel. It\nmemoizes a client and stops.\n\nSatisfies both hard requirements structural\n[…]\nere is no code path that could read them.\n\n17 tests green.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_013rdhA6XmS5AMV4zMnvpb1s",
          "is_bot": false,
          "headline": "feat(public-read): PublicReadProvider + usePublicRead + core barrel",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-19T04:41:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "36a21a7111d0a2f4cba61a8b2563f76078657c58",
          "body": "…surface\n\nNew @agora-sdk/public-read-core package. PublicReadRestClient covers all four\n/v7/:projectId/public/* routes; its config type has no token field, so sending\na credential is structurally impossible rather than merely discouraged — the\nsurface answers with a wildcard ACAO and no credentials,\n[…]\n, vitest alias, and all five package-list scripts\nupdated.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_013rdhA6XmS5AMV4zMnvpb1s",
          "is_bot": false,
          "headline": "feat(public-read): tokenless REST transport for the anonymous public …",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-19T04:39:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9d61b5e9b2f698227febfa98048533be53231c23",
          "body": "Ten TDD tasks covering @agora-sdk/public-read-{core,react-js}: transport,\nprovider, three hooks, the recursive renderer, the <PublicComments> drop-in,\ndocs propagation, and an opt-in e2e.\n\nRevised for the server's new by-foreign-id route (Jenova's catch — an embed\ncan't hardcode a per-install uuid):\n[…]\np now carries\nreal test code instead of a prose checklist.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_013rdhA6XmS5AMV4zMnvpb1s",
          "is_bot": false,
          "headline": "docs(plan): public-read implementation plan + foreignId addressing",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-19T04:31:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b41b877f0680093809021c45187d45987b37bbb9",
          "body": "Answers the agora-sdk fork's change request with a full design for the\n`public-read` feature group: a tokenless, read-only client for the server's\nmerged /v7/:projectId/public/* surface.\n\nDecisions settled in brainstorm:\n- name `public-read` (states the security posture), web-only at v1\n  (core + re\n[…]\n deleted-comment handling (blanked in place, not omitted).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_013rdhA6XmS5AMV4zMnvpb1s",
          "is_bot": false,
          "headline": "docs(spec): public-read — anonymous entity + comment reads",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-19T03:51:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "aecda95f204cf946f07382bc54d3f641a6fdb67f",
          "body": null,
          "is_bot": false,
          "headline": "workflow_dispatch:",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-05T05:29:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d024ac80d39c9f8a746ef53655fd5387cc014e61",
          "body": "…link\n\nThe root package.json committed a pnpm.overrides linking @agora-sdk/react-js\nto ../agora-sdk/packages/react-js — absent on CI runners, so\n--frozen-lockfile couldn't materialize it and tsc failed with 'Cannot find\nmodule @agora-sdk/react-js' across auth-react-js (CI + Publish, since v0.10.2).\n\n[…]\ne registry. Local fork dev is now opt-in via .pnpmfile.cjs\n(AGORA_SDK_LINK=1); default + CI stay on npm so the lockfile is stable.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(ci): resolve @agora-sdk/react-js from npm, not a committed local …",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-05T05:27:52Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f9e4e707d62136add218831369037f303d25f075",
          "body": "…cjs importers)\n\nThe greedy `packages/**/*` glob matched each built `dist/cjs/` (build:cjs\nwrites a marker package.json), so pnpm registered them as phantom workspace\npackages — non-deterministic `packages/<pkg>/dist/cjs: {}` importers that\nchurned the committed lockfile based on what had been built. Add `!**/dist/**`\nand regenerate a clean lockfile (8 stray importers removed).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(build): exclude dist from pnpm workspace glob (drop phantom dist/…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-05T05:16:51Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "7fa3a80e02726e684ead1e3c20ca4441c1536609",
          "body": null,
          "is_bot": false,
          "headline": "pnpm-lock.yml",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-05T05:15:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1a7a5eda00f55b648542f3abb22d8cec530de600",
          "body": null,
          "is_bot": false,
          "headline": "v0.10.2",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-05T05:04:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "915cff91a52c27779fec1bb56643d4bb734c91b0",
          "body": "Patch: fix a transiently-rejected secure-chat message sticking after a\nreload (useSecureMessages now re-attempts rejected rows on group advance;\nfail-closed preserved). Resolves the intermittent node-22 CI failure.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v0.10.1",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-04T12:05:30Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ee475e3b8b18f850586fcda4c7d13fe861a005d4",
          "body": "…ed preserved)\n\nuseSecureMessages' group-advance retry effect re-attempted only 'pending'\nrows; a message decrypted in the group-handle mid-swap window (e.g. right\nafter a reload processes a fresh Welcome) settles to 'rejected' and, with no\nsecond live delivery to rescue it, stuck forever. Now re-at\n[…]\n node-22 CI failure in browser-runtime's reload test\n(slower 2-vCPU runner widened the race; node 20 + reruns passed same commit).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(secure-chat): retry rejected messages on group advance (fail-clos…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-04T11:31:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "63f82f96849a2d39d57a7e37de166605ae705593",
          "body": "Minor release: @agora-sdk/auth-react-js email-link handlers (verify /\nreset / resend drop-ins) + the committed docs/social/secure-chat fixes\nunder Unreleased. Bumps all ten publishable packages 0.9.3 → 0.10.0.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v0.10.0",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-04T06:33:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9fad57b06c00962a7947f07ba9fa84e0a6f1ebb9",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): export email-link handlers; README/AUTH/CHANGELOG",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-04T06:30:38Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "949b31c2ccff331583e4519e5f0fca2e11ef0e9a",
          "body": "…rect POST, sends email)\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): useResendVerification hook + ResendVerificationButton (di…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-04T06:27:26Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "71cfad98df8b72b4a1e8bd8ae7a118f1e82d77ec",
          "body": "Adds RTL cleanup to the email-verification test too (shared DOM hardening).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): usePasswordReset hook + PasswordResetHandler drop-in form",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-04T06:26:28Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "94c98ed5140fbf8d057dcea3ff83c137ad5cf002",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): useEmailVerification hook + EmailVerificationHandler drop-in",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-04T06:23:04Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "60973e63a3ca02d59f6e8dad6834cf8c823b6218",
          "body": "…projectId mismatch)\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): shared parseAuthLink + stripTokenFromUrl (fail-closed on …",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-04T06:21:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "df340617b9d8d5e8409556dca80454af3bef4eca",
          "body": "… correction\n\nCorrects spec §3.5/§4: resend POSTs directly (core's useSendVerificationEmail\nomits the email the server requires). Adds the bite-sized TDD plan.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(auth): implementation plan for email-link handlers + spec resend…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-04T06:20:05Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6bf51d2fde2c937a7aed0d71f8746c7b65fdc14f",
          "body": null,
          "is_bot": false,
          "headline": "auth update",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-04T06:19:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1b36f76e5da78450f80c23b0798cb7f99779e02d",
          "body": null,
          "is_bot": false,
          "headline": "doc updates",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-04T06:17:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5f80baabf549cc74704800fefaf1e7c6b5922f04",
          "body": null,
          "is_bot": false,
          "headline": "secure-chat updates",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-04T06:17:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4adb35b1d499c0ae416f26e2f94e2d20a4b2183e",
          "body": null,
          "is_bot": false,
          "headline": "social updates",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-04T06:17:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "088c7be16c8947e30689c2d74488fd2cd9a4bd2d",
          "body": "Adds hook + component pairs to @agora-sdk/auth-react-js so the server's\nemailed verify-email/reset-password links stop 404-ing on consumer apps,\nmirroring the existing OAuth callback black-box.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(auth): design spec for email-link handlers (verify/reset/resend)",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-04T06:14:10Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a90e0fa06d7ffe578649466c0eec97bf09fc31bf",
          "body": "SocialRestClient.getTransparency() raw-cast the server's GET /social/transparency\nbody to the flat ResolvedSocialConfig, but the endpoint returns a nested DTO\n({ garden, analytics, decay }). Every flat *Enabled key resolved to undefined, so\neach useSocial* hook self-gated to disabled and fetched not\n[…]\nnow maps rather than casts. The three resolver-only fields\ntransparency doesn't expose get safe defaults. Covered by rest.test.ts.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(social-core): map transparency DTO instead of casting it",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-07-01T00:05:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a81cf526e4d5ea0b4462c76787cc215def5e78d4",
          "body": null,
          "is_bot": false,
          "headline": "vue design",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-29T04:31:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "64b3a221c5f253b9a2e22e495ab8203a008233bf",
          "body": "Bundle each feature guide inside its primary web package's npm tarball so it\ntravels with an install, generated drift-free from the root docs/ source:\n\n- copy:docs script (chained onto build) cp's docs/AUTH.md, docs/SECURE-CHAT.md,\n  docs/SOCIAL-GRAPH.md into auth-react-js / secure-chat-react-js /\n \n[…]\nME.\n- Bump all publishable packages + private root 0.9.2 -> 0.9.3; roll the\n  [Unreleased] notes into a [0.9.3] CHANGELOG section.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v0.9.3",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-29T03:08:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5fddc9d6bc7e56187c91d148716aea9344580f9b",
          "body": "Fix @agora-sdk/auth-react-js useOAuthCallback hang-to-timeout on successful\nlogin when a stale account is present (field report A8). The gate now keys on\nthe persisted active-account row (polled, since same-tab SDK writes emit no\nstorage event) instead of in-store auth, making it immune to the stale\n[…]\n prop.\n\nBump all publishable packages + private root 0.9.1 -> 0.9.2; roll the\n[Unreleased] notes into a [0.9.2] CHANGELOG section.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v0.9.2",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-28T07:54:52Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e239528abe272f676f06c759a32a52a8b117d850",
          "body": "Bump all publishable packages 0.9.0 → 0.9.1 (and the private root) for a\nclean re-publish after the provenance fix; nothing landed on npm at 0.9.0.\nRoll the [Unreleased] notes into a [0.9.1] CHANGELOG section.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v0.9.1",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-28T06:01:17Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e7f1a48facd1b5b6b32cdc6c7e0bfe904451d99e",
          "body": "npm publish with provenance (NPM_CONFIG_PROVENANCE) rejected every package\nwith `422 ... Failed to validate repository information`: the manifests still\nnamed the old `jenova-marie` org, which no longer matches the GitHub Actions\nbuild repo recorded in the sigstore attestation.\n\n- Update repository.\n[…]\nsed] → Fixed.\n- docs(AUTH, SECURE-CHAT): rename section headings (Overview / Getting\n  started / Further reading) for consistency.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(publish): point all manifests at agora-oss-org for npm provenance",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-28T05:59:26Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b564175f4e85654a5887b6010d2e25d027bf05a2",
          "body": "Document the social feature group across the canonical docs and prune stale\ncross-repo notes.\n\n- CLAUDE.md + ARCHITECTURE.md: describe @agora-sdk/social-{core,react-js,\n  react-native,expo} — the three commons lenses (Weather/Constellation/\n  Neighborhood) + transparency self-gating, REST-only/no-cr\n[…]\nuide),\n  README + AUTH.md refresh, remove resolved iuc-restore cross-repo notes.\n- CHANGELOG: record the above under [Unreleased].\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: document social feature group + testing guide; doc housekeeping",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-28T05:34:22Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "43b6b2197d36c45dadc96fa827dfbb8c59fa8237",
          "body": "…o them\n\nAdd docs/SECURE-CHAT.md and docs/AUTH.md; rewrite the root README to be a warm,\nfeature-light landing page that points to each feature's own guide (secure-chat,\nsocial, auth) instead of being secure-chat-specific. docs/SOCIAL.md already existed.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: per-feature guides (secure-chat, auth) + cozy README pointing t…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-28T05:22:54Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1fd11ee73e58544ad530d0f268ebf4defad29d91",
          "body": null,
          "is_bot": false,
          "headline": "v0.9.0",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-28T05:19:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e9e82e55459b44da4f21f1609fbfc63fe8131ab0",
          "body": null,
          "is_bot": false,
          "headline": "Default to the standalone `@agora/secure-chat` process",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-28T05:17:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f296f84900eeb616e7ada06fa4757b4468ea0e07",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): public barrel, build wiring, README + housekeeping (P7)",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-28T05:16:29Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "7920eb3cb67d00838e525b52416a626ce0705e2e",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): useAuthSelfHeal — stale-account self-heal (P6)",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-28T05:15:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "fe0a7c46e40937c1702fe1a76265e743b4e16177",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): useSignOutEverywhere — reliable full logout (P5)",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-28T05:15:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "99cb40df8ccd174998953afe8e81061ac9a97cff",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): OAuthCallbackHandler drop-in component (P3)",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-28T05:15:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "16134dccebcc4b44c1e633515a89b661f34cb017",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): useOAuthCallback — persistence-gated MPA callback (P1/P3)",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-28T05:15:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "47a98afa7ae46949eb1eb94fb2301418c5fc6633",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): useAuthStatus — first-class auth-ready signal (P4)",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-28T05:15:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1fd3bede1719b1f014cbb980fafeac3f1e5b0469",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): scaffold @agora-sdk/auth-react-js + accountStorage seam",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-28T05:15:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5556dea29acd19ccdf315df18016b38b19bb36db",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(auth): spec + plan for @agora-sdk/auth-react-js OAuth ergonomics",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-28T05:15:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "193b1c7081e2030377fdb9392e16e2e35e1ec6cd",
          "body": "Bump the private monorepo root `agora-sdk-plus` from 0.7.0 to 0.8.0 so\nevery package in the workspace reports the same version.\n\n- All nine published packages (@agora-sdk/secure-chat-* and\n  @agora-sdk/social-*) were already at 0.8.0; the root was the sole\n  outlier at 0.7.0.\n- Internal cross-packag\n[…]\nn publish — no pinned version numbers to update.\n- Root is `private: true`, so this is version hygiene, not a publish\n  change; no build or test impact.\n\nAuthored-By: Jenova Marie <jenova-marie@pm.me>",
          "is_bot": false,
          "headline": "🔧 config(monorepo): align workspace root version to 0.8.0",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-23T00:07:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "111e1033365881e872eedcbf3e1495577134e8e2",
          "body": null,
          "is_bot": false,
          "headline": "2026-06-21-iuc-restore-slicing-and-local-first-prerequisite",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T05:28:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "77f6b4c462d6ebcb5a5bb59d480a7804f8a28fd4",
          "body": "…ice-#2 AAD reconstruction\n\n- decodeIucControl: bound untrusted input tighter (maxBytes 4096 + maxDepth 1\n  for the flat control messages, not just maxItems)\n- restoreAad: drop the unknown-cast for compile-time-checked CBOR entries\n- seal.test: add negative-blindness test — the sealed blob never emb\n[…]\n  descriptor routing strings (AAD is bound, not embedded)\n- design spec: document the open-side AAD field provenance and the\n  count (history rows) vs chunkCount (blob chunks) distinction for slice #2",
          "is_bot": false,
          "headline": "🔒 security(secure-chat): harden IUC ENVELOPE foundation + document sl…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T04:07:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ff52d62ecd39521f7f6f5e5fffb835291065c11f",
          "body": null,
          "is_bot": false,
          "headline": "📝 docs(secure-chat): export the IUC ENVELOPE foundation surface",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T03:53:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c31dc8dfa785f7a44ded44d1152d11b922dd8137",
          "body": null,
          "is_bot": false,
          "headline": "✨ feat(secure-chat): add restore-blob REST methods + contract@0.13.0",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T03:36:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dc8df4b729147590b58e9b8aef5a358070295a06",
          "body": null,
          "is_bot": false,
          "headline": "✨ feat(secure-chat): add kind:1 IUC control-message codec",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T03:30:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b3af0ed6fd27b4e53c8942456903f9ef6aa89837",
          "body": null,
          "is_bot": false,
          "headline": "✨ feat(secure-chat): add IUC ENVELOPE blob AEAD (seal/open)",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T03:22:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e987b6051cd87b59c1f02de99fb3d2f214b942f6",
          "body": "…ransport)",
          "is_bot": false,
          "headline": "📝 docs(secure-chat): plan the IUC ENVELOPE foundation (seal/control/t…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T03:20:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7e81a7a2b0e2d79e46a3469ae5e9fd289d0e37e4",
          "body": "…/transport primitives)",
          "is_bot": false,
          "headline": "📝 docs(secure-chat): design the IUC ENVELOPE foundation (seal/control…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T03:09:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "397cfa42bb1686a48c75e933a153538a6fab3274",
          "body": null,
          "is_bot": false,
          "headline": "v0.8.0",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T02:56:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ee214262b3403494bec11718ee6a614f7f3fc728",
          "body": "…lation",
          "is_bot": false,
          "headline": "🧪 test(secure-chat): cover cross-conversation message-content key iso…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T02:39:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c1b457f36025b9bbf4cec7fba2ce1a6f57934244",
          "body": "…raming; reconcile to draft-08",
          "is_bot": false,
          "headline": "📝 docs(secure-chat): export MIMI content surface; supersede IUC v:2 f…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T02:27:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8e60d1ad7b45d7a47645a4e07ae5b7f51135e4db",
          "body": "…tions, edits, deletes)",
          "is_bot": false,
          "headline": "✨ feat(secure-chat): MIMI content in useSecureMessages (replies, reac…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T02:17:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "72acaae7724524e3973ee1a0018035172dec5c48",
          "body": "…plaintext",
          "is_bot": false,
          "headline": "♻️ refactor(secure-chat): persist decrypted content-frame bytes, not …",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T01:58:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "def6e707d5637326de937a2b6eae66168424ed70",
          "body": "…not 'unknown'\n\nThe ts-mls decrypt-error classifier only mapped a failed FramedContent\nsignature (CryptoVerificationError) to the 'unauthenticated' reason. The\ncommon active-attacker / byte-flip case fails the AEAD tag first, which\nts-mls surfaces as a CryptoError with a primitive-dependent opaque m\n[…]\nasons end-to-end, plus raw ts-mls/@noble error-string\ncharacterization pins so a future upstream reword fails loudly with a repro.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "🐛 fix(secure-chat): classify forged ciphertext as 'unauthenticated', …",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T01:54:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0d8ccb3e996ae4288f7904ca52a889eb8392491d",
          "body": null,
          "is_bot": false,
          "headline": "✨ feat(secure-chat): add MimiContent message fold reducer",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T01:53:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a53ae704293271713bdaac2b7f8ff07de4b351bc",
          "body": null,
          "is_bot": false,
          "headline": "✨ feat(secure-chat): add Tier-2 MimiContent builders",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T01:42:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "15c9f5515a9a2b0060abc3f963537207df46595b",
          "body": null,
          "is_bot": false,
          "headline": "✨ feat(secure-chat): add content routing frame",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T01:38:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "83775a577edc22958c4e5cbae4ea43407b58cefc",
          "body": null,
          "is_bot": false,
          "headline": "✨ feat(secure-chat): add MimiContent codec and content hashing",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T01:35:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "239f8abda54875997b799646d3dabf53f0716890",
          "body": null,
          "is_bot": false,
          "headline": "MIMI CBOR Content Format Implementation Plan",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T01:06:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3a4c9d629391ced05c85ac1c15c175c05c14daa1",
          "body": null,
          "is_bot": false,
          "headline": "🧪 test(secure-chat): add cbor2 differential oracle for the CBOR codec",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T01:04:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "25572e12fdab705871f5ddd8421375b33d6112a7",
          "body": null,
          "is_bot": false,
          "headline": "🧪 test(secure-chat): cover CBOR maxItems bound; doc CborTag fields",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T00:59:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "15c2d780938a35ad5743aecdc364adbf487b67f5",
          "body": null,
          "is_bot": false,
          "headline": "✨ feat(secure-chat): add deterministic CBOR codec for MIMI content",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T00:56:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "18736fc0149106e150525b3a68d07241000b34c9",
          "body": null,
          "is_bot": false,
          "headline": "CHANGELOG correction",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T00:47:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "29e632cf3f5a1f54f9d4e60f29ebf472d149e88d",
          "body": "The real-ts-mls hook/browser-runtime tests run under jsdom, but vitest executes\neach test module in its own vm realm whose ArrayBuffer/Uint8Array intrinsics\ndiffer from Node's main realm — where crypto.subtle lives. ts-mls/@hpke/@noble\nbuild key material with the vm-realm constructors and hand a bar\n[…]\npremature \"drop Node 20\" edits: publish.yml back to Node\n20, removed the speculative engines>=22, and rewrote the CHANGELOG entry.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "🐛 fix(test): share Node's WebCrypto realm in jsdom tests (Node 20 green)",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-21T00:03:57Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "aeb7b69efbfdc4741126429b7b715a88a5852ecf",
          "body": null,
          "is_bot": false,
          "headline": "fix ci branch",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-20T23:42:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c146669e5c25ad45daf9168c7fb778e27b53ecda",
          "body": "Cut the 0.7.0 release: bump all 9 packages + private root from 0.6.6 → 0.7.0,\nregenerate secure-chat-core VERSION, and freeze the [Unreleased] changelog as\n[0.7.0] (Keep-a-Changelog order: Added → Changed → Deprecated → Fixed).\n\nMinor bump: the diff since v0.6.5 includes a BREAKING change (dropped the\n@agora-sdk/core dependency; baseUrl now a required provider prop). The\nnever-tagged v0.6.6 bump is folded into this release.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "🔖 release: v0.7.0",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-20T23:29:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b7d682b15682f2d7e019dcb58482191b8d6bd994",
          "body": "…2 frame)\n\nApproved brainstorming spec for adopting the IETF MIMI content format\n(draft-ietf-mimi-content, CBOR-encoded MimiContent) as secure-chat's message\ncontent payload — replacing the unshipped bespoke v:2 JSON frame.\n\nKey decisions captured:\n- MIMI CBOR is the ONLY content format (zero users \n[…]\nout-of-order buffering.\n- Client-only: content stays fully opaque to the blind server, zero\n  @agora-server/contract change. Supersedes the IUC v:2 framing and closes\n  IUC canonicalization issue #12.",
          "is_bot": false,
          "headline": "📝 docs(secure-chat): design MIMI CBOR content format (replaces the v:…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-20T23:19:58Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "888de6ad87e1a2fa29ec234c24944537d99c84fd",
          "body": "…k decision\n\nThe agora-server team built and merged the IUC restore-blob relay. Fold the\nfinal facts into our docs.\n\n- implementation guide: dated \"Updates since received\" note — endpoint built\n  & merged; contract corrected to @agora-server/contract@0.13.0 (was 0.10.0)\n  with uploadRestoreBlobSchem\n[…]\nNKS, never\n  INLINE-falls-back; drain-as-you-go under the per-pair quota; optional\n  pre-seal compression; 15-min TTL is the binding constraint) and contract\n  bumped to 0.13.0 with exact export names",
          "is_bot": false,
          "headline": "📝 docs(secure-chat): record settled restore-blob contract + firm chun…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-20T22:50:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "aadf89ee5279976f6eac55ab716efb03948aeda3",
          "body": "A brand-new conversation surfaces to its recipient via secure:welcome (the\nserver emits it to this device's room when someone starts a DM). There is no\nsecure:member:joined on that path — that fires only when a member is added to\nan EXISTING group — so without a welcome listener the recipient's list\n[…]\nlcome and refresh(); the\n  event reaches only our own device room, so it's a precise \"a conversation\n  I'm now a member of just appeared\" trigger\n- test: a secure:welcome event triggers a list refresh",
          "is_bot": false,
          "headline": "🐛 fix(secure-chat): refresh conversation list on secure:welcome",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-20T22:50:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ad8379ed2033589400ca0bb936c32bc6a8c42201",
          "body": "connect() guarded on `this.socket?.connected`, so every call made during the\nasync connect window (each hook calls connect() before the handshake settles)\nre-entered the io() + listener-wiring block. socket.io multiplexes io(sameUrl)\nto ONE socket, so this didn't leak sockets — it stacked DUPLICATE \n[…]\ntence so io() + listener wiring runs exactly once\n  per socket lifetime; disconnect() still nulls it so a reconnect rebuilds\n- test: connect() called repeatedly mid-handshake wires listeners only once",
          "is_bot": false,
          "headline": "🐛 fix(secure-chat): guard socket connect() on existence, not .connected",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-20T22:49:50Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "534c282896c76da0ebde24d37d0f9024cad109a2",
          "body": "Expose RFC 9420's MLS Exporter through SecureChatCrypto as the prerequisite\nfor the IUC Short Authentication String (exporter-derived, not\nKeyPackage-derived, so a blind server can't grind a colliding device).\n\n- interface.ts: exportSecret(group, label, context, length) — derives an\n  app secret fro\n[…]\nts in one group derive the\n  same secret; epoch-binding)\n\nClient-only — no server, contract, or wire change. Implements the approved\nspec docs/superpowers/specs/2026-06-20-mls-exporter-seam-design.md.",
          "is_bot": false,
          "headline": "✨ feat(secure-chat): add exportSecret MLS Exporter to the crypto seam",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-20T22:49:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "914dbefeabf0f5f163279df7d75aa622b9f512fd",
          "body": null,
          "is_bot": false,
          "headline": "docs",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-20T06:54:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d59401ab3614226a5e4d0bcd4d3dbea702d5d762",
          "body": null,
          "is_bot": false,
          "headline": "secure-socket path",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-20T02:36:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1c3d39c356b3594e53c8c732d858d4faa5f52193",
          "body": "Fold the design + security review findings directly into the two specs and\nremove the now-redundant standalone .review.md notes (the findings now live in\nthe specs; the notes remain recoverable from history).\n\ndelivery-and-privacy-modes-design.md:\n- New \"Rollout sequencing (gate)\": server-delete is \n[…]\ns; reconcile the #1 attestation hardening with\n  delete-on-delivery; sha256 canonicalization + createdAt tiebreaker + consent\n  shows the SAS-verified identity + decline back-off; matching test cases.",
          "is_bot": false,
          "headline": "📝 docs(secure-chat): fold security reviews into delivery + IUC specs",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-18T22:37:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "245f06a421d52ad2fcaf921d87ae4ca86d04cb76",
          "body": null,
          "is_bot": false,
          "headline": "reviews",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-18T22:04:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "475cb1d46a0a2df4c7dcb3206b4d74d2adc7c4ad",
          "body": "…dmap)\n\n- Add the design spec docs/superpowers/specs/2026-06-18-encryption-at-rest-\n  design.md: scope, decisions (incl. the rejected XChaCha20 Approach C), the\n  key hierarchy + data flow, a full threat-model table (what at-rest does and\n  does NOT protect — unlocked-app memory is out of scope by d\n[…]\nted (recovery is now\n  IUC + at-rest) and add §5.5 \"Encryption at rest — done (Phase 2.5)\" with the\n  deferred later-work checklist (key/metadata encryption, RAM purge + auto-lock,\n  native keystore).",
          "is_bot": false,
          "headline": "📝 docs(secure-chat): document at-rest encryption (spec + README + roa…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-18T20:34:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "503472b943130c01378e30dc64c52786859ed35a",
          "body": "…e web store\n\nSeal everything the web client persists — MLS group/ratchet secrets, the\ndevice signing key, decrypted `msg:` history, and cursors — at rest behind a\npassword, closing the local IndexedDB plaintext gap (the blind server never\nsaw any of it; this protects disk / same-origin access).\n\n- \n[…]\neprecated tags only; full removal is a separate cleanup.\n- vitest: alias @agora-sdk/secure-chat-core to source so react-js modules can\n  import the runtime base64 helpers without first building dist/.",
          "is_bot": false,
          "headline": "🔒 security(secure-chat): add EncryptedStore at-rest encryption for th…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-18T20:34:36Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "61eee0152eb0a7826801d95f2ff843bba9c296cc",
          "body": "… design specs\n\nCapture two Phase-3/future design specs (with their review notes) that\nemerged from the reload-correctness work and converge on the same model:\ndevice = durable source of truth, server = blind delivery cache, IUC =\nthe only cross-device history path.\n\n- IUC (Inanna Underground Chat) \n[…]\ne-only) bracketed by a content-free \"🔒 Private chat\" marker.\n\nBoth depend on the durable on-device plaintext store landed in the\npreceding fix. Design captures only — no code or contract changes here.",
          "is_bot": false,
          "headline": "📝 docs(secure-chat): add IUC history-restore + delivery/privacy-modes…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-18T17:06:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b09622ae4624a46c95fea44ab479b092c0efd35c",
          "body": "…on't replay\n\nA message sent after a reload was rejected by the peer as a replay\n(\"Desired gen in the past\"). An MLS application message advances the\nleaf's single-use SEND ratchet, but the SDK persisted group state only\non join/Commit — never after a send. On reload it re-imported the\npre-send stat\n[…]\nerified red\nfirst (disabling the send-side persist reproduces the replay). Plus\nhook-level persist/store-hit tests and a repository round-trip.\npnpm test green (233), typecheck clean, build-all clean.",
          "is_bot": false,
          "headline": "🐛 fix(secure-chat): persist ratchet + decrypt-once store so reloads d…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-18T17:05:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f4b4ee54a8ed87f441391d5eaae571fce92e5cd8",
          "body": "…oviders\n\nsecure-chat and social used @agora-sdk/core for exactly one thing: the\ngetApiBaseUrl/getSocketUrl runtime-singleton fallback, letting a provider\nauto-inherit a Replyke app's URL when baseUrl/socketUrl weren't passed.\nThose are accessors to a singleton ReplykeProvider writes inside core\n(no\n[…]\nr now require a\n`baseUrl` prop; the @agora-sdk/core fallback is gone. Consumers that\nrelied on the Replyke auto-inherit must read the URL from their\n@agora-sdk/core config and pass it to the provider.",
          "is_bot": false,
          "headline": "🔧 refactor(monorepo): drop @agora-sdk/core dependency — standalone pr…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-18T11:20:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "523232f1f66060cc3a5831b2b3d87536f2ed1535",
          "body": "…elcome\n\nFixes the recipient stuck on \"⏳ waiting for key update\" forever (the DM\nlists but never decrypts, surviving reloads), plus the test harness that\nfound and now guards it.\n\nTwo compounding defects:\n\n- useSecureDevice.publishKeyPackages generated KeyPackages (whose PRIVATE\n  keys land only in \n[…]\ne / useSecureHandshakes unit tests for both defects.\n- De-flaked ts-mls/backup.test.ts (asserted random ciphertext bytes did\n  not contain 'x'); now asserts byte length + inequality deterministically.",
          "is_bot": false,
          "headline": "🐛 fix(secure-chat): persist KeyPackage keys + don't strand a failed W…",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-18T11:19:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f2497684adc946b63a5d857843164d2faa68e62b",
          "body": "Rename AGORA_E2E_TEST_DATABASE_URL → AGORA_E2E_DATABASE_URL across the\ne2e harness, docs, and .env, and add a documented .env.example.\n\n- The TEST_ prefix was misleading: the var holds whichever Postgres the\n  server is ACTUALLY running on (normally its DEV db while `pnpm dev:api`\n  is up) — distinc\n[…]\n_URL,\n  AGORA_E2E_SOCKET_URL) are unchanged; none carried TEST.\n\nPure rename + new example; no behavior change. Typecheck green; with the\nenv pointed at the running server's db, all 16 e2e tests pass.",
          "is_bot": false,
          "headline": "🔧 config(e2e): clarify db env var name and add .env.example",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-18T06:33:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ac8914eb7eae714510b203e69c436b0f4f09a140",
          "body": null,
          "is_bot": false,
          "headline": "swallow noisy tests issues",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-18T06:08:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0bae423bf85a467fb1b2c2e398f319d6f297cc37",
          "body": null,
          "is_bot": false,
          "headline": "dotenv .envrc",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-18T06:00:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "647c197ce504e3fb4189d00efb9791a4374e6b17",
          "body": "Add a Node TypeScript diagnostic that drives the full MLS secure-chat\nround-trip through a live agora-server, split across two OS processes so\nthe device-state persistence seam — where the browser's \"waiting for key\nupdate\" bug lives — is exercised for real and observably.\n\n- e2e/chat-diag.ts: `--ro\n[…]\nr a cascade\n- Add `pnpm chat-diag` script; design + plan under docs/superpowers\n- Logs only ciphertext summaries and its own diagnostic plaintext — never\n  group secrets, private keys, or privateState",
          "is_bot": false,
          "headline": "✨ feat(e2e): add chat-diag two-process secure-chat diagnostic harness",
          "author_name": "Jenova Marie",
          "author_login": "jenova-marie",
          "committed_at": "2026-06-18T06:00:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        }
      ],
      "releases_count": 18,
      "commits_last_year": 176,
      "latest_release_at": "2026-07-19T06:01:33Z",
      "latest_release_tag": "v0.11.0",
      "releases_from_tags": false,
      "days_since_last_push": 5,
      "active_weeks_last_year": 6,
      "days_since_latest_release": 5,
      "mean_days_between_releases": 0
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 37,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": []
    },
    "popularity": {
      "forks": 0,
      "stars": 0,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0,
        "collected_at": null
      },
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "packages/auth/react-js/tsconfig.json",
        "packages/public-read/core/tsconfig.json",
        "packages/public-read/react-js/tsconfig.json",
        "packages/secure-chat/core/tsconfig.json",
        "packages/secure-chat/crypto/tsconfig.json",
        "packages/secure-chat/expo/tsconfig.json",
        "packages/secure-chat/react-js/tsconfig.json",
        "packages/secure-chat/react-native/tsconfig.json",
        "packages/social/core/tsconfig.json",
        "packages/social/expo/tsconfig.json",
        "packages/social/react-js/tsconfig.json",
        "packages/social/react-native/tsconfig.json",
        "tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 46446,
      "source_files_sampled": 164,
      "oversized_source_files": 0,
      "agent_instruction_files": [
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 20141
    },
    "dependencies": {
      "manifests": [
        "package.json"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm"
      ],
      "dependencies": [],
      "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": 0,
        "merged_prs": 0,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "jenova-marie",
          "commits": 176,
          "avatar_url": "https://avatars.githubusercontent.com/u/202562814?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "publish.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "pnpm-lock.yaml"
      ],
      "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": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": null,
            "reason": "no pull request found",
            "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/30 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": 0,
            "reason": "no 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": 0,
            "reason": "project was created within the last 90 days. Please review its contents carefully",
            "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": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "no SAST tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 0,
            "reason": "26 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "a37662ccb44c3b391b26099879d3195941c79608",
        "ran_at": "2026-07-25T03:36:03Z",
        "aggregate_score": 2.6,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-19T06:21:04Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": null,
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/agora-oss-org/agora-sdk-plus",
    "host": "github.com",
    "name": "agora-sdk-plus",
    "owner": "agora-oss-org"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "at_risk",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 43,
      "inputs": {
        "security": 26,
        "vitality": 75,
        "community": 24,
        "governance": 15,
        "engineering": 70
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 75,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 58,
            "inputs": {
              "commits_last_year": 176,
              "human_commit_share": 1,
              "days_since_last_push": 5,
              "active_weeks_last_year": 6
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 5 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 5
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "6/52 weeks with commits",
                "points": 4.2,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 6
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "176 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 176
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 18,
              "latest_release_tag": "v0.11.0",
              "releases_from_tags": false,
              "days_since_latest_release": 5,
              "mean_days_between_releases": 0
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "18 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 18
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 5 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 5
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~-0 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 0
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "critical",
        "name": "Community & Adoption",
        "value": 24,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "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 (Apache-2.0)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "Apache-2.0"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "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
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "critical",
        "name": "Sustainability & Governance",
        "value": 15,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 10,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "critical",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution, PR acceptance. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution",
                    "pr_acceptance"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 1,
            "inputs": {
              "merged_prs": 0,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 0
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "no decided pull requests or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_decided_prs_or_data",
                    "params": {}
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 36,
            "inputs": {
              "followers": 0,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "agora-oss-org",
              "public_repos": 5,
              "account_age_days": 30
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "0 followers of agora-oss-org",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 0,
                      "login": "agora-oss-org"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "5 public repos, account ~0 yr old",
                "points": 5.8,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 5
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 0
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "good",
        "name": "Engineering Quality",
        "value": 70,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 60,
            "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": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "excellent",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "topics": [
                "agora",
                "agora-sdk",
                "end-to-end-encryption",
                "expo",
                "mls",
                "oauth",
                "open-source",
                "react",
                "react-native",
                "replyke",
                "sdk",
                "secure-chat",
                "self-hosted",
                "social-graph",
                "social-network",
                "typescript"
              ],
              "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": "16 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 16
                    }
                  }
                ],
                "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": "critical",
        "name": "Security",
        "value": 26,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "critical",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): CI-Tests, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "ci_tests",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 26,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 2.6
            },
            "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": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "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/30 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": "no update tool detected",
                "points": 0,
                "status": "missed",
                "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": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "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 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "no SAST tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "26 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 1
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "good",
        "name": "AI Readiness",
        "value": 70,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "good",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 78,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.61,
              "agent_instruction_files": [
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 20141
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "CLAUDE.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "61 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 32.5,
                "status": "partial",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 61,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 53,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "pnpm-lock.yaml"
              ],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "packages/auth/react-js/tsconfig.json",
                "packages/public-read/core/tsconfig.json",
                "packages/public-read/react-js/tsconfig.json",
                "packages/secure-chat/core/tsconfig.json",
                "packages/secure-chat/crypto/tsconfig.json",
                "packages/secure-chat/expo/tsconfig.json",
                "packages/secure-chat/react-js/tsconfig.json",
                "packages/secure-chat/react-native/tsconfig.json",
                "packages/social/core/tsconfig.json",
                "packages/social/expo/tsconfig.json",
                "packages/social/react-js/tsconfig.json",
                "packages/social/react-native/tsconfig.json",
                "tsconfig.json"
              ],
              "agent_commit_share": 0.45,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "packages/auth/react-js/tsconfig.json, packages/public-read/core/tsconfig.json, packages/public-read/react-js/tsconfig.json, packages/secure-chat/core/tsconfig.json, packages/secure-chat/crypto/tsconfig.json, packages/secure-chat/expo/tsconfig.json, packages/secure-chat/react-js/tsconfig.json, packages/secure-chat/react-native/tsconfig.json, packages/social/core/tsconfig.json, packages/social/expo/tsconfig.json, packages/social/react-js/tsconfig.json, packages/social/react-native/tsconfig.json, tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "packages/auth/react-js/tsconfig.json, packages/public-read/core/tsconfig.json, packages/public-read/react-js/tsconfig.json, packages/secure-chat/core/tsconfig.json, packages/secure-chat/crypto/tsconfig.json, packages/secure-chat/expo/tsconfig.json, packages/secure-chat/react-js/tsconfig.json, packages/secure-chat/react-native/tsconfig.json, packages/social/core/tsconfig.json, packages/social/expo/tsconfig.json, packages/social/react-js/tsconfig.json, packages/social/react-native/tsconfig.json, tsconfig.json"
                    }
                  }
                ],
                "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": "45 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 45,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "primary_language": "TypeScript",
              "largest_source_bytes": 46446,
              "source_files_sampled": 164,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "TypeScript (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "TypeScript"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/164 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 164,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-25T03:36:09.012631Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/a/agora-oss-org/agora-sdk-plus.svg",
  "full_name": "agora-oss-org/agora-sdk-plus",
  "license_state": "standard",
  "license_spdx": "Apache-2.0"
}

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 v1.13.0, Schema v0.27.0 — vollständige Methodik · Metriken-Wiki.

Wie ein einzelnes Ergebnis im Gesamtregister steht: aggregierte Statistiken.