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

tymrtn / U1F4E7

BYO mailbox email client for agents with superpowers.

RustLicencia propia★ 5 estrellas⑂ 2 forksdesde mar 2026Ver en GitHub ↗

tymrtn/U1F4E7 tiene un índice de salud de 52 sobre 100, lo que lo sitúa en la banda Moderado. Su puntuación más alta es Vitality (80/100) y la más baja, Community & Adoption (26/100). Se actualizó por última vez hace 1 día. Una sola persona concentra la mayor parte del trabajo reciente.

52
global / 100
Moderado

Índice de salud del software

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

52
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

Tyler MartinCuenta personal
10 seguidores43 repositorios públicosdesde abr 2013Copyright.sh

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

Métricas por categoría

Vitalidad

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

80Bueno · 22% del índice global
Cómo se puntúa
36/36Recencia de push — último push hace 1 días
9.7/36Cadencia de commits — 14/52 semanas con commits
18/18Volumen de commits — 111 commits en el último año
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10
Datos de entrada utilizados
commits_last_year111
human_commit_share1
days_since_last_push1
active_weeks_last_year14
Cómo se puntúa
27/27Publica versiones — 14 versiones publicadas
36/36Recencia de las versiones — última versión hace 9 días
27/27Cadencia de publicación — una versión cada ~9,1 días
0/10OpenSSF Scorecard: Signed-Releases — Project has not signed or included provenance with any releases.
Datos de entrada utilizados
releases_count14
latest_release_tagv1.0.0
releases_from_tagsno
days_since_latest_release9
mean_days_between_releases9,1

Comunidad y Adopción

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

26Crítico · 18% del índice global
Cómo se puntúa
9.8/60Estrellas — 5 estrellas
0/25Forks — 2 forks
0/15Observadores — 0 observadores
Datos de entrada utilizados
forks2
stars5
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Cómo se puntúa
22.5/22.5README
16.9/22.5Licencia — archivo de licencia presente, no es una licencia reconocida
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?

43En riesgo · 24% del índice global
Cómo se puntúa
9/54Factor bus — la mitad de los commits recae en 1 contribuyente(s)
0/22.5Distribución de commits — el principal contribuyente firma el 100% de los commits
1.4/13.5Amplitud de contribuyentes — 1 contribuyentes
3/10OpenSSF Scorecard: Contributors — project has 1 contributing companies or organizations -- score normalized to 3
Datos de entrada utilizados
bus_factor1
contributors_sampled1
top_contributor_share1
Cómo se puntúa
41.2/46.8Resolución de issues — 88% de issues cerradas
28.7/38.3Aceptación de PR — 24/32 PR decididos fusionados
0/15OpenSSF Scorecard: Code-Review — Found 0/19 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs24
open_issues6
closed_issues45
issue_closed_ratio0,882
closed_unmerged_prs8
Cómo se puntúa
10/30Respaldo de la propiedad — cuenta personal (usuario)
0/20Dominio verificado — no aplicable a cuentas de usuario
7.5/25Alcance del propietario — 10 seguidores de tymrtn
24/25Trayectoria — 43 repos públicos, cuenta de ~13 años
Datos de entrada utilizados
followers10
owner_typeUser
is_verified
owner_logintymrtn
public_repos43
account_age_days4836
Excluidos de la puntuación (sin datos o no aplicable): Dominio verificado. Los pesos restantes se han renormalizado.

Calidad de Ingeniería

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

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

Documentación

65Moderado
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
0/10Wiki
Datos de entrada utilizados
topics
has_wikino
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?

36En 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
2.5/2.5CI-Tests — 8 out of 8 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/19 approved changesets -- score normalized to 0
0.8/2.5Contributors — project has 1 contributing companies or organizations -- score normalized to 3
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.2/2.5Licencia — license file detected
7.5/7.5Maintained — 30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10
0/5Packaging — sin datos
0.5/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 1
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 — Project has not signed or included provenance with any releases.
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
5.2/7.5Vulnerabilities — 3 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate3,6
Excluidos de la puntuación (sin datos o no aplicable): packaging. 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.

79Bueno · 0% del índice global
Cómo se puntúa
45/45Instrucciones para agentes — CLAUDE.md
0/15Documentación legible por máquinas (llms.txt)
40/40Historial de commits legible — 97 de 100 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share0,97
agent_instruction_filesCLAUDE.md
agent_instruction_max_bytes3709
Cómo se puntúa
12.6/18Arranque con un solo comando — Cargo.toml, crates/cli/Cargo.toml, crates/dashboard/Cargo.toml (convención del toolchain, sin ejecutor de tareas)
22/22Pruebas automatizadas
0/11Configuración de lint / formato
11/11Verificación estática de tipos — crates/dashboard/web/tsconfig.json
10/10Entorno reproducible — lockfile
10/10Práctica demostrada con agentes — 44 de los últimos 100 commits con autoría o crédito de agente
0/8Mantenimiento automatizado — no se observan actualizaciones automáticas de dependencias
1/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 1
Datos de entrada utilizados
has_nixno
has_tests
lockfilesCargo.lock, package-lock.json
has_dockerfileno
typed_language
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configscrates/dashboard/web/tsconfig.json
agent_commit_share0,44
toolchain_manifestsCargo.toml, crates/cli/Cargo.toml, crates/dashboard/Cargo.toml, crates/email/Cargo.toml, crates/store/Cargo.toml
dependency_bot_commit_share0
Cómo se puntúa
45/45Código verificable por tipos — Rust (tipado estático)
51.7/55Tamaños de archivo manejables — 10/169 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languageRust
largest_source_bytes126.323
source_files_sampled169
oversized_source_files10

Datos clave

5estrellas de GitHub
1contribuidores
111commits en los últimos 12 meses
1días desde el último push
14versiones publicadas
1factor bus
6issues abiertas
crates.ioecosistemas de paquetes

Advertencias de recopilación de datos

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • Could not fetch crates package 'envelope-email' from its registry
  • Could not fetch crates package 'envelope-email-transport' from its registry
  • Could not fetch crates package 'envelope-email-store' from its registry
  • Could not fetch crates package 'envelope-email-dashboard' from its registry
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Más detalle

Historial de estrellas y forks 0 ★ / 2 ⇿
0Estrellas
2Forks

Cuándo se añadió cada estrella y fork, recopilado de GitHub y agrupado por día. El crecimiento acumulado se sitúa justo encima de las adiciones diarias que lo componen, de modo que ambos se leen en conjunto: la acumulación orgánica sostenida no se parece en nada a un pico abrupto y efímero. Cuando esa diferencia es medible, se informa como autenticidad del crecimiento.

111222212026-052026-052026-05
OpenSSF Scorecard 3.6 / 10
3.6agregado

Evaluación de seguridad independiente y agnóstica en cuanto a herramientas, procedente del proyecto de código abierto OpenSSF Scorecard. Cada comprobación premia una práctica de seguridad, no la herramienta de un proveedor concreto. Las comprobaciones que Scorecard no pudo determinar se marcan como n/d y se excluyen de la puntuación de seguridad (nunca se cuentan como cero).Scorecard v5.5.0 · 2026-07-27 18:56 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
10CI-Tests8 out of 8 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/19 approved changesets -- score normalized to 0
3Contributorsproject has 1 contributing companies or organizations -- score normalized to 3
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
9Licenselicense file detected
10Maintained30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10
n/dPackagingpackaging workflow not detected
1Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 1
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
0Signed-ReleasesProject has not signed or included provenance with any releases.
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
7Vulnerabilities3 existing vulnerabilities detected
Dependencias directas 83
RegistroPaqueteRestricción de versiónManifiesto
crates.ioenvelope-email-storecrates/cli/Cargo.toml
crates.ioenvelope-email-transportcrates/cli/Cargo.toml
crates.ioenvelope-email-dashboardcrates/cli/Cargo.toml
crates.iomail-buildercrates/cli/Cargo.toml
crates.ioclapcrates/cli/Cargo.toml
crates.iotokiocrates/cli/Cargo.toml
crates.iorustlscrates/cli/Cargo.toml
crates.ioserdecrates/cli/Cargo.toml
crates.ioserde_jsoncrates/cli/Cargo.toml
crates.ioanyhowcrates/cli/Cargo.toml
crates.iotracingcrates/cli/Cargo.toml
crates.iotracing-subscribercrates/cli/Cargo.toml
crates.iochronocrates/cli/Cargo.toml
crates.iouuidcrates/cli/Cargo.toml
crates.ioreqwestcrates/cli/Cargo.toml
crates.iourlcrates/cli/Cargo.toml
crates.iofutures-utilcrates/cli/Cargo.toml
crates.ioasync-imapcrates/cli/Cargo.toml
crates.iohickory-resolvercrates/cli/Cargo.toml
crates.iolettrecrates/cli/Cargo.toml
crates.iomime_guess2crates/cli/Cargo.toml
crates.iobase64crates/cli/Cargo.toml
crates.iorpasswordcrates/cli/Cargo.toml
crates.ioenvelope-email-storecrates/dashboard/Cargo.toml
crates.ioenvelope-email-transportcrates/dashboard/Cargo.toml
crates.ioaxumcrates/dashboard/Cargo.toml
crates.iotokiocrates/dashboard/Cargo.toml
crates.iotower-httpcrates/dashboard/Cargo.toml
crates.ioserdecrates/dashboard/Cargo.toml
crates.ioserde_jsoncrates/dashboard/Cargo.toml
crates.ioanyhowcrates/dashboard/Cargo.toml
crates.iotracingcrates/dashboard/Cargo.toml
crates.iochronocrates/dashboard/Cargo.toml
crates.iouuidcrates/dashboard/Cargo.toml
crates.iobase64crates/dashboard/Cargo.toml
crates.iofutures-utilcrates/dashboard/Cargo.toml
crates.ioreqwestcrates/dashboard/Cargo.toml
crates.iorandcrates/dashboard/Cargo.toml
crates.iorust-embed8crates/dashboard/Cargo.toml
crates.iomime_guess2crates/dashboard/Cargo.toml
crates.ioenvelope-email-storecrates/email/Cargo.toml
crates.iotokiocrates/email/Cargo.toml
crates.ioserdecrates/email/Cargo.toml
crates.ioserde_jsoncrates/email/Cargo.toml
crates.ioanyhowcrates/email/Cargo.toml
crates.iothiserrorcrates/email/Cargo.toml
crates.iotracingcrates/email/Cargo.toml
crates.iochronocrates/email/Cargo.toml
crates.iouuidcrates/email/Cargo.toml
crates.ioasync-imapcrates/email/Cargo.toml
crates.ioimap-protocrates/email/Cargo.toml
crates.iolettrecrates/email/Cargo.toml
crates.iomail-parsercrates/email/Cargo.toml
crates.iomail-buildercrates/email/Cargo.toml
crates.ioregex1crates/email/Cargo.toml
crates.iobase64crates/email/Cargo.toml
crates.iosha2crates/email/Cargo.toml
crates.iozip2crates/email/Cargo.toml
crates.ioreqwestcrates/email/Cargo.toml
crates.iourlcrates/email/Cargo.toml
crates.iohickory-resolvercrates/email/Cargo.toml
crates.iorustlscrates/email/Cargo.toml
crates.iotokio-rustlscrates/email/Cargo.toml
crates.iowebpki-rootscrates/email/Cargo.toml
crates.iofutures-utilcrates/email/Cargo.toml
crates.iorusqlitecrates/store/Cargo.toml
crates.iorusqlite_migration1.3crates/store/Cargo.toml
crates.ioserdecrates/store/Cargo.toml
crates.ioserde_jsoncrates/store/Cargo.toml
crates.ioanyhowcrates/store/Cargo.toml
crates.iothiserrorcrates/store/Cargo.toml
crates.iotracingcrates/store/Cargo.toml
crates.iouuidcrates/store/Cargo.toml
crates.iochronocrates/store/Cargo.toml
crates.ioaes-gcmcrates/store/Cargo.toml
crates.ioargon2crates/store/Cargo.toml
crates.iosha2crates/store/Cargo.toml
crates.iorandcrates/store/Cargo.toml
crates.iobase64crates/store/Cargo.toml
crates.iokeyring3crates/store/Cargo.toml
crates.iodirs-nextcrates/store/Cargo.toml
crates.iohostname0.4crates/store/Cargo.toml
crates.iowhoami1crates/store/Cargo.toml
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": 2097,
      "has_wiki": false,
      "homepage": null,
      "languages": {
        "CSS": 2536,
        "HTML": 1656,
        "Rust": 2532109,
        "Shell": 11723,
        "Svelte": 210343,
        "JavaScript": 3320,
        "TypeScript": 153187
      },
      "pushed_at": "2026-07-26T07:22:46Z",
      "created_at": "2026-03-18T17:52:15Z",
      "owner_type": "User",
      "updated_at": "2026-07-18T01:37:14Z",
      "description": "BYO mailbox email client for agents with superpowers.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": null,
      "default_branch": "main",
      "license_spdx_raw": "NOASSERTION",
      "primary_language": "Rust",
      "significant_languages": [
        "Rust"
      ]
    },
    "owner": {
      "blog": "copyright.sh",
      "name": "Tyler Martin",
      "type": "User",
      "login": "tymrtn",
      "company": "Copyright.sh",
      "location": "Spain",
      "followers": 10,
      "avatar_url": "https://avatars.githubusercontent.com/u/4305058?v=4",
      "created_at": "2013-04-30T17:23:15Z",
      "is_verified": null,
      "public_repos": 43,
      "account_age_days": 4836
    },
    "license": {
      "state": "custom",
      "spdx_id": null,
      "raw_spdx": "NOASSERTION",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v1.0.0",
          "kind": "major",
          "published_at": "2026-07-18T06:41:46Z"
        },
        {
          "tag": "v0.13.1",
          "kind": "patch",
          "published_at": "2026-07-17T06:28:06Z"
        },
        {
          "tag": "v0.12.0",
          "kind": "minor",
          "published_at": "2026-07-02T22:45:58Z"
        },
        {
          "tag": "v0.11.7",
          "kind": "patch",
          "published_at": "2026-07-02T17:19:21Z"
        },
        {
          "tag": "v0.11.6",
          "kind": "patch",
          "published_at": "2026-07-02T00:00:45Z"
        },
        {
          "tag": "v0.11.0",
          "kind": "minor",
          "published_at": "2026-06-17T18:40:11Z"
        },
        {
          "tag": "v0.10.2",
          "kind": "patch",
          "published_at": "2026-06-02T15:16:23Z"
        },
        {
          "tag": "v0.10.1",
          "kind": "patch",
          "published_at": "2026-06-02T10:47:32Z"
        },
        {
          "tag": "v0.10.0",
          "kind": "minor",
          "published_at": "2026-05-30T10:33:39Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2026-04-27T18:31:38Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2026-04-21T08:38:14Z"
        },
        {
          "tag": "v0.4.1",
          "kind": "patch",
          "published_at": "2026-04-19T17:28:03Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-04-14T15:25:48Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-04-09T18:34:09Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "be98752bd247b356c8639757ab888f633975a5da",
          "body": "Envelope v2 → 1.0.0: agent fleet, webmail cutover, send-safety hardening",
          "is_bot": false,
          "headline": "Merge pull request #84 from tymrtn/feat/v2",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-07-18T01:37:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7df578e9dd02798ca6f921b936483573d426ae47",
          "body": "Root cause of the Linux CI failure: web/tsconfig.json extends\n`./.svelte-kit/tsconfig.json`, which `svelte-kit sync` generates. The web CI job\nruns `npm test` before `npm run build`, so `.svelte-kit/` didn't exist yet and\nrolldown (vite 8's bundler) failed to load the tsconfig — surfacing as the\nmis\n[…]\nt — it was\nchasing the symptom. Verified 111/111 in a fresh node:22 Linux container (npm ci\n+ npm test) reproducing the CI environment exactly.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci(web): run `svelte-kit sync` before vitest so the tsconfig resolves",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-18T01:31:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b62c9b7396325920e5d68768ae0509fdd966d1a6",
          "body": "…ndling node:module\n\nVitest 4 renamed the deps.optimizer 'client' key to 'web', so the existing\nworkaround was a silent no-op. On Linux CI the optimization pass tried to bundle\nrolldown/runtime.js's 'node:module' import as web code and crashed at startup\n(passed on macOS where optimization succeeds). Disable web+ssr dep optimization\nfor the test run. Frontend vitest 111/111 locally on cold cache.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci(web): fix vitest dep-optimizer key (client->web) so Linux stops bu…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-18T01:18:08Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f78270d5f4fa3132d6142f34f847a17608b6fbb9",
          "body": "First CI run on the branch surfaced three environment/test-isolation failures\n(none in product code):\n\n- Test isolation across platforms. CLI integration tests overrode only HOME,\n  which isolates config on macOS (Application Support) but NOT on Linux, where\n  dirs_next::config_dir() honors XDG_CONF\n[…]\n test\n--workspace 1063 passed / 0 failed; all CLI integration suites pass under\nENVELOPE_HOME isolation; frontend vitest 111/111 on cold cache.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: green the pipeline — test isolation, smoke assertion, Node 22",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-18T01:07:41Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6e27b6e88193a48aae04f32dc6d2bd795ceacc83",
          "body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(changelog): note drafts-land-in-IMAP fix under 1.0.0",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-15T06:36:39Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "284925e0261a8c798802fe6e375ad89932d9604e",
          "body": "Draft create/reply/forward previously appended to the IMAP Drafts folder only\nbest-effort: any failure (no IMAP host, connect error, folder-detection miss, or\nthe APPEND itself) was swallowed with a warning and the draft was persisted as a\nlocal-only SQLite record — invisible to Mail.app and every o\n[…]\ner rely on the removed local-only path).\n\nGate: fmt clean; clippy 0 errors; check-orphans clean; cargo test --workspace\n1063 passed / 0 failed.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(drafts): drafts always land in the real IMAP Drafts folder",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-15T05:05:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "581d70ab0f4302eb12a0f9d6ec2cbf39824d9661",
          "body": "Two parallel v2 lineages shared Waves 0-4 and diverged after Wave 3. This folds\ncodex/v0.13-release-hardening's unique hardening into feat/v2, keeping this\nbranch's cutover, IPv6 SSRF fix, and 1.0.0 framing.\n\nBrought in from codex/v0.13:\n- secret_input.rs: account passwords and license keys via hidd\n[…]\nlean; clippy 0 errors; check-orphans clean; cargo test --workspace\n1061 passed / 0 failed (incl. merged CLI hardening tests); frontend 111/111.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "merge: reconcile codex/v0.13 send-safety hardening into feat/v2 (1.0.0)",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-13T00:27:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1e87c395d48ac5f73d65effd04789d5425a07a97",
          "body": "First public release. Version drives the tag-triggered release workflow and the\nCHANGELOG 1.0.0 entry.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(release): bump workspace version to 1.0.0",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-12T04:38:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c9847687083200706974bea6fab78eff3150df6b",
          "body": "W5. The SvelteKit webmail (v2) now serves at the site root and IS the dashboard.\nThe old read-mostly v1 static dashboard is deleted.\n\n- Frontend rebuilt with paths.base='' (root) instead of '/v2'; assets now\n  resolve at /_app/... and the committed web/build/ bundle is regenerated.\n- Router: `/` ser\n[…]\n-workspace 0 failed (20 suites);\ncheck-orphans clean; root render browser-verified (SPA shell, /_app assets,\n/cockpit fallback, /api JSON 404).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(v2)!: cutover — v2 webmail is the dashboard, remove v1",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-12T04:34:21Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "880532444d3efe225a73203c0659df7787ea6813",
          "body": null,
          "is_bot": false,
          "headline": "fix(release): harden 0.13.1",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-12T03:56:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6f91ab9be91eeb212dbac61ee3a6b38655f4af63",
          "body": "L15 (draft): CHANGELOG 1.0.0 entry covering the v2 arc — multi-agent identity,\nwebmail dashboard, bulk ops, durable webhooks, SSE, Linux support, passphrase\ncreds, and the three security items (MCP trust boundary, dashboard CSRF, webhook\nSSRF guard).\n\nL12: reconciled Show HN + r/selfhosted drafts — \n[…]\ncy clamp,\nattributed approve, actions tail, license gate, watch stream, VPS curl-install,\nwebmail), all commands verified against the CLI tree.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(v2): 1.0.0 changelog, reconciled launch posts, demo shot list",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-11T20:18:42Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6beb33915c6aa2d51952f4533d6d8530a9e827c3",
          "body": "… targets\n\nAdversarial review of wave 4 found a HIGH: check_ipv6_ssrf only tested\nloopback/unspecified/ULA/link-local segment masks, so a blocked IPv4 target\nsmuggled through an IPv6 literal (e.g. http://[::ffff:169.254.169.254]/) passed\nthe guard. On a dual-stack host that routes mapped v6 to v4, t\n[…]\nfied checks. Regression tests cover mapped metadata/\nloopback/RFC1918, compatible-form metadata, and a public mapped address staying\npermitted.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(security): SSRF guard rejects IPv4-mapped/compatible IPv6 webhook…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-11T20:18:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "85444360d76d529f424407c9ee4ab9dfcf2333dc",
          "body": "…boarding\n\nDemo surfaces + onboarding for the agent-fleet launch narrative.\n\nW3d composer: reply/forward, send-later (send_after), undo-send (now+10s +\ndiscard), drafts stamped created_by=\"human:<identity>\". Send paths stay\nGovernor-gated and respect the send-mode ceiling.\n\nW3e cockpit (the headline\n[…]\n--check clean; clippy 0 errors; release build ok;\ncargo test --workspace 273+ passing / 0 failed; check-orphans clean;\nfrontend vitest 111/111.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(v2): wave 4 — cockpit attribution, composer, rules authoring, on…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-11T20:11:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5af1c1e5c9b039c5cda0b9284ca5d5ed8b11e572",
          "body": "… safety (t_bb6f8ff1)\n\nPackage the complete v2 working state from feat/v2 HEAD 53347ab as one\ncoherent release candidate, reconstructed byte-for-byte from the verified\nt_a4231f3d backup (tracked patch SHA256-matched; untracked files cmp-verified).\n\nOutbound send safety (task t_bb6f8ff1): UTC/RFC3339\n[…]\ng failure\n(parse_action_webhook_rejects_link_local_metadata); web 111 passed.\nClippy: 0 errors (baseline-aware; 2 new stylistic warnings noted).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(release): 0.13.0 release candidate — coherent v2 + outbound send…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-11T04:35:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "53347abf9a901e4656fb4b6403f352f94eea2efd",
          "body": "… SSE, license persistence\n\n- bulk operations: crates/email/bulk.rs — Uids/Search targets (cap 500,\n  checked post-resolution), move/copy/flag/delete/tag with partial-\n  failure isolation (batched chunks retry per-UID), dry-run, range\n  coalescing. envelope bulk CLI (delete without --confirm runs as\n[…]\nsarial review: no\ncritical/high; medium EXPUNGE finding fixed pre-commit; SSRF\nroute-guard + legacy-unsigned-route warning queued as hardening.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(v2): wave 3 — bulk ops, durable event push, webmail list+reader,…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-09T08:26:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2ffd5d94df39b5e09f435d95851fb728fd7a39ec",
          "body": "…l, release pipeline\n\n- MCP agent context: ENVELOPE_AGENT_TOKEN resolves a stored identity at\n  startup (unknown/revoked token fails loud, never anonymous fallback);\n  every tool call is authorized pre-dispatch via an explicit tool→action\n  map (unknown tools deny); send/reply/send_draft all clamp t\n[…]\nerified in rust:latest container (3m59s, exit 0). Adversarial\nreview: ship after F1 send_draft ceiling fix (verified by 2 new\nmcp_stdio tests).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(v2): wave 2 — MCP agent identity enforcement, wired webmail shel…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-09T07:16:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c0d0ea72a450f32d3dd07a8876fec5b2dcb993da",
          "body": "…rase creds, SvelteKit shell\n\n- store migration 9: agent_identities (envtok_ tokens stored as SHA-256\n  hash + display prefix only, raw shown once at create) and\n  agent_policies (allowed accounts/folders/actions, send_mode_ceiling,\n  allow_recipients); additive nullable agent_id on action_log + eve\n[…]\nrors), release build, 871\nworkspace tests + 7 frontend tests green. Adversarial review: ship\n(no blockers; follow-ups noted for wave 2 wiring).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(v2): wave 1 foundations — agent identities, agent policy, passph…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-09T06:34:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6340c4a917944a343cc3bd527eafec6c975ad42f",
          "body": "… keyring backend\n\n- MCP transport wraps external email content (read/inbox/search) in an\n  untrusted-content envelope: {_envelope_trust, _warning, content} so\n  agents treat message bodies as data, never instructions. CLI --json\n  stays byte-identical; contract gains additive trust_model block\n  (s\n[…]\nseline), release\nbuild, 832 workspace tests green. Adversarial review: ship (no\nblockers). Linux store crate verified in rust:latest container.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(security): v2 wave 0 — MCP trust boundary, dashboard CSRF, Linux…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-09T06:07:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5a02033537aa8b29c443d4a4efdcee4bef07f10b",
          "body": null,
          "is_bot": false,
          "headline": "Open draft links in composer",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-06T23:02:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f5fb2b5be56be958525395f639374ed1b43c3441",
          "body": null,
          "is_bot": false,
          "headline": "Fix dashboard draft message deep links",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-06T22:13:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4fdf7812449fab69afcd7c604d04fc6e75cc925c",
          "body": null,
          "is_bot": false,
          "headline": "fix: serialize client sent copy From headers (#82)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-07-04T22:36:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "00d9f77930a80a27120ab007eb0518362df131af",
          "body": null,
          "is_bot": false,
          "headline": "fix: close sent-copy source QA gaps (#80)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-07-04T22:02:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e33b53df98c1a33c0e0f38415aea939e560e3cf9",
          "body": null,
          "is_bot": false,
          "headline": "fix: label provider and client sent copies (#78)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-07-04T18:20:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0978f4910d0db22177f07d898784e0dc231b484b",
          "body": null,
          "is_bot": false,
          "headline": "fix: preserve sent and draft proof for custom folders (#76)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-07-04T16:41:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "444bdf46eec7838afa82a116b909fc0f53d2842f",
          "body": "Build the default From mailbox through lettre::Mailbox instead of hand-concatenating a header string, so account display names are quoted/encoded safely.\n\nWhen display_name is missing or blank, fall back to account.name if it is non-empty and not the account email address itself. Keep explicit from_\n[…]\nage for display_name priority, account-name fallback, redundant email-name suppression, blank display_name fallback, and comma-bearing names.\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(smtp): fall back to account name for From header (#75)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-07-04T16:09:20Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "62e9daaead9a36bca6893a9f6ee7c0a318c0e847",
          "body": "AUDIT-RESULTS.md (Mar 2026 Rust-migration audit), docs/ORPHANS-AUDIT.md, and\ndocs/agent-cockpit-backend-followups.md were internal working notes referencing\nlong-resolved v0.3.0-era state — agent-audience, not user-facing. Preserved in\nthe internal working tree; the public repo now ships only user/dev docs.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: remove internal audit/TODO docs from the public repo",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-02T22:21:05Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2fe70a6fc64a4dde55d6f8d86fbe6bdc4a185cd8",
          "body": "…e (0.12.0)\n\nThe dashboard REST API reads/deletes mail, manages accounts, and queues sends.\nIt bound 127.0.0.1 but had zero authentication, so a `tailscale serve` front-end\n(or any non-loopback bind) exposed the whole mailbox surface to every reachable\ndevice. This adds fail-closed auth without chan\n[…]\nfirst (tailnet identity, no\ntoken to type). 19 new tests; contract surface unchanged. Adversarial security\nreview found no bypass or token leak.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(dashboard): authenticate the API before any non-loopback exposur…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-07-02T22:20:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6b8d431d89f71421d2677033703abcfffb68b188",
          "body": null,
          "is_bot": false,
          "headline": "fix: open dashboard draft review deep links (#72)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-07-02T17:19:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4dda6b4c0ff3005d092ccb14c9b9d29b3c6c7f15",
          "body": "* chore: local envelope 0.10.4 release snapshot\n\n* release: envelope 0.11.0 agent runtime fixes\n\n* feat: tackle remaining envelope runtime issues\n\n* feat: gate outbound mail through Governor attribution\n\n* ci: align Governor guard with attribution gate",
          "is_bot": false,
          "headline": "Gate outbound mail through Governor attribution (#70)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-07-01T23:56:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cde39b75488537c009749d8699a9fba3b84c408d",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(release): bump to 0.10.2",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-06-02T15:16:20Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f8de0fddb8827a76ccda9d85c2fb67c2ff005d83",
          "body": "Clicking a message in any Drafts folder ([Gmail]/Drafts, Drafts, etc.)\nnow opens it in the composer pre-filled with To/Subject/body, matching\nGmail's own behaviour. The read-only reader made no sense for draft\ncontent.\n\nUses existing folderMatchesSmart('drafts') which normalises [Gmail]/\nprefixes, s\n[…]\ners.\n\nNote: the original IMAP draft is not auto-deleted — user handles that\nmanually or via a rule. A toast explains this on open.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(dashboard): open Drafts folder messages in composer, not reader",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-06-02T15:10:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c9f6e026c1b04e47e2ba2907c6876eba655c2173",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(release): bump to 0.10.1",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-06-02T10:47:29Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c34b5b523fa5632b52aa63f236e97f401123f6a0",
          "body": "The naive `find(\"?=\")` search in remaining[2..] misfired on Q-encoded\nsubjects whose encoded text begins with `=XX` (multibyte UTF-8 sequences,\naccented characters, emoji): the `?` separator between the encoding type\nand the text, followed by the leading `=` of `=XX`, forms a spurious `?=`\nthat was \n[…]\n and `=C3=89` (É)\n- B-encoded subject containing base64 padding `=`\n- Uppercase `UTF-8?Q` labels (already worked, now confirmed)\n\nCo-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(email): decode RFC 2047 MIME encoded-word subjects correctly",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-06-02T10:08:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4ab3faaf6415dcb01bda65bd8654835e4dba1af3",
          "body": "list_failed_auth() was returning all-time failures with no time window,\ncausing the dashboard to permanently flip accounts to UNAVAILABLE whenever\ncockpit.auth.items was non-empty — even from verify failures days/weeks ago.\nAdds a 4-hour recency filter (datetime('now', '-4 hours')) so only current\na\n[…]\n the table for audit.\nIncludes a regression test verifying that a 5-hour-old row is excluded and a\njust-written row is included.\n\nCo-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(dashboard): bound failed_auth classification to recent failures only",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-06-02T10:05:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "db1e663f4ca29cfef62ac757d45ff18d3383b013",
          "body": "Wire visibilitychange listener to restart the auto-refresh timer when\na hidden tab regains focus. The scheduleAutoRefresh loop (90s unified,\n120s per-account), cancelAutoRefresh on active search, and the\nselectUnifiedInbox/selectAccount schedule calls were already in place;\nthis adds the missing tab-visibility restart in wireEvents.\n\nCo-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(dashboard): add background auto-refresh (90s, visibility-gated)",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-06-02T10:05:05Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6f28c48d5a77fbdc60f7d4b72d252b7c33364854",
          "body": "Add count_active_drafts() to the store with a SQL query scoped to\nstatus IN ('draft', 'pending_review'), excluding sent/discarded\nhistorical rows. Expose the count via /stats so the dashboard stat\ntile shows actionable drafts only, not the 409-total-ever count.\n\nCo-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(dashboard): count only active drafts in stat tile",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-06-02T10:05:02Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b08c32f31fbc7c5c1388e748b26408f951b9f4e5",
          "body": "…uth failures\n\nStale accounts have an outdated cache but working credentials; the right\naction is to reload folders and messages via selectAccount(), not to run\nthe /verify credential probe. Split renderAccountHealthPanel so stale\nstatus renders a Refresh button (calls selectAccount) while auth_failed,\nunavailable, and reconnecting statuses continue to render Reconnect\n(calls POST /accounts/{id}/verify).\n\nCo-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(dashboard): show Refresh for stale accounts, Reconnect only for a…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-06-02T10:04:04Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "de5069f0a7afb4bbc30ed2721094f3a48c2d32fa",
          "body": "…box rows\n\nHide the account-scope chip by default in unified inbox message rows and\nreveal it only on row hover. At scale (50+ messages) this eliminates the\npersistent `email · INBOX` label clutter without removing discoverability.\nRow height and per-account view are unaffected.\n\nCo-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(dashboard): reduce account-scope label visual noise in unified in…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-06-02T10:03:49Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "fd6c238cac1805853ad162e889880ba7dec95cdc",
          "body": "Add id=\"reader-meta\" to the .reader-meta div and toggle hidden class in\nrenderReaderEmpty/renderReader so From/To/Date/State labels are not\nvisible when no message is selected.\n\nCo-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(dashboard): hide reader meta rows in empty state",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-06-02T10:01:54Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1887ebe764e0bf0442e9dabd830cb93a1338d60f",
          "body": "The marketing site is deployed via Netlify CLI from the parent working\ndirectory (envelope-email/u1f4e7.com/), not from the code repo. Having a\nsecond copy committed here creates drift risk and violates the \"no\nduplicate code\" principle — the repo is the product surface, the site is\na sibling deployed independently.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: remove duplicate u1f4e7.com site from product repo",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-06-01T15:35:14Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9661c0306b539c47c2e3762a5276469fb489d707",
          "body": "Adversarial review caught that the shift-click range anchor was a raw\nindex into renderedMessageKeys, which drifts when the list re-sorts or a\nbackground poll prepends a message — a later shift-click would then select\nthe wrong range. Store the anchor as a message key (matching the j/k focus\npath) a\n[…]\nngle repaint.\n\nVerified in-browser: anchor survives a forced re-render and shift-click\nstill selects the correct contiguous range.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(dashboard): store shift-select anchor as message key, not raw index",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-05-30T10:26:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ee75cec80a6c7640e7ce1e266a5032dde6e9c4b2",
          "body": "Documents the fully-baked dashboard interaction model: contextual\naffordances, wired star/reconnect/bulk, the Gmail keyboard + multi-select\nlayer, reader autosize, and the reply/bulk-status polish. Aggregate-cockpit\nread-only invariant explicitly preserved in the notes.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(release): bump workspace to 0.10.0 + CHANGELOG/README",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-05-30T10:21:48Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c970f8929ea2a35ba611f40980719d6aff674b59",
          "body": "…tosize + polish\n\nPhase 2 Gmail-parity layer plus the open QA polish items, all verified\nin-browser against a real cached-message dataset on the dev instance.\n\nKeyboard shortcuts (vanilla keydown, suppressed while typing / in modals):\n- j/k focus nav, Enter/o open, x select, s star, e archive, # del\n[…]\ns added for the keyboard layer, shift-select/focus nav,\nreader autosize (with allow-scripts tripwire), and bulk-status auto-clear.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(dashboard): Gmail-parity keyboard layer, multi-select, reader au…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-05-29T20:14:33Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fdb84119d6ec1097d5bdcec68b4ed53e795aac38",
          "body": null,
          "is_bot": false,
          "headline": "fix(dashboard): close PR 60 review blockers",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-05-27T16:45:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dee16230256f60012ab4dbb8efa80714bf1df280",
          "body": null,
          "is_bot": false,
          "headline": "fix: harden dashboard freshness and rendering safety",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-05-27T16:15:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5411762d5b5d55afde670c2e599e99efb6b766e2",
          "body": "…st count\n\nFound during the Phase 3 visual QA sweep: clicking a smart mailbox\n(Needs Attention, Snoozed when no account selected, Sent/Drafts/All\nMail when no account selected) routed to renderMailboxNotice() which\nwas setting #list-count.textContent to the `kind` argument\n(`'pending'`, `'not_availa\n[…]\nhey don't render as warning-red.\n\nVerified live at :3142 — smart mailbox notices now have an empty\ncount cell and a clean neutral notice below.\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(dashboard): renderMailboxNotice no longer leaks `pending` into li…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-05-24T09:12:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "963c134e627035a8d0c10273d6893670313907a3",
          "body": "User found multiple UX failures on the live dashboard after the Phase 1\ncontextual-affordance pass landed. Root causes were:\n- All accounts in 'cache missing' state were misclassified as\n  'unavailable' (a failure), so the new Reconnect-gated logic still\n  rendered Reconnect on every row.\n- \"All acc\n[…]\nproduction DB. Empty cache state shows a single CTA; per-\naccount inbox shows full subjects + dates; HEALTHY accounts have no\nReconnect button.\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(dashboard): cache_missing UX + message row layout (visual sweep)",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-05-23T09:50:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ee84c14971ed827c3fa98f313263368b5785a9d2",
          "body": "Phase 1.3 + partial 1.4 of the \"fully baked\" plan. Loops the existing\nper-message DELETE and POST /move endpoints client-side with bounded\nconcurrency (4 in-flight). Move / Label / Spam stay honestly stubbed\nuntil their folder-picker / keyword input / spam-rule UIs ship.\n\nNew helpers:\n- `runBulkOp({\n[…]\ntor-friendly \"arriving in v0.10.0\" toast (Phase 1a copy).\nThese need a folder picker / keyword input / spam-rule UI to wire\nhonestly; deferred.\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(dashboard): wire bulk delete + bulk archive via existing endpoints",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-05-23T09:25:37Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "69852df7052de28c7e6730ba315fc0ceb9536b6a",
          "body": "Phase 1.2 + 1.7 of the \"fully baked\" plan. Both interactions move from\nlocal-only stubs to actually mutating server state via existing\nper-message and per-account endpoints (no new routes needed).\n\nStar (msg-star button):\n- Click POSTs `/api/accounts/{id}/messages/{uid}/flags` with\n  add/remove `[\"\\\n[…]\neriveAccountHealth` (the\nrender path) doesn't contain `/verify`. The reconnect onclick handler\nis allowed to call it; first-paint render isn't.\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(dashboard): wire star → IMAP \\Flagged and Reconnect → /verify",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-05-23T09:23:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8fc6660f14c4aa0810bcd179803fcb531bc1a1b5",
          "body": "Phase 1b of the \"dashboard fully baked\" plan. Addresses the specific\ncomplaint: \"giant reconnect buttons when it's healthy\" — and \"click\nreconnect just gets not_available: reconnect flow is not wired yet\".\n\nThe Reconnect button now only renders when the account is in a state\nthat actually needs oper\n[…]\ne\n  contract; adds a regression guard requiring HEALTH_NEEDS_ACTION\n  gating so the button can't slip back to being rendered\n  unconditionally.\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(dashboard): gate Reconnect button on actual unhealthy status",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-05-23T09:18:44Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "93def0daebba1bd61985546e72829901d588bc48",
          "body": "…scriptions, hide bulk toolbar with no selection\n\nPhase 1a + 1c of the \"dashboard fully baked\" plan (plan:\n~/.claude/plans/toasty-meandering-lantern.md). Addresses Tyler's\n\"giant reconnect buttons when it's healthy / not_available: not wired\nyet LAME\" feedback.\n\nDesign principle: every visible contr\n[…]\n27.0.0.1:3142/ via Claude-in-Chrome read_page:\nno leaked architectural labels on smart mailbox buttons; bulk toolbar\nabsent with zero messages.\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(dashboard): contextual affordances pass — strip leaked status de…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-05-23T08:50:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ed28e0eea7a8819f4f49a513b47b326c811ed507",
          "body": "…start, ops primitives\n\nConsolidates ~15k lines of v0.9.0 work that was sitting uncommitted in the\nworking tree. CHANGELOG already documents this as v0.9.0 (dated 2026-05-20)\nbut no commit, tag, or release exists. The running Tailscale dashboard is\nbuilt from this code; without this commit, the enti\n[…]\ngate read-only, send safety,\n  evidence export, quickstart, keychain import\n\nTested: cargo build, cargo test --workspace (299 + doctests pass).\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(v0.9.0): catchup dashboard shell, agent cockpit, contract, quick…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-05-23T08:41:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0ff3d92152712e716a9a8e721ceeb6242438f3e1",
          "body": "Fixes #51.",
          "is_bot": false,
          "headline": "fix(thread): scope UID cache lookup by account (#52)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-05-15T07:38:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "28d3cd53d9785522a3928d8570ac5c58495c2f3f",
          "body": null,
          "is_bot": false,
          "headline": "feat: return dashboard review URLs for drafts (#44)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-05-11T21:54:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "03e574ccaf47c71acf889853f5e6b3fd9e71240d",
          "body": null,
          "is_bot": false,
          "headline": "feat: add dashboard draft deep links (#43)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-05-11T21:38:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "701f16463281ac64c55bdc494e88445962f2eec2",
          "body": null,
          "is_bot": false,
          "headline": "docs: add BYO email landing pages (#41)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-05-11T21:17:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4e92128b3d0d90762cabb3e8bc1af030888c7ebb",
          "body": "* fix(imap): drain server greeting before login\n\n* feat: add deliverability DNS posture check",
          "is_bot": false,
          "headline": "feat: add deliverability DNS posture check (#40)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-05-11T21:16:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "66e3374a6ea3fa082eb7c2f12dbecc62a790849d",
          "body": null,
          "is_bot": false,
          "headline": "fix: avoid full body fetches during rule runs (#42)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-05-11T21:16:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "02e7e11ac43a364b096cc7f4f97f75a4b83b1ae7",
          "body": "Default backup exports to Envelope app-data archives.\\n\\nVerified:\\n- cargo fmt --check\\n- cargo test -p envelope-email backup -- --nocapture\\n- cargo test -p envelope-email -- --nocapture\\n- GitHub Build and test\\n- Governor re-intro guard",
          "is_bot": false,
          "headline": "fix(backup): default exports to app-data archives (#32)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-05-05T16:45:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1471a0e0cc1b7829310c98a1dda4f2046beb1496",
          "body": "…(#19) (#26)\n\nRestore idempotency previously depended on either the NDJSON sidecar or\ndestination Message-ID duplicate detection. Messages with message_id=null\nhad no fallback: a crash after APPEND but before the sidecar write would\nsilently duplicate the message on rerun.\n\nIntroduce a write-ahead p\n[…]\ng\n  silently swallowed.\n\nHash/Eq on RestoreStateRecord excludes the status field so both phases\nresolve to the same HashSet entry.\n\nCo-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(backup): make restore idempotent for messages without Message-ID …",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-05-05T10:13:15Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "99f42839b1b32a650b51ac17241d6b7eb6725871",
          "body": "Implements issue #11 evidence collect/verify workflow.\\n\\n- Adds read-only evidence collection with raw .eml preservation\\n- Adds manifest/index/checksum bundle outputs and verifier\\n- Adds bounded header-based thread expansion\\n- Adds traversal/symlink/strict verification tests\\n- Documents evidence bundle caveats and project invariants\\n\\nVerified with cargo fmt --check, cargo test --workspace, Claude final review, and GitHub CI.",
          "is_bot": false,
          "headline": "feat: add evidence-grade mailbox export",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-05-05T09:52:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a75eb57556c74eee95ada7d7e3f5488e034bcef2",
          "body": "Preflights migration state writes and makes post-APPEND state failures fatal/machine-readable. Fixes #8.",
          "is_bot": false,
          "headline": "fix(migrate): harden state write failures (#16)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-05-05T08:33:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1da074aa1249377d44f38a2fdd08355c95293a17",
          "body": "Uses EXAMINE for source-side migrate folder access. Fixes #9.",
          "is_bot": false,
          "headline": "fix(migrate): examine source folders read-only (#15)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-05-05T08:32:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "710d6facc511cf2f54dbdbe31a55d5aca16b55fd",
          "body": "Adds same-account and same-physical-mailbox restore guards. Fixes #7.",
          "is_bot": false,
          "headline": "fix(backup): reject same-source restores (#14)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-05-05T08:32:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "426a87a224065555fa3127cf2df5c95fee9f48e3",
          "body": "Verifies backup archive bytes before dry-run restore plans. Fixes #10.",
          "is_bot": false,
          "headline": "fix(backup): verify archives during restore dry-run (#13)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-05-05T08:04:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "60b4111d2794bd2f8d4841c0a7b885e218f84f24",
          "body": "Adds paths/doctor diagnostics for effective Envelope app-data, DB, and credential paths. Fixes #6.",
          "is_bot": false,
          "headline": "fix(cli): expose Envelope state paths (#12)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-05-05T07:57:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5c4774e8d596c14de7c8bc8af535618b94685158",
          "body": "* [verified] Add OTP event runtime\n\n* chore: remove unused dashboard import\n\n* fix(imap): quote mailbox names for UID COPY\n\nQuote destination mailboxes before calling async-imap uid_copy so folders with spaces, such as WorkMail's Junk E-mail, are sent as valid IMAP quoted strings.\n\nCloses #1\n\n* feat: add safe IMAP migration and rules dashboard\n\n* feat: add staged mailbox backup restore",
          "is_bot": false,
          "headline": "feat: add staged mailbox backup restore (#5)",
          "author_name": "Tyler Martin",
          "author_login": "tymrtn",
          "committed_at": "2026-05-04T08:34:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ec73fad31bb44f22843547209f3306f17be41981",
          "body": "Add MCP server section, IMAP IDLE, verification code extraction,\nscheduled send, contacts, and webhook actions to quick start,\ncomparison tables, and CLI reference. Update test count to 194.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: update README for v0.5.0 features",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-21T08:43:02Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "df102ebcf82a50d0b2a1f97b6001ff466171bc74",
          "body": "IMAP IDLE push (envelope watch), verification code extraction\n(envelope code), MCP stdio server (envelope mcp), scheduled send\n(--at), contacts with rules integration, webhook rule actions,\nand SQLite schema migrations via rusqlite_migration.\n\n194 tests, 0 failures. Codex QA review: 4 findings fixed (timezone\nconsistency, migration bootstrap, MCP tool parity, scheduled send\nattachment guard).\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: v0.5.0 — agent infrastructure release",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-19T22:24:02Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1490b509b2844ee4a86c399a99ea773128a6ffd6",
          "body": null,
          "is_bot": false,
          "headline": "remove internal agent instructions from public repo",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-19T18:47:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c7edeee5639f5f5efbe5eb20e2e629ab0fd14e42",
          "body": "…Cloudflare, Resend), architecture diagram",
          "is_bot": false,
          "headline": "docs: README upgrade — hero section, comparison tables (vs Himalaya, …",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-19T18:31:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c548a53f0d6dcb1cd95ca226678dd3b4cfc5fb90",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump to v0.4.1",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-19T17:26:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0addfef09dbf41f5236a9df81db03760fae209f2",
          "body": null,
          "is_bot": false,
          "headline": "chore: rename repo to tymrtn/U1F4E7, update all references + brew tap",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-19T17:22:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d91e193c8aafbe117c19483c328af50945ece12a",
          "body": null,
          "is_bot": false,
          "headline": "fix(cli): expose snooze check-replies subcommand",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-18T18:31:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a5b463a3ff689e5661f24ce6096649ffa0450456",
          "body": "…pSender::send",
          "is_bot": false,
          "headline": "fix(dashboard): update compose handler for from_override param in Smt…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-15T22:18:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7d4ca0fff5904002384c0f8c01bcea0f292f93bf",
          "body": "v0.4.0 gives agents mailbox management — the agent doesn't just\ninteract with email, it programs the mailbox to sort itself.\n\nNew features:\n- envelope tag set/show/list — score messages on arbitrary dimensions\n  (urgent, interesting, etc.) and apply freeform tags. Keyed on\n  Message-ID for stability\n[…]\nbject decoding, loading indicators, account list\ncollapse, sequential folder/message loading, IMAP retry on stale\nconnections, rich --help with examples.\n\n167 tests passing. ci/check-orphans.sh clean.",
          "is_bot": false,
          "headline": "feat(v0.4.0): rules engine, message scoring, unsubscribe, Sieve export",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-14T15:25:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "833e8d2565e7497e9548fa4baf01ff93cfd0dbf1",
          "body": null,
          "is_bot": false,
          "headline": "feat(dashboard): background unsnooze sweep every 60s in envelope serve",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-14T15:21:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "774fc70efdc8893b820aace424295b5773d72e4d",
          "body": "Generates RFC 5228 Sieve scripts from Envelope rules. Only rules with\npure IMAP-level matches (FROM/TO/SUBJECT) are exportable — tag/score\nrules are local-only and are skipped with a warning. ManageSieve upload\ndeferred to v0.5.\n\nNew: crates/email/src/sieve.rs\n- export_sieve(rules) → (script_text, s\n[…]\nulti-rule\n\nNew: envelope rule export --account <id> [--json]\n- Outputs Sieve script to stdout\n- JSON mode includes script + skipped list + exported count\n\n167 tests passing. ci/check-orphans.sh clean.",
          "is_bot": false,
          "headline": "feat(email): Sieve script export + envelope rule export command",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-14T15:19:17Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b13243f2d29d44d1389e266e9d31e3d8d9c27430",
          "body": "…ngine\n\nThree new CLI command modules wired into main.rs:\n\n- `envelope tag set/show/list` — apply freeform tags and numeric scores\n  to messages (keyed on Message-ID for stability across folder moves)\n- `envelope rule create/list/test/run/enable/disable/delete` — CRUD for\n  match+action rules with d\n[…]\naction\n- pub mod unsubscribe in email crate (previously unregistered)\n- reqwest dependency for RFC 8058 one-click POST unsubscribe\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(cli): add tag, rule, and unsubscribe commands for v0.4.0 rules e…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-14T15:09:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e99f894bdabdd5432fad2678baec10e3f2ea8aec",
          "body": "…folder error recovery",
          "is_bot": false,
          "headline": "fix(dashboard): retry stale IMAP connections, collapse account list, …",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-10T23:02:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dd05e95f242aa110fa6ac683c42995fa46ca3fff",
          "body": "…serde\n\nPure computation module — no DB queries. Takes a MessageContext (from/to/\nsubject + tags + scores) and evaluates a MatchExpr tree against it.\n\nMatchExpr variants:\n  From(glob), To(glob), Subject(glob) — case-insensitive glob matching\n  HasTag(name) — message has this freeform tag\n  ScoreAbov\n[…]\ne runner.\n\n15 new tests: glob exact/star/question/case, MatchExpr evaluation for\neach variant + composition, JSON round-trip for expressions and actions,\nCLI flag builder with single-condition unwrap.",
          "is_bot": false,
          "headline": "feat(email): rules matching engine with glob, tags, scores, and JSON …",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-10T22:07:36Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "733a2dac73185ee581bbf513d90a3b2073251317",
          "body": "Three new SQLite tables + store CRUD modules for the rules engine:\n\n1. message_tags (account_id, message_id, tag) — freeform string tags\n   keyed on Message-ID (not UID) for stability across folder moves.\n   UID + folder stored as non-key columns for fast IMAP lookups.\n\n2. message_scores (account_id\n[…]\nate_rule, get_rule, find_rule_by_name, list_rules,\n  list_enabled_rules, enable_rule, disable_rule, delete_rule,\n  increment_rule_hit\n\nTests: 47 store tests passing (7 new). ci/check-orphans.sh clean.",
          "is_bot": false,
          "headline": "feat(store): message_tags + message_scores + rules tables for v0.4.0",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-10T22:06:09Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c1145704bf9a89d67325d4ec057d9282f8856ac0",
          "body": "…d provider list",
          "is_bot": false,
          "headline": "feat(cli): rich --help with getting-started examples, agent usage, an…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-10T22:03:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "95c23ff3ff79f53cbafe89a2dbc155ac3819dec8",
          "body": null,
          "is_bot": false,
          "headline": "docs: brew install tymrtn/envelope/u1f4e7",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-10T21:37:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "70e673160361720680c350ca70fa7055b66a6e79",
          "body": null,
          "is_bot": false,
          "headline": "docs: two-step brew install (tap then install)",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-10T16:27:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f7dcd7f19d8b9cac1b2c14df37bb59f19a205279",
          "body": null,
          "is_bot": false,
          "headline": "docs: add brew install now that the tap exists",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-10T16:06:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7f904379964644ffe68eeea206a0d2a968ad0bfd",
          "body": null,
          "is_bot": false,
          "headline": "docs: simplify install — source-only, drop cargo/brew/naming footnote",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-10T15:12:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "caebf9e74216f9154eba039aad69a68ad2db215c",
          "body": null,
          "is_bot": false,
          "headline": "docs: sharpen positioning — email mastery for agents",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-10T15:11:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "47ba42abce9d0077fb9e006c9435d2ab99409b73",
          "body": "…inbox title",
          "is_bot": false,
          "headline": "fix(dashboard): sequential folder/message loading + account label in …",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-10T15:09:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "66c0a4b62d014f4ae133181e352ea6b6b7ea8183",
          "body": null,
          "is_bot": false,
          "headline": "fix(dashboard): add loading indicators for folders, inbox, and reader",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-10T15:05:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a73608da1851f94984b7e5fb58e2976c03266ffe",
          "body": "IMAP ENVELOPE returns subjects as raw bytes which may contain RFC 2047\nencoded words like =?utf-8?q?Palvelupyynt=C3=B6?=. The dashboard was\ndisplaying these raw encoded strings instead of decoded text.\n\nAdded decode_rfc2047() which handles:\n- Q-encoding (quoted-printable with _→space)\n- B-encoding (\n[…]\n).\n\n7 new unit tests: plain text passthrough, Q-encoding with UTF-8 multibyte,\nB-encoding, mixed plain+encoded, multiple consecutive encoded words,\nQ-encoding underscore→space, Q-encoding hex escapes.",
          "is_bot": false,
          "headline": "fix(imap): decode RFC 2047 encoded subjects in ENVELOPE responses",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-10T15:01:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d36beb1aa283509b2d03a75cb3588aa69726258c",
          "body": "…sers",
          "is_bot": false,
          "headline": "docs: remove governor/policy references from README — irrelevant to u…",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-10T14:51:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ef422dcb0e3eb244180fd66ebd94b74279e76843",
          "body": "Final documentation and CI pass for the v0.3.0 release.\n\nREADME.md (complete rewrite):\n- New \"Why\" section explaining the agent-native BYO-mailbox pitch\n- Updated install instructions with cargo install envelope-email →\n  envelope binary rename note\n- Provider support matrix (Gmail / Outlook.com / W\n[…]\nor change.\n\nFinal tally: 113 tests passing (40 store + 63 email + 10 dashboard),\nci/check-orphans.sh exits 0, cargo clippy has zero errors (warnings\nonly — tightening to -D warnings deferred to v0.4).",
          "is_bot": false,
          "headline": "docs(v0.3.0): README rewrite + CHANGELOG + CLAUDE.md + CI workflow",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-09T18:31:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "557a5825981f73cc7c270c738a6138aedfc72640",
          "body": "Replaces the placeholder dashboard page with a working three-pane email\nclient. The HTML/CSS aesthetic is ported verbatim from U1F4E7 (Instrument\nSans + DM Mono, light bg-paper theme, green/red accent colors, Tailwind\nCDN). Frontend is vanilla JS (no build step) talking to the REST API\nmounted in th\n[…]\nr yet (backend endpoint works, no UI panel).\n- No drafts editor — just list.\n\nCommits the tasks that cover accounts/folders/messages/read/compose/reply\nin one pass since they share the same code path.",
          "is_bot": false,
          "headline": "feat(dashboard): full email-client UI ported from Python aesthetic",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-09T18:25:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "af5c6f6106905650fdbab35207c35bf83c9eebb0",
          "body": "Replaces the 214-line single-file dashboard stub with a proper module\nlayout backing a full email-client REST API. The scaffold compiles and\nserves; individual handler implementations exist as working code, but\nthe frontend is still a placeholder — the Python UI port lands next.\n\nNew layout:\n  crate\n[…]\nd:\n  envelope serve --port 3141\n  curl /             → placeholder index\n  curl /api/stats    → {\"accounts\":15,\"snoozed\":0}\n  curl /api/accounts → full account list\n\nci/check-orphans.sh still exits 0.",
          "is_bot": false,
          "headline": "feat(dashboard): module restructure + full REST API scaffold",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-09T18:16:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4aec4e882ed8f2daaa8e7877b9966aab5ac56abf",
          "body": "Adds three new capabilities to the email crate, all needed by the v0.3.0\ndashboard rewrite (reply, reply-all, compose with attachments):\n\n1. crates/email/src/reply.rs (new) — reply header construction.\n   - build_reply_headers(parent) → { in_reply_to, references, subject, to, cc }\n   - build_reply_a\n[…]\nto SmtpSender::send_simple (drafts have\n   their own --attach path still TODO).\n\nTests: 63 email + 40 store + 10 dashboard = 113 passing. Zero clippy\nwarnings in new code. ci/check-orphans.sh exits 0.",
          "is_bot": false,
          "headline": "feat(email): reply headers + SMTP attachments + --attach CLI flag",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-09T18:10:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "00c13e427f1c7bde2383be6238384af72fcd1501",
          "body": "Recovers ~3,487 lines of feature code that shipped in commit 27f3919\n\"feat(drafts): IMAP-first draft management\" but were never wired into\nthe module tree. See docs/ORPHANS-AUDIT.md for the full history of\nthis silent regression.\n\nSnooze (restored):\n- Recreate SnoozedMessage struct in models.rs with\n[…]\n remain.\n\nenvelope --help now shows:\n  snooze      Snooze a message, list snoozed, or unsnooze\n  unsnooze    Check for due snoozes and return to original folder\n  thread      View conversation threads",
          "is_bot": false,
          "headline": "feat(v0.3.0): restore orphaned snooze + threading features",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-09T18:04:44Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d97b099f175ea1f8eb4cc8c3c26c58199c555568",
          "body": "Three changes preparing for v0.3.0:\n\n1. Rename binary target from envelope-email to envelope, bump workspace\n   version to 0.3.0, update clap command name. Cargo package name stays\n   envelope-email to preserve the crates.io slot — only [[bin]] name\n   changes, which is a standard Cargo pattern. car\n[…]\n counts in both text and JSON output. Add FolderStats to store models.\n\nNo functional regressions. All prior tests still pass; two new tests added\n(test_fetch_uses_body_peek, test_map_flag_name_seen).",
          "is_bot": false,
          "headline": "feat(v0.3.0): binary rename + BODY.PEEK regression guard + folder_stats",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-09T17:55:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0c87c49d0b66a506f5f7c0784c9ffa7045791c83",
          "body": "Adds ci/check-orphans.sh which fails when any .rs file in crates/*/src/\nis not declared via `mod` or `pub mod`. Orphan files compile silently —\n`cargo build` never reads them — so entire features can vanish without\nany build error.\n\nFull git history audit (see docs/ORPHANS-AUDIT.md) identified commi\n[…]\nmands/thread.rs   (239 lines)\n\nThese features will be restored as part of v0.3.0 (snooze + threading).\n\ncheck-orphans.sh currently exits 1 on main as expected — restoration\nwork will flip it to green.",
          "is_bot": false,
          "headline": "chore(ci): add orphan detection guard + audit of historic losses",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-09T17:48:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d4887320d08fa0720e235619c641a9d9e1e234b1",
          "body": "Envelope is a single-purpose email client. Governor/policy/scoring\ncode does not belong in this repo — it was incorrectly added in\n9e67d9b as \"optional governor integration\" along with a --no-governor\nbypass flag, which is a self-documenting backdoor on a public tool.\n\nRemoved:\n- crates/cli/src/gove\n[…]\ndraft-send\n\nAdded a hard rule to CLAUDE.md forbidding reintroduction. If a caller\nwants governance, they wrap envelope from the outside:\n\n  governor envelope send --to x@y.com -- --attr user_requested",
          "is_bot": false,
          "headline": "refactor(cli): remove all governor integration and --no-governor bypass",
          "author_name": "tymrtn",
          "author_login": "tymrtn",
          "committed_at": "2026-04-09T17:35:30Z",
          "body_truncated": true,
          "is_coding_agent": false
        }
      ],
      "releases_count": 14,
      "commits_last_year": 111,
      "latest_release_at": "2026-07-18T06:41:46Z",
      "latest_release_tag": "v1.0.0",
      "releases_from_tags": false,
      "days_since_last_push": 1,
      "active_weeks_last_year": 14,
      "days_since_latest_release": 9,
      "mean_days_between_releases": 9.1
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 42,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": []
    },
    "popularity": {
      "forks": 2,
      "stars": 5,
      "watchers": 0,
      "fork_history": {
        "days": [
          {
            "date": "2026-05-07",
            "count": 1
          },
          {
            "date": "2026-05-18",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 2,
        "total_forks": 2
      },
      "star_history": null,
      "open_issues_and_prs": 9
    },
    "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": [
        "crates/dashboard/web/tsconfig.json"
      ],
      "toolchain_manifests": [
        "Cargo.toml",
        "crates/cli/Cargo.toml",
        "crates/dashboard/Cargo.toml",
        "crates/email/Cargo.toml",
        "crates/store/Cargo.toml"
      ],
      "largest_source_bytes": 126323,
      "source_files_sampled": 169,
      "oversized_source_files": 10,
      "agent_instruction_files": [
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 3709
    },
    "dependencies": {
      "manifests": [
        "Cargo.toml"
      ],
      "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": [
        "crates"
      ],
      "dependencies": [
        {
          "name": "envelope-email-store",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "envelope-email-transport",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "envelope-email-dashboard",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "mail-builder",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "clap",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "tokio",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "rustls",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "serde",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "serde_json",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "anyhow",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "tracing",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "tracing-subscriber",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "chrono",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "uuid",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "reqwest",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "url",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "futures-util",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "async-imap",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "hickory-resolver",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "lettre",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "mime_guess",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "2"
        },
        {
          "name": "base64",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "rpassword",
          "manifest": "crates/cli/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "envelope-email-store",
          "manifest": "crates/dashboard/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "envelope-email-transport",
          "manifest": "crates/dashboard/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "axum",
          "manifest": "crates/dashboard/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "tokio",
          "manifest": "crates/dashboard/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "tower-http",
          "manifest": "crates/dashboard/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "serde",
          "manifest": "crates/dashboard/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "serde_json",
          "manifest": "crates/dashboard/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "anyhow",
          "manifest": "crates/dashboard/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "tracing",
          "manifest": "crates/dashboard/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "chrono",
          "manifest": "crates/dashboard/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "uuid",
          "manifest": "crates/dashboard/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "base64",
          "manifest": "crates/dashboard/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "futures-util",
          "manifest": "crates/dashboard/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "reqwest",
          "manifest": "crates/dashboard/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "rand",
          "manifest": "crates/dashboard/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "rust-embed",
          "manifest": "crates/dashboard/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "8"
        },
        {
          "name": "mime_guess",
          "manifest": "crates/dashboard/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "2"
        },
        {
          "name": "envelope-email-store",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "tokio",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "serde",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "serde_json",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "anyhow",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "thiserror",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "tracing",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "chrono",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "uuid",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "async-imap",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "imap-proto",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "lettre",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "mail-parser",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "mail-builder",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "regex",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "base64",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "sha2",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "zip",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "2"
        },
        {
          "name": "reqwest",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "url",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "hickory-resolver",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "rustls",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "tokio-rustls",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "webpki-roots",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "futures-util",
          "manifest": "crates/email/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "rusqlite",
          "manifest": "crates/store/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "rusqlite_migration",
          "manifest": "crates/store/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1.3"
        },
        {
          "name": "serde",
          "manifest": "crates/store/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "serde_json",
          "manifest": "crates/store/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "anyhow",
          "manifest": "crates/store/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "thiserror",
          "manifest": "crates/store/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "tracing",
          "manifest": "crates/store/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "uuid",
          "manifest": "crates/store/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "chrono",
          "manifest": "crates/store/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "aes-gcm",
          "manifest": "crates/store/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "argon2",
          "manifest": "crates/store/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "sha2",
          "manifest": "crates/store/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "rand",
          "manifest": "crates/store/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "base64",
          "manifest": "crates/store/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "keyring",
          "manifest": "crates/store/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "3"
        },
        {
          "name": "dirs-next",
          "manifest": "crates/store/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "hostname",
          "manifest": "crates/store/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.4"
        },
        {
          "name": "whoami",
          "manifest": "crates/store/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        }
      ],
      "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": 3,
        "merged_prs": 24,
        "open_issues": 6,
        "closed_ratio": 0.882,
        "closed_issues": 45,
        "closed_unmerged_prs": 8
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "tymrtn",
          "commits": 111,
          "avatar_url": "https://avatars.githubusercontent.com/u/4305058?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "release.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "Cargo.lock",
        "package-lock.json"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "8 out of 8 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/19 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 3,
            "reason": "project has 1 contributing companies or organizations -- score normalized to 3",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 9,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 1,
            "reason": "dependency not pinned by hash detected -- score normalized to 1",
            "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": 0,
            "reason": "Project has not signed or included provenance with any releases.",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 7,
            "reason": "3 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "be98752bd247b356c8639757ab888f633975a5da",
        "ran_at": "2026-07-27T18:56:52Z",
        "aggregate_score": 3.6,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-18T06:41:50Z",
      "oldest_open_prs": [
        {
          "number": 28,
          "created_at": "2026-05-05T09:56:05Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 85,
          "created_at": "2026-07-15T00:26:10Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 86,
          "created_at": "2026-07-26T06:02:51Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-18T01:37:08Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 4,
          "created_at": "2026-05-04T07:27:25Z",
          "last_comment_at": "2026-06-17T19:19:06Z",
          "last_comment_author": "tymrtn"
        },
        {
          "number": 34,
          "created_at": "2026-05-06T07:45:17Z",
          "last_comment_at": "2026-07-02T21:52:32Z",
          "last_comment_author": "tymrtn"
        },
        {
          "number": 36,
          "created_at": "2026-05-06T11:04:59Z",
          "last_comment_at": "2026-06-17T19:19:04Z",
          "last_comment_author": "tymrtn"
        },
        {
          "number": 46,
          "created_at": "2026-05-13T15:35:57Z",
          "last_comment_at": "2026-07-02T21:52:30Z",
          "last_comment_author": "tymrtn"
        },
        {
          "number": 54,
          "created_at": "2026-05-16T13:00:41Z",
          "last_comment_at": "2026-06-17T19:19:03Z",
          "last_comment_author": "tymrtn"
        },
        {
          "number": 83,
          "created_at": "2026-07-04T22:55:05Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/tymrtn/U1F4E7",
    "host": "github.com",
    "name": "U1F4E7",
    "owner": "tymrtn"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 52,
      "inputs": {
        "security": 36,
        "vitality": 80,
        "community": 26,
        "governance": 43,
        "engineering": 67
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 80,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 74,
            "inputs": {
              "commits_last_year": 111,
              "human_commit_share": 1,
              "days_since_last_push": 1,
              "active_weeks_last_year": 14
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 1 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 1
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "14/52 weeks with commits",
                "points": 9.7,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 14
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "111 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 111
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "releases_count": 14,
              "latest_release_tag": "v1.0.0",
              "releases_from_tags": false,
              "days_since_latest_release": 9,
              "mean_days_between_releases": 9.1
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "14 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 14
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 9 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 9
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~9.1 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 9.1
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "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": 26,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 10,
            "inputs": {
              "forks": 2,
              "stars": 5,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "5 stars",
                "points": 9.8,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 5
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "2 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "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": "at_risk",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 44,
            "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": "license file present, not a recognized license",
                "points": 16.9,
                "status": "partial",
                "details": [
                  {
                    "code": "license_custom",
                    "params": {}
                  }
                ],
                "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": "at_risk",
        "name": "Sustainability & Governance",
        "value": 43,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 13,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "merged_prs": 24,
              "open_issues": 6,
              "closed_issues": 45,
              "issue_closed_ratio": 0.882,
              "closed_unmerged_prs": 8
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "88% of issues closed",
                "points": 41.2,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 88
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "24/32 decided PRs merged",
                "points": 28.7,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 24,
                      "decided": 32
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/19 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 52,
            "inputs": {
              "followers": 10,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "tymrtn",
              "public_repos": 43,
              "account_age_days": 4836
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "10 followers of tymrtn",
                "points": 7.5,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 10,
                      "login": "tymrtn"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "43 public repos, account ~13 yr old",
                "points": 24,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 43
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 13
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 67,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 68,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "2 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "8 out of 8 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 65,
            "inputs": {
              "topics": [],
              "has_wiki": false,
              "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": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "at_risk",
        "name": "Security",
        "value": 36,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Packaging. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "packaging"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 36,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 17,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 1,
              "scorecard_aggregate": 3.6
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "8 out of 8 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/19 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 0.8,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.2,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 1",
                "points": 0.5,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "3 existing vulnerabilities detected",
                "points": 5.2,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 2
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "good",
        "name": "AI Readiness",
        "value": 79,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.97,
              "agent_instruction_files": [
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 3709
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "CLAUDE.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "97 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 97,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 67,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "Cargo.lock",
                "package-lock.json"
              ],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "crates/dashboard/web/tsconfig.json"
              ],
              "agent_commit_share": 0.44,
              "toolchain_manifests": [
                "Cargo.toml",
                "crates/cli/Cargo.toml",
                "crates/dashboard/Cargo.toml",
                "crates/email/Cargo.toml",
                "crates/store/Cargo.toml"
              ],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "Cargo.toml, crates/cli/Cargo.toml, crates/dashboard/Cargo.toml (toolchain convention, no task runner)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "toolchain_convention",
                    "params": {
                      "files": "Cargo.toml, crates/cli/Cargo.toml, crates/dashboard/Cargo.toml"
                    }
                  }
                ],
                "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": "crates/dashboard/web/tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "crates/dashboard/web/tsconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "44 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 44,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 1",
                "points": 1,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 97,
            "inputs": {
              "primary_language": "Rust",
              "largest_source_bytes": 126323,
              "source_files_sampled": 169,
              "oversized_source_files": 10
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Rust (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Rust"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "10/169 source files over 60KB",
                "points": 51.7,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 169,
                      "oversized": 10
                    }
                  }
                ],
                "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": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "Could not fetch crates package 'envelope-email' from its registry",
    "Could not fetch crates package 'envelope-email-transport' from its registry",
    "Could not fetch crates package 'envelope-email-store' from its registry",
    "Could not fetch crates package 'envelope-email-dashboard' from its registry",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-27T18:57:04.274677Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/t/tymrtn/U1F4E7.svg",
  "full_name": "tymrtn/U1F4E7",
  "license_state": "custom",
  "license_spdx": null
}

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

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

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