Registro público
Informe de salud del softwareesquema 0.27.0 · métricas 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 estrellas⑂ 0 forksdesde jun 2026Ver en GitHub ↗

agora-oss-org/agora-sdk-plus tiene un índice de salud de 43 sobre 100, lo que lo sitúa en la banda En riesgo. Su puntuación más alta es Vitality (75/100) y la más baja, Sustainability & Governance (15/100). Se actualizó por última vez hace 5 días. Una sola persona concentra la mayor parte del trabajo reciente.

43
global / 100
En riesgo

Índice de salud del software

Las métricas se agrupan en categorías ponderadas sobre una escala de 1 a 100. El resultado global parte de su media; cuando la evidencia pública activa la Política de Jurisdicciones de Alto Riesgo, la calificación se ajusta y recibe el límite 49 (En riesgo). Preparación para IA queda fuera.

43
Excelente85-100Ejemplar; cumple prácticamente todos los criterios evaluados
Bueno70-84Saludable; carencias menores
Moderado50-69Aceptable con carencias notables; se recomienda revisión
En riesgo30-49Debilidades significativas; su adopción exige cautela
Crítico1-29Problemas graves (proyecto abandonado, un solo mantenedor, sin higiene)
VitalidadComunidad yAdopciónSostenibilidady GobernanzaCalidad deIngenieríaSeguridadPreparaciónpara IA

Perfil de puntuación

Cada eje es una categoría. La forma importa más que la media: un proyecto sano llena toda la figura, mientras que un perfil de picos y cráteres indica que la fortaleza en una dimensión enmascara el riesgo en otra.

Titularidad

Agora OSS OrgOrganización
0 seguidores5 repositorios públicosdesde jun 2026

Este repositorio está respaldado por una organización: una custodia compartida y responsable que puede sobrevivir a cualquier mantenedor individual.

Métricas por categoría

Vitalidad

¿Está vivo el proyecto: se escribe código y se publican versiones?

75Bueno · 22% del índice global
Cómo se puntúa
36/36Recencia de push — último push hace 5 días
4.2/36Cadencia de commits — 6/52 semanas con commits
18/18Volumen de commits — 176 commits en el último año
0/10OpenSSF Scorecard: Maintained — project was created within the last 90 days. Please review its contents carefully
Datos de entrada utilizados
commits_last_year176
human_commit_share1
days_since_last_push5
active_weeks_last_year6
Cómo se puntúa
27/27Publica versiones — 18 versiones publicadas
36/36Recencia de las versiones — última versión hace 5 días
27/27Cadencia de publicación — una versión cada ~0 días
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count18
latest_release_tagv0.11.0
releases_from_tagsno
days_since_latest_release5
mean_days_between_releases0
Excluidos de la puntuación (sin datos o no aplicable): OpenSSF Scorecard: Signed-Releases. Los pesos restantes se han renormalizado.

Comunidad y Adopción

¿Tiene el proyecto usuarios, descargas, atención y unas condiciones acogedoras para quienes contribuyen?

24Crítico · 18% del índice global
Cómo se puntúa
0/60Estrellas — 0 estrellas
0/25Forks — 0 forks
0/15Observadores — 0 observadores
Datos de entrada utilizados
forks0
stars0
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Cómo se puntúa
22.5/22.5README
22.5/22.5Licencia — licencia reconocida (Apache-2.0)
0/18Guía CONTRIBUTING
0/13.5Código de conducta
0/7.2Plantilla de issues
0/6.3Plantilla de PR
Datos de entrada utilizados
has_readme
has_license
has_contributingno
has_issue_templateno
has_code_of_conductno
has_pull_request_templateno

Sostenibilidad y Gobernanza

¿Sobrevivirá el proyecto a sus personas: factor bus, capacidad de respuesta, quién lo respalda y mantenimiento del paquete?

15Crítico · 24% del índice global
Cómo se puntúa
9/54Factor bus — la mitad de los commits recae en 1 contribuyente(s)
0/22.5Distribución de commits — el principal contribuyente firma el 100% de los commits
1.4/13.5Amplitud de contribuyentes — 1 contribuyentes
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Datos de entrada utilizados
bus_factor1
contributors_sampled1
top_contributor_share1
Cómo se puntúa
0/46.8Resolución de issues — sin issues o sin datos
0/38.3Aceptación de PR — sin PR decididos o sin datos
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs0
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
Excluidos de la puntuación (sin datos o no aplicable): Resolución de issues, Aceptación de PR. Los pesos restantes se han renormalizado.
Cómo se puntúa
30/30Respaldo de la propiedad — propiedad de una organización
0/20Dominio verificado
0/25Alcance del propietario — 0 seguidores de agora-oss-org
5.8/25Trayectoria — 5 repos públicos, cuenta de ~0 años
Datos de entrada utilizados
followers0
owner_typeOrganization
is_verified
owner_loginagora-oss-org
public_repos5
account_age_days30

Calidad de Ingeniería

¿Existen unas prácticas mínimas de ingeniería y documentación?

70Bueno · 20% del índice global
Cómo se puntúa
24/24Flujos de trabajo de CI — 2 flujo(s) de trabajo
24/24Pruebas presentes
0/16Configuración de linter
0/9.6Hooks de pre-commit
0/6.4.editorconfig
0/20OpenSSF Scorecard: CI-Tests — sin datos
Datos de entrada utilizados
has_ci
has_tests
has_editorconfigno
has_linter_configno
has_precommit_configno
Excluidos de la puntuación (sin datos o no aplicable): OpenSSF Scorecard: CI-Tests. Los pesos restantes se han renormalizado.

Documentación

85Excelente
Cómo se puntúa
30/30README
25/25Directorio de documentación
0/15Sitio de documentación / página del proyecto
10/10Descripción del repositorio
10/10Topics — 16 topics
10/10Wiki
Datos de entrada utilizados
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_wiki
homepage
has_readme
has_docs_dir
has_description

Seguridad

¿Son sólidas las prácticas visibles de seguridad y de cadena de suministro, sin exposición jurisdiccional de alto riesgo sin resolver?

26Crítico · 16% del índice global
Cómo se puntúa
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 — sin datos
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.5Licencia — 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 — sin datos
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0/7.5Vulnerabilities — 26 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate2,6
Excluidos de la puntuación (sin datos o no aplicable): ci_tests, signed_releases. Los pesos restantes se han renormalizado.

Preparación para IA

¿Hasta qué punto está el repositorio preparado para desarrollarse y mantenerse con agentes de codificación de IA? Es una insignia independiente y experimental — peso 0,0, de modo que se presenta por separado y no afecta a la puntuación de salud global.

70Bueno · 0% del índice global
Cómo se puntúa
45/45Instrucciones para agentes — CLAUDE.md
0/15Documentación legible por máquinas (llms.txt)
32.5/40Historial de commits legible — 61 de 100 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share0,61
agent_instruction_filesCLAUDE.md
agent_instruction_max_bytes20.141
Cómo se puntúa
0/18Arranque con un solo comando
22/22Pruebas automatizadas
0/11Configuración de lint / formato
11/11Verificación estática de tipos — 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/10Entorno reproducible — lockfile
10/10Práctica demostrada con agentes — 45 de los últimos 100 commits con autoría o crédito de agente
0/8Mantenimiento automatizado — no se observan actualizaciones automáticas de dependencias
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Datos de entrada utilizados
has_nixno
has_tests
lockfilespnpm-lock.yaml
has_dockerfileno
typed_language
bootstrap_files
has_devcontainerno
has_linter_configno
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
Cómo se puntúa
45/45Código verificable por tipos — TypeScript (tipado estático)
55/55Tamaños de archivo manejables — 0/164 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languageTypeScript
largest_source_bytes46.446
source_files_sampled164
oversized_source_files0

Datos clave

0estrellas de GitHub
1contribuidores
176commits en los últimos 12 meses
5días desde el último push
18versiones publicadas
1factor bus
0issues abiertas
npmecosistemas de paquetes

Advertencias de recopilación de datos

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

Más detalle

OpenSSF Scorecard 2.6 / 10
2.6agregado

Evaluación de seguridad independiente y agnóstica en cuanto a herramientas, procedente del proyecto de código abierto OpenSSF Scorecard. Cada comprobación premia una práctica de seguridad, no la herramienta de un proveedor concreto. Las comprobaciones que Scorecard no pudo determinar se marcan como n/d y se excluyen de la puntuación de seguridad (nunca se cuentan como cero).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
n/dCI-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
n/dSigned-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
0Vulnerabilities26 existing vulnerabilities detected
Todas las dependencias no recopilado

No fue posible recopilar el conjunto de dependencias resuelto para este informe: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Informe JSON sin procesar legible por máquina
{
  "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"
}

Las puntuaciones son señales, no garantías. Reflejan prácticas públicamente visibles en GitHub; no son una auditoría de código ni una garantía de seguridad.

Los datos ausentes se excluyen y los pesos se renormalizan; nunca se puntúan como cero. La metodología es versionada y abierta: métricas v1.13.0, esquema v0.27.0 — metodología completa · wiki de métricas.

Cómo se sitúa un resultado dentro del registro general: estadísticas agregadas.