Registro público
Informe de salud del softwareesquema 0.27.0 · métricas 1.13.0 · 2026-07-27 18:47 UTC

XoRHub / waas

Cloud Workspace solution for kubernetes gitops friendly

Go · TypeScriptApache-2.0★ 4 estrellas⑂ 0 forksdesde dic 2024Ver en GitHub ↗

XoRHub/waas tiene un índice de salud de 63 sobre 100, lo que lo sitúa en la banda Moderado. Su puntuación más alta es Engineering Quality (90/100) y la más baja, Community & Adoption (37/100). Se actualizó por última vez hoy. Una sola persona concentra la mayor parte del trabajo reciente.

63
global / 100
Moderado

Í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.

63
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

XoRHubOrganización
1 seguidor5 repositorios públicosdesde dic 2024

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

Ecosistemas de paquetes

RegistroPaqueteVersiónDescargas / mesVersionesÚltima publicación
Gogithub.com/XoRHub/waasv0.3.0-2hace 0 días

Métricas por categoría

Vitalidad

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

80Bueno · 22% del índice global
Cómo se puntúa
36/36Recencia de push — último push hace 0 días
2.8/36Cadencia de commits — 4/52 semanas con commits
18/18Volumen de commits — 596 commits en el último año
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Datos de entrada utilizados
commits_last_year596
human_commit_share0,94
days_since_last_push0
active_weeks_last_year4
Cómo se puntúa
27/27Publica versiones — 4 versiones publicadas
36/36Recencia de las versiones — última versión hace 0 días
27/27Cadencia de publicación — una versión cada ~2,5 días
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count4
latest_release_tagchart-0.3.0
releases_from_tagsno
days_since_latest_release0
mean_days_between_releases2,5
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?

37En riesgo · 18% del índice global
Cómo se puntúa
7.7/60Estrellas — 4 estrellas
0/25Forks — 0 forks
0/15Observadores — 0 observadores
Datos de entrada utilizados
forks0
stars4
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)
18/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_contributing
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?

44En riesgo · 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
23.4/46.8Resolución de issues — 50% de issues cerradas
24.2/38.3Aceptación de PR — 71/112 PR decididos fusionados
0/15OpenSSF Scorecard: Code-Review — Found 0/8 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs71
open_issues2
closed_issues2
issue_closed_ratio0,5
closed_unmerged_prs41
Cómo se puntúa
30/30Respaldo de la propiedad — propiedad de una organización
0/20Dominio verificado
2.2/25Alcance del propietario — 1 seguidores de XoRHub
9/25Trayectoria — 5 repos públicos, cuenta de ~1 años
Datos de entrada utilizados
followers1
owner_typeOrganization
is_verified
owner_loginXoRHub
public_repos5
account_age_days601
Cómo se puntúa
25/25Publicado y resoluble — 1 paquete(s) en go
35/35Recencia de publicación — última publicación hace 0 días
12/20Historial de versiones — 2 versiones en el registro
20/20No obsoleto — activo, ni obsoleto ni retirado
Datos de entrada utilizados
packagesgithub.com/XoRHub/waas
ecosystemsgo
any_deprecatedno
min_days_since_publish0

Calidad de Ingeniería

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

90Excelente · 20% del índice global
Cómo se puntúa
24/24Flujos de trabajo de CI — 6 flujo(s) de trabajo
24/24Pruebas presentes
16/16Configuración de linter — .golangci.yml, eslint.config.js
0/9.6Hooks de pre-commit
0/6.4.editorconfig
20/20OpenSSF Scorecard: CI-Tests — 10 out of 10 merged PRs checked by a CI test -- score normalized to 10
Datos de entrada utilizados
has_ci
has_tests
has_editorconfigno
has_linter_config
has_precommit_configno

Documentación

100Excelente
Cómo se puntúa
30/30README
25/25Directorio de documentación
15/15Sitio de documentación / página del proyecto — https://xorhub.github.io/website
10/10Descripción del repositorio
10/10Topics — 6 topics
10/10Wiki
Datos de entrada utilizados
topicsgitops, guacd, kubernetes, operator, waas, workspace
has_wiki
homepagehttps://xorhub.github.io/website
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?

62Moderado · 16% del índice global
Cómo se puntúa
7.5/7.5Binary-Artifacts — no binaries found in the repo
2.2/7.5Branch-Protection — branch protection is not maximal on development and all release branches
2.5/2.5CI-Tests — 10 out of 10 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/8 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
10/10Dangerous-Workflow — no dangerous workflow patterns detected
7.5/7.5Dependency-Update-Tool — update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Licencia — license file detected
7.5/7.5Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
0/5Packaging — sin datos
4/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 8
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — sin datos
7.5/7.5Token-Permissions — GitHub workflow tokens follow principle of least privilege
6/7.5Vulnerabilities — 2 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate6,2
Excluidos de la puntuación (sin datos o no aplicable): packaging, 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.

82Bueno · 0% del índice global
Cómo se puntúa
45/45Instrucciones para agentes — AGENTS.md
0/15Documentación legible por máquinas (llms.txt)
40/40Historial de commits legible — 93 de 94 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share0,989
agent_instruction_filesAGENTS.md
agent_instruction_max_bytes3058
Cómo se puntúa
18/18Arranque con un solo comando — .mise.toml, Makefile, operator/Makefile, shared/Makefile
22/22Pruebas automatizadas
11/11Configuración de lint / formato — .golangci.yml, eslint.config.js
11/11Verificación estática de tipos — frontend/tsconfig.json
10/10Entorno reproducible — Dockerfile, lockfile
0/10Práctica demostrada con agentes — ningún commit con autoría de agente entre los últimos 100
8/8Mantenimiento automatizado — 4 de los últimos 100 commits son actualizaciones automáticas de dependencias
8/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 8
Datos de entrada utilizados
has_nixno
has_tests
lockfilesgo.sum, package-lock.json
has_dockerfile
typed_language
bootstrap_files.mise.toml, Makefile, operator/Makefile, shared/Makefile
has_devcontainerno
has_linter_config
typecheck_configsfrontend/tsconfig.json
agent_commit_share0
toolchain_manifestsapi-server/go.mod, operator/go.mod, shared/go.mod, test/smoke/go.mod, wwt/go.mod
dependency_bot_commit_share0,04
Cómo se puntúa
45/45Código verificable por tipos — Go (tipado estático)
55/55Tamaños de archivo manejables — 0/363 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languageGo
largest_source_bytes45.356
source_files_sampled363
oversized_source_files0
Cómo se puntúa
0/40Esquema de API (OpenAPI/GraphQL/proto)
0/20Servidor MCP
40/40Ejemplos ejecutables — examples
Datos de entrada utilizados
example_dirsexamples
has_mcp_signalno
api_schema_files

Datos clave

4estrellas de GitHub
1contribuidores
596commits en los últimos 12 meses
0días desde el último push
4versiones publicadas
1factor bus
2issues abiertas
Go, npmecosistemas de paquetes

Advertencias de recopilación de datos

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • Could not fetch go package 'github.com/xorhub/waas/wwt' from its registry
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Más detalle

OpenSSF Scorecard 6.2 / 10
6.2agregado

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-27 18:47 UTC

10Binary-Artifactsno binaries found in the repo
3Branch-Protectionbranch protection is not maximal on development and all release branches
10CI-Tests10 out of 10 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/8 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
10Dangerous-Workflowno dangerous workflow patterns detected
10Dependency-Update-Toolupdate tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
n/dPackagingpackaging workflow not detected
8Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 8
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
n/dSigned-Releasesno releases found
10Token-PermissionsGitHub workflow tokens follow principle of least privilege
8Vulnerabilities2 existing vulnerabilities detected
Dependencias directas 47
RegistroPaqueteRestricción de versiónManifiesto
Gogithub.com/coreos/go-oidc/v3v3.20.0api-server/go.mod
Gogithub.com/go-chi/chi/v5v5.3.1api-server/go.mod
Gogithub.com/go-chi/httpratev0.16.0api-server/go.mod
Gogithub.com/golang-jwt/jwt/v5v5.3.1api-server/go.mod
Gogithub.com/golang-migrate/migrate/v4v4.19.1api-server/go.mod
Gogithub.com/google/uuidv1.6.0api-server/go.mod
Gogithub.com/jackc/pgx/v5v5.10.0api-server/go.mod
Gogithub.com/prometheus/client_golangv1.23.2api-server/go.mod
Gogithub.com/xorhub/waas/operatorv0.0.0api-server/go.mod
Gogithub.com/xorhub/waas/sharedv0.0.0api-server/go.mod
Gogolang.org/x/cryptov0.54.0api-server/go.mod
Gogolang.org/x/oauth2v0.36.0api-server/go.mod
Gogopkg.in/yaml.v3v3.0.1api-server/go.mod
Gok8s.io/apiv0.36.2api-server/go.mod
Gok8s.io/apimachineryv0.36.2api-server/go.mod
Gok8s.io/client-gov0.36.2api-server/go.mod
Gomodernc.org/sqlitev1.54.0api-server/go.mod
Gosigs.k8s.io/controller-runtimev0.24.1api-server/go.mod
Gosigs.k8s.io/yamlv1.6.0api-server/go.mod
npm@tanstack/react-query^5.90.21frontend/package.json
npmguacamole-common-js^1.5.0frontend/package.json
npmi18next^26.0.0frontend/package.json
npmi18next-browser-languagedetector^8.0.0frontend/package.json
npmreact^19.1.0frontend/package.json
npmreact-dom^19.1.0frontend/package.json
npmreact-i18next^17.0.0frontend/package.json
npmreact-router^8.0.0frontend/package.json
npmyaml^2.9.0frontend/package.json
npmzustand^5.0.3frontend/package.json
Gogithub.com/prometheus/client_golangv1.23.2operator/go.mod
Gogithub.com/robfig/cron/v3v3.0.1operator/go.mod
Gogolang.org/x/cryptov0.54.0operator/go.mod
Gogolang.org/x/textv0.40.0operator/go.mod
Gok8s.io/apiv0.36.2operator/go.mod
Gok8s.io/apimachineryv0.36.2operator/go.mod
Gok8s.io/client-gov0.36.2operator/go.mod
Gok8s.io/utilsv0.0.0-20260707023825-cf1189d6abe3operator/go.mod
Gosigs.k8s.io/controller-runtimev0.24.1operator/go.mod
Gosigs.k8s.io/yamlv1.6.0operator/go.mod
Gogithub.com/golang-jwt/jwt/v5v5.3.1shared/go.mod
Gogithub.com/invopop/jsonschemav0.14.0shared/go.mod
Gok8s.io/apiv0.36.2shared/go.mod
Gosigs.k8s.io/yamlv1.6.0shared/go.mod
Gogithub.com/golang-jwt/jwt/v5v5.3.1wwt/go.mod
Gogithub.com/gorilla/websocketv1.5.4-0.20250319132907-e064f32e3674wwt/go.mod
Gogithub.com/prometheus/client_golangv1.23.2wwt/go.mod
Gogithub.com/xorhub/waas/sharedv0.0.0wwt/go.mod
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": [
        "gitops",
        "guacd",
        "kubernetes",
        "operator",
        "waas",
        "workspace"
      ],
      "is_fork": false,
      "size_kb": 5461,
      "has_wiki": true,
      "homepage": "https://xorhub.github.io/website",
      "languages": {
        "Go": 1593996,
        "CSS": 1862,
        "HTML": 775,
        "Shell": 12237,
        "Python": 6118,
        "Makefile": 19651,
        "Dockerfile": 2680,
        "JavaScript": 1338,
        "TypeScript": 780319,
        "Go Template": 2676
      },
      "pushed_at": "2026-07-27T10:36:16Z",
      "created_at": "2024-12-03T17:40:39Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-27T10:32:59Z",
      "description": "Cloud Workspace solution for kubernetes gitops friendly",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "Apache-2.0",
      "default_branch": "main",
      "license_spdx_raw": "Apache-2.0",
      "primary_language": "Go",
      "significant_languages": [
        "Go",
        "TypeScript"
      ]
    },
    "owner": {
      "blog": null,
      "name": null,
      "type": "Organization",
      "login": "XoRHub",
      "company": null,
      "location": null,
      "followers": 1,
      "avatar_url": "https://avatars.githubusercontent.com/u/190526170?v=4",
      "created_at": "2024-12-03T17:33:28Z",
      "is_verified": null,
      "public_repos": 5,
      "account_age_days": 601
    },
    "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": "chart-0.3.0",
          "kind": "other",
          "published_at": "2026-07-27T10:36:16Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-07-27T10:12:16Z"
        },
        {
          "tag": "waas-chart-0.2.0",
          "kind": "other",
          "published_at": "2026-07-19T23:08:09Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-07-19T22:54:27Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "2f58c241322e4c716ac66bbd8ef635547588339d",
          "body": "…mponents--chart\n\nchore(main): release chart 0.3.0",
          "is_bot": false,
          "headline": "Merge pull request #79 from XoRHub/release-please--branches--main--co…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-27T10:32:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "63a079548fb7a0b92af8676b70ba7228df806cda",
          "body": null,
          "is_bot": true,
          "headline": "chore(main): release chart 0.3.0",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-07-27T10:13:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dad86d043f8768672302759dd432c853000ae903",
          "body": "…mponents--waas\n\nchore(main): release 0.3.0",
          "is_bot": false,
          "headline": "Merge pull request #78 from XoRHub/release-please--branches--main--co…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-27T10:08:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "35b3c1788bbb2a0405a047cf8f286a146da222fa",
          "body": null,
          "is_bot": true,
          "headline": "chore(main): release 0.3.0",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-07-27T08:57:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eb23444c388abaf0ea65fb7d43e92fcab854e014",
          "body": "…gest to 59ccf09 (#120)\n\nCo-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): update nginxinc/nginx-unprivileged:1.31-alpine docker di…",
          "author_name": "renovate[bot]",
          "author_login": "renovate[bot]",
          "committed_at": "2026-07-27T08:52:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eb51e04926b39985ad20ec6d769bb831f0b6d006",
          "body": "fix(deps): update go-non-major",
          "is_bot": false,
          "headline": "Merge pull request #119 from XoRHub/renovate/go-non-major",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-27T08:46:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ed084e3aa6622cd915765553ac3fade9c606ed0d",
          "body": null,
          "is_bot": true,
          "headline": "fix(deps): update go-non-major",
          "author_name": "renovate[bot]",
          "author_login": "renovate[bot]",
          "committed_at": "2026-07-27T04:28:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f0679b3066bc8177d2e41742d3043a67fd3dbadf",
          "body": "Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): update frontend-dev-non-major (#118)",
          "author_name": "renovate[bot]",
          "author_login": "renovate[bot]",
          "committed_at": "2026-07-27T04:27:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7da6ab1d0c2c38904f15994045cb99ad740aa03b",
          "body": "…st-1.x\n\nchore(deps): update dependency helm-unittest/helm-unittest to v1.1.2",
          "is_bot": false,
          "headline": "Merge pull request #95 from XoRHub/renovate/helm-unittest-helm-unitte…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-26T14:13:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "40336bf9026dc33fc698cafe47e68e3cab801004",
          "body": null,
          "is_bot": true,
          "headline": "chore(deps): update dependency helm-unittest/helm-unittest to v1.1.2",
          "author_name": "renovate[bot]",
          "author_login": "renovate[bot]",
          "committed_at": "2026-07-26T14:11:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "40570dd52c86f0ee93223fa27b8576db73a438ba",
          "body": null,
          "is_bot": false,
          "headline": "docs(readme): add AI disclosure",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T23:04:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "85ef3a7b3ceccbf18faf19216cbc6537057f221c",
          "body": "Kept as the point-in-time record it is — the analysis is not rewritten —\nwith two corrections found while remediating F6, and a delivery section\nnaming what shipped per finding. Three landed as something other than\nwhat was prescribed and three deliberately shipped nothing; a status\nthat reports either wrongly is the drift F15 was about.",
          "is_bot": false,
          "headline": "docs(audit): record audit 3 and what was delivered against it",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T23:00:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e10b43aed8136f06dee8486f29c5edb27a54ee7d",
          "body": "ci: report patch coverage instead of hiding it",
          "is_bot": false,
          "headline": "Merge pull request #116 from XoRHub/ci/codecov-patch-informational",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T22:49:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f9ff9349b41da6396a2c154195a5db96b16fffc1",
          "body": "patch: off was right when the frontend sat at 7.9% and any patch status\nwould have been red on every PR — a check nobody reads is worse than\nnone. At 69% it only hides the number: the project status cannot stand\nin for it, since api-server's ~3 700 statements make its 1% band worth\n~50 entirely uncovered new lines, and a wave lands as many small PRs\nthat each fit inside it.\n\ninformational, so it reports without ever failing a merge. Validated\nagainst Codecov's own /validate endpoint.",
          "is_bot": false,
          "headline": "ci: report patch coverage instead of hiding it",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T22:48:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a50472e36dbed78776e7a3e43042e0239737cd27",
          "body": "add some easy test",
          "is_bot": false,
          "headline": "Merge pull request #115 from XoRHub/test/uncovered-session-branches",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T22:42:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "68338fbea1cf0fee8131940c756e9d94c76b52a6",
          "body": "The first version asserted only that no entries appeared for a name no\nfixture ever wrote — a syncPending emptied of its whole body passed it.\nIt now leads with the nominal case, so doing nothing fails, and captures\nslog to hold the distinction its own comment claimed: a delete event\nstays silent, a\n[…]\ne blind spot on the frontend: every case answered any path, so a\nprobe pointed at a route that does not exist would have kept both suites\ngreen while sending the whole fleet to the unavailable screen.",
          "is_bot": false,
          "headline": "test: make the syncPending cases bite, and pin the probed route",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T22:38:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c9a55ce341283276c240ae963221d253347584d5",
          "body": "Both are swallowed on purpose — the queue is best-effort and the next\nevent re-queues — so nothing but a test proves they do not take the\nconsumer loop down with them, nor that a deleted image stays silent while\nan unreachable API server does not.",
          "is_bot": false,
          "headline": "test(api-server): cover syncPending's two swallowed failures",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T22:22:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a096b3a40c4876cbcbba64e09499cab2a865e064",
          "body": "The boot probe's 401-vs-anything-else rule is what makes the api-server's\n503 worth answering: reading an outage as \"signed out\" would sign the\nfleet out, which is precisely what the 503 exists to prevent. The SSO\nlanding's clearLocal-not-logout decision has the same shape — one\nhiccuping profile fetch must not revoke the account everywhere.",
          "is_bot": false,
          "headline": "test(frontend): cover the two places a session is established",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T22:21:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3111ade104502ff459bb030ab4d7ca292daabc42",
          "body": "App.tsx pulls in every page and builds the router at module scope, so the\none piece of logic in it that decides whether a browser is signed in\ncould not be exercised without mounting the whole application.",
          "is_bot": false,
          "headline": "refactor(frontend): move the boot session probe out of App",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T22:21:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "23fec7c9663bd66e5888a61563f856ae01a011e5",
          "body": "docs: cover self-revoking edits and the last-admin guard",
          "is_bot": false,
          "headline": "Merge pull request #114 from XoRHub/fix/admin-self-revocation",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T22:14:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "17e1c346a27c96edc824143ee4bc8cdc8d56d04d",
          "body": "Serializable isolation plus a retry was the first design; taking the lock\nreplaced it and left the loop unreachable — PostgreSQL raises no 40001 at\nthe default isolation level, so the branch could never run and could\nnever be covered. The doc comment still described the design that was\nreplaced.",
          "is_bot": false,
          "headline": "refactor(api-server): drop the retry the admin-floor lock made dead",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T22:07:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "399e9542c51f8aff3e1c2950e1b6a227a380dd8f",
          "body": "CORS was at 0% while carrying the header that tells the SPA its session\nended — the one place deciding what a cross-origin browser may read of a\nresponse. Plus two refusals every admin edit goes past (unknown account,\nunknown role) and the 204 path, which is the shape logout answers with.",
          "is_bot": false,
          "headline": "test: cover the untested branches the patch report flagged",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T22:00:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0bbf8bc3ec09d6f415803254e60babd5eb288228",
          "body": "The exemption is stated in docs/governance.md and in the guarded\nwriters' doc, but nothing held it: routing syncUser through\nSetRoleUnlessLastAdmin broke the documented contract with every test\nstill green. Verified by doing exactly that — this one fails.",
          "is_bot": false,
          "headline": "test(api-server): pin the IdP's exemption from the admin floor",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T21:44:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "007e91f745fab61bf26f24dc0a705d34f31b6d9d",
          "body": "…heck\n\nTwo admins dropping their rights at the same moment write two different\nrows: neither blocks the other, and both count a seat the other is about\nto vacate. Proven against PostgreSQL — without the fix, both demotions\nland and no administrator is left. The guarded writers lock the admin\nseats f\n[…]\n way back, and that mode has one — redeploy without the flag and\nsign in as the bootstrap admin. Enforcing it there would only block the\ncleanup of a local admin account nobody can sign into any more.",
          "is_bot": false,
          "headline": "fix(api-server): enforce the admin floor in the write, not in a pre-c…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T21:39:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4ba42b36f0738dda0cfbe1bdca6901b47fae2d23",
          "body": "… header\n\nThe OIDC role sync writes the role directly: with adminGroups set the\nIdP owns it, and an IdP-driven demotion is undone by re-adding the group,\nunlike the API path which has no way back. Access-Control-Expose-Headers\nis insurance only — the portal fetches relative paths and could not read\na cross-origin header if it ever moved.",
          "is_bot": false,
          "headline": "docs: scope the last-admin guard to the admin API, expose the session…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T21:13:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ce014d6c0c14fe498e820da4e45db8ce8f0a1f66",
          "body": "The api layer becomes the single reader of the header, so every endpoint\nthat revokes its own caller is covered without repeating the rule per\nhook: useUpdateProfile drops its client-side password test and only\nrefrains from putting the user back from a body describing an account it\njust lost. Unknown reasons are ignored — the union is never widened from\na string off the wire.",
          "is_bot": false,
          "headline": "fix(frontend): sign out from the server's session-ended announcement",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T21:03:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0a9e3983ae856b4ab6e86c406eed2c8e512a853a",
          "body": "An admin demoting, deactivating or password-resetting their OWN account\nrevoked their session doing it, and the browser kept a dead cookie until\nsome later 401. middleware.EndSession becomes the single way to close a\nsession in a response: it expires the cookie and names the reason in a\nheader, beca\n[…]\n\nactive administrator cannot lose their rights. There is no in-product\nway back from zero admins — WAAS_ADMIN_PASSWORD only ever seeds an\nempty users table, it never re-applies to an existing account.",
          "is_bot": false,
          "headline": "feat(api-server): end the session when an edit revokes its own author",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T21:03:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7b6980b730cfcd80a6bd340bbeb33208e6a313a3",
          "body": "The session is gone the moment the request succeeds, so staying on\nscreen only defers the discovery to the next click — and to a generic\nexpiry notice that reads like a failure rather than like what the user\njust asked for. Handled in useUpdateProfile rather than in the page, so\nit does not depend on react-query callback ordering.",
          "is_bot": false,
          "headline": "fix(frontend): sign out explicitly after a password change",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T20:37:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aedbf7884a967eb91a9dae11190bee9b32df3902",
          "body": "…eir password\n\nThe change already revokes every token of the account, this browser's\nincluded; leaving the cookie in the jar makes the UI look signed in\nuntil some later request 401s. Re-minting is not an option: a token\nissued in the same second as the revocation bound is itself rejected.",
          "is_bot": false,
          "headline": "fix(api-server): expire the session cookie when the caller changes th…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T20:37:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f8870fe4bce4dfeafb7aa384f79e34a1ee74b6f1",
          "body": "fix: make the per-user namespace actually per-user",
          "is_bot": false,
          "headline": "Merge pull request #113 from XoRHub/fix/personal-namespace-collision",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T20:30:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d181424bad8a62a6e04fbe71dc92bf1ab3087b8e",
          "body": "Truncation thresholds depend on the pattern's shape, not on the values:\neach token gets (63 - literals) / count and never borrows what a\nshorter neighbour leaves unused. Written down so the shape is chosen\nknowingly, since a hashed namespace is the visible symptom.",
          "is_bot": false,
          "headline": "docs(placement): document the name budget and its fixed shares",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T20:24:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4014cf7da8d232c4ffca34d85df350e717eee842",
          "body": "Sanitization into a DNS-1123 label is lossy, so alice.smith and\nalice_smith are distinct to the UNIQUE constraint yet share one personal\nnamespace, its ownership label and its ResourceQuota. Directories\nalready number their homonyms (jdoe, jdoe2), so a collision is refused\nat both identity doors rat\n[…]\na whole\ndirectory would end up with one working account. Those resolve through\nthe first and last groups of the account id instead — unique per\naccount and, unlike a hash, queryable back to its owner.",
          "is_bot": false,
          "headline": "feat(api-server): make the per-user namespace actually per-user",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T20:16:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d2bd265a8f678f4bcffefad28bbb6893f0d272b5",
          "body": "The webhook admitted placement and the operator decided ownership\nlabelling with two byte-identical copies of the prefix rule. They must\nagree: a namespace one calls personal and the other does not gets a\nquota without an owner.",
          "is_bot": false,
          "headline": "refactor(operator): give the personal-namespace rule one home",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T19:37:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4b75a8aac957421ef61e6a31fbfe4f72fb87f79b",
          "body": "fix(api-server): cap the Postgres connection pool",
          "is_bot": false,
          "headline": "Merge pull request #112 from XoRHub/fix/bound-blocking-paths",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T15:07:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "60b9b57b89ccc0c5b3cdac0b1d3d827b1a694d70",
          "body": "The force-sync 503 was mapped on context.DeadlineExceeded, but a Go\nclient-timeout error also satisfies that match — so a source that hangs\nuntil the fetch timeout (a wrong URL, an unreachable registry) answered\n503 'timed out, try again' instead of the 502 with the fetch error an\nadmin debugs from.\n[…]\nSyncBusy sentinel when it\ngives up waiting for the semaphore, and AdminSyncImage maps the 503 on\nthat sentinel alone: busy behind another image's sync means 503, a slow\nor broken source keeps the 502.",
          "is_bot": false,
          "headline": "fix(api-server): keep a hanging catalog source a 502, not a busy 503",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T14:31:49Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8bd29074ad4d1b49283a37f63594593cdd5a13aa",
          "body": "The sync semaphore serializes across ALL images, so a force-sync could\nwait behind an unrelated image's fetch inside a user-facing HTTP request\nthe server never times out (WriteTimeout stays 0 for SSE). SyncNow now\ncarries a 15 s end-to-end deadline — one worst-case fetch plus headroom\n— and the syn\n[…]\nyable server condition), keeping 502 for a broken catalog\nsource. Serialization semantics are unchanged; the audit's per-image\nlocking alternative was deliberately not built. Audit 2026-07 finding\nF8.",
          "is_bot": false,
          "headline": "fix(api-server): bound the admin catalog force-sync with a deadline",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T14:24:46Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9c56ccc474de2d191d04af49fa84d927124a9487",
          "body": "The per-request revocation check is deliberately uncached, so every\nauthenticated request costs one primary-key read — and the pgx path set\nno pool limits, so a Postgres slowdown converted request concurrency\ninto unbounded connection growth against a default max_connections of\n100, amplifying a slo\n[…]\nce.md\naccepts only for a real failure. 25 open/idle connections per replica\nand a 30-minute lifetime turn that amplifier into a queue; the no-cache\ndecision stays untouched. Audit 2026-07 finding F10.",
          "is_bot": false,
          "headline": "fix(api-server): cap the Postgres connection pool",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T14:24:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1dbe8141a1d04cd5bab8c959256bd0859fb6d9c0",
          "body": "test(helm): cover placement pattern wiring and default policy grants",
          "is_bot": false,
          "headline": "Merge pull request #111 from XoRHub/chore/breaking-change-guards",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T13:28:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "594266fa42ff0a396193af9bb6b1ff3cecd68758",
          "body": "The status table still said 'Deferred — closed by the planned\ntoken-refresh work'; the session moved to an httpOnly cookie and the\nSPA stores no credential at all, which closed it outright. Status\ncell only — the point-in-time body is untouched.",
          "is_bot": false,
          "headline": "docs: record security finding 13 as fixed by the cookie switch",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T13:19:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c32f4416bab0b721e8eda1f6000b38f4a22cf177",
          "body": "The removal shipped with its remediation only in the commit footer and\nthe future chart CHANGELOG; the docs a user actually reads still\ndescribed volumes as granted (governance.md) or the post-change state\nas if it had always been so (accepted-limitations.md).",
          "is_bot": false,
          "headline": "docs: note the bootstrap default policy no longer grants volumes",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T13:19:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "382c3c1eb8c638dffb66ef0ff457ab7f979b23f8",
          "body": "Two breaking chart defaults had one-sided or no test coverage:\n\n- WAAS_DEFAULT_NAMESPACE_PATTERN had zero asserts although the webhook\n  requires the operator and api-server values to match; assert the\n  per-user default and the shared-namespace opt-out on both Deployments.\n- default_policy_test.yaml only asserted volumes is absent; pin the\n  exact default allow-list (dropping env or schedule was invisible) and\n  render the documented volumes re-grant once.",
          "is_bot": false,
          "headline": "test(helm): cover placement pattern wiring and default policy grants",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T13:19:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f42ad4fbf961799d17c15e57ebf053d83c3bb84e",
          "body": "fix(api-server): retry lifecycle updates on conflict, surface 409",
          "is_bot": false,
          "headline": "Merge pull request #110 from XoRHub/fix/workspace-update-conflicts",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T13:01:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "436b9e34beebb433eb3fb3e4cd34b6301fdf4888",
          "body": "UpdateOverrides, SetPaused and Reload ran one fetch -> mutate -> Update\ncycle: a concurrent reconcile status-patch made the Update fail 409,\nwhich fell past policyDenial and surfaced as a 500. Wrap the cycle in\nretry.RetryOnConflict with the re-fetch inside the loop, and map a\nconflict that outlives the retries to an RFC 7807 409.",
          "is_bot": false,
          "headline": "fix(api-server): retry lifecycle updates on conflict, surface 409",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T12:53:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "acf15e4cab71187ba634cbfa70d4399235f59df7",
          "body": "fix(api-server): keep role and active out of full-row user writes",
          "is_bot": false,
          "headline": "Merge pull request #109 from XoRHub/fix/login-stale-user-columns",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T12:25:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4e02df51468f5367ba6e198fa14b2ee4736810ea",
          "body": "RecordLogin, SetRole and SetActive each declare ErrUserNotFound, but an\nUPDATE matching no row is not an SQL error: only the RowsAffected check\nstops them returning nil on a user that no longer exists, and nothing\nexercised it. SetTokensValidAfter's leg was already covered — these are\nits three siblings.",
          "is_bot": false,
          "headline": "test(api-server): pin ErrUserNotFound on the targeted user writers",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T12:20:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "949f4765bab46acf05f6f44c7dd2b0110cef2879",
          "body": "A full-row Update carries a copy read before the write; Login spends\n~50-100ms in argon2id in between, so a deactivation or demotion landing\nin that window was silently written back stale — undoing exactly the two\ncolumns per-request revocation reads (the same race c8d9268d9b55 closed\nfor tokens_valid_after only). SetRole and SetActive are now their only\nwriters, Login stamps last_login_at through the targeted RecordLogin,\nand the OIDC login syncs the IdP-driven role through SetRole.",
          "is_bot": false,
          "headline": "fix(api-server): keep role and active out of full-row user writes",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T12:04:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1a72c313ae4fa4f386d14306095ae8b8dab26b5e",
          "body": "Fix/catalog auto sync on creation",
          "is_bot": false,
          "headline": "Merge pull request #108 from XoRHub/fix/catalog-auto-sync",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T08:04:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8c8477f6c28138f8e7ca7e4591b0eb7f495f1e24",
          "body": null,
          "is_bot": false,
          "headline": "Merge branch 'main' into fix/catalog-auto-sync",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T08:00:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "50bf8bb6d205cd49f433e5cff9de12c1f29b3e3e",
          "body": "chore(deps): update dependency react-router to v8.3.0",
          "is_bot": false,
          "headline": "Merge pull request #90 from XoRHub/renovate/react-router-monorepo",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T08:00:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "23d749f57d9ae3eb3e9a9ad4fa2fa9e112fb825b",
          "body": null,
          "is_bot": false,
          "headline": "docs: state that only the ticker retries a failed catalog sync",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T07:42:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "14397971bab0d6047e34f17703afccc641f553ff",
          "body": null,
          "is_bot": false,
          "headline": "fix(api-server): sync the catalog when an image first becomes eligible",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T07:41:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3a3561573bcb503b93b5f6ab175561fe6dbde9b4",
          "body": "…ource\n\nThe worker status-patches the same object as soon as a sync lands, so the\nread-modify-Update raced the fake client's resourceVersion check.",
          "is_bot": false,
          "headline": "test(api-server): retry on conflict when a test re-points a catalog s…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T07:41:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c59a14e3e5b5d4690a7594d42da9e3708f74275f",
          "body": "…ync lock\n\nChecking it outside the mutex let the startup syncAll and the watch's\nADDED burst both pass the gate and fetch the same manifest twice.",
          "is_bot": false,
          "headline": "fix(api-server): evaluate the catalog resync discriminant under the s…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T07:41:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ef0866d93d89652ecc0bc28a4c2a248aa3117b79",
          "body": null,
          "is_bot": false,
          "headline": "docs: describe automatic catalog sync on creation and source change",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T07:41:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b7ac606398c858d7add0b504dc405e5433543a37",
          "body": "…ed image watch\n\nThe one existing WorkspaceImage watch gains an observer that hands\neligible events to a coalescing consumer; the source itself is the\nresync discriminant, so status patches and re-lists are no-ops.\nWorks with the ticker disabled (catalogSyncInterval <= 0).",
          "is_bot": false,
          "headline": "feat(api-server): sync manifest-created catalog sources from the shar…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T07:41:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "726c0ec55276242dfe4267539e78ef4102c29a07",
          "body": "… an image\n\nSynchronous best-effort on the PUT: the response carries the discovered\nentries, a fetch failure never fails the write.",
          "is_bot": false,
          "headline": "feat(api-server): fetch the catalog when an admin creates or repoints…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T07:41:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "10932b0692d46347b053e226a6936f8ed54f4578",
          "body": "…rce-sync trunk",
          "is_bot": false,
          "headline": "refactor(api-server): factor the catalog-sync eligibility gate and fo…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T07:41:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c6dac57a3e6baeecb956183f6e9b3791786fd96e",
          "body": "…-ref\n\nchore(dev): one catalog entry per image ref in the k3d dev catalog",
          "is_bot": false,
          "headline": "Merge pull request #107 from XoRHub/chore/dev-catalog-duplicate-image…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T07:12:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7df0a7d30babe537e381042181068acba366810d",
          "body": "ubuntu-xfce and dev-ssh both approved docker.io/xorhub/ubuntu-desktop-noble\nverbatim. FindImage returns the first exact match, so dev-ssh's narrower\n[ssh, vnc] envelope won by name order and shadowed the rdp approval:\n`make smoke` failed on rdp with a ProtocolMismatch naming an image the\ntemplate never picked. SSH is a capability of that image, not a separate\none, so the dev-ssh template needs no entry of its own.",
          "is_bot": false,
          "headline": "chore(dev): one catalog entry per image ref in the k3d dev catalog",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T07:11:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ba3e02ca732c4b6d2abd6355a58d0978859bda8b",
          "body": "Move the browser session to an httpOnly cookie (audit finding #13)",
          "is_bot": false,
          "headline": "Merge pull request #106 from XoRHub/feat/session-cookie-server",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T07:08:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6a554248046aa0df37f5031321c512732be0a13b",
          "body": "…ntial\n\nThe portal no longer holds a token anywhere a script can reach: the\nzustand persist middleware is gone, api.ts sends credentials:'same-origin'\ninstead of an Authorization header, and the SSO callback stops handing the\ntoken back in the URL fragment. That closes audit finding #13 — an XSS has\n[…]\n update would otherwise tear\ndown and reopen the stream.\n\nBREAKING CHANGE: the SSO callback redirect no longer carries a token in\nits fragment. Anything that scraped it must read GET /auth/me instead.",
          "is_bot": false,
          "headline": "feat(frontend)!: authenticate with the session cookie, store no crede…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T06:39:51Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e13037af3a7211c6f1cd98d120403788dc3d9b0a",
          "body": null,
          "is_bot": false,
          "headline": "docs: describe the session cookie transport and its CSRF guard",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T06:39:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "616cb5ba5290f42179ff2af579c0bfdca0c0fe46",
          "body": "…lback\n\nHttpOnly puts the token out of JavaScript's reach, closing the XSS\nexfiltration path of audit finding #13. Both entry points keep their\ncurrent response shape — the token still goes out in the login body (how\na non-browser client obtains one) and in the OIDC fragment — so the\nfrontend keeps working unchanged until it switches to the cookie.\nLogout expires it on top of revoking it server-side.",
          "is_bot": false,
          "headline": "feat(api-server): hand browsers a session cookie at login and SSO cal…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T06:39:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7d053851a805e9561c73c95fbcbfde782c043203",
          "body": "Second transport for the same waas-api JWT, read after the Authorization\nheader so every non-browser client is untouched. A cookie rides along by\nitself, unlike a header a cross-site page cannot set, so the cookie path\nrequires Sec-Fetch-Site: same-origin — Fetch Metadata rather than a\nsynchronized token, with SameSite=Strict as the backstop. Audience\nisolation and the per-request user re-check apply identically.",
          "is_bot": false,
          "headline": "feat(api-server): accept the access token from a session cookie",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T06:39:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ee64795ad364ba687d33328b9869dd069677f17a",
          "body": "feat(operator)!: default workload placement to a per-user namespace\nfeat(helm)!: default workload placement to a per-user namespace",
          "is_bot": false,
          "headline": "Merge pull request #105 from XoRHub/feat/default-namespace-per-user",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T06:18:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9b5089a099f06bcccbc2615e797fbde651c9d73c",
          "body": null,
          "is_bot": false,
          "headline": "docs(placement): flag retained homes and correct the secretKeyRef claim",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T06:09:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d362ba6e5fa205a026cd8fe932aea0b442c2a87c",
          "body": "The \"waas-<user>-*\" prefix is a name rule, not proof of ownership: with\nthe per-user default it now designates a real user's namespace, quota and\nretained volumes included.",
          "is_bot": false,
          "headline": "fix(operator): refuse a deviation into another user's personal namespace",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T06:09:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "00c179760c2387cc051354bd5db4cfe33ef62f83",
          "body": "A username sanitizing past the token budget resolves to a truncated,\nhash-suffixed namespace that \"waas-\"+Sanitize(user) never matches: the\nowner lost the ownership label, the quota and the placement right on\ntheir own namespace.",
          "is_bot": false,
          "headline": "fix(operator): resolve the personal namespace instead of rebuilding it",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T06:08:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1b6d9148869a1de63b02fa9e5c95b06bd73ebfe4",
          "body": null,
          "is_bot": false,
          "headline": "fix(frontend): cite the per-user default in the placement hint",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T05:55:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5cdc1418fd0e1ba7dd200e613b6f3e43207160dc",
          "body": null,
          "is_bot": false,
          "headline": "docs: document the per-user placement default and the shared opt-in",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T05:55:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "60532d2de871193a064bc374c8b193ab5d6c43e3",
          "body": "BREAKING CHANGE: with workspaces.defaultNamespacePattern unset, new\nworkspaces now land in \"waas-{user}\" instead of the shared\n\"waas-workspaces\". Existing workspaces keep their frozen\nspec.targetNamespace; set defaultNamespacePattern to \"waas-workspaces\"\nto keep the previous shared behavior.",
          "is_bot": false,
          "headline": "feat(helm)!: default workload placement to a per-user namespace",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T05:55:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "097e9cef710ce5f9f24082f026f83fe7a0333bf6",
          "body": "With the per-user default its pods would resolve secretKeyRef in\nnamespaces the seed script never provisions; dev-ssh becomes the\ncanonical explicit shared-namespace opt-in.",
          "is_bot": false,
          "headline": "fix(dev): pin dev-ssh to the shared namespace its seeded Secret lives in",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T05:40:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "49d7166e245f3bdbc2337be6d56b85a487aceb6d",
          "body": null,
          "is_bot": false,
          "headline": "test(api-server): expect the per-user default from the namespace preview",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T05:40:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b58d0a9236c8a7a515fd711e7a56f30f77c5515b",
          "body": "… opt-in\n\nPersonal namespaces (now the nominal case) get ownership label and\npolicy-derived quota; an explicit shared pattern gets neither. Comments\nrealigned: shared is the opt-in, not the default.",
          "is_bot": false,
          "headline": "test(operator): pin the per-user default bootstrap against the shared…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T05:39:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aa76c9ac25e43fb3d3072824ab23aaa0e991154c",
          "body": "The built-in pattern becomes waas-{user}; a shared namespace is now an\nexplicit admin opt-in (literal pattern). Only NEW workspaces are\naffected — spec.targetNamespace is frozen at creation.",
          "is_bot": false,
          "headline": "feat(operator)!: default workload placement to a per-user namespace",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T05:37:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "887a3c35fabee97c8bf76784447f801533658d1d",
          "body": "…verride\n\ndocs(audit): update decision",
          "is_bot": false,
          "headline": "Merge pull request #104 from XoRHub/fix/default-policy-drop-volumes-o…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T04:58:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f007542ee1fd2832edb1dedaf1517b0a39e4a197",
          "body": null,
          "is_bot": false,
          "headline": "docs(audit): close finding 11 with the measurement behind the decision",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T04:55:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "adb7bcb7a4aa0b8626aa3f37637f2cdbc8418850",
          "body": "The comment justified baseline by a first-boot chown supposedly needing\ncapabilities. Measured against the published catalog: all three images\nrun under restricted with allowPrivilegeEscalation=false, drop=[ALL] and\nseccompProfile=RuntimeDefault. The real reasons are that the enforce\nlevel is the cl\n[…]\nd that leaving the container\nsecurityContext empty keeps an add-if-absent cluster mutation policy in\ncharge of filling it. docs/placement.md gains the measurement and the\nprocedure to raise the level.",
          "is_bot": false,
          "headline": "docs(operator): correct why placed namespaces enforce baseline",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T04:54:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a33b3588fc9e0f40cf774e6693fac20ea539fadc",
          "body": "…t leaves\n\nThe host guard closes the naive case but is not a boundary — guacd\nre-resolves at dial time. What would actually contain it, an egress\nNetworkPolicy on the platform pods, does not exist: the policies from\nfindings 5/8/10 cover desktop namespaces only.",
          "is_bot": false,
          "headline": "docs(audit): record finding 7 as mitigated, and the containment gap i…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T04:05:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "48551ff5fd5b85876531d3d3fec6c8f8f535fea3",
          "body": "The report is public and reads as a list of live weaknesses; most are\nclosed. A status table up front keeps the point-in-time record intact\nwhile stating what still stands.",
          "is_bot": false,
          "headline": "docs(audit): head the report with the current remediation status",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T04:03:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1ee6136764fea5e185369cca6a264d57f0876698",
          "body": "Both asked the platform to judge how a delegated pod-spec-shaped field\nmay be used, or which PSA level a namespace must enforce. Neither is the\nplatform's call. Also corrects the audit's own mitigation claim for 9:\nPSA does not backstop the volumes half.",
          "is_bot": false,
          "headline": "docs(audit): record findings 9 and 11 as a cluster-admin arbitration",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T04:03:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3a85015560553a8c98f1622e7d02073954409eb8",
          "body": "fix(api-server): reject in-cluster targets for remote workspaces",
          "is_bot": false,
          "headline": "Merge pull request #103 from XoRHub/fix/remote-workspace-host-guard",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T04:02:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2c2777d86361710ce9d09451fe73a33c08a6b51c",
          "body": null,
          "is_bot": false,
          "headline": "docs: describe the remote-workspace target restriction",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T03:58:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "637a45dabb847af1db2a8ce18938e1fede5c3a46",
          "body": null,
          "is_bot": false,
          "headline": "feat(helm): expose apiServer.clusterDomain and remoteBlockedCIDRs",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T03:58:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "89979f36b28d8e78c0c60156dc8781c7798a4e9f",
          "body": "Guardrail, not a boundary (guacd re-resolves at dial; rebinding bypasses it).\nEnforced at create, update and connect. RFC1918 stays allowed and DNS\nfailures fail open — both deliberate.",
          "is_bot": false,
          "headline": "feat(api-server): reject in-cluster targets for remote workspaces",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T03:58:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "82d60bd68b9babb5d0fbf1bd1bf14117a77f1bb4",
          "body": null,
          "is_bot": false,
          "headline": "feat(api-server): discover the cluster DNS domain from resolv.conf",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T03:58:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "757f0467ef94285467ad3415c2978b851a54c2cd",
          "body": "…verride\n\nfix(helm)!: stop granting the volumes override in the default policy",
          "is_bot": false,
          "headline": "Merge pull request #102 from XoRHub/fix/default-policy-drop-volumes-o…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T03:37:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "454ad22872e79a1aff8785f67c8519589cbfa7e4",
          "body": "The allow-list gates the field, never its content. Spell out the\nprimitive that hands a tenant (any Secret in the workspace namespace, via\nsecret/projected/csi/cephfs alike), why PSA does not backstop it, and\nwhich cluster-side tool to pair with the delegation.",
          "is_bot": false,
          "headline": "docs: state what delegating the pod-spec-shaped override rights grants",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T03:28:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fc614eb2a368f8caaee408db3c086bc31e9a5504",
          "body": "The catch-all baseline policy delegated `volumes` to every authenticated\nuser, so wherever a template also delegated it the tenant could attach an\narbitrary volume source to their own desktop — including a `secret:`\nmounting any Secret co-located in the workspace namespace. Nothing in\nKubernetes sto\n[…]\nhat relied on\nit must grant the right explicitly via defaultPolicy.overrides.allowedFields\nor a higher-priority WorkspacePolicy, and should read the implications in\ndocs/accepted-limitations.md first.",
          "is_bot": false,
          "headline": "fix(helm)!: stop granting the volumes override in the default policy",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T03:27:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2d30c0198feec5dddd99608baafed5a335eeae66",
          "body": null,
          "is_bot": false,
          "headline": "docs: remove old stuff not needed anymore",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T02:43:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "43947097a9f2fbc96c1a8430458359da45db7d58",
          "body": "feat(helm): parameterize the bundled postgres sslmode",
          "is_bot": false,
          "headline": "Merge pull request #101 from XoRHub/fix/postgres-sslmode",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T02:41:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4b0245c419713cae6c5b34e55c0ff010f7513fd5",
          "body": "The chart-built connection URL pinned sslmode=disable. It still defaults\nthere — the bundled StatefulSet serves no TLS — but an operator who wires\ncertificates into that instance can now raise it. External databases are\nunaffected: their URL carries its own sslmode.",
          "is_bot": false,
          "headline": "feat(helm): parameterize the bundled postgres sslmode",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T02:38:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fa3429494412fb72ee206cece4a9b3ac9f77257a",
          "body": "fix(api-server): enforce immediate session revocation",
          "is_bot": false,
          "headline": "Merge pull request #100 from XoRHub/fix/token-revocation",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-25T02:27:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ac7b8bafb7d526d16c0b1f40834709cd377e2b52",
          "body": null,
          "is_bot": false,
          "headline": "docs: note the availability trade of the per-request user check",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-24T22:16:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5e4b9fcd5286adf888ec07773341ec1ac6b00619",
          "body": "logout() now revokes every session of the account server-side, so the\nerror paths that only meant to drop this browser's state — a 401 from\nthe api funnel, a failed profile fetch after SSO — get clearLocal().",
          "is_bot": false,
          "headline": "fix(frontend): clear local auth state instead of revoking on error paths",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-24T22:16:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c8d9268d9b55fd48fb35c2772b467be3e122cb3e",
          "body": "A full-row Update carries a copy read before the write; Login spends\n~50-100ms in argon2id in between, so a concurrent logout's revocation\nwas silently written back stale. SetTokensValidAfter is now the only\nwriter, and the callers revoke after their row update.",
          "is_bot": false,
          "headline": "fix(api-server): keep the token bound out of full-row user writes",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-24T22:16:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d58306af74f084259f18523214f73e83fbffdb4d",
          "body": "Global logout semantics and the open-connection residual (wwt verifies\nthe connection token once at open; open SSE streams are never re-vetted).",
          "is_bot": false,
          "headline": "docs(docs): document the session revocation model",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-24T21:59:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "da3096341a9c9f124cbf378b0842c0a9be08d191",
          "body": "Best-effort POST /auth/logout before clearing local state; raw fetch to\navoid the api.ts import cycle and its 401-handler recursion.",
          "is_bot": false,
          "headline": "feat(frontend): revoke the session server-side on logout",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-24T21:59:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4fe23bbd5678a71d9fb579a5f65e4b19eb3b5473",
          "body": "Auth and StreamAuth now reject 401 when the account is gone, disabled,\nits role diverged from the claims, or the token predates the revocation\nbound — closing audit finding #2 (revocation ineffective for up to 8h).\nRole divergence rejects rather than degrading to the DB role: honoring\nthe token with a substituted role would split one request between two\nsources of truth. DB errors answer 503, never 401 (the frontend logs\nout on 401).",
          "is_bot": false,
          "headline": "fix(api-server): re-check user state on every authenticated request",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-24T21:59:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "25ffb30a6373f07ed5bd978218cf3007c105a10d",
          "body": "…assword change\n\nPOST /auth/logout stamps the caller's token bound (global logout, audited);\nadmin/profile paths stamp it on the same row write as the change itself.\nNever stamped at login: the fresh token would die on the iat comparison.",
          "is_bot": false,
          "headline": "feat(api-server): revoke sessions on logout, deactivation, role and p…",
          "author_name": "DrummyFloyd",
          "author_login": "DrummyFloyd",
          "committed_at": "2026-07-24T21:47:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 4,
      "commits_last_year": 596,
      "latest_release_at": "2026-07-27T10:36:16Z",
      "latest_release_tag": "chart-0.3.0",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 4,
      "days_since_latest_release": 0,
      "mean_days_between_releases": 2.5
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 62,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "github.com/XoRHub/waas",
          "exists": true,
          "license": null,
          "keywords": [],
          "ecosystem": "go",
          "matches_repo": true,
          "registry_url": "https://pkg.go.dev/github.com/XoRHub/waas",
          "is_deprecated": false,
          "latest_version": "v0.3.0",
          "repository_url": "https://github.com/XoRHub/waas",
          "versions_count": 2,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": null,
          "latest_published_at": "2026-07-27T10:08:18Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 0
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 4,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": null,
      "open_issues_and_prs": 7
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": false,
      "bootstrap_files": [
        ".mise.toml",
        "Makefile",
        "operator/Makefile",
        "shared/Makefile"
      ],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "frontend/tsconfig.json"
      ],
      "toolchain_manifests": [
        "api-server/go.mod",
        "operator/go.mod",
        "shared/go.mod",
        "test/smoke/go.mod",
        "wwt/go.mod"
      ],
      "largest_source_bytes": 45356,
      "source_files_sampled": 363,
      "oversized_source_files": 0,
      "agent_instruction_files": [
        "AGENTS.md"
      ],
      "agent_instruction_max_bytes": 3058
    },
    "dependencies": {
      "manifests": [
        "api-server/go.mod",
        "frontend/package.json",
        "operator/go.mod",
        "shared/go.mod",
        "wwt/go.mod"
      ],
      "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": [
        "go",
        "npm"
      ],
      "dependencies": [
        {
          "name": "github.com/coreos/go-oidc/v3",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v3.20.0"
        },
        {
          "name": "github.com/go-chi/chi/v5",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v5.3.1"
        },
        {
          "name": "github.com/go-chi/httprate",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.16.0"
        },
        {
          "name": "github.com/golang-jwt/jwt/v5",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v5.3.1"
        },
        {
          "name": "github.com/golang-migrate/migrate/v4",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v4.19.1"
        },
        {
          "name": "github.com/google/uuid",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.6.0"
        },
        {
          "name": "github.com/jackc/pgx/v5",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v5.10.0"
        },
        {
          "name": "github.com/prometheus/client_golang",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.23.2"
        },
        {
          "name": "github.com/xorhub/waas/operator",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.0.0"
        },
        {
          "name": "github.com/xorhub/waas/shared",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.0.0"
        },
        {
          "name": "golang.org/x/crypto",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.54.0"
        },
        {
          "name": "golang.org/x/oauth2",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.36.0"
        },
        {
          "name": "gopkg.in/yaml.v3",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v3.0.1"
        },
        {
          "name": "k8s.io/api",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.36.2"
        },
        {
          "name": "k8s.io/apimachinery",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.36.2"
        },
        {
          "name": "k8s.io/client-go",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.36.2"
        },
        {
          "name": "modernc.org/sqlite",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.54.0"
        },
        {
          "name": "sigs.k8s.io/controller-runtime",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.24.1"
        },
        {
          "name": "sigs.k8s.io/yaml",
          "manifest": "api-server/go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.6.0"
        },
        {
          "name": "@tanstack/react-query",
          "manifest": "frontend/package.json",
          "ecosystem": "npm",
          "version_constraint": "^5.90.21"
        },
        {
          "name": "guacamole-common-js",
          "manifest": "frontend/package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.5.0"
        },
        {
          "name": "i18next",
          "manifest": "frontend/package.json",
          "ecosystem": "npm",
          "version_constraint": "^26.0.0"
        },
        {
          "name": "i18next-browser-languagedetector",
          "manifest": "frontend/package.json",
          "ecosystem": "npm",
          "version_constraint": "^8.0.0"
        },
        {
          "name": "react",
          "manifest": "frontend/package.json",
          "ecosystem": "npm",
          "version_constraint": "^19.1.0"
        },
        {
          "name": "react-dom",
          "manifest": "frontend/package.json",
          "ecosystem": "npm",
          "version_constraint": "^19.1.0"
        },
        {
          "name": "react-i18next",
          "manifest": "frontend/package.json",
          "ecosystem": "npm",
          "version_constraint": "^17.0.0"
        },
        {
          "name": "react-router",
          "manifest": "frontend/package.json",
          "ecosystem": "npm",
          "version_constraint": "^8.0.0"
        },
        {
          "name": "yaml",
          "manifest": "frontend/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.9.0"
        },
        {
          "name": "zustand",
          "manifest": "frontend/package.json",
          "ecosystem": "npm",
          "version_constraint": "^5.0.3"
        },
        {
          "name": "github.com/prometheus/client_golang",
          "manifest": "operator/go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.23.2"
        },
        {
          "name": "github.com/robfig/cron/v3",
          "manifest": "operator/go.mod",
          "ecosystem": "go",
          "version_constraint": "v3.0.1"
        },
        {
          "name": "golang.org/x/crypto",
          "manifest": "operator/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.54.0"
        },
        {
          "name": "golang.org/x/text",
          "manifest": "operator/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.40.0"
        },
        {
          "name": "k8s.io/api",
          "manifest": "operator/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.36.2"
        },
        {
          "name": "k8s.io/apimachinery",
          "manifest": "operator/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.36.2"
        },
        {
          "name": "k8s.io/client-go",
          "manifest": "operator/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.36.2"
        },
        {
          "name": "k8s.io/utils",
          "manifest": "operator/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.0.0-20260707023825-cf1189d6abe3"
        },
        {
          "name": "sigs.k8s.io/controller-runtime",
          "manifest": "operator/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.24.1"
        },
        {
          "name": "sigs.k8s.io/yaml",
          "manifest": "operator/go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.6.0"
        },
        {
          "name": "github.com/golang-jwt/jwt/v5",
          "manifest": "shared/go.mod",
          "ecosystem": "go",
          "version_constraint": "v5.3.1"
        },
        {
          "name": "github.com/invopop/jsonschema",
          "manifest": "shared/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.14.0"
        },
        {
          "name": "k8s.io/api",
          "manifest": "shared/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.36.2"
        },
        {
          "name": "sigs.k8s.io/yaml",
          "manifest": "shared/go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.6.0"
        },
        {
          "name": "github.com/golang-jwt/jwt/v5",
          "manifest": "wwt/go.mod",
          "ecosystem": "go",
          "version_constraint": "v5.3.1"
        },
        {
          "name": "github.com/gorilla/websocket",
          "manifest": "wwt/go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.5.4-0.20250319132907-e064f32e3674"
        },
        {
          "name": "github.com/prometheus/client_golang",
          "manifest": "wwt/go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.23.2"
        },
        {
          "name": "github.com/xorhub/waas/shared",
          "manifest": "wwt/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.0.0"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 5,
        "merged_prs": 71,
        "open_issues": 2,
        "closed_ratio": 0.5,
        "closed_issues": 2,
        "closed_unmerged_prs": 41
      },
      "bus_factor": 1,
      "bot_contributors": 2,
      "top_contributors": [
        {
          "type": "User",
          "login": "DrummyFloyd",
          "commits": 555,
          "avatar_url": "https://avatars.githubusercontent.com/u/26741817?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci-frontend.yml",
        "ci-go.yml",
        "ci-helm.yml",
        "ci-images.yml",
        "ci-security.yml",
        "ci.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [
        ".golangci.yml",
        "eslint.config.js"
      ],
      "has_editorconfig": false,
      "has_linter_config": true,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "go.sum",
        "package-lock.json"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 3,
            "reason": "branch protection is not maximal on development and all release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "10 out of 10 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/8 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 0,
            "reason": "project has 0 contributing companies or organizations -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 10,
            "reason": "update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 8,
            "reason": "dependency not pinned by hash detected -- score normalized to 8",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 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": 10,
            "reason": "GitHub workflow tokens follow principle of least privilege",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 8,
            "reason": "2 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "2f58c241322e4c716ac66bbd8ef635547588339d",
        "ran_at": "2026-07-27T18:47:02Z",
        "aggregate_score": 6.2,
        "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-27T10:36:49Z",
      "oldest_open_prs": [
        {
          "number": 56,
          "created_at": "2026-07-19T03:06:16Z",
          "last_comment_at": "2026-07-19T03:06:18Z",
          "last_comment_author": "renovate"
        },
        {
          "number": 57,
          "created_at": "2026-07-19T03:06:25Z",
          "last_comment_at": "2026-07-19T03:06:27Z",
          "last_comment_author": "renovate"
        },
        {
          "number": 67,
          "created_at": "2026-07-19T03:07:34Z",
          "last_comment_at": "2026-07-19T03:56:26Z",
          "last_comment_author": "codecov"
        },
        {
          "number": 88,
          "created_at": "2026-07-21T07:40:06Z",
          "last_comment_at": "2026-07-21T07:42:20Z",
          "last_comment_author": "codecov"
        },
        {
          "number": 121,
          "created_at": "2026-07-27T08:48:02Z",
          "last_comment_at": "2026-07-27T08:49:50Z",
          "last_comment_author": "codecov"
        }
      ],
      "last_merged_pr_at": "2026-07-27T10:32:17Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 3,
          "created_at": "2026-07-12T23:32:15Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 117,
          "created_at": "2026-07-25T23:13:18Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/XoRHub/waas",
    "host": "github.com",
    "name": "waas",
    "owner": "XoRHub"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 63,
      "inputs": {
        "security": 62,
        "vitality": 80,
        "community": 37,
        "governance": 44,
        "engineering": 90
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 80,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 67,
            "inputs": {
              "commits_last_year": 596,
              "human_commit_share": 0.94,
              "days_since_last_push": 0,
              "active_weeks_last_year": 4
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "4/52 weeks with commits",
                "points": 2.8,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 4
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "596 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 596
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 4,
              "latest_release_tag": "chart-0.3.0",
              "releases_from_tags": false,
              "days_since_latest_release": 0,
              "mean_days_between_releases": 2.5
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "4 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 4
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~2.5 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 2.5
                    }
                  }
                ],
                "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": "maintained",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": null,
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": 0,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 0 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 37,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 8,
            "inputs": {
              "forks": 0,
              "stars": 4,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "4 stars",
                "points": 7.7,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 4
                    }
                  }
                ],
                "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": "good",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "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": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 44,
        "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": "at_risk",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 48,
            "inputs": {
              "merged_prs": 71,
              "open_issues": 2,
              "closed_issues": 2,
              "issue_closed_ratio": 0.5,
              "closed_unmerged_prs": 41
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "50% of issues closed",
                "points": 23.4,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 50
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "71/112 decided PRs merged",
                "points": 24.2,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 71,
                      "decided": 112
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/8 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": 41,
            "inputs": {
              "followers": 1,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "XoRHub",
              "public_repos": 5,
              "account_age_days": 601
            },
            "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": "1 followers of XoRHub",
                "points": 2.2,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 1,
                      "login": "XoRHub"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "5 public repos, account ~1 yr old",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 5
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 1
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 92,
            "inputs": {
              "packages": [
                "github.com/XoRHub/waas"
              ],
              "ecosystems": "go",
              "any_deprecated": false,
              "min_days_since_publish": 0
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on go",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "go"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 0 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "2 published versions",
                "points": 12,
                "status": "partial",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "excellent",
        "name": "Engineering Quality",
        "value": 90,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "good",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 84,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": true,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "6 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 6
                    }
                  }
                ],
                "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": ".golangci.yml, eslint.config.js",
                "points": 16,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".golangci.yml, eslint.config.js"
                    }
                  }
                ],
                "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": "10 out of 10 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "excellent",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "topics": [
                "gitops",
                "guacd",
                "kubernetes",
                "operator",
                "waas",
                "workspace"
              ],
              "has_wiki": true,
              "homepage": "https://xorhub.github.io/website",
              "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": "https://xorhub.github.io/website",
                "points": 15,
                "status": "met",
                "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": "6 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 6
                    }
                  }
                ],
                "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": "moderate",
        "name": "Security",
        "value": 62,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "moderate",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Packaging, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "packaging",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 62,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 6.2
            },
            "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 is not maximal on development and all release branches",
                "points": 2.2,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "10 out of 10 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/8 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "update tool detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 8",
                "points": 4,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file 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": "GitHub workflow tokens follow principle of least privilege",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "2 existing vulnerabilities detected",
                "points": 6,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              }
            ]
          }
        ],
        "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": 82,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.989,
              "agent_instruction_files": [
                "AGENTS.md"
              ],
              "agent_instruction_max_bytes": 3058
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "AGENTS.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "AGENTS.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": "93 of 94 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 93,
                      "sampled": 94
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "excellent",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 88,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "go.sum",
                "package-lock.json"
              ],
              "has_dockerfile": true,
              "typed_language": true,
              "bootstrap_files": [
                ".mise.toml",
                "Makefile",
                "operator/Makefile",
                "shared/Makefile"
              ],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [
                "frontend/tsconfig.json"
              ],
              "agent_commit_share": 0,
              "toolchain_manifests": [
                "api-server/go.mod",
                "operator/go.mod",
                "shared/go.mod",
                "test/smoke/go.mod",
                "wwt/go.mod"
              ],
              "dependency_bot_commit_share": 0.04
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": ".mise.toml, Makefile, operator/Makefile, shared/Makefile",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".mise.toml, Makefile, operator/Makefile, shared/Makefile"
                    }
                  }
                ],
                "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": ".golangci.yml, eslint.config.js",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".golangci.yml, eslint.config.js"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "frontend/tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "frontend/tsconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "Dockerfile, lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Dockerfile, lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "no agent-authored commits among the last 100",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_authored_commits",
                    "params": {
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "4 of the last 100 commits are automated dependency updates",
                "points": 8,
                "status": "met",
                "details": [
                  {
                    "code": "dependency_bot_commits",
                    "params": {
                      "count": 4,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 8",
                "points": 8,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "primary_language": "Go",
              "largest_source_bytes": 45356,
              "source_files_sampled": 363,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Go (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Go"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/363 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 363,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "at_risk",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "example_dirs": [
                "examples"
              ],
              "has_mcp_signal": false,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": "examples",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "examples"
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "Could not fetch go package 'github.com/xorhub/waas/wwt' from its registry",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-27T18:47:18.135361Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/x/XoRHub/waas.svg",
  "full_name": "XoRHub/waas",
  "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 agregadasGo.