Registro público
Informe de salud del softwareesquema 0.26.0 · métricas 1.13.0 · 2026-07-22 03:06 UTC

codespeak-dev / twip

Twip is a lightweight tool for recording the full timeline of agentic/git changes in the project

GoApache-2.0★ 0 estrellas⑂ 0 forksdesde jun 2026Ver en GitHub ↗

codespeak-dev/twip tiene un índice de salud de 49 sobre 100, lo que lo sitúa en la banda En riesgo. Su puntuación más alta es Vitality (69/100) y la más baja, Community & Adoption (24/100). Se actualizó por última vez hace 4 días. 2 personas concentran la mayor parte del trabajo reciente.

49
global / 100
En riesgo

Índice de salud del software

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

49
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

CodeSpeakOrganización
29 seguidores12 repositorios públicosdesde jun 2025

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

Ecosistemas de paquetes

RegistroPaqueteVersiónDescargas / mesVersionesÚltima publicación
Gogithub.com/codespeak-dev/twipv0.4.7-15hace 4 días

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 4 días
4.2/36Cadencia de commits — 6/52 semanas con commits
16.6/18Volumen de commits — 70 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_year70
human_commit_share1
days_since_last_push4
active_weeks_last_year6
Cómo se puntúa
16.2/27Publica versiones — 15 etiquetas de versión (sin releases de GitHub)
36/36Recencia de las versiones — última versión hace 4 días
27/27Cadencia de publicación — una versión cada ~2,8 días
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count15
latest_release_tagv0.4.7
releases_from_tags
days_since_latest_release4
mean_days_between_releases2,8
Excluidos de la puntuación (sin datos o no aplicable): OpenSSF Scorecard: Signed-Releases. Los pesos restantes se han renormalizado.

Comunidad y Adopción

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

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

Sostenibilidad y Gobernanza

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

67Moderado · 24% del índice global
Cómo se puntúa
25.2/54Factor bus — la mitad de los commits recae en 2 contribuyente(s)
13.8/22.5Distribución de commits — el principal contribuyente firma el 39% de los commits
5.4/13.5Amplitud de contribuyentes — 4 contribuyentes
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Datos de entrada utilizados
bus_factor2
contributors_sampled4
top_contributor_share0,386
Cómo se puntúa
46.8/46.8Resolución de issues — 100% de issues cerradas
38.2/38.3Aceptación de PR — 4/4 PR decididos fusionados
0/15OpenSSF Scorecard: Code-Review — Found 1/23 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs4
open_issues0
closed_issues2
issue_closed_ratio1
closed_unmerged_prs0
Cómo se puntúa
30/30Respaldo de la propiedad — propiedad de una organización
0/20Dominio verificado
10.6/25Alcance del propietario — 29 seguidores de codespeak-dev
10.3/25Trayectoria — 12 repos públicos, cuenta de ~1 años
Datos de entrada utilizados
followers29
owner_typeOrganization
is_verified
owner_logincodespeak-dev
public_repos12
account_age_days391
Cómo se puntúa
25/25Publicado y resoluble — 1 paquete(s) en go
35/35Recencia de publicación — última publicación hace 4 días
20/20Historial de versiones — 15 versiones en el registro
20/20No obsoleto — activo, ni obsoleto ni retirado
Datos de entrada utilizados
packagesgithub.com/codespeak-dev/twip
ecosystemsgo
any_deprecatedno
min_days_since_publish4

Calidad de Ingeniería

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

44En riesgo · 20% del índice global
Cómo se puntúa
0/24Flujos de trabajo de CI
24/24Pruebas presentes
0/16Configuración de linter
0/9.6Hooks de pre-commit
0/6.4.editorconfig
0/20OpenSSF Scorecard: CI-Tests — 0 out of 3 merged PRs checked by a CI test -- score normalized to 0
Datos de entrada utilizados
has_cino
has_tests
has_editorconfigno
has_linter_configno
has_precommit_configno
Cómo se puntúa
30/30README
25/25Directorio de documentación
0/15Sitio de documentación / página del proyecto
10/10Descripción del repositorio
0/10Topics
10/10Wiki
Datos de entrada utilizados
topics
has_wiki
homepage
has_readme
has_docs_dir
has_description

Seguridad

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

30En riesgo · 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 — 0 out of 3 merged PRs checked by a CI test -- score normalized to 0
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 1/23 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
0/10Dangerous-Workflow — sin datos
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Licencia — license file detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
0/5Packaging — sin datos
5/5Pinned-Dependencies — all dependencies are pinned
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — sin datos
0/7.5Token-Permissions — sin datos
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated14
scorecard_versionv5.5.0
checks_inconclusive4
scorecard_aggregate3
Excluidos de la puntuación (sin datos o no aplicable): dangerous_workflow, packaging, signed_releases, token_permissions. Los pesos restantes se han renormalizado.

Preparación para IA

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

68Moderado · 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 — 63 de 70 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share0,9
agent_instruction_files
agent_instruction_max_bytes
Cómo se puntúa
12.6/18Arranque con un solo comando — go.mod (convención del toolchain, sin ejecutor de tareas)
22/22Pruebas automatizadas
0/11Configuración de lint / formato
11/11Verificación estática de tipos — Go (tipado estático)
10/10Entorno reproducible — lockfile
10/10Práctica demostrada con agentes — 35 de los últimos 70 commits con autoría o crédito de agente
0/8Mantenimiento automatizado — no se observan actualizaciones automáticas de dependencias
10/10OpenSSF Scorecard: Pinned-Dependencies — all dependencies are pinned
Datos de entrada utilizados
has_nixno
has_tests
lockfilesgo.sum
has_dockerfileno
typed_language
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configs
agent_commit_share0,5
toolchain_manifestsgo.mod
dependency_bot_commit_share0
Cómo se puntúa
45/45Código verificable por tipos — Go (tipado estático)
55/55Tamaños de archivo manejables — 0/70 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languageGo
largest_source_bytes26.159
source_files_sampled70
oversized_source_files0

Datos clave

0estrellas de GitHub
4contribuidores
70commits en los últimos 12 meses
4días desde el último push
15versiones publicadas
2factor bus
0issues abiertas
Goecosistemas de paquetes

Advertencias de recopilación de datos

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

Más detalle

OpenSSF Scorecard 3.0 / 10
3.0agregado

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-22 03:06 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
0CI-Tests0 out of 3 merged PRs checked by a CI test -- score normalized to 0
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 1/23 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
n/dDangerous-Workflowno workflows found
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
n/dPackagingpackaging workflow not detected
10Pinned-Dependenciesall dependencies are pinned
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
n/dSigned-Releasesno releases found
n/dToken-PermissionsNo tokens found
10Vulnerabilities0 existing vulnerabilities detected
Dependencias directas 1
RegistroPaqueteRestricción de versiónManifiesto
Gogithub.com/spf13/cobrav1.10.2go.mod
Todas las dependencias no recopilado

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

Informe JSON sin procesar legible por máquina
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 385,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "Go": 522519,
        "CSS": 10291,
        "HTML": 1012,
        "Shell": 2413
      },
      "pushed_at": "2026-07-17T17:22:34Z",
      "created_at": "2026-06-11T14:59:26Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-17T17:22:41Z",
      "description": "Twip is a lightweight tool for recording the full timeline of agentic/git changes in the project",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "Apache-2.0",
      "default_branch": "main",
      "license_spdx_raw": "Apache-2.0",
      "primary_language": "Go",
      "significant_languages": [
        "Go"
      ]
    },
    "owner": {
      "blog": "https://codespeak.dev",
      "name": "CodeSpeak",
      "type": "Organization",
      "login": "codespeak-dev",
      "company": null,
      "location": null,
      "followers": 29,
      "avatar_url": "https://avatars.githubusercontent.com/u/217932755?v=4",
      "created_at": "2025-06-25T12:58:42Z",
      "is_verified": null,
      "public_repos": 12,
      "account_age_days": 391
    },
    "license": {
      "state": "standard",
      "spdx_id": "Apache-2.0",
      "raw_spdx": "Apache-2.0",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.4.7",
          "kind": "patch",
          "published_at": "2026-07-17T17:22:46Z"
        },
        {
          "tag": "v0.4.6",
          "kind": "patch",
          "published_at": "2026-07-17T14:48:09Z"
        },
        {
          "tag": "v0.4.5",
          "kind": "patch",
          "published_at": "2026-07-09T16:22:16Z"
        },
        {
          "tag": "v0.4.4",
          "kind": "patch",
          "published_at": "2026-07-07T13:50:17Z"
        },
        {
          "tag": "v0.4.3",
          "kind": "patch",
          "published_at": "2026-07-01T15:17:59Z"
        },
        {
          "tag": "v0.4.2",
          "kind": "patch",
          "published_at": "2026-06-29T14:30:03Z"
        },
        {
          "tag": "v0.4.1",
          "kind": "patch",
          "published_at": "2026-06-24T15:32:41Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-06-23T18:35:26Z"
        },
        {
          "tag": "v0.3.4",
          "kind": "patch",
          "published_at": "2026-06-23T16:20:58Z"
        },
        {
          "tag": "v0.3.3",
          "kind": "patch",
          "published_at": "2026-06-22T17:05:54Z"
        },
        {
          "tag": "v0.3.2",
          "kind": "patch",
          "published_at": "2026-06-22T11:19:14Z"
        },
        {
          "tag": "v0.3.1",
          "kind": "patch",
          "published_at": "2026-06-18T13:57:45Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-06-12T11:56:55Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-06-11T17:39:46Z"
        },
        {
          "tag": "v0.1.0",
          "kind": "minor",
          "published_at": "2026-06-11T15:18:10Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "e95d8567cbfc082b4abfa8f1de1f9815a727717e",
          "body": "…bing\n\nAn append made while the caller's environment redirects git's object\nwrites (GIT_OBJECT_DIRECTORY from an IDE/agent checkpointer's shadow\nstore, or a receive-pack quarantine exported to hooks) put the journal\ncommit in the redirected store while update-ref advanced the real ref —\nrefs are not\n[…]\nted value.\n\nComplements the dangling-head self-heal (#6): recovery repairs a repo\nalready broken; the scrub removes the mechanism that broke it.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: scrub inherited repo-redirect GIT_* env from twip's own git plum…",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-07-17T17:22:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a629379b5d469720e1b5097112a0f5390d25e8e9",
          "body": "…ads, doctor diagnosis (#6)\n\nA journal head whose commit object is lost underneath the ref (external prune\nor a sandbox discarding a detached recorder's writes) previously killed twip\npermanently and broke the user's repo: every append failed at commit-tree,\nlog/audit read the journal as healthy-emp\n[…]\nagent hooks must not die).\n- doctor: name the dangling-head state explicitly, before the divergence probe\n  misreports it, with the repair path.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: survive a dangling journal head — self-heal on append, honest re…",
          "author_name": "Mikhail Sveshnikov",
          "author_login": "mike0sv",
          "committed_at": "2026-07-17T14:48:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fc978d11d8f119e4240eeab5e358ddd73e96fc80",
          "body": "…ose and withholds itself on findings\n\nEvery mirror path funnels through SyncPush (bundled hook, hook-manager jobs\nregardless of ordering, manual `twip sync push`), so the secrets gate now\nlives there instead of in any hook: no wiring or configuration can route\naround it, and the previous gap — the \n[…]\nonfig discovery,\n  scan invocation and finding summaries — shared by the gate and\n  `twip redact`, which previously carried this code privately.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: sync push self-gates — the mirror scans what it would newly exp…",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-07-09T16:22:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8c517cd6147fab0a245f8c0b0f1b848fa2d32f0e",
          "body": "…y unpushed commits, and defers remote changes to explicit --propagate\n\nHardens twip redact so a redacted secret becomes truly unreachable locally\nwhile twip stays a gentle addition to the dev loop — nothing on the remote\nis ever touched without an explicit flag:\n\n- fix: rewriting a worktree snapsho\n[…]\n tip (safe —\n  each clone is its journal's sole writer; anything else is refused,\n  never clobbered), plus remote deletion of dropped keep-refs.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: redact clears secrets from keep-refs + stale mirrors, scans onl…",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-07-09T15:41:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "22b9e2ca223d011c91ecf152783e182d5072fca9",
          "body": "…apshot to avoid excessive git diff ingestion from tools that traverse git folder (gitleaks/betterleaks)",
          "is_bot": false,
          "headline": "fix: twip ref tree elements carry forward the most recent worktree sn…",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-07-07T13:50:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "732175013685339a05b391a169250e3af6cedbea",
          "body": null,
          "is_bot": false,
          "headline": "feat: redact now uses betterleaks + docs update",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-07-01T15:17:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8c70c5dc0b1b8e0e9f341e015e17aaace91d47c6",
          "body": null,
          "is_bot": false,
          "headline": "fix: enable claude session appending by default",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-29T14:30:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "af3f7bb972670329049638a9ab2cf1b866f00154",
          "body": "…o interrupt twip report",
          "is_bot": false,
          "headline": "fix: append recent claude session log to twip report + allow ctrl-c t…",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-29T14:15:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ee638438bbb240d4bf4683b134f0496896b96172",
          "body": null,
          "is_bot": false,
          "headline": "feat: add twip report to easily construct markdown summaries of problems",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-29T13:58:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "134365719934a1fd2f2e96ed428d4c1bbae5b284",
          "body": "…g local twip binary or not (if symlinked)",
          "is_bot": false,
          "headline": "feat: twip update command to simplify/automate the process of updatin…",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-29T12:55:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "55adadcb2aa00551bfbb498b5b64db1311bdbf69",
          "body": "…ctor command to check existing install",
          "is_bot": false,
          "headline": "feat: always pre-pend twip to PATH, not just leave existing + twip do…",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-29T12:43:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f268859f20d02f513a434d57fb4bf15857f9b6b3",
          "body": "On session-start, capture any transcript lines already present before the hook fires (Codex startup records) instead of baselining past them",
          "is_bot": false,
          "headline": "feat: capture Codex startup records on session-start",
          "author_name": "Alexey Ivanov",
          "author_login": "aifgi",
          "committed_at": "2026-06-24T16:44:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e1a790dd006438216da8dd6dc52642c52c9901a5",
          "body": "* feat: add cheap filter for read-only untracked gitops to avoid expensive classification and twip call on every gitop\n\n* feat: twip redact command that uses gitleaks (if avail) to filter and redact api keys from blobs",
          "is_bot": false,
          "headline": "Twip redact command to remove gitleaks-flagged keys/tokens",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-24T15:32:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0839c8d499c5cd0ffc50520e8a9063a7746ea071",
          "body": "The backward walk in Event() matched on worktree_id alone, but worktree_id is only unique within a clone. With two synced clones both using the default worktree_id \"main\", the walk would stop at the other clone's snapshot and diff against it, fabricating cross-clone changes in the detail panel.",
          "is_bot": false,
          "headline": "fix: scope prev-snapshot walk to (clone, worktree_id)",
          "author_name": "Alexey Ivanov",
          "author_login": "aifgi",
          "committed_at": "2026-06-24T11:04:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d50907995653adad2bad73a1e2dc97a1920807c2",
          "body": "Show compact \"op [sub]\" label (e.g. \"worktree list\") instead of the full\nargv with -c/--git-dir/etc. prefixes. Mirrors gitOpAndSub logic from\ngitshim.go; storage and detail panel are unchanged.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: strip git global flags in timeline gitop display",
          "author_name": "Alexey Ivanov",
          "author_login": "aifgi",
          "committed_at": "2026-06-23T18:35:26Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "51275a5448c356416f1a3d3f1aed07ed3eba4fe0",
          "body": "Adds SidechainTranscript to the store reader, exposes sidechains as\nSidechainDetail in the EventDetail read model, and renders each one in\nthe UI under a clearly labelled \"subagent transcript · <id>\" section.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: show subagent (sidechain) transcripts in detail panel",
          "author_name": "Alexey Ivanov",
          "author_login": "aifgi",
          "committed_at": "2026-06-23T18:15:16Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ee429157ce4979efc434cbabc6b66786f8d17cd9",
          "body": "In symlinkBinary, the idempotency check resolves the existing link's target via filepath.EvalSymlinks but doesn't resolve src. On macOS, t.TempDir() returns a path under /tmp which is a symlink to /private/tmp, so after resolving, target becomes /private/tmp/... but src is still /tmp/... — the comparison fails and the function re-links instead of returning (false, nil).",
          "is_bot": false,
          "headline": "Fix TestSymlinkBinary on MacOS",
          "author_name": "Alexey Ivanov",
          "author_login": "aifgi",
          "committed_at": "2026-06-23T18:10:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "29093a47fb1ef0980b19cfe3d7525de4e440bb00",
          "body": null,
          "is_bot": false,
          "headline": "Add Codex agent support to Twip",
          "author_name": "aifgi",
          "author_login": "aifgi",
          "committed_at": "2026-06-23T18:00:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ffffccc7cad1822f6f0b7a1e5a73ce45cc55cf1a",
          "body": "…-checks pass through unrecorded",
          "is_bot": false,
          "headline": "fix: Skip write-tree and some remote commands in git shim — IDE dirty…",
          "author_name": "Alexey Ivanov",
          "author_login": "aifgi",
          "committed_at": "2026-06-23T17:48:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "90cbfb706070c87ecc0791445ef5038fe4f7ecb8",
          "body": "`twip init` without --agent now installs hooks for all registered agents\n(Claude Code and Codex). Pass `--agent <name>` to target a single agent.\nREADME updated to mention Codex as a supported agent.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: twip init installs all agents by default",
          "author_name": "Alexey Ivanov",
          "author_login": "aifgi",
          "committed_at": "2026-06-23T17:20:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ba95d96c40ee855e291143dcc1f1b8a20cf9fdc1",
          "body": null,
          "is_bot": false,
          "headline": "feat: shim snapshots git rm",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-23T17:16:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0f5684b60a347802b22cd239d2e065c8faefc5bd",
          "body": "Create internal/hookutil with ParseStdin, Truncate, HookCommand,\nIsTwipHook, MarshalNoEscape, and MarshalIndentNoEscape, keeping\ninternal/agent a pure domain package (Agent interface, Event, Cursor,\nQuality, transcript I/O). Remove agent/util.go entirely.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: extract hook infrastructure into internal/hookutil",
          "author_name": "Alexey Ivanov",
          "author_login": "aifgi",
          "committed_at": "2026-06-23T16:48:48Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "dcda67b85f9883b40c299f773883ae9c9121adfa",
          "body": "# Conflicts:\n#\tcmd/twip/init.go",
          "is_bot": false,
          "headline": "Merge remote-tracking branch 'origin/main' into feat/codex",
          "author_name": "Alexey Ivanov",
          "author_login": "aifgi",
          "committed_at": "2026-06-23T16:46:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "705b1f4afafc9ad4ae71f22647463db77aa022ea",
          "body": "…oid blocking",
          "is_bot": false,
          "headline": "fix: let user git return immediately, then handle twip logging, to av…",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-23T16:20:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6fabc0e753d9727161c4c300e2af3a8041bdea2b",
          "body": "- codex/codex.go: guard os.ReadFile in hookSessionStart so a transient\n  read failure leaves the cursor at prior.Main instead of resetting it\n  to 0 (which would cause the next Stop to re-capture the full transcript)\n- codex/install.go: decodeMatchers now returns an error instead of\n  silently disca\n[…]\nreplace the three \"ok\" string\n  literals with string(agent.QualityOK) so the comparisons stay correct\n  if the constant value is ever changed\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: harden Codex agent against read errors and malformed hooks",
          "author_name": "Alexey Ivanov",
          "author_login": "aifgi",
          "committed_at": "2026-06-23T16:20:12Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cb492e5778178266f5f7513b5a7d22fed0f95077",
          "body": null,
          "is_bot": false,
          "headline": "Add forked session id to UI",
          "author_name": "Alexey Ivanov",
          "author_login": "aifgi",
          "committed_at": "2026-06-23T16:10:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d11b1dd4985414cdd85720ef1d2d535f9d4173fc",
          "body": "…p's internals directly call system git to skip shim hop",
          "is_bot": false,
          "headline": "fix: check if command is read-only before finding repo-root etc + twi…",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-23T16:09:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "637a8a8f4493ef217057edc146c70e99aeadc6f6",
          "body": null,
          "is_bot": false,
          "headline": "Store agent identity on events",
          "author_name": "Alexey Ivanov",
          "author_login": "aifgi",
          "committed_at": "2026-06-23T15:46:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e4ef038c43bf71619818c1432621677b3ef88165",
          "body": "…pper bound on SessionStart back-scan",
          "is_bot": false,
          "headline": "feat: use a persistent snapshot index + cap file size in snapshot + u…",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-23T15:41:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ea2846bb023df3a260895fc6cbe2568a76db4105",
          "body": "…ions, and tool-use change-gate\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test: add Codex e2e tests covering realistic hook sequence, fork sess…",
          "author_name": "Alexey Ivanov",
          "author_login": "aifgi",
          "committed_at": "2026-06-23T15:10:10Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "839031355ac02949ac88494cc22eac678de8dde5",
          "body": "When a Codex session is forked, the child's transcript file begins with\nthe parent's content. SessionStart now reads that preamble in a single\npass, stores it as a transcript delta on the session-start event, and\nrecords the parent session ID in forked_from. This ensures a forked\nsession's full transcript is reconstructable from the journal.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: capture Codex fork session preamble and parent link",
          "author_name": "Alexey Ivanov",
          "author_login": "aifgi",
          "committed_at": "2026-06-23T14:53:01Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "74da7464c0f2c413cbb4c3b457416dcefa9190b9",
          "body": "…to manually fetch remote logs",
          "is_bot": false,
          "headline": "feat: default disable fetching of remote twip logs + twip sync fetch …",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-23T14:15:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1e3b785196b601d7902bc00d539f1b4b06ea1904",
          "body": "…ull binary, to avoid inconsistencies",
          "is_bot": false,
          "headline": "feat: twip bin folder now contains symlink to go bin directory, not f…",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-23T13:50:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4d1fe0815981b33d9488313e59a5cbfe9e9b8d18",
          "body": "Adds internal/agent/codex, a new Agent implementation for OpenAI Codex\nCLI. Installs hooks into .codex/hooks.json (SessionStart, UserPromptSubmit,\nStop, PostToolUse, SubagentStop) and ensures .codex/config.toml has\n[features] hooks = true. Uses task_complete JSONL sentinel for flush\ndetection; subag\n[…]\nReadDelta) and\nValidateAgentID into internal/agent so both claudecode and codex reuse\nthem. Updates twip init messaging to be agent-agnostic.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add Codex agent support",
          "author_name": "aifgi",
          "author_login": "aifgi",
          "committed_at": "2026-06-22T18:24:13Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cf1917cca61306673cb703f0eeace0d3c4a24711",
          "body": "…ternal git calls",
          "is_bot": false,
          "headline": "fix: don't record readonly sub-subcommands + gc disabled on twip's in…",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-22T17:05:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4f480e04ec58c7c68ee19aaef7149e9a9ef5e8cf",
          "body": null,
          "is_bot": false,
          "headline": "chore: bring install up to date",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-22T16:50:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "48afd393a132e56c163ce7eafa35dfc1d366a0cc",
          "body": null,
          "is_bot": false,
          "headline": "feat: early exit + batched git ops for SessionStart hook",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-22T11:19:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3c6d5afd804553d4416d6097b0884c22f18224cb",
          "body": null,
          "is_bot": false,
          "headline": "feat: resizable pane width in web UI",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-22T10:31:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "090782c2ca08d819949fab4d7176876c835d7450",
          "body": "…e lock problems",
          "is_bot": false,
          "headline": "fix: dirty worktree check uses --no-optional-locks flag to avoid stal…",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-19T12:29:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b1d4e21c9bca9d6ec45692c74adc7b0eafbaa3b8",
          "body": "… warning",
          "is_bot": false,
          "headline": "fix: if sandbox prevents .git operations, avoid logging and pass soft…",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-19T12:26:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c1bc2f4c51d8f971e4a39130f33b79c109595e07",
          "body": "Global Installation pipeline",
          "is_bot": false,
          "headline": "Merge pull request #1 from codespeak-dev/feature/global-install",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-18T13:57:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b700a73f4aec2c42b14090215fda35b40a152697",
          "body": null,
          "is_bot": false,
          "headline": "docs: update docs to be in sync",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-18T13:27:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d3027e36476395b881e06cf06196213af31f8350",
          "body": "…ook trigger in enviornments with pre-established git hooks",
          "is_bot": false,
          "headline": "fix: add --no-verify support to twip sync push to avoid double-push h…",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-18T13:23:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3ff3b894e343b90804e223931550ed11c250bb4f",
          "body": "…tallation as part fo twip featureset",
          "is_bot": false,
          "headline": "feat: add global bashrc installation, and setup git pre-push hook ins…",
          "author_name": "Ethan Dias Alberto",
          "author_login": "EDiasAlberto",
          "committed_at": "2026-06-17T15:56:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "831cea79aad5257701bd732bcdcebec67135596c",
          "body": null,
          "is_bot": false,
          "headline": "Fix bug with infinite self-calling recursion through shim",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-12T11:56:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "998ce4a782ca5cc3b65925d1841392d598177be7",
          "body": "Previously twip recorded only turn boundaries (prompt-submit/stop). Now it\nalso captures mid-turn worktree states by hooking Claude Code's PostToolUse\nfor the mutating tools (Edit/Write/MultiEdit/NotebookEdit/Bash), so the\ntimeline shows how a turn's changes accreted, not just the end state.\n\n  - Ne\n[…]\ntE2E_ToolUseEvents drives the path end-to-end (Edit/Write recorded,\nread-only Bash dropped, seq contiguous, audit clean); install test updated.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Record intermediate mutating tool calls (PostToolUse)",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-12T11:29:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0f0cd6d8600fd423f6ec9c1dfce031b42ab4340a",
          "body": "twip init now wires cross-clone sync that rides on ordinary git, so\nthere's nothing extra to run:\n\n  - push: a pre-push hook mirrors this clone's journal + pins + stash to\n    the remote you push to (TWIP_SYNC_PUSH-guarded against recursion;\n    best-effort, never blocks your push). Merge-preserving\n[…]\n (no commits yet) left a 0-byte temp index that git rejects (\"index\nfile smaller than expected\"); now we drop it and let git build a fresh one.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Sync: share journals across the team over normal git",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T17:39:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a06dee841924381e8aa5f099fcef89a7e87df45d",
          "body": "Module path now matches the public remote (github.com/codespeak-dev/twip),\nso `go install github.com/codespeak-dev/twip/cmd/twip@latest` works. README\ninstall section leads with the one-liner; intro trimmed to a blurb.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Rename module to github.com/codespeak-dev/twip; go-install README",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T15:18:10Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a5d722ed306dd3f6e7c6dd58de366b1497d0edd4",
          "body": null,
          "is_bot": false,
          "headline": "README clean-up",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T15:12:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4f66f2ef2e03c7a5d92a469df6c442827e6a9818",
          "body": "Rollout enablers for putting twip on real repos (local per-dev recording):\n- `twip version`: build info via runtime/debug.ReadBuildInfo (version, vcs\n  revision + dirty flag, Go version) — so it's clear what build everyone is on.\n- scripts/install.sh: builds + installs twip (go install ./cmd/twip), \n[…]\nam rollout\" section: install once per machine, then enable a repo by\n  committing .claude/settings.json (safe no-op without twip).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add `twip version` + install script + team-rollout docs",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T15:06:57Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b8f4f1791d6673a02caabf8873e4c474ec5fc683",
          "body": "The amber \"gitop\" kind label clashed with the branch chip color and is no longer\nneeded — git-ops are distinguished by their column placement now. Use the default\ntext color.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Browser: drop the special git-op label color",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "97310e4957896bdfa64c8230332aa9524d8b09c5",
          "body": "The fixed 12rem git-text column left dead space between the git and session\nconnectors. Measure the widest git description after render and set all git-text\ncells to that width (capped at 22rem) — snug, with no leftover slack, while still\nuniform so the session connector stays aligned across rows.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Browser: fit the git-text column to its content",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8cebda402332fc4f991312ed93c22ed1db6b4ebc",
          "body": "Reflow each row into five cells, left to right: git connector | git-op\ndescription | session connector | session description | timestamp. The git-op's\ntext now sits to the left of the session lane (only on git-op rows), and session\ntext to its right (only on session rows). The connector cells are fi\n[…]\nworkspace) and the git-text column is fixed (12rem) so the session\nconnector and its vertical lines stay aligned across every row.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Browser: lay out git text between the two connectors",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "56b7c429b5827ae19794bbdd9fe770593f781d0f",
          "body": "The git lane connected only between git-ops, so session events before the first\ngit-op (tail) and after the last (head) had no connector — leaving \"which branch\nwas this on?\" unanswered even though every event records its branch. Drive the\nconnector over all of a workspace's rows (colored by each row's effective\nbranch); dots and switch labels stay on git-ops only.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Browser: extend git-lane connector across the whole timeline",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b8f0c25c67141e5937606a2697f2601015d683bc",
          "body": "Replace the per-branch idea with a single continuous git lane whose vertical\nconnector recolors when the branch switches, plus a same-color branch label at\neach switch (and the first op). Connect ALL consecutive git-ops (no gaps); each\nsegment is colored by the branch HEAD is on during it (the effec\n[…]\nt), so no capture/schema change is needed and it works on existing\ndata. The session lane and per-workspace columns are unchanged.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Browser: one git lane, recolors per branch (Option A)",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "09ce46d7defc67c69ef4e0b8961fa8d9e6c17632",
          "body": "A resume reopens the same session id, producing session-end (seq N) then\nsession-start (seq N+1) with the same id. The session connector linked them,\nbridging the new sitting's start back to the prior end. Now a session-start\nalways begins a fresh segment (no downward connection), so each sitting is its\nown segment and the lane interrupts at session end.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Browser: a session-start never bridges to a prior sitting (resume fix)",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8f8a800d2fed92ca34adcca509fe799129fc51b0",
          "body": "Both lanes were built over the merged workspace event sequence, which caused two\nbugs: an interleaving git-op broke the session line, and the branch spine ran\nthrough session rows producing node-less stubs at branch switches.\n\nNow each lane connects only its own nodes, spanning across the other lane\n[…]\ning\n  interleaving git-ops), interrupts only at session end.\n\nBranch chips now live on the git lane (newest git-op + each switch).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Browser: connect each lane over its own node type",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "49d0916a2fc492fe2d0a3bb1bc34592bbebf3ea7",
          "body": "The node's vertical padding sat outside the rail (which only stretches to the\ncontent box), leaving a dead gap between every row where the connector couldn't\ndraw — so same-lane consecutive events looked disconnected. Move the vertical\npadding onto .body so the rail spans the full row height and adjacent\ntop/bottom segments meet.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Browser: connect lane segments across rows (remove inter-row gap)",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "36018d9a39bc40745989e3ebeab44f8f0094913b",
          "body": "Generalize the timeline graph from a single branch/session pair to one column per\nworkspace = (clone, worktree) — the real unit of concurrency. A single workspace\nrenders exactly as before (branch spine + session overlay); concurrent worktrees,\nand other clones' journals once fetched, fan into paral\n[…]\nad model).\n\nVerified the data layer with a simulated teammate journal (different author) and\na field-less event; audit unaffected.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Browser: lane by workspace (clone, worktree); label clones by author",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b23834087833b21b2414c1614c93d706f7b664c8",
          "body": "Replace the single rail + group headers with two independent vertical lanes,\nmatching how the data actually decomposes:\n\n- Branch lane: a continuous spine (every event is on some branch); breaks only at\n  a branch switch. Git ops are the nodes here.\n- Session lane: drawn only across a session's span\n[…]\nun begins; a small legend labels the lanes. Updated the\nrequirements doc to match (incl. the object viewer + on-demand endpoints).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Browser: two-lane branch/session timeline graph",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7435f22e10be4b8e3ed97f20e6e758e80f008a5e",
          "body": "Make the detail panel interactive without preloading content:\n\n- Clickable SHAs (head, git-op before/after, archived stash) open a slide-over\n  viewer showing `git show` for that commit, with +/-/@@ diff coloring.\n- Clickable changed-files open the per-file unified diff (prev snapshot → this\n  snaps\n[…]\n hex/HEAD; paths passed after `--`).\nreadmodel.EventDetail exposes prevTree for the per-file diff base. Esc / × closes\nthe viewer.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Browser: clickable SHAs/files, on-demand diffs, pretty JSON",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8f515f997cad3fe4e72d4ef3bcecda55f773ce39",
          "body": "Previously the shim recorded only a destructive allow-list (which excluded\n`commit`, so `git commit --amend` produced no event — a destructive op silently\nunrecorded). Now:\n\n- Record every git op except a skip-list of read-only/noisy commands\n  (status/log/diff/rev-parse/…). So commit, amend, branch\n[…]\nudit verifies a\n  changed before_head is still present.\n\nFixes the `commit --amend` gap and makes destructive-op capture lossless.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Record all mutating git ops; preserve rewritten history",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "73f4100c6fa8205ae2239b75559272654d940df7",
          "body": "Replace the bare server-rendered pages with a single-page app — still one Go\nbinary (vanilla JS + CSS embedded via go:embed, no build step).\n\n- Vertical timeline rail: each event is a node on a connected rail, dot-colored\n  by type (session-start/prompt/stop/session-end in cool hues, git ops in ambe\n[…]\n>. readmodel Entry /\nEventDetail / FileChange gain JSON tags for a clean API. Old turn.html/event.html\ntemplate rendering removed.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Rebuild the timeline browser: GitKraken-style SPA",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1724a113499593b78dbf71b6f6fe92a7b4cdfc6c",
          "body": "A stash entry is a separate commit reachable only via refs/stash, not part of the\nworktree — so the shim's worktree snapshot can't preserve it, and a `stash drop`/\n`pop`/`clear` orphans the commit (GC-eligible, lost). When the shim sees a `stash`\nop it now pins the current stack under refs/twip/stas\n[…]\nsh commit keeps its\nindex/untracked parents), kept separate from the journal so they don't introduce\nmerge commits into the chain.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Archive refs/stash entries before a stash op orphans them",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4c7d8d756d302d8dc23fd81237c7d5d1b1f91d0e",
          "body": "…trism\n\nThe read side still treated a session as the addressing key — a leftover from the\nabandoned per-session-ref model. Events are now addressed by their commit id\neverywhere, with session demoted to a pure attribution field:\n\n- readmodel: Turn(session, seq) -> Event(commit); TurnDetail -> EventD\n[…]\nand output (log/show/audit/init) was going to\nstderr and couldn't be piped or captured. Point the root command's output at\nstdout.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Address events by id, not (session, seq): finish removing session-cen…",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ca4127d13f06299b1e6dc50e5cdca93bebbfd5e1",
          "body": "Grouping the log by session was a leftover from the abandoned per-session-ref\nmodel. The journal IS the timeline, so `twip log` now renders every event\n(agent turns and git ops) merged by time, newest first, with the session id as\nan attribution column (\"-\" for session-independent events) rather tha\n[…]\nDetail field (the prompt for a turn, or the git-op argv),\npopulated in Timeline and shown in both `twip log` and the web timeline.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Make `twip log` a flat journal timeline (drop session grouping)",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "add56d325c2263ddecd757ebeba6755c42ff37f9",
          "body": "Git offers only post-op hooks (or none) for worktree-destructive operations, so\na hook can never take the pre-destruction snapshot that matters. A git shim can:\nit snapshots the dirty worktree BEFORE running the real git, then records the op.\n\n- store: GitOpMeta {op, argv, before/after head, exit_co\n[…]\n dirty worktree and asserts twip\npreserved the destroyed content in a pre-op snapshot; plus benign-op and\nnon-enabled-repo no-ops.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v2: capture destructive git operations via a git shim",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "36f49756290244df7950544e2902fbc276b05208",
          "body": "Replace per-session refs (refs/twip/sessions/<session-id>) with one\nappend-only journal per clone (refs/twip/journal/<clone-id>). Attribution\n(kind, session_id, worktree_id, head, branch) moves into meta/event.json as\nfields rather than the ref name, so the journal holds every kind of event —\ninclud\n[…]\ne concurrency test races 4 writers x 10 appends and asserts a linear chain\n  (no merge commits) with no lost or duplicated events.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Refactor storage to a single per-clone journal",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e9350d800764e43fdcee21e36c392af5234b4680",
          "body": "An append-only timeline of repository states across agent sessions.\nCapture unconditionally at event time, derive at read time, never delete:\nan inference bug yields a wrong view over correct immutable facts, not loss.\n\nv1 (Claude Code only; agent-extension seam in place for future agents):\n- Per-se\n[…]\n.\n\nDeferred to v2: git shim/tripwire for destructive ops, refs/stash archiving,\ncross-machine sync, graded commit<->session links.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Initial commit: twip v1 — Claude Code session recorder",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "31bf6d4461ea4147ea6f2f83ed6ca4a818ee5212",
          "body": null,
          "is_bot": false,
          "headline": "Initial commit",
          "author_name": "Dmitry Savvinov",
          "author_login": "dsavvinov",
          "committed_at": "2026-06-11T14:59:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 15,
      "commits_last_year": 70,
      "latest_release_at": "2026-07-17T17:22:46Z",
      "latest_release_tag": "v0.4.7",
      "releases_from_tags": true,
      "days_since_last_push": 4,
      "active_weeks_last_year": 6,
      "days_since_latest_release": 4,
      "mean_days_between_releases": 2.8
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 37,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "github.com/codespeak-dev/twip",
          "exists": true,
          "license": null,
          "keywords": [],
          "ecosystem": "go",
          "matches_repo": true,
          "registry_url": "https://pkg.go.dev/github.com/codespeak-dev/twip",
          "is_deprecated": false,
          "latest_version": "v0.4.7",
          "repository_url": "https://github.com/codespeak-dev/twip",
          "versions_count": 15,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": null,
          "latest_published_at": "2026-07-17T17:22:46Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 4
        }
      ]
    },
    "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
      },
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [
        "go.mod"
      ],
      "largest_source_bytes": 26159,
      "source_files_sampled": 70,
      "oversized_source_files": 0,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "go.mod"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "go"
      ],
      "dependencies": [
        {
          "name": "github.com/spf13/cobra",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.10.2"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 0,
        "merged_prs": 4,
        "open_issues": 0,
        "closed_ratio": 1,
        "closed_issues": 2,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 2,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "EDiasAlberto",
          "commits": 27,
          "avatar_url": "https://avatars.githubusercontent.com/u/64550351?v=4"
        },
        {
          "type": "User",
          "login": "dsavvinov",
          "commits": 26,
          "avatar_url": "https://avatars.githubusercontent.com/u/6999635?v=4"
        },
        {
          "type": "User",
          "login": "aifgi",
          "commits": 16,
          "avatar_url": "https://avatars.githubusercontent.com/u/483793?v=4"
        },
        {
          "type": "User",
          "login": "mike0sv",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/5938179?v=4"
        }
      ],
      "contributors_sampled": 4,
      "top_contributor_share": 0.386
    },
    "quality_signals": {
      "has_ci": false,
      "has_tests": true,
      "ci_workflows": [],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "go.sum"
      ],
      "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": 0,
            "reason": "0 out of 3 merged PRs checked by a CI test -- score normalized to 0",
            "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 1/23 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": null,
            "reason": "no workflows found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 0,
            "reason": "project was created within the last 90 days. Please review its contents carefully",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 10,
            "reason": "all dependencies are pinned",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": null,
            "reason": "No tokens found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 10,
            "reason": "0 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "e95d8567cbfc082b4abfa8f1de1f9815a727717e",
        "ran_at": "2026-07-22T03:06:11Z",
        "aggregate_score": 3,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-17T17:22:35Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": "2026-07-17T14:48:10Z",
      "ci_last_conclusion": null,
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/codespeak-dev/twip",
    "host": "github.com",
    "name": "twip",
    "owner": "codespeak-dev"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "at_risk",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 49,
      "inputs": {
        "security": 30,
        "vitality": 69,
        "community": 24,
        "governance": 67,
        "engineering": 44
      },
      "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": 70,
              "human_commit_share": 1,
              "days_since_last_push": 4,
              "active_weeks_last_year": 6
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 4 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 4
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "6/52 weeks with commits",
                "points": 4.2,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 6
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "70 commits in the last year",
                "points": 16.6,
                "status": "partial",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 70
                    }
                  }
                ],
                "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": 15,
              "latest_release_tag": "v0.4.7",
              "releases_from_tags": true,
              "days_since_latest_release": 4,
              "mean_days_between_releases": 2.8
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "15 version tags (no GitHub releases)",
                "points": 16.2,
                "status": "partial",
                "details": [
                  {
                    "code": "version_tags_no_releases",
                    "params": {
                      "count": 15
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 4 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 4
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~2.8 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 2.8
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "critical",
        "name": "Community & Adoption",
        "value": 24,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (Apache-2.0)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "Apache-2.0"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 67,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "at_risk",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 44,
            "inputs": {
              "bus_factor": 2,
              "contributors_sampled": 4,
              "top_contributor_share": 0.386
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "2 contributor(s) cover half of all commits",
                "points": 25.2,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 39% of commits",
                "points": 13.8,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 39
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "4 contributors",
                "points": 5.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 4
                    }
                  }
                ],
                "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": "excellent",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "merged_prs": 4,
              "open_issues": 0,
              "closed_issues": 2,
              "issue_closed_ratio": 1,
              "closed_unmerged_prs": 0
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "100% of issues closed",
                "points": 46.8,
                "status": "met",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "4/4 decided PRs merged",
                "points": 38.2,
                "status": "met",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 4,
                      "decided": 4
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 1/23 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 51,
            "inputs": {
              "followers": 29,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "codespeak-dev",
              "public_repos": 12,
              "account_age_days": 391
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "29 followers of codespeak-dev",
                "points": 10.6,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 29,
                      "login": "codespeak-dev"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "12 public repos, account ~1 yr old",
                "points": 10.3,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 12
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 1
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "github.com/codespeak-dev/twip"
              ],
              "ecosystems": "go",
              "any_deprecated": false,
              "min_days_since_publish": 4
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on go",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "go"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 4 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 4
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "15 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 15
                    }
                  }
                ],
                "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": "at_risk",
        "name": "Engineering Quality",
        "value": 44,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "critical",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 24,
            "inputs": {
              "has_ci": false,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "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": "0 out of 3 merged PRs checked by a CI test -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "good",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 75,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "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": "at_risk",
        "name": "Security",
        "value": 30,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Dangerous-Workflow, Packaging, Signed-Releases, Token-Permissions. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "dangerous_workflow",
                    "packaging",
                    "signed_releases",
                    "token_permissions"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 30,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 14,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 4,
              "scorecard_aggregate": 3
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "0 out of 3 merged PRs checked by a CI test -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 1/23 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 workflows found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "all dependencies are pinned",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "No tokens found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "0 existing vulnerabilities detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 68,
        "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.9,
              "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": "63 of 70 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 63,
                      "sampled": 70
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "good",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 76,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "go.sum"
              ],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0.5,
              "toolchain_manifests": [
                "go.mod"
              ],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "go.mod (toolchain convention, no task runner)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "toolchain_convention",
                    "params": {
                      "files": "go.mod"
                    }
                  }
                ],
                "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": "Go (statically typed)",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Go"
                    }
                  }
                ],
                "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": "35 of the last 70 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 35,
                      "sampled": 70
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "all dependencies are pinned",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "primary_language": "Go",
              "largest_source_bytes": 26159,
              "source_files_sampled": 70,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Go (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Go"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/70 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 70,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-22T03:06:21.847895Z",
  "schema_version": "0.26.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/c/codespeak-dev/twip.svg",
  "full_name": "codespeak-dev/twip",
  "license_state": "standard",
  "license_spdx": "Apache-2.0"
}

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

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

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