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

groscy / data-loom

Local dashboard for spec-driven development: a phased OpenSpec roadmap (WHAT) and an MCP topology (HOW).

TypeScript · JavaScript · CSSMIT★ 0 estrellas⑂ 0 forksdesde jun 2026Ver en GitHub ↗

groscy/data-loom tiene un índice de salud de 56 sobre 100, lo que lo sitúa en la banda Moderado. Su puntuación más alta es Engineering Quality (76/100) y la más baja, Sustainability & Governance (33/100). Se actualizó por última vez hace 2 días. Una sola persona concentra la mayor parte del trabajo reciente.

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

56
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

Cyril GrossenbacherCuenta personal
2 seguidores15 repositorios públicosdesde oct 2021

Este repositorio pertenece a una cuenta personal. Un proyecto con un único propietario conlleva más riesgo de continuidad que uno respaldado por una organización.

Ecosistemas de paquetes

RegistroPaqueteVersiónDescargas / mesVersionesÚltima publicaciónEtiquetas
npm@lyric_dev/data-loom0.13.0304717hace 6 díasopenspecmcpdashboardroadmapspec-driven-developmentclaude-code

Métricas por categoría

Vitalidad

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

69Moderado · 22% del índice global
Cómo se puntúa
36/36Recencia de push — último push hace 2 días
3.5/36Cadencia de commits — 5/52 semanas con commits
17.1/18Volumen de commits — 80 commits en el último año
0/10OpenSSF Scorecard: Maintained — project was created within the last 90 days. Please review its contents carefully
Datos de entrada utilizados
commits_last_year80
human_commit_share1
days_since_last_push2
active_weeks_last_year5
Cómo se puntúa
16.2/27Publica versiones — 24 etiquetas de versión (sin releases de GitHub)
36/36Recencia de las versiones — última versión hace 6 días
27/27Cadencia de publicación — una versión cada ~1,6 días
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count24
latest_release_tagv0.13.0
releases_from_tags
days_since_latest_release6
mean_days_between_releases1,6
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?

42En riesgo · 18% del índice global
Cómo se puntúa
0/60Estrellas — 0 estrellas
0/25Forks — 0 forks
0/15Observadores — 0 observadores
Datos de entrada utilizados
forks0
stars0
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Cómo se puntúa
22.5/22.5README
22.5/22.5Licencia — licencia reconocida (MIT)
18/18Guía CONTRIBUTING
0/13.5Código de conducta
0/7.2Plantilla de issues
6.3/6.3Plantilla de PR
Datos de entrada utilizados
has_readme
has_license
has_contributing
has_issue_templateno
has_code_of_conductno
has_pull_request_template
Cómo se puntúa
46.5/80Descargas mensuales — 3047 descargas/mes en npm
0/20Dependientes en el registro — no lo informa este ecosistema
Datos de entrada utilizados
packages@lyric_dev/data-loom
dependents
ecosystemsnpm
total_downloads
monthly_downloads3047
Excluidos de la puntuación (sin datos o no aplicable): Dependientes en el registro. Los pesos restantes se han renormalizado.

Sostenibilidad y Gobernanza

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

33En 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
0/46.8Resolución de issues — sin issues o sin datos
0/38.3Aceptación de PR — 0/2 PR decididos fusionados
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs0
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs2
Excluidos de la puntuación (sin datos o no aplicable): Resolución de issues. Los pesos restantes se han renormalizado.
Cómo se puntúa
10/30Respaldo de la propiedad — cuenta personal (usuario)
0/20Dominio verificado — no aplicable a cuentas de usuario
3.4/25Alcance del propietario — 2 seguidores de groscy
18.4/25Trayectoria — 15 repos públicos, cuenta de ~4 años
Datos de entrada utilizados
followers2
owner_typeUser
is_verified
owner_logingroscy
public_repos15
account_age_days1751
Excluidos de la puntuación (sin datos o no aplicable): Dominio verificado. Los pesos restantes se han renormalizado.
Cómo se puntúa
25/25Publicado y resoluble — 1 paquete(s) en npm
35/35Recencia de publicación — última publicación hace 6 días
20/20Historial de versiones — 17 versiones en el registro
20/20No obsoleto — activo, ni obsoleto ni retirado
Datos de entrada utilizados
packages@lyric_dev/data-loom
ecosystemsnpm
any_deprecatedno
min_days_since_publish6

Calidad de Ingeniería

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

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

Documentación

100Excelente
Cómo se puntúa
30/30README
25/25Directorio de documentación
15/15Sitio de documentación / página del proyecto — https://github.com/groscy/data-loom#readme
10/10Descripción del repositorio
10/10Topics — 6 topics
10/10Wiki
Datos de entrada utilizados
topicsclaude-code, dashboard, mcp, openspec, roadmap, spec-driven-development
has_wiki
homepagehttps://github.com/groscy/data-loom#readme
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?

61Moderado · 16% del índice global
Cómo se puntúa
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — sin datos
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
10/10Dangerous-Workflow — no dangerous workflow patterns detected
7.5/7.5Dependency-Update-Tool — update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Licencia — license file detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
5/5Packaging — packaging workflow detected
1.5/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 3
0/5SAST — no SAST tool detected
5/5Security-Policy — security policy file detected
0/7.5Signed-Releases — sin datos
7.5/7.5Token-Permissions — GitHub workflow tokens follow principle of least privilege
5.2/7.5Vulnerabilities — 3 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate5,4
Excluidos de la puntuación (sin datos o no aplicable): ci_tests, signed_releases. Los pesos restantes se han renormalizado.
Cómo se puntúa
35/35Dependencias directas libres de avisos conocidos — ninguna dependencia directa tiene un aviso conocido
13.2/25Dependencias indirectas libres de avisos conocidos — 1 afectados: @hono/node-server 1.19.15 (moderate 5.9)
40/40Sin avisos pendientes — ningún aviso lleva público más de 90 días
Datos de entrada utilizados
sourceosv
advisories1
affected_packages1
assessed_packages96
unassessed_packages0
affected_by_severitymoderate 1
direct_affected_packages0
Se cotejó el cierre de dependencias en tiempo de ejecución de npm:@lyric_dev/data-loom@0.13.0 —lo que arrastra la instalación del paquete publicado—: 96 paquetes. No se analiza la alcanzabilidad.

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.

54Moderado · 0% del índice global
Cómo se puntúa
0/45Instrucciones para agentes — sin CLAUDE.md / AGENTS.md / reglas de editor
0/15Documentación legible por máquinas (llms.txt)
40/40Historial de commits legible — 67 de 80 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share0,838
agent_instruction_files
agent_instruction_max_bytes
Cómo se puntúa
0/18Arranque con un solo comando
22/22Pruebas automatizadas
0/11Configuración de lint / formato
11/11Verificación estática de tipos — tsconfig.json
10/10Entorno reproducible — lockfile
10/10Práctica demostrada con agentes — 76 de los últimos 80 commits con autoría o crédito de agente
5/8Mantenimiento automatizado — automatización de dependencias configurada, no observada en los commits muestreados
3/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 3
Datos de entrada utilizados
has_nixno
has_tests
lockfilespackage-lock.json
has_dockerfileno
typed_language
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configstsconfig.json
agent_commit_share0,95
toolchain_manifests
dependency_bot_commit_share0
Cómo se puntúa
45/45Código verificable por tipos — TypeScript (tipado estático)
52.7/55Tamaños de archivo manejables — 1/24 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languageTypeScript
largest_source_bytes83.024
source_files_sampled24
oversized_source_files1
Cómo se puntúa
0/40Esquema de API (OpenAPI/GraphQL/proto)
20/20Servidor MCP
0/40Ejemplos ejecutables
Datos de entrada utilizados
example_dirs
has_mcp_signal
api_schema_files

Datos clave

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

Más detalle

OpenSSF Scorecard 5.4 / 10
5.4agregado

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 17:31 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
n/dCI-Testsno pull request found
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
10Dangerous-Workflowno dangerous workflow patterns detected
10Dependency-Update-Toolupdate tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
10Packagingpackaging workflow detected
3Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 3
0SASTno SAST tool detected
10Security-Policysecurity policy file detected
n/dSigned-Releasesno releases found
10Token-PermissionsGitHub workflow tokens follow principle of least privilege
7Vulnerabilities3 existing vulnerabilities detected
Dependencias directas 2
RegistroPaqueteRestricción de versiónManifiesto
npm@modelcontextprotocol/sdk^1.29.0package.json
npmws^8.18.0package.json
Todas las dependencias 117

Conjunto completo de dependencias resueltas según el grafo de dependencias de GitHub: 2 paquetes directos y 115 indirectos (transitivos). El cierre transitivo es completo cuando el repositorio incluye un lockfile.

RegistroPaqueteVersiónRelación
npm@modelcontextprotocol/sdk1.29.0directa
npmws8.21.0directa
npm@hono/node-server1.19.14indirecta
npm@types/node26.1.1indirecta
npm@types/ws8.18.1indirecta
npm@typescript/typescript-aix-ppc647.0.2indirecta
npm@typescript/typescript-darwin-arm647.0.2indirecta
npm@typescript/typescript-darwin-x647.0.2indirecta
npm@typescript/typescript-freebsd-arm647.0.2indirecta
npm@typescript/typescript-freebsd-x647.0.2indirecta
npm@typescript/typescript-linux-arm7.0.2indirecta
npm@typescript/typescript-linux-arm647.0.2indirecta
npm@typescript/typescript-linux-loong647.0.2indirecta
npm@typescript/typescript-linux-mips64el7.0.2indirecta
npm@typescript/typescript-linux-ppc647.0.2indirecta
npm@typescript/typescript-linux-riscv647.0.2indirecta
npm@typescript/typescript-linux-s390x7.0.2indirecta
npm@typescript/typescript-linux-x647.0.2indirecta
npm@typescript/typescript-netbsd-arm647.0.2indirecta
npm@typescript/typescript-netbsd-x647.0.2indirecta
npm@typescript/typescript-openbsd-arm647.0.2indirecta
npm@typescript/typescript-openbsd-x647.0.2indirecta
npm@typescript/typescript-sunos-x647.0.2indirecta
npm@typescript/typescript-win32-arm647.0.2indirecta
npm@typescript/typescript-win32-x647.0.2indirecta
npmaccepts2.0.0indirecta
npmajv8.20.0indirecta
npmajv-formats3.0.1indirecta
npmbody-parser2.3.0indirecta
npmbytes3.1.2indirecta
npmcall-bind-apply-helpers1.0.2indirecta
npmcall-bound1.0.4indirecta
npmcontent-disposition1.1.0indirecta
npmcontent-type1.0.5indirecta
npmcontent-type2.0.0indirecta
npmcookie0.7.2indirecta
npmcookie-signature1.2.2indirecta
npmcors2.8.6indirecta
npmcross-spawn7.0.6indirecta
npmdebug4.4.3indirecta
npmdepd2.0.0indirecta
npmdunder-proto1.0.1indirecta
npmee-first1.1.1indirecta
npmencodeurl2.0.0indirecta
npmes-define-property1.0.1indirecta
npmes-errors1.3.0indirecta
npmes-object-atoms1.1.2indirecta
npmescape-html1.0.3indirecta
npmetag1.8.1indirecta
npmeventsource3.0.7indirecta
npmeventsource-parser3.1.0indirecta
npmexpress5.2.1indirecta
npmexpress-rate-limit8.5.2indirecta
npmfast-deep-equal3.1.3indirecta
npmfast-uri3.1.2indirecta
npmfinalhandler2.1.1indirecta
npmforwarded0.2.0indirecta
npmfresh2.0.0indirecta
npmfunction-bind1.1.2indirecta
npmget-intrinsic1.3.0indirecta
npmget-proto1.0.1indirecta
npmgopd1.2.0indirecta
npmhas-symbols1.1.0indirecta
npmhasown2.0.4indirecta
npmhono4.12.27indirecta
npmhttp-errors2.0.1indirecta
npmiconv-lite0.7.2indirecta
npminherits2.0.4indirecta
npmip-address10.2.0indirecta
npmipaddr.js1.9.1indirecta
npmis-promise4.0.0indirecta
npmisexe2.0.0indirecta
npmjose6.2.3indirecta
npmjson-schema-traverse1.0.0indirecta
npmjson-schema-typed8.0.2indirecta
npmmath-intrinsics1.1.0indirecta
npmmedia-typer1.1.0indirecta
npmmerge-descriptors2.0.0indirecta
npmmime-db1.54.0indirecta
npmmime-types3.0.2indirecta
npmms2.1.3indirecta
npmnegotiator1.0.0indirecta
npmobject-assign4.1.1indirecta
npmobject-inspect1.13.4indirecta
npmon-finished2.4.1indirecta
npmonce1.4.0indirecta
npmparseurl1.3.3indirecta
npmpath-key3.1.1indirecta
npmpath-to-regexp8.4.2indirecta
npmpkce-challenge5.0.1indirecta
npmproxy-addr2.0.7indirecta
npmqs6.15.3indirecta
npmrange-parser1.3.0indirecta
npmraw-body3.0.2indirecta
npmrequire-from-string2.0.2indirecta
npmrouter2.2.0indirecta
npmsafer-buffer2.1.2indirecta
npmsend1.2.1indirecta
npmserve-static2.2.1indirecta
npmsetprototypeof1.2.0indirecta
npmshebang-command2.0.0indirecta
npmshebang-regex3.0.0indirecta
npmside-channel1.1.1indirecta
npmside-channel-list1.0.1indirecta
npmside-channel-map1.0.1indirecta
npmside-channel-weakmap1.0.2indirecta
npmstatuses2.0.2indirecta
npmtoidentifier1.0.1indirecta
npmtype-is2.1.0indirecta
npmtypescript7.0.2indirecta
npmundici-types8.3.0indirecta
npmunpipe1.0.0indirecta
npmvary1.1.2indirecta
npmwhich2.0.2indirecta
npmwrappy1.0.2indirecta
npmzod4.4.3indirecta
npmzod-to-json-schema3.25.2indirecta
Avisos de dependencias 1

Instalar npm:@lyric_dev/data-loom@0.13.0 arrastra 96 paquetes, directos y transitivos: 1 tienen avisos conocidos, de los cuales 0 son dependencias directas.

PaqueteVersiónRelaciónGravedadAvisosCorregido en
@hono/node-server1.19.15indirectamoderada12.0.5

Un aviso significa que la versión registrada en el grafo de dependencias cae dentro del rango afectado de un aviso. No se analiza la alcanzabilidad, y el grafo incluye fijaciones de desarrollo y prueba: un hallazgo puede referirse al utillaje y no al software distribuido.

Informe JSON sin procesar legible por máquina
{
  "data": {
    "repo": {
      "topics": [
        "claude-code",
        "dashboard",
        "mcp",
        "openspec",
        "roadmap",
        "spec-driven-development"
      ],
      "is_fork": false,
      "size_kb": 698,
      "has_wiki": true,
      "homepage": "https://github.com/groscy/data-loom#readme",
      "languages": {
        "CSS": 35094,
        "HTML": 6671,
        "JavaScript": 104682,
        "TypeScript": 133790
      },
      "pushed_at": "2026-07-25T11:47:42Z",
      "created_at": "2026-06-27T08:35:10Z",
      "owner_type": "User",
      "updated_at": "2026-07-20T23:11:08Z",
      "description": "Local dashboard for spec-driven development: a phased OpenSpec roadmap (WHAT) and an MCP topology (HOW).",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "master",
      "license_spdx_raw": "MIT",
      "primary_language": "TypeScript",
      "significant_languages": [
        "TypeScript",
        "JavaScript",
        "CSS"
      ]
    },
    "owner": {
      "blog": null,
      "name": "Cyril Grossenbacher",
      "type": "User",
      "login": "groscy",
      "company": null,
      "location": null,
      "followers": 2,
      "avatar_url": "https://avatars.githubusercontent.com/u/92256856?v=4",
      "created_at": "2021-10-10T12:27:20Z",
      "is_verified": null,
      "public_repos": 15,
      "account_age_days": 1751
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.13.0",
          "kind": "minor",
          "published_at": "2026-07-20T23:10:53Z"
        },
        {
          "tag": "v0.12.1",
          "kind": "patch",
          "published_at": "2026-07-20T20:38:52Z"
        },
        {
          "tag": "v0.12.0",
          "kind": "minor",
          "published_at": "2026-07-20T17:07:09Z"
        },
        {
          "tag": "v0.11.0",
          "kind": "minor",
          "published_at": "2026-07-20T16:02:22Z"
        },
        {
          "tag": "v0.10.1",
          "kind": "patch",
          "published_at": "2026-07-18T21:26:18Z"
        },
        {
          "tag": "v0.10.0",
          "kind": "minor",
          "published_at": "2026-07-18T20:23:35Z"
        },
        {
          "tag": "v0.9.1",
          "kind": "patch",
          "published_at": "2026-07-17T21:46:42Z"
        },
        {
          "tag": "v0.9.0",
          "kind": "minor",
          "published_at": "2026-07-11T10:38:56Z"
        },
        {
          "tag": "v0.8.1",
          "kind": "patch",
          "published_at": "2026-07-08T01:20:06Z"
        },
        {
          "tag": "v0.8.0",
          "kind": "minor",
          "published_at": "2026-07-06T17:58:28Z"
        },
        {
          "tag": "v0.7.0",
          "kind": "minor",
          "published_at": "2026-07-04T13:21:03Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2026-07-03T21:28:01Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2026-07-01T10:35:22Z"
        },
        {
          "tag": "v0.4.1",
          "kind": "patch",
          "published_at": "2026-06-29T21:31:52Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-06-29T21:04:22Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-06-29T18:51:09Z"
        },
        {
          "tag": "v0.2.4",
          "kind": "patch",
          "published_at": "2026-06-29T16:39:29Z"
        },
        {
          "tag": "v0.2.3",
          "kind": "patch",
          "published_at": "2026-06-29T05:49:26Z"
        },
        {
          "tag": "v0.2.2",
          "kind": "patch",
          "published_at": "2026-06-28T19:45:12Z"
        },
        {
          "tag": "v0.2.1",
          "kind": "patch",
          "published_at": "2026-06-28T19:25:04Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-06-28T17:56:56Z"
        },
        {
          "tag": "v0.1.2",
          "kind": "patch",
          "published_at": "2026-06-27T12:58:20Z"
        },
        {
          "tag": "v0.1.1",
          "kind": "patch",
          "published_at": "2026-06-27T11:31:18Z"
        },
        {
          "tag": "v0.1.0",
          "kind": "minor",
          "published_at": "2026-06-27T11:11:51Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "a866d48a5db3424652915ff6aa57946a276fb78e",
          "body": "…nto the documentation\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release v0.13.0 — the atlas opens on a navigable C4 map that drills i…",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-20T23:10:53Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6ce1050005ad193fd5a1f2e884db96d8abf08471",
          "body": "The atlas map ships, so its change moves into the archive and its deltas land in\nspecs/: atlas-derivation gains the co-change relations requirement, atlas-view\nhas its subpage and building-block requirements rewritten, and atlas-map arrives\nas a capability in its own right.\n\nThe loop closes on itself — the archived change now appears in the map it added,\nand the two new edges it creates are labelled from the change that introduced\nthem.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: archive add-atlas-c4-map and sync the settled specs",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-20T22:52:59Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "7d24be3722b022337ccbf47930bffb70a34fd551",
          "body": "…mentation\n\nThe atlas was the only view without a picture: 21 capabilities as one 9900px\nscrolling document that only got longer as the archive grew. It now opens on a\nC4-style board on the same canvas controller as the roadmap and topology —\nsystem, then domain, then capability — handing off to the\n[…]\ne window resizing and visual\nappearance remain unverified — the in-app browser pane delivers no\nResizeObserver callbacks and cannot screenshot.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: the atlas opens on a navigable C4 map that drills into the docu…",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-20T22:31:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "20e56489c1062e0c982102a65261b9be2d4a9032",
          "body": "Both task lists ended with live window resizing unverified, because this\npreview environment never delivers ResizeObserver callbacks -- a freshly\nattached probe observer fired 0 times across a real viewport height change.\nConfirmed in a real browser after v0.12.1: resizing drives the minimap\ncrossover correctly on both the roadmap and the MCP topology. The observer\npath was correct as written.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: close the outstanding resize verification in both canvas archives",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-20T21:01:10Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6a0efe0f6658e83551d9c333f5a8978f32653b3b",
          "body": "…ridor\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release v0.12.1 — MCP topology traces stay inside the hub-to-card cor…",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-20T20:38:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "aa32289c4474329a950aaca14f1069e6e75c937d",
          "body": "Each connection turns at its own vertical channel, placed at 452 - i*22 on the\nleft bank and mirrored on the right. The corridor those channels must occupy is\nonly 178px wide (card edge 346 to chip edge 524), and nothing bounded the walk:\nfrom bank index 5 the final leg doubled back, from 14 the ver\n[…]\n share an ordering, so no trace's horizontal leg can fall inside\nanother's vertical span. Reordering would move traces without fixing anything.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: keep MCP topology traces inside the hub-to-card corridor",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-20T20:38:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6056d54c395a410f0d1815dc2016ea0755944a16",
          "body": "…ooms like the roadmap\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release v0.12.0 — MCP topology grows with the server count and pans/z…",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-20T17:07:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f5a1970fcd2135f2b930df50f80c353cd42a1e1b",
          "body": "…e roadmap\n\nThe topology board had the opposite problem to the roadmap: the canvas was\nfrozen at 1200x640 and servers were *compressed* into a constant 496px band,\nso from 19 servers the ~56px cards overlapped silently and from 42 the trace\nchannels left the viewBox. Nothing capped, wrapped or scrol\n[…]\ndecide without a\nmeasurable viewport, and the tab-switch handler revalidates the revealed view\nrather than relying on the ResizeObserver alone.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: MCP topology grows with the server count and pans/zooms like th…",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-20T17:07:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e7b8412a792a0fd3c79e2f4a27022058925439a9",
          "body": "… retired to the Atlas\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release v0.11.0 — roadmap pan/zoom canvas with minimap; archived band…",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-20T16:02:22Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5e660dab2e34949d5a839742b1ddad56ee6d24ed",
          "body": "The archived \"done\" band predated the System Atlas, which now tells the\narchive's story properly: every archived change appears under Decisions &\nrationale with its date and recorded design, and each settled capability\nlinks back to the change that shaped it. The band was a bare list of names\ntaking\n[…]\nx card height. Real cards run 128-187px, so connectors met taller cards\nup to ~35px off centre. They now anchor to each card's measured centre.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: roadmap pan/zoom canvas with minimap; drop the archived done band",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-20T16:02:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "282a53265776cf41738e3dff5bb778257baef252",
          "body": null,
          "is_bot": false,
          "headline": "Release v0.10.1 — simplified README",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-18T21:26:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b104852f7ffe149c81123d2a0aa5054eebf86a13",
          "body": "Trim the README to a concise description plus Install and Use sections;\nmove the autostart internals, MCP-registration walkthrough, security\nmodel, and design principles out to their dedicated docs. Bring it up to\ndate with the Atlas view.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: simplify README to install + use",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-18T21:26:15Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c2cdceaf18983fb325b88fb4d272f313f43c70da",
          "body": "…e-last-visit overlay",
          "is_bot": false,
          "headline": "Release v0.10.0 — System Atlas: derived architecture docs with a sinc…",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-18T20:23:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "47657b7e90816e60d2e054f82ec23bd712175d40",
          "body": "Layer a personalized \"what changed since your last visit\" overlay onto\nthe System Atlas. It reads the per-requirement provenance the atlas\nalready serves and compares it to a client-side cursor — no daemon\nchanges.\n\n- mark building blocks, their groups, and individual requirements whose\n  provenance\n[…]\norage (never written to\n  the workspace); the first visit seeds a clean baseline.\n\nImplements the add-atlas-recency OpenSpec change (archived).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: atlas since-last-visit recency overlay",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-18T18:47:12Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2ed082782654483e90e7ff9fae2ee061e7bd79c6",
          "body": "Add a System Atlas subpage that presents the settled system as living,\nArc42-flavored documentation, derived from the OpenSpec workspace and\nserved read-only over loopback like the roadmap.\n\n- daemon: assemble an AtlasModel (overview from config.yaml context,\n  building blocks from specs/ with requi\n[…]\nnce with deep-links, and a per-capability\n  \"shaping decisions & history\" section.\n\nImplements the add-system-atlas OpenSpec change (archived).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: System Atlas — derived Arc42-flavored architecture docs",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-18T18:45:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c0a4d5f70454413ab11b05b88ef072ef54503a5a",
          "body": "Integrates the two open Dependabot dev-dependency PRs. Both are\nbuild-time only — no change to the published runtime. Verified: the\nproject builds cleanly under TypeScript 7.0.2 and the emitted CLI runs.\n\nCloses #1\nCloses #2\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(deps-dev): bump @types/node to 26 and typescript to 7",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-17T22:02:11Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ec5d4a0dbde88838d6515229ae1fbd0a3e6262c8",
          "body": null,
          "is_bot": false,
          "headline": "Release v0.9.1 — hide flashing CLI console windows on Windows",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-17T21:46:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3433a8278c04aa6af4bfdb29087a63178e4d87e0",
          "body": "The daemon runs headless (detached / autostart, with no console of its\nown), so spawning the `openspec` and `claude` CLIs through a Windows shell\n— and spawning `clip` for the tray's copy-URL — made Windows allocate a\nfresh console window that flashed to the foreground and stole focus. It was\nmost v\n[…]\nuts across\ngenuine context switches produced zero visible console windows, with\npositive-control windows confirming the check could detect one.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: stop CLI console windows flashing on Windows",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-17T21:43:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ec2f52c84b8a91003150b6a1fb96b6ede08fb36b",
          "body": "Add the standard GitHub repository files: CONTRIBUTING and SECURITY\nguides, issue templates (bug/feature + config), a pull request\ntemplate, a build/typecheck CI workflow across Node 20 and 22, and a\nDependabot config for the npm and github-actions ecosystems.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: add community health files, CI, and dependabot",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-13T21:27:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "bbf643fbb931b2b1f6571f915a71e449edaa969e",
          "body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release v0.9.0 — proposal task list in the change detail panel",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-11T10:38:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5177a365e47760667c7b1ca7e840f20ef53d3d5f",
          "body": "Move the completed show-proposal-tasks change into the dated archive and\nfold its deltas into the settled specs: the new \"Per-change task list\nattached to the model\" requirement into roadmap-derivation, and the\nexpanded \"Node detail inspection\" requirement into roadmap-view.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: archive show-proposal-tasks and sync its specs",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-11T10:38:38Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "fbcfc91286e2bfbf31e4d31b0156035dc861253c",
          "body": "Read each non-archived change's tasks.md directly (the CLI exposes only\ncounts, not task text) and attach a structured, section-grouped task list\nto its node, riding the existing model broadcast. The detail panel renders\nthe full list below the kept progress bar: done items get a check and\nstrikethr\n[…]\nd progress bar live-update on a tasks.md edit without re-selecting the\nnode, skipping the slide-in animation when the panel is already visible.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: show the proposal task list in the change detail panel",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-11T10:38:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "13bb7d08f0a800a1829d788b9e55aa30a6ecbe25",
          "body": "Document the daemon's three tiers, its four subsystems, the live\nwrite-back loop, and a module map, with an architecture diagram. Link it\nfrom the README.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: add ARCHITECTURE.md with module map and diagram",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-11T10:37:47Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a2d8ee02e16b2effbb7906391beb89915882f76e",
          "body": "Move the completed add-dashboard-command-handoff change into the dated\narchive and fold its command-handoff requirements into the roadmap-view\nspec. Housekeeping left over from the v0.8.0 release.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: archive add-dashboard-command-handoff and sync its spec",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-11T10:37:39Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "52125fadd79f7af3c91a547e0313ce3784e2a662",
          "body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release v0.8.1 — horizontally scrollable roadmap for deep plans",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-08T01:20:06Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "92b6b5efa9ee85a89f4f3f4ca3b301ee4cf8a20c",
          "body": "Applies the roadmap-view delta to the canonical spec: adds \"Phase columns\nkeep a fixed footprint at any depth\" and \"Horizontal scrolling for wide\nroadmaps\", and removes the stale \"Vertically stacked phase bands\"\nrequirement (the shipped layout is horizontal columns, not vertical bands).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: archive horizontal-scroll-roadmap and sync its spec",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-08T01:19:48Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d10e3dcf98792315e6c9706183ced1564bf1d82d",
          "body": "The roadmap laid phases left-to-right across a fixed-width design canvas,\ndividing that width evenly among however many phases existed. Past ~3-4\nphases the per-phase spacing shrank below a card's width, so phase frames\nand change cards overlapped and clipped -- a 9-phase plan was unreadable.\n\nGive \n[…]\ntacking are\nunchanged (they already worked in canvas units). Client-side only -- the\ndaemon, phase derivation, and roadmap model are untouched.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: make the roadmap horizontally scrollable for deep plans",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-08T01:19:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e986e3b21540bfd733669f612a25307ed2011c78",
          "body": "…the dashboard\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release v0.8.0 — copy weave/apply/archive commands to clipboard from …",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-06T17:58:28Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c21084e1177bed739e79ecce07ea4352793bf545",
          "body": "Surface the three agent-driven workflows as contextual, clipboard-copy\nactions on the roadmap view, each shown only where DataLoom already proves\nthe precondition:\n\n- Weave on the dependency-review banner -> /loom:weave\n- Apply on a change's card and detail panel -> /opsx:apply <name>\n- Archive on a\n[…]\nds -- it\nnever executes the workflows, and the daemon/MCP server are unchanged.\n\nCaptured under openspec/changes/add-dashboard-command-handoff.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: copy weave/apply/archive commands to clipboard from the dashboard",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-06T16:59:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "39ace3621e4dee2ab916562d7c6a05a184c0a7c9",
          "body": "…t, and one-command setup\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release v0.7.0 — on-demand shim, supervised always-on, weave-as-promp…",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-04T13:21:03Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "bda3fdfc71a6a9a6ba91681a2d3a6cb5d89578fd",
          "body": "Move one-command-setup (the `data-loom up` verb, implemented in 7613a7a)\ninto openspec/changes/archive/2026-07-04-one-command-setup, and sync its\nnew guided-setup capability into openspec/specs. All 19 specs validate; no\nopen changes remain.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: archive one-command-setup and sync its spec",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-04T13:18:34Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "7613a7a1e28e3fef6456d8afd49cc23d90d324d5",
          "body": "`data-loom up [project]` takes a fresh machine to a fully working always-on\nDataLoom in one paste: it verifies the openspec prerequisite up front (and\nexits non-zero with the install command, changing nothing, when it's\nmissing), then runs the same enable sequence as `autostart enable` (register\naut\n[…]\ned: composed flow + idempotent double-run (no duplicate registrations),\nand the missing-openspec abort leaves the system untouched and exits 1.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add `data-loom up` one-command setup verb",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-04T10:58:41Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3140098a60359e25a4634be242aca7dac0dd8604",
          "body": "On Linux and macOS, `autostart enable` starts the daemon via the supervisor\nitself (systemd `enable --now`, launchd `RunAtLoad`), so the follow-up\n`lifecycle.start()` spawned a second detached instance that raced the\nsupervised one for the loopback port — the loser exited 0 via the\nsingle-instance g\n[…]\ny fire on next login), and runAutostart\nstarts the daemon itself only when registration didn't. Found during\nharden-always-on WSL verification.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: skip redundant daemon start when the supervisor already launched it",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-04T10:45:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b1d3942555f50a23068dc5aacb0e31bdf18555af",
          "body": "Move harden-always-on (implemented in 31d0857, verified on real systemd)\ninto openspec/changes/archive/2026-07-04-harden-always-on, and sync its\ndeltas into openspec/specs: startup-autolaunch's Per-OS mechanism becomes\nthe supervising form (Scheduled Task / LaunchAgent KeepAlive / systemd unit)\nwith\n[…]\ngacy-registration migration; daemon-lifecycle gains the update\ncommand. All 18 specs validate.\n\none-command-setup remains the only open change.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: archive harden-always-on and sync its specs",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-04T10:34:41Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a4256a93341ecdb480138d98fb8c6c4e29a759f6",
          "body": "Tasks 4.1/4.2 verified end-to-end on the Linux systemd path via a real\n`systemctl --user` unit in WSL2 (portable node + isolated prefix, torn down\nafter):\n- crash (kill -9 of MainPID) → systemd auto-restarts (NRestarts 0→1, new\n  pid, reachable again)\n- `data-loom stop` → unit inactive, not restarte\n[…]\nk creation); the systemd unit proves\nthe same restart-on-failure contract. Windows clean-stop exit-0 was verified\nseparately via /api/shutdown.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: verify harden-always-on supervised restart on real systemd",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-04T10:07:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c7ce91189253c76ab217b4938cdc321149c6b69b",
          "body": "Dependency declared during the weave review — `up` should register the\nsupervised autostart form and rewrite the README once, after harden-always-on\nlands.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: record one-command-setup depends on harden-always-on",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-04T09:50:12Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2b2fae9a4c110f78238be66d646e224b0b5c7fb4",
          "body": "Move add-tray-icon and add-connect-claude-code (shipped in v0.6.0) plus\non-demand-daemon and serve-weave-as-prompt (implemented in 31d0857) into\nopenspec/changes/archive/2026-07-04-*, and sync their delta specs into\nopenspec/specs: new capabilities tray-indicator, claude-code-integration\n(merged con\n[…]\nlaude Code registration on enable) and\nroadmap-mcp-server (weave served as an MCP prompt).\n\nharden-always-on and one-command-setup remain open.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: archive four completed changes and sync capability specs",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-04T09:50:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "32fb8a47fe9e49b0c16cccfe99a718412bb83ab5",
          "body": "Finish the harden-always-on apply (implementation landed in 31d0857).\nVerification found that on Windows `data-loom stop` force-terminated the\ndaemon with exit 1 (process.kill -> TerminateProcess, handler skipped),\nwhich a restart-on-failure supervisor would misread as a crash and relaunch\n— breakin\n[…]\nopen: the\nOS-triggered restart can't be exercised on this host (non-elevated Task\nScheduler access denied) and needs a real supervised session.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: record harden-always-on apply — Windows clean-stop fix",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-04T09:48:52Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "31d0857975b3a692581dbe4cb88cbb3865ecbcb2",
          "body": "Add `data-loom mcp-shim`: a client-spawned stdio MCP endpoint that starts\nthe daemon through the existing detached lifecycle path when the loopback\nport is dead, waits (bounded) for it to answer, then proxies MCP traffic to\nthe daemon's HTTP `/mcp` for the life of the session. The shim defines no\nto\n[…]\nht work from the serve-weave-as-prompt and harden-always-on changes;\nthey are included here because the shim wiring won't compile without them.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: on-demand daemon launch via a stdio MCP shim",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-04T09:26:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8000002e9fa91ea53bc36d6067c42eff805b7aa5",
          "body": "Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release v0.6.0 — system-tray indicator and Claude Code auto-registration",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-03T21:28:01Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b7bb107733f57715e990613cefaf5b3fb13a0e0b",
          "body": "Capture a change to make the daemon's weave review workflow an MCP prompt\n(the single source of truth, always matching the running server), with\nthe installed /loom:weave file shrinking to a thin, version-stamped alias\nprovisioned by `connect claude-code` and self-healed on daemon startup —\nreplacing the current agent-mediated install path that drifts and never\nrefreshes.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: propose serving the weave workflow as an MCP prompt",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-03T20:56:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4dae11ea290d781af060b28888ed5f57fab4c569",
          "body": "Capture a change for a client-spawned stdio shim that starts the daemon\nwhen it isn't running and proxies MCP traffic to its loopback HTTP\nendpoint, removing \"remember to start DataLoom\" as a failure class for\nClaude Code sessions. Registered via a new `connect claude-code\n--on-demand` mode, complementary to (and independent of) the always-on\nsupervision path.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: propose an on-demand daemon launch via a stdio MCP shim",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-03T20:56:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "523fb4fdb3aa0b8d0f107d38a1cee8d9108035cf",
          "body": "Capture a `data-loom up` change: check the openspec prerequisite up front\n(fail fast, no partial setup), then run the existing enable sequence\n(login autostart, daemon start, Claude Code registration), finishing with\na state summary. Re-runnable and idempotent, so it doubles as a setup\nhealth check.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: propose a one-command guided setup verb",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-03T20:56:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8e3b5b4ef436f9b2b5ed4d66bbe0fe8db6344d32",
          "body": "Capture a change to replace fire-and-forget login items with native\nper-user supervisors (Windows Scheduled Task, macOS LaunchAgent KeepAlive,\nLinux systemd user unit) so a crashed daemon restarts automatically, a\nstable launcher so autostart survives Node version-manager churn and npm\nrelocations, and a `data-loom update` verb tying upgrade + restart +\nre-registration together.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: propose hardening the always-on daemon with real OS supervision",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-03T20:56:01Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e661c568ae60f63a112b97272c4827777acb6aa0",
          "body": "Add `data-loom connect/disconnect claude-code`, registering the daemon's\nloopback MCP endpoint at user scope through Claude Code's own CLI (never\nwriting ~/.claude.json directly), with graceful fallback to the manual\n`claude mcp add` line when the `claude` CLI is absent. `autostart enable`\nnow chain\n[…]\nregistration in as a best-effort step (--no-connect to\nskip), so enabling always-on can both host and register the MCP endpoint\nin one command.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: register DataLoom with Claude Code via a connect command",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-03T20:55:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "868ce54037fd0e33b129f4121563cb88e047de16",
          "body": "Give the detached background daemon a glanceable \"is DataLoom running?\"\nsignal plus one-click open/copy/stop, since there is no console or window\nonce it starts in background mode. Hardens daemon startup with graceful\nEADDRINUSE handling (point at the already-running instance instead of\ncrashing) so a foreground launch never fights the tray of a background one.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add a system-tray indicator for the running daemon",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-03T20:54:47Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4ceabcfee859396e668cbac35b4a35ed37faa040",
          "body": "The serverInfo version was hardcoded and stuck at 0.4.1 through the 0.5.0\nrelease. Read it from the package.json shipped next to the compiled code so\nit can never drift again.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: advertise the real package version in the MCP server info",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-03T20:50:02Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3d73ff412fac92a56cd04626885632c41c5c6b1d",
          "body": "The background daemon keeps serving the previously installed global package\nuntil it is both reinstalled and restarted, so a release could leave a stale\ndaemon answering on the port (as happened with the MCP parse-error fix).\n\nAdd scripts/sync-global.mjs — build, pack to a temp tarball, install it\ng\n[…]\nreshly installed CLI shim — wired to postpublish so every `npm publish`\ndoes it automatically. Also runnable manually via `npm run sync-global`.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: sync the global install and restart the daemon on publish",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-03T20:46:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "66d1c850c146a5afe762127abb67721ec787eced",
          "body": "… not a 500\n\nA tools/call body containing unescaped Windows-path backslashes\n(\"D:\\projects\\...\" — \\p is not a valid JSON escape) failed JSON.parse in\nreadJsonBody, and the SyntaxError fell through handleMcp's generic catch as an\nopaque HTTP 500 {\"error\":\"internal error\"} — misreporting a client enco\n[…]\nrse failure to HTTP 400 with a JSON-RPC -32700 error whose message\nechoes the parser's complaint and hints at escaping Windows path backslashes.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: answer malformed MCP request bodies with a JSON-RPC parse error,…",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-03T20:39:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c1f77b0d547108e53c63540c1eb756c3db9a1750",
          "body": "…op support\n\nAdd detached background run mode with start/stop/restart/status lifecycle\ncommands and a single-instance port guard; per-user login autostart\n(Windows Startup shortcut, macOS LaunchAgent, Linux XDG) via\nautostart enable|disable|status; and Claude Desktop registration\n(connect/disconnect\n[…]\norm with an\nmcp-remote stdio bridge fallback. All served by the one existing\nloopback daemon; foreground launch and security posture unchanged.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release v0.5.0 — background daemon, login autostart, and Claude Deskt…",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-07-01T10:35:22Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "21750a1aa149053427b51187c223eff34760c9ec",
          "body": "Security hardening for the HTTP MCP endpoint added in v0.4.0. Moving the\nMCP server onto the loopback HTTP daemon made it reachable by the browser\nand other local processes; this closes that surface.\n\n- Host + Origin guard on every HTTP request and the WebSocket upgrade:\n  reject a non-loopback Host\n[…]\ndual local-process risk is documented.\n\nArchives openspec change harden-mcp-endpoint and syncs the roadmap-daemon\nand roadmap-mcp-server specs.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release v0.4.1 — harden the daemon-hosted MCP endpoint",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-29T21:31:52Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0161b4cabf221504846ca91e8bac5c679be176c0",
          "body": "Serve the MCP server from the running dashboard daemon over Streamable-HTTP\ninstead of a per-project stdio process, so setup is once per machine rather\nthan once per project.\n\n- Daemon hosts an MCP endpoint at /mcp (127.0.0.1:4317) via\n  StreamableHTTPServerTransport; one registration serves every p\n[…]\nistrations with the single user-scope HTTP registration.\n\nArchives openspec change serve-mcp-from-daemon and syncs the roadmap-mcp-server\nspec.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release v0.4.0 — daemon-hosted HTTP MCP server",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-29T21:04:22Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3170a85a05b663514e9a347b33af36b4c1fe26bf",
          "body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release v0.3.0 — blueprint redesign",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-29T18:51:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5853c676f85455394e0c9c1e4eb78adb34c4db24",
          "body": "…opology\n\nRe-skin both views into a drafting-paper blueprint system with a light/dark\ntheme switch (persisted to localStorage), all colours driven by CSS variables.\n\n- Roadmap: framed dependency graph — phase-band frames, full proposal cards\n  (status bar, pills, waiting note, caps/tasks, NEXT-UP), \n[…]\npx) with slide-in.\n- Project dropdown options themed so the native popup is readable in both themes.\n\nFront-end only — no daemon/model changes.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: blueprint redesign — framed roadmap graph + circuit-board MCP t…",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-29T18:49:57Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5cca2bed5ec588370d93245cf7ee0b019c786eee",
          "body": "The embedded /loom:weave command (written by install_weave_skill) still\npointed `claude mcp add` at the unscoped `npx data-loom`; correct it to\nthe published scoped package name.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Scope the weave command's register example to @lyric_dev/data-loom",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-29T16:45:44Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b9d3e561292a9eeb57c4476f1f35b5bcf6b53db2",
          "body": "Unscoped `data-loom` is blocked by npm's name-similarity rule (too close\nto the existing `dataloom` package), so publish as `@lyric_dev/data-loom`.\nThe installed bin command stays `data-loom`. Update README install/MCP docs.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Publish under @lyric_dev scope (v0.2.4)",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-29T16:39:29Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "58ee0a3ce7e71e98135f719e8b702451d7cbff18",
          "body": "First release on the npm-distribution pipeline (npx data-loom). Bumped to\n0.2.3 because v0.2.2 is taken by the prior exe release.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release v0.2.3 — first npm publish",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-29T05:49:26Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "99a00ea172af769d2842d800d418e5b6c023d0d7",
          "body": "The unsigned DataLoom.exe tripped Windows SmartScreen and AV false\npositives; code signing is the only real fix and carries cost/eligibility\nfriction. The app is already a Node daemon + browser SPA with a `data-loom`\nbin, so publish to npm instead: `npx data-loom` runs under the user's\nalready-signe\n[…]\ned-launch, and app-branding\ncapabilities; supersedes the strip-corrupted-signature exploration (both\narchived under openspec/changes/archive/).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Distribute via npm; remove the Windows SEA executable build",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-29T05:28:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3841271c7480e238f245b2430198b37f938fc1da",
          "body": "Maintenance release: tag the esbuild advisory fix and Node 24 CI action\nupgrades (6a3a16f) as a build, exercising the new node24 actions.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release v0.2.2",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-28T19:45:12Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6a3a16fa8448bda1d6871d1ff4b6464f9c83b875",
          "body": "- Bump esbuild ^0.24.0 -> ^0.25.0 (resolved 0.25.12), clearing\n  GHSA-67mh-4wv8-2f99 (the dev-server CORS advisory); npm audit is now\n  clean. We only use esbuild for bundling, not its dev server, so it was\n  not exploitable here, but this clears the Dependabot alert.\n- Upgrade release workflow acti\n[…]\n v4 -> v6, softprops/action-gh-release\n  v2 -> v3 (files/fail_on_unmatched_files inputs unchanged), clearing the\n  Node 20 deprecation warning.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix esbuild dev-server advisory and modernize CI action runtimes",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-28T19:43:06Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "15d94f85c6fab5e4862dbfca76c356d9c576019c",
          "body": "- install_weave_skill MCP tool writes a global /loom:weave command that\n  runs the dependency review (list -> propose -> confirm -> apply); the\n  server advertises it in its connect-time instructions\n- release workflow now publishes a SHA-256 checksum (DataLoom.exe.sha256)\n  beside the exe; README d\n[…]\nx, still to come)\n- Archive add-weave-skill and add-release-checksums; sync the\n  roadmap-mcp-server and release-pipeline specs\n- Bump to 0.2.1\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add /loom:weave skill provisioning and release checksums (v0.2.1)",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-28T19:25:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "75527385f4833a91e70d0a7ab792ff6f8f865d5d",
          "body": "- data-loom mcp: stdio MCP server exposing open proposals plus\n  dependency tools (list_open_proposals, set_dependency,\n  mark_independent), reasoned under the user's own authenticated Claude\n- Dependency-review state derived from `## Depends On` presence;\n  pending proposals get a roadmap \"needs re\n[…]\ncy-review; sync the\n  roadmap-mcp-server / roadmap-derivation / roadmap-view specs\n- Bump version to 0.2.0; document the new tool in the README\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add MCP server mode and dependency-review workflow (v0.2.0)",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-28T17:56:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cb37feaf2989493b4450eb3bb64d0c5241c6ee61",
          "body": "- Extend roadmap-view (8 -> 10 requirements) with the stacked-band layout\n- Move the change to openspec/changes/archive/2026-06-27-phase-band-layout/\n\nAll changes archived; 0 active.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Archive phase-band-layout; settle into roadmap-view baseline",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-27T12:58:20Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c6d458070c599a4c27f598ed7ea32923289c4114",
          "body": "Render phases as vertically stacked dashed bands (earliest on top) with\ncards in a row, a downward phase-progression arrow between bands, and\ndashed dependency connectors between cards. Status/readiness badges,\nconflicts, the project selector, and the done-band are unchanged.\nView-only (public/).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Restructure roadmap into stacked phase bands",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-27T12:58:06Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "002cc5066a219513a8ec7c22b14a0d04bf3b6266",
          "body": "- Create openspec/specs/phase-planning/spec.md\n- Move the change to openspec/changes/archive/2026-06-27-add-phase-planning/\n\nAll changes archived; 0 active.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Archive add-phase-planning; settle phase-planning into baseline",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-27T12:48:22Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a03155289323900c8daddeddb2c24d8288e66729",
          "body": "- Proposals can declare `## Depends On: <change names>`; the derivation\n  merges those edges with capability-derived ones, so interdependent open\n  proposals sequence into phases even when they only touch baseline\n  capabilities\n- Classify each open proposal ready/blocked/done — finer than phase: a\n\n[…]\new\n\nVerified against a synthetic Depends-On graph (blocked, ready-before-\narchive, archived-satisfied, unknown->conflict) and the live roadmap.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Implement phase planning: explicit deps + readiness guidance",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-27T12:47:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7354f54baec8e2b71c2297f95b0ef88c52f43d92",
          "body": "- Extend self-contained-launch (3->5) and project-selection (4->5)\n- Move the change to openspec/changes/archive/2026-06-27-fix-exe-first-run/\n\nAll changes archived; 0 active.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Archive fix-exe-first-run; settle launch fixes into baseline",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-27T11:31:18Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1004fb72442125cd1c905cc0e66f9c09f1c5e6c1",
          "body": "Make a double-clicked DataLoom.exe usable:\n- Resilient launch: if the launch dir has no openspec/ workspace, use the\n  first discovered project, else start in a no-project picker state —\n  never exit (except for the missing openspec prerequisite)\n- Open the default browser to the dashboard on startu\n[…]\nprompt; discoverProjects no longer offers a non-openspec dir as current\n- Bump version to 0.1.1; suppress browser-open in the dev launch config\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix exe first-run: serve without a project + open browser",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-27T11:30:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "857e8cca9b4a6441519da8cea92342149f29d155",
          "body": "- Create openspec/specs/app-branding/spec.md (4 requirements)\n- Move the change to openspec/changes/archive/2026-06-27-brand-dataloom/\n\nAll changes archived; 0 active, 10 baseline capabilities.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Archive brand-dataloom; settle app-branding into baseline",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-27T11:11:51Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4b510f9f8fec582c1b4b6ef92a7b2b2b00887cbf",
          "body": "- Add public/icon.svg: a woven warp/weft tile with data-node dots\n- Header logo + \"DataLoom\" name, favicon, and page title\n- Packaging: render DataLoom.ico from the SVG, set it + ProductName on\n  the exe via rcedit, output DataLoom.exe, embed icon.svg as a SEA asset\n- Release workflow and README reference DataLoom / DataLoom.exe\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Brand the app as DataLoom with an app icon",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-27T11:11:40Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8ff06f3f3e3616b2dc8c5b405b3157e20d324bc8",
          "body": "- Create openspec/specs/{project-selection,self-contained-launch,release-pipeline}\n- Extend roadmap-daemon (6->7), roadmap-view (7->8), mcp-discovery (3->4)\n- Move the change to openspec/changes/archive/2026-06-27-self-contained-multi-project/\n\nAll changes archived; 0 active, 9 baseline capabilities.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Archive self-contained-multi-project; settle specs into baseline",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-27T10:55:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "121fc2fa4598ec2e986f35159dbeeae7a2832018",
          "body": "Implement self-contained-multi-project:\n\n- Standalone Windows .exe via Node SEA (esbuild bundle + embedded\n  public/ assets + postject). openspec stays an external prerequisite\n  the exe invokes, exiting with install guidance if missing.\n- Runtime-selectable project: launch arg + in-app header selec\n[…]\ne runs from a directory with no public/ (embedded\nassets), lists real projects, switches live, and exits with guidance\nwhen openspec is absent.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add standalone exe, multi-project selection, and README",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-27T10:55:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2badb23223f7df1782477a7ca6e3c0ee71c001c7",
          "body": "Archive the final change and sync its capabilities:\n\n- Extend openspec/specs/roadmap-derivation (6 -> 9 requirements) with\n  cycle detection, dangling-dependency detection, and conflict info\n- Extend openspec/specs/roadmap-view (5 -> 7) with conflict marking and\n  relationship surfacing\n- Move the change to\n  openspec/changes/archive/2026-06-27-add-roadmap-conflict-detection/\n\nAll changes are now archived; data_loom is feature-complete.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Archive add-roadmap-conflict-detection; settle final specs into baseline",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-27T10:18:16Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c6485299b2326e7b6df638917bc6faadf57a2469",
          "body": "Build add-roadmap-conflict-detection — surface ordering problems on the\nroadmap:\n\n- Derivation: detect dependency cycles (DFS back-edge), promote\n  unsatisfied (Modified-but-unowned, non-baseline) capabilities to\n  dangling conflicts, attach a conflicts[] to the model defensively\n- View: a conflicts\n[…]\nerified:\nclean workspace reports zero conflicts; a synthetic cycle and dangling\ndependency are both detected; the banner and node marks render.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Implement conflict detection (cycle + dangling deps)",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-27T10:15:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "299c059fbf096af7bee668a896210c9602368c6c",
          "body": "Archive the completed MCP topology change and sync its capabilities:\n\n- Create openspec/specs/{mcp-discovery,mcp-availability,topology-view}\n- Extend openspec/specs/roadmap-daemon (4 -> 6 requirements) with the\n  config-reading and topology-serving requirements\n- Move the change to openspec/changes/archive/2026-06-27-add-mcp-topology/\n\nOnly add-roadmap-conflict-detection remains (Phase 1).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Archive add-mcp-topology; settle Phase 2 specs into baseline",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-27T10:05:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "da23af0fc2a4dce263d7c5e0bf7e13e278554cda",
          "body": "Build add-mcp-topology — the \"how / with what do I develop?\" view:\n\n- Discovery: merge MCP servers from ~/.claude.json (global + project)\n  and ~/.claude/.mcp.json, dedupe across scopes/path-variants, detect\n  transport, and redact secrets at the boundary (env/tokens never reach\n  the client)\n- Pass\n[…]\ntasks.md and marks all\n19 tasks complete. Verified against the real local config: comfyui\nalready-running, unreal on-demand, no secrets leaked.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Implement Phase 2: MCP topology (HOW tab)",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-27T10:01:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1a6128e01c08225347fc9506776991f8602a6c31",
          "body": "Archive the completed Phase 1 change and sync its three capabilities\ninto the spec baseline:\n\n- Create openspec/specs/{roadmap-daemon,roadmap-derivation,roadmap-view}\n  (15 requirements total)\n- Move the change to\n  openspec/changes/archive/2026-06-27-scaffold-roadmap-daemon/\n\nWith the foundation se\n[…]\nhanges (add-mcp-topology,\nadd-roadmap-conflict-detection) now resolve their dependencies against\nthe baseline and are unblocked (both Phase 1).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Archive scaffold-roadmap-daemon; settle Phase 1 specs into baseline",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-27T09:44:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2db648414040a22e47f311ebb1bc287ce40fa341",
          "body": "Build the data_loom foundation (scaffold-roadmap-daemon):\n\n- Node daemon: loopback HTTP + WebSocket push, debounced openspec/\n  file-watcher, startup openspec CLI availability check\n- Derivation: capability-ownership dependency DAG, topological phases,\n  task-based status (independent axis), cycle/d\n[…]\nn and recomputes live on\nedit. Marks all 26 tasks complete and records the derivation\ndata-source clarification in the roadmap-derivation spec.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Implement Phase 1: roadmap daemon, derivation, and live view",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-27T09:37:33Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f1b3bf8198a28c3e56a741c0592c0d12a39e30dc",
          "body": "Set up the spec-driven workflow and propose the initial phased roadmap\nas three dependency-linked changes:\n\n- scaffold-roadmap-daemon (Phase 1): local Node daemon + browser SPA,\n  derived dependency DAG, phased \"what to develop\" roadmap, live\n  file-watching\n- add-mcp-topology (Phase 2): hub-and-spo\n[…]\ne 2): surface dependency cycles\n  and dangling / out-of-order dependencies\n\nProject context and decisions are recorded in openspec/config.yaml.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add OpenSpec proposals for the data_loom dashboard",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-27T09:15:20Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6b958f5d3b59ba70166b197cd6a9401e58f527f7",
          "body": null,
          "is_bot": false,
          "headline": "Initial commit",
          "author_name": "Cyril Grossenbacher",
          "author_login": "groscy",
          "committed_at": "2026-06-27T08:35:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 24,
      "commits_last_year": 80,
      "latest_release_at": "2026-07-20T23:10:53Z",
      "latest_release_tag": "v0.13.0",
      "releases_from_tags": true,
      "days_since_last_push": 2,
      "active_weeks_last_year": 5,
      "days_since_latest_release": 6,
      "mean_days_between_releases": 1.6
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 85,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": true
    },
    "ecosystem": {
      "packages": [
        {
          "name": "@lyric_dev/data-loom",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "openspec",
            "mcp",
            "dashboard",
            "roadmap",
            "spec-driven-development",
            "claude-code"
          ],
          "ecosystem": "npm",
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/@lyric_dev/data-loom",
          "is_deprecated": false,
          "latest_version": "0.13.0",
          "repository_url": "https://github.com/groscy/data-loom",
          "versions_count": 17,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 3047,
          "first_published_at": "2026-06-29T16:41:36.897000Z",
          "latest_published_at": "2026-07-20T23:11:24.457000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 6
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 0,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0,
        "collected_at": null
      },
      "open_issues_and_prs": 3
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": true,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 83024,
      "source_files_sampled": 24,
      "oversized_source_files": 1,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "package.json"
      ],
      "advisories": {
        "error": null,
        "scope": "published_package",
        "source": "osv",
        "findings": [
          {
            "name": "@hono/node-server",
            "direct": false,
            "version": "1.19.15",
            "severity": "moderate",
            "ecosystem": "npm",
            "cvss_score": 5.9,
            "advisory_ids": [
              "GHSA-frvp-7c67-39w9"
            ],
            "fixed_version": "2.0.5",
            "advisory_count": 1,
            "oldest_advisory_days": 5
          }
        ],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {
          "moderate": 1
        },
        "advisory_count": 1,
        "affected_count": 1,
        "assessed_count": 96,
        "malicious_count": 0,
        "assessed_package": "npm:@lyric_dev/data-loom@0.13.0",
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm"
      ],
      "dependencies": [
        {
          "name": "@modelcontextprotocol/sdk",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.29.0"
        },
        {
          "name": "ws",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^8.18.0"
        }
      ],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "@modelcontextprotocol/sdk",
            "direct": true,
            "version": "1.29.0",
            "ecosystem": "npm"
          },
          {
            "name": "ws",
            "direct": true,
            "version": "8.21.0",
            "ecosystem": "npm"
          },
          {
            "name": "@hono/node-server",
            "direct": false,
            "version": "1.19.14",
            "ecosystem": "npm"
          },
          {
            "name": "@types/node",
            "direct": false,
            "version": "26.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "@types/ws",
            "direct": false,
            "version": "8.18.1",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-aix-ppc64",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-darwin-arm64",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-darwin-x64",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-freebsd-arm64",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-freebsd-x64",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-linux-arm",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-linux-arm64",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-linux-loong64",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-linux-mips64el",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-linux-ppc64",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-linux-riscv64",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-linux-s390x",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-linux-x64",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-netbsd-arm64",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-netbsd-x64",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-openbsd-arm64",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-openbsd-x64",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-sunos-x64",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-win32-arm64",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript/typescript-win32-x64",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "accepts",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "ajv",
            "direct": false,
            "version": "8.20.0",
            "ecosystem": "npm"
          },
          {
            "name": "ajv-formats",
            "direct": false,
            "version": "3.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "body-parser",
            "direct": false,
            "version": "2.3.0",
            "ecosystem": "npm"
          },
          {
            "name": "bytes",
            "direct": false,
            "version": "3.1.2",
            "ecosystem": "npm"
          },
          {
            "name": "call-bind-apply-helpers",
            "direct": false,
            "version": "1.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "call-bound",
            "direct": false,
            "version": "1.0.4",
            "ecosystem": "npm"
          },
          {
            "name": "content-disposition",
            "direct": false,
            "version": "1.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "content-type",
            "direct": false,
            "version": "1.0.5",
            "ecosystem": "npm"
          },
          {
            "name": "content-type",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "cookie",
            "direct": false,
            "version": "0.7.2",
            "ecosystem": "npm"
          },
          {
            "name": "cookie-signature",
            "direct": false,
            "version": "1.2.2",
            "ecosystem": "npm"
          },
          {
            "name": "cors",
            "direct": false,
            "version": "2.8.6",
            "ecosystem": "npm"
          },
          {
            "name": "cross-spawn",
            "direct": false,
            "version": "7.0.6",
            "ecosystem": "npm"
          },
          {
            "name": "debug",
            "direct": false,
            "version": "4.4.3",
            "ecosystem": "npm"
          },
          {
            "name": "depd",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "dunder-proto",
            "direct": false,
            "version": "1.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "ee-first",
            "direct": false,
            "version": "1.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "encodeurl",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "es-define-property",
            "direct": false,
            "version": "1.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "es-errors",
            "direct": false,
            "version": "1.3.0",
            "ecosystem": "npm"
          },
          {
            "name": "es-object-atoms",
            "direct": false,
            "version": "1.1.2",
            "ecosystem": "npm"
          },
          {
            "name": "escape-html",
            "direct": false,
            "version": "1.0.3",
            "ecosystem": "npm"
          },
          {
            "name": "etag",
            "direct": false,
            "version": "1.8.1",
            "ecosystem": "npm"
          },
          {
            "name": "eventsource",
            "direct": false,
            "version": "3.0.7",
            "ecosystem": "npm"
          },
          {
            "name": "eventsource-parser",
            "direct": false,
            "version": "3.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "express",
            "direct": false,
            "version": "5.2.1",
            "ecosystem": "npm"
          },
          {
            "name": "express-rate-limit",
            "direct": false,
            "version": "8.5.2",
            "ecosystem": "npm"
          },
          {
            "name": "fast-deep-equal",
            "direct": false,
            "version": "3.1.3",
            "ecosystem": "npm"
          },
          {
            "name": "fast-uri",
            "direct": false,
            "version": "3.1.2",
            "ecosystem": "npm"
          },
          {
            "name": "finalhandler",
            "direct": false,
            "version": "2.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "forwarded",
            "direct": false,
            "version": "0.2.0",
            "ecosystem": "npm"
          },
          {
            "name": "fresh",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "function-bind",
            "direct": false,
            "version": "1.1.2",
            "ecosystem": "npm"
          },
          {
            "name": "get-intrinsic",
            "direct": false,
            "version": "1.3.0",
            "ecosystem": "npm"
          },
          {
            "name": "get-proto",
            "direct": false,
            "version": "1.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "gopd",
            "direct": false,
            "version": "1.2.0",
            "ecosystem": "npm"
          },
          {
            "name": "has-symbols",
            "direct": false,
            "version": "1.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "hasown",
            "direct": false,
            "version": "2.0.4",
            "ecosystem": "npm"
          },
          {
            "name": "hono",
            "direct": false,
            "version": "4.12.27",
            "ecosystem": "npm"
          },
          {
            "name": "http-errors",
            "direct": false,
            "version": "2.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "iconv-lite",
            "direct": false,
            "version": "0.7.2",
            "ecosystem": "npm"
          },
          {
            "name": "inherits",
            "direct": false,
            "version": "2.0.4",
            "ecosystem": "npm"
          },
          {
            "name": "ip-address",
            "direct": false,
            "version": "10.2.0",
            "ecosystem": "npm"
          },
          {
            "name": "ipaddr.js",
            "direct": false,
            "version": "1.9.1",
            "ecosystem": "npm"
          },
          {
            "name": "is-promise",
            "direct": false,
            "version": "4.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "isexe",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "jose",
            "direct": false,
            "version": "6.2.3",
            "ecosystem": "npm"
          },
          {
            "name": "json-schema-traverse",
            "direct": false,
            "version": "1.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "json-schema-typed",
            "direct": false,
            "version": "8.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "math-intrinsics",
            "direct": false,
            "version": "1.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "media-typer",
            "direct": false,
            "version": "1.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "merge-descriptors",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "mime-db",
            "direct": false,
            "version": "1.54.0",
            "ecosystem": "npm"
          },
          {
            "name": "mime-types",
            "direct": false,
            "version": "3.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "ms",
            "direct": false,
            "version": "2.1.3",
            "ecosystem": "npm"
          },
          {
            "name": "negotiator",
            "direct": false,
            "version": "1.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "object-assign",
            "direct": false,
            "version": "4.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "object-inspect",
            "direct": false,
            "version": "1.13.4",
            "ecosystem": "npm"
          },
          {
            "name": "on-finished",
            "direct": false,
            "version": "2.4.1",
            "ecosystem": "npm"
          },
          {
            "name": "once",
            "direct": false,
            "version": "1.4.0",
            "ecosystem": "npm"
          },
          {
            "name": "parseurl",
            "direct": false,
            "version": "1.3.3",
            "ecosystem": "npm"
          },
          {
            "name": "path-key",
            "direct": false,
            "version": "3.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "path-to-regexp",
            "direct": false,
            "version": "8.4.2",
            "ecosystem": "npm"
          },
          {
            "name": "pkce-challenge",
            "direct": false,
            "version": "5.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "proxy-addr",
            "direct": false,
            "version": "2.0.7",
            "ecosystem": "npm"
          },
          {
            "name": "qs",
            "direct": false,
            "version": "6.15.3",
            "ecosystem": "npm"
          },
          {
            "name": "range-parser",
            "direct": false,
            "version": "1.3.0",
            "ecosystem": "npm"
          },
          {
            "name": "raw-body",
            "direct": false,
            "version": "3.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "require-from-string",
            "direct": false,
            "version": "2.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "router",
            "direct": false,
            "version": "2.2.0",
            "ecosystem": "npm"
          },
          {
            "name": "safer-buffer",
            "direct": false,
            "version": "2.1.2",
            "ecosystem": "npm"
          },
          {
            "name": "send",
            "direct": false,
            "version": "1.2.1",
            "ecosystem": "npm"
          },
          {
            "name": "serve-static",
            "direct": false,
            "version": "2.2.1",
            "ecosystem": "npm"
          },
          {
            "name": "setprototypeof",
            "direct": false,
            "version": "1.2.0",
            "ecosystem": "npm"
          },
          {
            "name": "shebang-command",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "shebang-regex",
            "direct": false,
            "version": "3.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "side-channel",
            "direct": false,
            "version": "1.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "side-channel-list",
            "direct": false,
            "version": "1.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "side-channel-map",
            "direct": false,
            "version": "1.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "side-channel-weakmap",
            "direct": false,
            "version": "1.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "statuses",
            "direct": false,
            "version": "2.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "toidentifier",
            "direct": false,
            "version": "1.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "type-is",
            "direct": false,
            "version": "2.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "typescript",
            "direct": false,
            "version": "7.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "undici-types",
            "direct": false,
            "version": "8.3.0",
            "ecosystem": "npm"
          },
          {
            "name": "unpipe",
            "direct": false,
            "version": "1.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "vary",
            "direct": false,
            "version": "1.1.2",
            "ecosystem": "npm"
          },
          {
            "name": "which",
            "direct": false,
            "version": "2.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "wrappy",
            "direct": false,
            "version": "1.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "zod",
            "direct": false,
            "version": "4.4.3",
            "ecosystem": "npm"
          },
          {
            "name": "zod-to-json-schema",
            "direct": false,
            "version": "3.25.2",
            "ecosystem": "npm"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 117,
        "direct_count": 2,
        "indirect_count": 115
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 3,
        "merged_prs": 0,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 2
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "groscy",
          "commits": 80,
          "avatar_url": "https://avatars.githubusercontent.com/u/92256856?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "release.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "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": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": null,
            "reason": "no pull request found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 0,
            "reason": "project has 0 contributing companies or organizations -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 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": 0,
            "reason": "project was created within the last 90 days. Please review its contents carefully",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 3,
            "reason": "dependency not pinned by hash detected -- score normalized to 3",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "no SAST tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 10,
            "reason": "security policy file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 10,
            "reason": "GitHub workflow tokens follow principle of least privilege",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 7,
            "reason": "3 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "a866d48a5db3424652915ff6aa57946a276fb78e",
        "ran_at": "2026-07-27T17:31:25Z",
        "aggregate_score": 5.4,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": true,
      "has_dependabot_config": true
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-25T20:35:25Z",
      "oldest_open_prs": [
        {
          "number": 3,
          "created_at": "2026-07-18T13:22:31Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 4,
          "created_at": "2026-07-18T13:22:57Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 5,
          "created_at": "2026-07-25T11:47:43Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": null,
      "ci_last_conclusion": "FAILURE",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/groscy/data-loom",
    "host": "github.com",
    "name": "data-loom",
    "owner": "groscy"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 56,
      "inputs": {
        "security": 61,
        "vitality": 69,
        "community": 42,
        "governance": 33,
        "engineering": 76
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "moderate",
        "name": "Vitality",
        "value": 69,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 57,
            "inputs": {
              "commits_last_year": 80,
              "human_commit_share": 1,
              "days_since_last_push": 2,
              "active_weeks_last_year": 5
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 2 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 2
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "5/52 weeks with commits",
                "points": 3.5,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 5
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "80 commits in the last year",
                "points": 17.1,
                "status": "partial",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 80
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 88,
            "inputs": {
              "releases_count": 24,
              "latest_release_tag": "v0.13.0",
              "releases_from_tags": true,
              "days_since_latest_release": 6,
              "mean_days_between_releases": 1.6
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "24 version tags (no GitHub releases)",
                "points": 16.2,
                "status": "partial",
                "details": [
                  {
                    "code": "version_tags_no_releases",
                    "params": {
                      "count": 24
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 6 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 6
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~1.6 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 1.6
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 42,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "good",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 77,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 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": 6.3,
                "status": "met",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "moderate",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 58,
            "inputs": {
              "packages": [
                "@lyric_dev/data-loom"
              ],
              "dependents": null,
              "ecosystems": "npm",
              "total_downloads": null,
              "monthly_downloads": 3047
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "3,047 downloads/month across npm",
                "points": 46.5,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 3047,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 33,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 10,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "critical",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 1,
            "inputs": {
              "merged_prs": 0,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 2
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "0/2 decided PRs merged",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 0,
                      "decided": 2
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 40,
            "inputs": {
              "followers": 2,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "groscy",
              "public_repos": 15,
              "account_age_days": 1751
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "2 followers of groscy",
                "points": 3.4,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 2,
                      "login": "groscy"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "15 public repos, account ~4 yr old",
                "points": 18.4,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 15
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 4
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "@lyric_dev/data-loom"
              ],
              "ecosystems": "npm",
              "any_deprecated": false,
              "min_days_since_publish": 6
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on npm",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 6 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 6
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "17 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 17
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "good",
        "name": "Engineering Quality",
        "value": 76,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 60,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "2 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "excellent",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "topics": [
                "claude-code",
                "dashboard",
                "mcp",
                "openspec",
                "roadmap",
                "spec-driven-development"
              ],
              "has_wiki": true,
              "homepage": "https://github.com/groscy/data-loom#readme",
              "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://github.com/groscy/data-loom#readme",
                "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": 61,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "moderate",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): CI-Tests, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "ci_tests",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 54,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 5.4
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "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": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 3",
                "points": 1.5,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "no SAST tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "GitHub workflow tokens follow principle of least privilege",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "3 existing vulnerabilities detected",
                "points": 5.2,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Matched the npm:@lyric_dev/data-loom@0.13.0 runtime dependency closure — what installing the published package pulls in — 96 packages. Reachability is not analyzed.",
            "notes": [
              {
                "code": "advisories_scope_published",
                "params": {
                  "package": "npm:@lyric_dev/data-loom@0.13.0",
                  "assessed": 96
                }
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 88,
            "inputs": {
              "source": "osv",
              "advisories": 1,
              "affected_packages": 1,
              "assessed_packages": 96,
              "unassessed_packages": 0,
              "affected_by_severity": "moderate 1",
              "direct_affected_packages": 0
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "no direct dependency carries a known advisory",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "no_direct_advisories",
                    "params": {}
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "1 affected: @hono/node-server 1.19.15 (moderate 5.9)",
                "points": 13.2,
                "status": "partial",
                "details": [
                  {
                    "code": "advisories_affected",
                    "params": {
                      "count": 1,
                      "packages": "@hono/node-server 1.19.15 (moderate 5.9)"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory has been public longer than 90 days",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "advisories_none_stale",
                    "params": {
                      "days": 90
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "excellent",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 96,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 54,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.838,
              "agent_instruction_files": [],
              "agent_instruction_max_bytes": null
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "no CLAUDE.md / AGENTS.md / editor rules",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_instructions",
                    "params": {}
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "67 of 80 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 67,
                      "sampled": 80
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 61,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "package-lock.json"
              ],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "tsconfig.json"
              ],
              "agent_commit_share": 0.95,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "tsconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "76 of the last 80 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 76,
                      "sampled": 80
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "dependency automation configured, none observed in the sampled commits",
                "points": 5,
                "status": "partial",
                "details": [
                  {
                    "code": "dependency_bot_config_only",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 3",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 98,
            "inputs": {
              "primary_language": "TypeScript",
              "largest_source_bytes": 83024,
              "source_files_sampled": 24,
              "oversized_source_files": 1
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "TypeScript (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "TypeScript"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "1/24 source files over 60KB",
                "points": 52.7,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 24,
                      "oversized": 1
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "critical",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 20,
            "inputs": {
              "example_dirs": [],
              "has_mcp_signal": true,
              "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": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "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": [],
  "report_type": "repository",
  "generated_at": "2026-07-27T17:31:30.757942Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/g/groscy/data-loom.svg",
  "full_name": "groscy/data-loom",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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