Registro público
Informe de salud del softwareesquema 0.27.0 · métricas 1.13.0 · 2026-07-28 02:00 UTC

forestrie / arbor

forestrie services respository

GoSin licencia detectada★ 0 estrellas⑂ 1 forkdesde oct 2025Ver en GitHub ↗

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

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

55
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

forestrieOrganización
0 seguidores19 repositorios públicosdesde jul 2025

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

Ecosistemas de paquetes

RegistroPaqueteVersiónDescargas / mesVersionesÚltima publicación
Gogithub.com/forestrie/arborv0.1.24-24hace 3 días

Métricas por categoría

Vitalidad

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

90Excelente · 22% del índice global
Cómo se puntúa
36/36Recencia de push — último push hace 2 días
20.1/36Cadencia de commits — 29/52 semanas con commits
18/18Volumen de commits — 579 commits en el último año
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Datos de entrada utilizados
commits_last_year579
human_commit_share1
days_since_last_push2
active_weeks_last_year29
Cómo se puntúa
27/27Publica versiones — 20 versiones publicadas
36/36Recencia de las versiones — última versión hace 3 días
27/27Cadencia de publicación — una versión cada ~0,7 días
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count20
latest_release_tagv0.1.24
releases_from_tagsno
days_since_latest_release3
mean_days_between_releases0,7
Excluidos de la puntuación (sin datos o no aplicable): OpenSSF Scorecard: Signed-Releases. Los pesos restantes se han renormalizado.

Comunidad y Adopción

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

12Crítico · 18% del índice global
Cómo se puntúa
0/60Estrellas — 0 estrellas
0/25Forks — 1 forks
0/15Observadores — 0 observadores
Datos de entrada utilizados
forks1
stars0
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Cómo se puntúa
22.5/22.5README
0/22.5Licencia — no se detectó ningún archivo de licencia
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_licenseno
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?

55Moderado · 24% del índice global
Cómo se puntúa
9/54Factor bus — la mitad de los commits recae en 1 contribuyente(s)
9.6/22.5Distribución de commits — el principal contribuyente firma el 57% de los commits
2.7/13.5Amplitud de contribuyentes — 2 contribuyentes
3/10OpenSSF Scorecard: Contributors — project has 1 contributing companies or organizations -- score normalized to 3
Datos de entrada utilizados
bus_factor1
contributors_sampled2
top_contributor_share0,575
Cómo se puntúa
0/46.8Resolución de issues — sin issues o sin datos
36.9/38.3Aceptación de PR — 80/83 PR decididos fusionados
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs80
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs3
Excluidos de la puntuación (sin datos o no aplicable): Resolución de issues. Los pesos restantes se han renormalizado.
Cómo se puntúa
30/30Respaldo de la propiedad — propiedad de una organización
0/20Dominio verificado
0/25Alcance del propietario — 0 seguidores de forestrie
11.5/25Trayectoria — 19 repos públicos, cuenta de ~1 años
Datos de entrada utilizados
followers0
owner_typeOrganization
is_verified
owner_loginforestrie
public_repos19
account_age_days370
Cómo se puntúa
25/25Publicado y resoluble — 1 paquete(s) en go
35/35Recencia de publicación — última publicación hace 3 días
20/20Historial de versiones — 24 versiones en el registro
20/20No obsoleto — activo, ni obsoleto ni retirado
Datos de entrada utilizados
packagesgithub.com/forestrie/arbor
ecosystemsgo
any_deprecatedno
min_days_since_publish3

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 — 3 flujo(s) de trabajo
24/24Pruebas presentes
0/16Configuración de linter
0/9.6Hooks de pre-commit
0/6.4.editorconfig
14/20OpenSSF Scorecard: CI-Tests — 23 out of 30 merged PRs checked by a CI test -- score normalized to 7
Datos de entrada utilizados
has_ci
has_tests
has_editorconfigno
has_linter_configno
has_precommit_configno
Cómo se puntúa
30/30README
25/25Directorio de documentación
0/15Sitio de documentación / página del proyecto
10/10Descripción del repositorio
0/10Topics
10/10Wiki
Datos de entrada utilizados
topics
has_wiki
homepage
has_readme
has_docs_dir
has_description

Seguridad

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

38En 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
1.8/2.5CI-Tests — 23 out of 30 merged PRs checked by a CI test -- score normalized to 7
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
0.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
0/2.5Licencia — license file not detected
7.5/7.5Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
0/5Packaging — sin datos
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — sin datos
7.5/7.5Token-Permissions — GitHub workflow tokens follow principle of least privilege
0/7.5Vulnerabilities — 29 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate3,8
Excluidos de la puntuación (sin datos o no aplicable): packaging, signed_releases. Los pesos restantes se han renormalizado.

Preparación para IA

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

79Bueno · 0% del índice global
Cómo se puntúa
45/45Instrucciones para agentes — .cursor/rules/branch-naming.mdc, .cursor/rules/commit-conventions.mdc, .cursor/rules/docs-workflow.mdc, .cursor/rules/go-comments.mdc, .cursor/rules/linear-mcp-forestrie.mdc, .cursor/rules/types-single-responsibility.mdc, AGENTS.md, CLAUDE.md
0/15Documentación legible por máquinas (llms.txt)
40/40Historial de commits legible — 100 de 100 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share1
agent_instruction_files.cursor/rules/branch-naming.mdc, .cursor/rules/commit-conventions.mdc, .cursor/rules/docs-workflow.mdc, .cursor/rules/go-comments.mdc, .cursor/rules/linear-mcp-forestrie.mdc, .cursor/rules/types-single-responsibility.mdc, AGENTS.md, CLAUDE.md
agent_instruction_max_bytes4169
Cómo se puntúa
12.6/18Arranque con un solo comando — services/custodian/src/go.mod, services/pkgs/delegatekeys/go.mod, services/pkgs/delegationcert/go.mod (convención del toolchain, sin ejecutor de tareas)
22/22Pruebas automatizadas
0/11Configuración de lint / formato
11/11Verificación estática de tipos — Go (tipado estático)
10/10Entorno reproducible — Dockerfile, lockfile
10/10Práctica demostrada con agentes — 73 de los últimos 100 commits con autoría o crédito de agente
0/8Mantenimiento automatizado — no se observan actualizaciones automáticas de dependencias
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Datos de entrada utilizados
has_nixno
has_tests
lockfilesgo.sum
has_dockerfile
typed_language
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configs
agent_commit_share0,73
toolchain_manifestsservices/custodian/src/go.mod, services/pkgs/delegatekeys/go.mod, services/pkgs/delegationcert/go.mod, services/pkgs/logid/go.mod, services/pkgs/logredact/go.mod, services/pkgs/publishproof/go.mod, services/pkgs/s3storage/go.mod, services/publisher/src/go.mod, services/ranger/src/go.mod, services/scout/src/go.mod, services/sealer/src/go.mod, services/sharder/go.mod, services/signer/src/go.mod, services/univocity/src/go.mod
dependency_bot_commit_share0
Cómo se puntúa
45/45Código verificable por tipos — Go (tipado estático)
55/55Tamaños de archivo manejables — 0/302 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languageGo
largest_source_bytes31.405
source_files_sampled302
oversized_source_files0

Datos clave

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

Advertencias de recopilación de datos

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

Más detalle

OpenSSF Scorecard 3.8 / 10
3.8agregado

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-28 02:00 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
7CI-Tests23 out of 30 merged PRs checked by a CI test -- score normalized to 7
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 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
0Licenselicense file not detected
10Maintained30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
n/dPackagingpackaging workflow not detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
n/dSigned-Releasesno releases found
10Token-PermissionsGitHub workflow tokens follow principle of least privilege
0Vulnerabilities29 existing vulnerabilities detected
Dependencias directas 4
RegistroPaqueteRestricción de versiónManifiesto
Gok8s.io/apiv0.34.1services/sharder/go.mod
Gok8s.io/apimachineryv0.34.1services/sharder/go.mod
Gok8s.io/client-gov0.34.1services/sharder/go.mod
Gosigs.k8s.io/controller-runtimev0.22.3services/sharder/go.mod
Todas las dependencias no recopilado

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

Informe JSON sin procesar legible por máquina
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 1530,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "Go": 1262573,
        "Shell": 1239,
        "Dockerfile": 11051
      },
      "pushed_at": "2026-07-25T18:27:57Z",
      "created_at": "2025-10-11T18:25:54Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-25T18:28:02Z",
      "description": "forestrie services respository",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": null,
      "default_branch": "main",
      "license_spdx_raw": null,
      "primary_language": "Go",
      "significant_languages": [
        "Go"
      ]
    },
    "owner": {
      "blog": null,
      "name": null,
      "type": "Organization",
      "login": "forestrie",
      "company": null,
      "location": null,
      "followers": 0,
      "avatar_url": "https://avatars.githubusercontent.com/u/222178494?v=4",
      "created_at": "2025-07-22T07:43:05Z",
      "is_verified": null,
      "public_repos": 19,
      "account_age_days": 370
    },
    "license": {
      "state": "absent",
      "spdx_id": null,
      "raw_spdx": null,
      "file_present": false,
      "scorecard_found": false,
      "profile_has_license": false
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.1.24",
          "kind": "patch",
          "published_at": "2026-07-24T13:34:53Z"
        },
        {
          "tag": "v0.1.23",
          "kind": "patch",
          "published_at": "2026-07-19T21:51:53Z"
        },
        {
          "tag": "v0.1.22",
          "kind": "patch",
          "published_at": "2026-07-19T18:17:05Z"
        },
        {
          "tag": "v0.1.21",
          "kind": "patch",
          "published_at": "2026-07-18T17:17:15Z"
        },
        {
          "tag": "v0.1.20",
          "kind": "patch",
          "published_at": "2026-07-18T14:38:14Z"
        },
        {
          "tag": "v0.1.19",
          "kind": "patch",
          "published_at": "2026-07-18T13:20:09Z"
        },
        {
          "tag": "v0.1.18",
          "kind": "patch",
          "published_at": "2026-07-18T12:38:24Z"
        },
        {
          "tag": "v0.1.17",
          "kind": "patch",
          "published_at": "2026-07-18T12:17:16Z"
        },
        {
          "tag": "v0.1.16",
          "kind": "patch",
          "published_at": "2026-07-18T11:48:53Z"
        },
        {
          "tag": "v0.1.15",
          "kind": "patch",
          "published_at": "2026-07-18T11:12:51Z"
        },
        {
          "tag": "v0.1.14",
          "kind": "patch",
          "published_at": "2026-07-10T23:16:19Z"
        },
        {
          "tag": "v0.1.13",
          "kind": "patch",
          "published_at": "2026-07-10T18:41:26Z"
        },
        {
          "tag": "v0.1.12",
          "kind": "patch",
          "published_at": "2026-07-05T11:09:11Z"
        },
        {
          "tag": "v0.1.11",
          "kind": "patch",
          "published_at": "2026-07-05T10:57:24Z"
        },
        {
          "tag": "v0.1.10",
          "kind": "patch",
          "published_at": "2026-07-03T23:43:33Z"
        },
        {
          "tag": "v0.1.9",
          "kind": "patch",
          "published_at": "2026-07-03T23:31:38Z"
        },
        {
          "tag": "v0.1.8",
          "kind": "patch",
          "published_at": "2026-07-03T22:32:06Z"
        },
        {
          "tag": "v0.1.7",
          "kind": "patch",
          "published_at": "2026-07-02T17:57:19Z"
        },
        {
          "tag": "v0.1.6",
          "kind": "patch",
          "published_at": "2026-07-02T12:36:05Z"
        },
        {
          "tag": "v0.1.4",
          "kind": "patch",
          "published_at": "2026-03-17T12:10:17Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "4af072e25c9518340a1c876906aaae52d24a331b",
          "body": "…) (#84)\n\nDELEGATE_KEY_EPOCH defaulted to 0 in LoadConfig, so a deployment that\nnever mentioned it silently ran with delegation-in-advance disabled. 0\n(off) and >= 1 (on) are both deliberate operational postures for\nADR-0050; inheriting one because nobody said anything is the failure\nmode worth clos\n[…]\ns; the 0/>=1 semantics and the uint32 parse are untouched.\n\n\nClaude-Session: https://claude.ai/code/session_01WWSsvP66PFeyxcJ7NSFU3A\n\nCo-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(sealer): require DELEGATE_KEY_EPOCH — no in-code default (FOR-390…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-25T18:27:57Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9ce33f142575b78fb057a5ac31b2de195dcd73f2",
          "body": "* feat(storage): publish log objects with an explicit cache policy\n\nMassifs are overwritten in place on every commit until full, then frozen\nforever. They were published to a CDN-fronted store with no Cache-Control at\nall, so the edge applied heuristic caching to a mutable object. Both\ndirections of\n[…]\ne Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VWzPGqfpPPhWcXpw3yD6dE\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(storage): publish log objects with an explicit cache policy (#83)",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-24T13:04:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a213ebf4cd6a8b1321039286395bb4a191cfbcc2",
          "body": "…lan tests (FOR-410) (#81)\n\n* fix(sealer): cross-massif validation, hardened boundary guard, seal-plan tests (FOR-410 R1/R3/R4/R5)\n\nplan-2607-09 remediations on the #79 boundary-base fix:\n\n- R1: catch-up runs carry each massif's freshly computed accumulator and\n  require byte-equality with the next \n[…]\nused.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01PQjHUiEiVNZ7yzEC5jTKxd\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(sealer): cross-massif validation, hardened boundary guard, seal-p…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-19T19:32:06Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "53e4ab47f4ba94c552c4413c6690a12af2afb461",
          "body": "…(FOR-411) (#82)\n\nA mined revert against a log with no on-chain state was terminally\nacked under ADR-0008, whose next-seal catch-up premise fails for a\ngenesis log — three fresh forests stranded on 2026-07-19 with\nInvalidReceiptInclusionProof (root cause: FOR-410 base drift, fixed\nsealer-side in #79\n[…]\n  content change (FOR-410 self-heal re-seal) still clears immediately.\n\n\nClaude-Session: https://claude.ai/code/session_01NxGJoVt29rhHdhrCXfQD5L\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(publisher): virgin-log reverts defer to sweep; poison cache ages …",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-19T19:30:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7052c6fd26f3cbf4a71b05bfb9e9398a559e6e4d",
          "body": "Claude-Session: https://claude.ai/code/session_01PQjHUiEiVNZ7yzEC5jTKxd\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(plans): FOR-410 review remediation (plan-2607-09) (#80)",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-19T19:05:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ea779148443db0c9d06ab04dcf579b89e7f296ee",
          "body": "…0, ADR-0056) (#79)\n\nRe-seals drifted the checkpoint base to the previous seal (sth(b->c)),\nviolating the boundary invariant the publisher's relay documents and the\nretained-chain verification depends on (proven live: sth(159->206) on a\nlane-A massif-0 log where sth(0->206) is required).\n\nThe proof \n[…]\nfted-legacy self-heal,\nboundary monotonicity. Full sealer suite green.\n\n\nClaude-Session: https://claude.ai/code/session_01PQjHUiEiVNZ7yzEC5jTKxd\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(sealer): pin checkpoint base to the massif entry boundary (FOR-41…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-19T18:11:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "226d265919e19121af924a60386c1af70a89dc7c",
          "body": "…rder (#78)\n\nSecond lane-a finding: the budget check fired before assembling and\ngroup order was map-random, so every sweep burned its 16 submissions on\na random poison subset (unpublishable=16, capDeferred~300 each sweep)\nand a fresh forest's genesis gap could wait many sweeps — the trust\nladder ti\n[…]\nforests today), raising the priority of the R4 delivery investigation.\n\n\nClaude-Session: https://claude.ai/code/session_01NxGJoVt29rhHdhrCXfQD5L\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(publisher): resync budget gates submissions only, deterministic o…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-19T17:32:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d18b3e09ab2670c24966f498cff4e626b6904cad",
          "body": "…out) (#77)\n\nFirst lane-a enablement findings: 85 historical poison seals re-mined\ntheir reverts every sweep (gas + chain spam + ERROR flood), the\nsubmission burst pushed everything behind it past ReceiptTimeout, and\ndriveLowerMassifs swallowed retry outcomes silently.\n\n- Poison cache keyed by (key,\n[…]\ns on ETag change;\nbudget bounds the burst with CapDeferred accounting.\n\n\nClaude-Session: https://claude.ai/code/session_01NxGJoVt29rhHdhrCXfQD5L\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(publisher): resync poison cache + submission budget (FOR-408 roll…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-19T17:08:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1720f40d0bf2720f62b3af22f96923ef1d95d9a3",
          "body": "…lves (#76)\n\nFOR-409 (#71) gave scout a go.mod replace ../../pkgs/logredact, but its\nimage built with context ./services/scout, so 'go mod download' failed\nand main's Build and Deploy has been red since e02d9f8 (PR CI runs only\ngo-test, not the docker build). Mirror the publisher pattern: context\n./services with -f, copy pkgs/logredact alongside scout/src.\n\n\nClaude-Session: https://claude.ai/code/session_01NxGJoVt29rhHdhrCXfQD5L\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(scout): build image from services/ context so pkgs/logredact reso…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-19T16:37:16Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3c3fa32e784d574746366a555a3e054f810d8dd9",
          "body": "…8) (#75)\n\nW1: the sweep submits exclusively through SubmitBatch so chainNonce\nstays the single in-process nonce authority (sweepCore has no Submit;\nChainWriter.Submit documented CLI-only); regression test pins that an\ninterleaved sweep submission takes the next counter nonce with no\nPendingNonceAt \n[…]\nues fail Validate\nloudly rather than silently disabling the backstop).\n\n\nClaude-Session: https://claude.ai/code/session_01NxGJoVt29rhHdhrCXfQD5L\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(publisher): resync review remediation W1-W5 (FOR-408, plan-2607-0…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-19T16:19:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "54923d28a714241ecd50bb3c6bd2898b4e0e76d4",
          "body": "…(#74)\n\nAdversarial review of the merged plan-2607-07 implementation (#73):\nHigh — the sweep's synchronous Submit bypasses the batch path's\nin-process nonce counter (duplicate-nonce churn exactly in the\npost-outage window); Mediums — acks coupled to the config flag rather\nthan sweep health (and disa\n[…]\nwn acceptance criteria.\nW1+W2 gate lane enablement of RESYNC_INTERVAL.\n\n\nClaude-Session: https://claude.ai/code/session_01NxGJoVt29rhHdhrCXfQD5L\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(plan): plan-2607-08 — resync sweep review remediation (FOR-408) …",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-19T16:12:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2abddc34d29b536bd88f367482765c414a5d3a07",
          "body": "…plan-2607-07) (#73)\n\nR1: a periodic sweep (RESYNC_INTERVAL; default off, rollout inert)\nlists the checkpoints prefix, coalesces to the highest massif per log,\nand re-drives the one-shot publish for anything not yet anchored, in\nroot-first passes so anchoring a genesis unblocks its children within\nt\n[…]\nead-lettered; one sweep anchors the forest in three\nroot-first passes.\n\n\nClaude-Session: https://claude.ai/code/session_01NxGJoVt29rhHdhrCXfQD5L\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(publisher): resync sweep — notification-loss backstop (FOR-408, …",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-19T14:46:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "346973f7fa93bd8274ff7b29792e9d1c8e19db6b",
          "body": "…408) (#72)\n\nRoot cause of the 2026-07-19 lane-a incident: R2 event notifications for\ntwo consecutive fresh forests' genesis .sth PUTs were never delivered,\nand the publisher — unlike the sealer (resync.go) — has no\nreconciliation backstop, so the forests stranded behind the owner-gate\nuntil their c\n[…]\niliation\nsweep + ack dependency-blocked messages + loss observability.\n\n\nClaude-Session: https://claude.ai/code/session_01NxGJoVt29rhHdhrCXfQD5L\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(plan): plan-2607-07 — publisher notification-loss backstop (FOR-…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-19T14:33:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e02d9f8b32d4f8fffebd1f1d940757fc6e1634dc",
          "body": "The services derive AWS_SECRET_ACCESS_KEY = hex(sha256(R2_TOKEN)) when\nunset, and the config dumps logged secrets as bare sha256 hex — the\nsame function — so the R2_TOKEN log line printed a live SigV4\ncredential whenever the derive convention was active. Add\nlogredact.Fingerprint (domain-separated, \n[…]\nrty: a fingerprint can never equal (or prefix) the derived\ncredential.\n\n\nClaude-Session: https://claude.ai/code/session_01NxGJoVt29rhHdhrCXfQD5L\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(logredact): domain-separated credential fingerprints (FOR-409) (#71)",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-19T14:33:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d74e19d0cef8f65a88ab5365d332dac730550ccf",
          "body": "* fix(publisher): drain owner_not_anchored in-cycle (FOR-395)\n\nA child checkpoint whose owner (authority log) is not yet anchored on\nchain waited a full VISIBILITY_TIMEOUT (~90s) for redelivery, because\nprocessBatch released owner_not_anchored groups straight away and the\nlease had to lapse. Measure\n[…]\n6 sec 8: F1 fixed; F2\n(per-pass full re-assemble is O(N children x passes)) and F3 (the\nsynchronous drain stalls the poll loop up to OwnerWait) left as\nprioritised follow-ups; F4-F6 accepted/deferred.",
          "is_bot": false,
          "headline": "fix(publisher): drain owner_not_anchored in-cycle (FOR-395) (#70)",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-17T18:05:29Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "96ce7133183bc1b786458d50abc078c9a680fd3c",
          "body": "… (#69)\n\nA child log waits ~90s to anchor after its owner because\nowner_not_anchored is handled by letting the queue lease lapse rather\nthan by waiting for the dependency. Measured on lane-A: alice was\nprocessed one second before david published, then waited a full\nVISIBILITY_TIMEOUT for redelivery.\n[…]\nsumes topological batch ordering.\n\nFOR-394 (no DLQ, silent drop) is deferred with a sizing note: it is\nCloudflare config, not bespoke queue work -- the bespoke SequencingQueue\nis a different pipeline.",
          "is_bot": false,
          "headline": "docs(plans): plan-2607-06 publisher owner_not_anchored wait (FOR-395)…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-17T14:27:39Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "da3ea33da5ba486babd558f023109c8110e1b98c",
          "body": "…) (#68)\n\n* feat(sealer): level-triggered resync backstop (ADR-0007 phase-3 / plan-2607-04)\n\nAdds the correctness backstop to the edge-triggered queue path (F1): a resync\nloop that pages the coordinator active-delegation set and re-drives any log\nwhose massif head has advanced past its latest checkp\n[…]\nanthropic.com>\n\n* docs(plan): mark R1-R4 fixed in resync review remediation\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "FOR-390: sealer level-triggered resync backstop (F1 fix, plan-2607-04…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-15T17:42:24Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "19a6823238d608e8ea709139239a69ffa6469c8c",
          "body": "… (#66)\n\nWhen CheckpointLog returns ErrDelegationPending/ErrDelegationExpired the consumer\ndefers the seal (does not ack, awaits queue redelivery) but logged it at INFO —\ninvisible at the deployed \"notice\" (INFO+2) level. A log stuck awaiting a\ndelegation (e.g. an advance certificate not pre-submitt\n[…]\n} counter, so a checkpoint blocked on\ndelegation is an explicit operator signal rather than silence.\n\nNo behaviour change to the seal/ack path.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sealer): surface delegation-deferred checkpoints (WARN + metric)…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-15T13:49:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "be9eccc5837a779d910573ab59b06e9e41b5f13e",
          "body": "…OR-390) (#65)\n\nThe shared delegatekeys module (added in #64) is a local go.mod replace; both\nDockerfiles COPY each replaced pkg explicitly, so without pkgs/delegatekeys\n`go mod download` fails: open /build/pkgs/delegatekeys/go.mod: no such file.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(docker): copy pkgs/delegatekeys into sealer + custodian images (F…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-14T18:01:02Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9c85a726a5bd79e8378390f58f1e1d19bd8ed0a7",
          "body": "…ases G, J) (#64)\n\n* feat(pkgs): extract shared delegatekeys derivation (FOR-390 phase G1)\n\nSingle source of truth for standing delegate-key derivation, canonical\nCOSE_Key encoding, and the delegated_pubkey_hash identity, so the sealer\n(holds private keys) and the custodian (re-derives public keys t\n[…]\nry engine unit-tested (eventual\nsuccess; cancel stops without wiring keys).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(FOR-390): custodian registrar + voucher, sealer boot posture (ph…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-14T17:51:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ab871f072ddb39d3daf986abacb216679120c124",
          "body": "…-390 phase D) (#63)\n\nWires the standing delegate-key set (arbor#62) into the lease hot path so the\nsealer requests a pre-signed wide certificate instead of minting an ephemeral\nkey per log. Additive and off without DELEGATE_KEY_EPOCH.\n\nWhen delegation-in-advance is enabled (DelegateKeySet present):\n[…]\nge\nreject (uncovered window), foreign-key reject, N-1 rotation-overlap accept, and\nthe cert->key resolution round-trip (current, N-1, foreign).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sealer): route seal issuance through standing delegate keys (FOR…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-13T17:17:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3392ff5c0225fb8189317997480a0975c0e86d67",
          "body": "* feat(sealer): standing delegate-key schedule (FOR-390 phase B)\n\nDerive standing delegate keys from a KMS-MAC seed at boot and advertise\nthe current key to the coordinator, so advance delegation certificates\ncan be pre-issued (ADR-0050 / plan-2607-20 phase B). No private material\nis ever at rest: t\n[…]\nng path).\n\nRegistration stays best-effort and off without DELEGATE_KEY_EPOCH.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sealer): standing delegate-key schedule (FOR-390 phase B) (#62)",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-13T14:32:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8f53e78f28dd32a6156da7efe67b9dba3ef42e95",
          "body": "…vation (FOR-390, ADR-0050 phase A) (#61)\n\nThe seed for the sealer's standing delegate keys is derived inside KMS\n(HMAC-SHA256 MacSign over a fixed server-side prefix + sealerId + epoch)\nrather than stored anywhere. MacSign is deterministic per key version, so\ndelegate keys — and every advance deleg\n[…]\nKey seams;\n  tests pin auth, allowlist, epoch validation, the fixed MAC input, seed\n  determinism, and epoch-bump rotation — no GCP dependency.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(custodian): POST /api/delegate-seed — KMS-MAC delegate-seed deri…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-13T14:31:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "11c26dc0fe5095458ffc083e034c6f4624538087",
          "body": "…suance-storm note (#60)\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(plan-2607-01): lane-A poll-ceiling results (~4s warm) + churn/is…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-12T23:37:43Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "135a39a99da922574568424896e512fffd32666f",
          "body": "…OR-386) (#59)\n\n* feat(sealer): DELEGATION_MAX_LEASES — configurable lease-cache cap (FOR-386)\n\nWith padded delegation ranges the lease cache is latency-load-bearing:\nevicting an active log's lease forces a fresh issuance round-trip (~10s+\nwith a wallet signer) on its next seal. Expose the LRU cap (\n[…]\nm>\n\n* docs(plan-2607-01): fold FOR-386 items into phase 1.5 + phase 2 scope\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sealer): DELEGATION_MAX_LEASES — configurable lease-cache cap (F…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-12T23:35:42Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d72befb3432c158f3965623f50f3a3b9f572c61d",
          "body": "…tions (#58)\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(plan-2607-01): FOR-386 measured win + follow-on latency/scale op…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-12T23:17:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "35ad50bfe63d66f057d3a33d7884eca69dba640c",
          "body": "…-386) (#57)\n\n#55 padded the mmrEnd PARAMETER to EnsureValidForLog, which serves as both\nthe cache-coverage window and the issuance range. Every append therefore\nasked the cache to cover [start, newEnd+pad] — an end that advances past the\npreviously issued certificate by construction — so the cache \n[…]\nequent grown windows with ZERO issuer calls until the log outgrows the\npad, and the outgrown re-issuance is itself padded from the true window.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(sealer): pad only the issuance request, not the cache window (FOR…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-12T22:52:24Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "753cc130abd765503157f24baa470c95a43205ad",
          "body": "…(#56)\n\nThe contract returns `LogConfig memory` — a single tuple. The hand-rolled\nunivocityViewABI declared four flat outputs, so go-ethereum mis-decoded the\ntuple head offset as `kind` and read garbage offsets for the dynamic rootKey:\n\n  abi: cannot marshal in to go slice: offset … would go over sl\n[…]\nABI and unwrap via abi.ConvertType.\nRegression test pins the decode against raw eth_call return bytes captured\nfrom the live v0.1.7 deployment.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(univocity): logConfig ABI is a tuple, not flat outputs (FOR-389) …",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-12T22:26:52Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0ccd5ca98a3ecefe34c03edf5c3794488416cca7",
          "body": "… (FOR-386) (#55)\n\nDelegation certificates bind [mmrStart, mmrEnd] and the sealer requested the\nminimal per-seal window, so every append missed the (coverage-based) lease\ncache and paid a fresh issuance round-trip: measured ~17s per append on lane A\neven with an instantly-responsive signer, and a li\n[…]\n\nceiling + ~1.2s execution), phase 2 long-poll then removes the wake ceiling.\n\nFollow-up (Linear): per-log pad via the forest genesis document.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sealer): padded delegation ranges — one cert covers many appends…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-12T22:20:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "06cb65fba687cfe3282815a87f1b95d95d8ee883",
          "body": "…acking (#48)\n\nAdds a Tracking & decisions section to the sealer-trigger plan: Linear project\n'Low-latency sealer trigger' (Phase 0 = FOR-379, Phase 1 = FOR-380) under the\nSelf hosted, remote, sealer initiative; Phase 1 producer auth = Cloudflare\nQueues-push token via forest-1/Doppler; canonical seal-hint/nudge terminology\n(now in devdocs glossary); Phase 0 lane-A baseline as a soft AC of FOR-379.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(plan-2607-01): record grill-with-docs decisions + FOR-379/380 tr…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-12T21:31:07Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0426f2eb8013e2f3d5a781977eb38ac47e35e4fe",
          "body": "… recorded (#54)\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(plan-2607-01): phase 0-1 rollout results — lane A live, baseline…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-12T21:30:20Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5a71fb12836baa93f89613c7abb34bdaa6f1f090",
          "body": "…se 1) (#53)\n\n* feat(ranger): publish seal hints to the sealer queue after massif commits (FOR-380, ADR-0007 phase 1)\n\nDeletes the one uncontrollable leg of the sealer wake path (R2 PutObject event\n-> Cloudflare notification delivery -> queue): after a log group commits and\nacks, the ranger publishe\n[…]\n): 2607-03 verification addendum — re-review clean, R2 stays a rollout gate\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(ranger): seal hints into the sealer queue (FOR-380, ADR-0007 pha…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-12T20:58:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "18e9abd711ec7a186c914a8dcefa0039abb9c047",
          "body": "…379, ADR-0007 phase 0) (#50)\n\nBaseline observability for the low-latency sealer trigger work (ADR-0007 /\nplan-2607-01). Without these we cannot prove the phase-1 win or see which wake\npath fires.\n\n- sealer_seal_trigger_total{source}: accepted seal triggers by wake source.\n  Only r2_event fires toda\n[…]\n an optional Metrics handle (nil disables recording);\n  the queue consumer now passes its handles through.\n\nNo behaviour change beyond metrics.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sealer): trigger-source counter + checkpoint-lag histogram (FOR-…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-12T20:49:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a5e5f3563f376afd91f3ba61ef67951b358b797b",
          "body": "…FOR-383) (#52)\n\n* ci: PR-triggered gofmt/vet/test gate; un-swallow test:unit failures (FOR-383)\n\narbor had no PR-triggered Go test workflow — build-deploy.yml runs on push to\nmain only. Worse, test:unit ended every module's command with `exit 0`, so\ntest failures did not even fail the main-branch p\n[…]\nalignment\ndrift on main — evidence the gate works; landing the fix with it.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: PR-triggered gofmt/vet/test gate; un-swallow test:unit failures (…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-12T20:43:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0fcc0267b34e7f4962114c0276b815dd43998463",
          "body": "…(#49)\n\nThe per-service .envrc unconditionally exported GOWORK=$(pwd)/go.work, but\ngo.work is gitignored (generated by `task bootstrap`). Pointing Go/gopls at a\nmissing workspace file breaks builds and LSP. Only export GOWORK when the file\nexists; otherwise fall back to module mode (committed go.mod\n[…]\npplies gofmt struct-field alignment in sealer config/erc1271/trust-root\nand univocity chain (whitespace only, no semantic change).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(envrc): guard GOWORK export when go.work absent; gofmt alignment …",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-12T17:56:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a6c2c2d183c95d4d61762fcd0f784a00d81c19be",
          "body": "…inistic-cbor\n\narbor: RFC 8949 §4.2 canonical CBOR across all services",
          "is_bot": false,
          "headline": "Merge pull request #46 from forestrie/fix/delegation-cert-core-determ…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-12T16:41:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7c912658326a3b5dc80a90850971031b0bfb1645",
          "body": "The publisher was paying gas to rediscover that a checkpoint can't anchor:\nfirst-checkpoint bootstraps revert deterministically (InconsistentReceipt\nSignature) yet were retried every visibility timeout, and the true reason was\nmasked in metrics. Diagnosis on forest-dev-5: 33 attempts, 100% reverting\n[…]\nthe retry storm (33->6 reverts) and unmasks reasons. Pre-send\neth_call (6->0) is deferred. Upstream root cause tracked in FOR-378.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(publisher): terminal-ack unpublishable checkpoints (FOR-377) (#47)",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-12T14:24:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b5b521e58fbf8f3a3e263ee829e7720139cdce9a",
          "body": "Route every wire/signature CBOR encode through a shared SortCoreDeterministic\nEncMode. The package-default cbor.Marshal uses SortNone — random order for Go\nmaps, declaration order for structs — both non-conformant with the strict\nCOSE/SCITT §4.2 profile used by canopy and the rest of arbor.\n\n- univo\n[…]\nse Sign1 path, and scout responses were likewise already conformant.\n\nRefs: status-2607-03-remove-cbor-x-for-scitt-cose-canonicity\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "arbor: enforce RFC 8949 §4.2 canonical CBOR across all service encoders",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-12T14:13:24Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "853670e9e294b74c819f931a2ea4d58ae3bf5050",
          "body": "…al CBOR\n\nThe delegation-cert protected/payload map encoder and the sealer's\ndelegated-key encoder used fxamacker's SortCanonical, which is the legacy\nRFC 7049 *length-first* map ordering. That diverges from RFC 8949 §4.2 core\ndeterministic (bytewise) — the COSE/SCITT canonical profile already used \n[…]\n delegation-cose golden test asserts\nagainst the same fixed inputs).\n\nRefs: status-2607-03-remove-cbor-x-for-scitt-cose-canonicity\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "delegationcert: use SortCoreDeterministic (RFC 8949 §4.2) for canonic…",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-12T13:14:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4b694d4e287de092ea2cc9c1968b85a925d1f68e",
          "body": "…25) (#45)\n\nThe publisher was the only arbor service missing from the semver release\nbuild matrix (same omission univocity had, fixed in e06c8d3). Without it,\nno publisher:vX.Y.Z image is produced, so ledger-b cannot pin the publisher\nby semver and cannot receive it through the lane-A-validated prom\n[…]\nggered + orchestrator dispatch).\nIt already has a Dockerfile and publisher:build/publisher:push tasks, so it\nbuilds identically to its siblings.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(release): build and push publisher in semver release loop (FOR-3…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-10T23:03:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "166d9b7db6db63d9aa3a168dff99cfbebefc7c75",
          "body": "docs: ADR-0007 low-latency sealer trigger + plan-2607-01 (FOR-335)",
          "is_bot": false,
          "headline": "Merge pull request #44 from forestrie/robin/for-335-sealer-trigger-adr",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-10T21:26:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "406cf88f8e22d24cfc3752807d5b260e6081d8c8",
          "body": "Ranger-originated seal hints replace R2 event notifications as the\nprimary sealer wake path; long-poll seal coordinator in phase 2; R2\nevents demoted to backstop. Adds the arbor ADR index README and the\nfirst date-cohort plan.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: ADR-0007 low-latency sealer trigger + plan-2607-01 (FOR-335)",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-10T21:25:47Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "67a15615a58b2a052a51ae06add5629d4cdc3563",
          "body": "…bject\n\nfix(s3storage): GetOptions{} must read full object (FOR-325)",
          "is_bot": false,
          "headline": "Merge pull request #43 from forestrie/robin/for-325-getoptions-full-o…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-10T00:18:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4b40eba3a61fe1f4d51c2a141011840c8f8b9082",
          "body": "Zero-value RangeLength was treated as a 1-byte range, so univocity's\nforest registry genesis scan decoded EOF for every genesis and reported\nforests=0 — breaking grant PATCH and logId trust resolution.",
          "is_bot": false,
          "headline": "fix(s3storage): GetOptions{} must read full object, not bytes=0-0",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-10T00:18:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d283b0025a55a183972f2a974104833aa6133664",
          "body": "…payment-receipt\n\nfix(publisher): classify InvalidPaymentReceipt reverts (FOR-325)",
          "is_bot": false,
          "headline": "Merge pull request #42 from forestrie/robin/for-325-classify-invalid-…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-10T00:11:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bb2f86c3479666cb48d9bc029f6fb7e6212d5b45",
          "body": "Empty self-inclusion against a non-root log surfaces as this selector;\ndecode it so queue metrics named the failure instead of \"execution reverted\".",
          "is_bot": false,
          "headline": "fix(publisher): classify InvalidPaymentReceipt reverts (FOR-325)",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-10T00:10:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "daf16f379163028700c72e1bd5935b2d658151d3",
          "body": "…estamp\n\nfix(univocity): patch stored grant idtimestamp after sequencing (FOR-325)",
          "is_bot": false,
          "headline": "Merge pull request #41 from forestrie/robin/for-325-grant-store-idtim…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-10T00:04:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5efc2d147144f47c2247a25485f0bf61a4f15918",
          "body": "Public helper for store rewrite so recovery tools and the PATCH handler\nshare the same unprotected-header merge.",
          "is_bot": false,
          "headline": "refactor(univocity): export SetTransparentStatementIdtimestamp",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-09T23:49:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1c76dda1f7966bb64b331d154663d0ac2710bc89",
          "body": "…325)\n\nCreation grants were stored with unprotected -65537 all-zero, while ranger\nassigns a snowflake idtimestamp to the massif leaf. publishCheckpoint then\nbound the wrong leaf and reverted InvalidReceiptInclusionProof.\n\nAdd PATCH /api/forest/{R}/grants/{subject}/idtimestamp so canopy can write\nthe sequenced value into the owned grant store once registration status\nresolves.",
          "is_bot": false,
          "headline": "fix(univocity): patch stored grant idtimestamp after sequencing (FOR-…",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-09T23:47:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2129a51f4972e46e9cf34010260ad9ce7bc5eb4a",
          "body": "…-325) (#40)\n\n* fix(publisher): retry tip-lag eth_call when decoding revert reasons\n\nPublic Base Sepolia RPCs often return \"block not found\" for eth_call at\nthe receipt block before the tip catches up, masking IUnivocity names as\nopaque retry reasons. Retry within the receipt timeout until classific\n[…]\nfor later seals. The\non-chain proof binds mmrEnd, so publishCheckpoint reverted with\nCheckpointIndexOutOfDelegationRange. Require the cached lease bounds to\ncover the requested MMR range before reuse.",
          "is_bot": false,
          "headline": "fix(publisher): retry tip-lag eth_call for revert classification (FOR…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-09T23:16:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "287a85c42eeb3a962a41233980663aa7e6ac1111",
          "body": "* fix(publisher): classify delegation and cosecbor reverts (FOR-325)\n\nThe lane-A InconsistentReceiptSignature(ALG_ES256, ALG_KS256) reverts\nsurfaced as reason=unrecognized in publisher metrics because\nunivocityErrorsABI only covered a subset of IUnivocity errors;\ndiagnosis required manual eth_call r\n[…]\nerved on the live revert.\n\n* test(publisher): pin all univocityErrorsABI selectors (FOR-325)\n\nGuard against transcription typos silently degrading revert\nclassification to unrecognized (plan-0050 L4).",
          "is_bot": false,
          "headline": "fix(publisher): classify delegation and cosecbor reverts (FOR-325) (#39)",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-09T21:12:03Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c0036eb66b843a0b396462288f589685bbc6c445",
          "body": "fix(publisher): rebuild head proof segment when on-chain size lags in a massif",
          "is_bot": false,
          "headline": "Merge pull request #38 from forestrie/fix/sealer-reseal-boundary-proof",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-09T18:23:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a511d3b2aee5b3e81889973c099a4024a6d309fe",
          "body": "…s in a massif\n\nThe publisher's Approach-C proof relay only chained embedded per-massif\nconsistency proofs and errored when no embedded proof started at the on-chain\nsize. But the univocity contract requires the first proof's TreeSize1 to equal\nthe on-chain currentSize, and a checkpoint's single emb\n[…]\neckpoints (no sealer change,\nno migration). Multi-massif cross-massif catch-up (boundary-based relay) is a\nfollow-up. See devdocs plan-2607-09.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(publisher): rebuild the head proof segment when on-chain size lag…",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-08T18:16:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "77fa4387c01676c1388d3e567a5f7a024eb86a94",
          "body": "ci(publisher): build+push task and workflow steps (FOR-318)",
          "is_bot": false,
          "headline": "Merge pull request #37 from forestrie/robin/for-318-provisioning",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-07T10:26:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5d9b173b051ab40d96253a90bb431682cdf1d459",
          "body": "Add taskfiles/service-publisher.yml (build/push/pause/resume, mirroring\nsealer), register it in the Taskfile includes, and add Build/Push Publisher\nImage steps to build-deploy.yml so CI produces publisher:<tag> for Flux image\nautomation. The bootstrap block + go.work for publisher and test:unit\ndiscovery already landed with FOR-317.\n\nRefs FOR-318.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci(publisher): build+push task and workflow steps (FOR-318)",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-06T23:32:22Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2b560c4574918b073d1d1633e77a95357619d8da",
          "body": "feat(publisher): FOR-317 multi-forest checkpoint publisher service (core + daemon + CLI)",
          "is_bot": false,
          "headline": "Merge pull request #36 from forestrie/robin/for-317-publisher-service",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-06T23:28:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b125a20306ad41cefb79b1e5870127a2e812a48a",
          "body": "… test)\n\nTwo-agent adversarial review of the ack-on-revert + coalescing work found no\nHigh/Medium loss/double-publish/mis-ack bugs; the embedded-proof chaining is\ncontract-valid and coalescing sibling-acks are safe. Applying the Low cleanups:\n\n- Remove StatusReverted from PublishResult.ShouldAck and\n[…]\ncatch-up and\n  bootstrap (on-chain size 0). Previously only treeSize linkage was asserted.\n\ngofmt/vet/-race green.\n\nRefs FOR-317, plan-2607-08.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(publisher): round-3 review hardening (dead ack-path, chain crypto…",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-06T23:07:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c2e429fb6378fd7070b43b71fb884471b861396e",
          "body": "…oofs\n\nMulti-massif catch-up + batch coalescing, reusing the sealer's already-computed\nper-seal proofs — no massif node data is read for earlier massifs.\n\n- publishproof (Approach C): AssemblePublish's catch-up path now builds the\n  consistency-proof chain by RELAYING each pending checkpoint's own e\n[…]\nn); consumer coalesce\ngrouping keeps the highest massif with the rest as subsumed siblings.\ngofmt/vet/-race green.\n\nRefs FOR-317, plan-2607-08.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(publisher): coalesce-to-highest via chained embedded per-seal pr…",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-06T22:50:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "bbf1e9349627920fee93866e2855026ed5943c87",
          "body": "…1/2/3/4/5]\n\nRound-2 review found a checkpoint-mis-ack: a stale catch-up proof reverts with\nerrors outside the transient allowlist, and unknown reverts defaulted to ack,\nso a valid-but-not-yet-anchored checkpoint could be acked and dropped.\n\nMake the ack decision authoritative on on-chain size inste\n[…]\nision\n(superseded/reverted/uncertain), batch superseded-acks, RevertLabel, R2-4\nvalidation. gofmt/vet/-race green.\n\nRefs FOR-317, plan-2607-08.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(publisher): authoritative ack-on-revert via logState re-read [R2-…",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-06T22:12:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2913ea4ce75a6064b995ba05bec8a90d823ea2e7",
          "body": "The publisher EOA is single-writer (nothing else sends from the wallet;\npreserved under scaling by wallet-per-replica), so the account nonce only\nadvances by our own admissions. Exploit that:\n\n- Per-chain in-process nonce counter (chainNonce, batchsubmit.go): while txs\n  are in flight, hand out nonc\n[…]\n it.\nUnit tests: reseed-only-when-drained + in-flight continuity, reconcile\nroll-back. gofmt/vet/-race green.\n\nRefs FOR-317, plan-2607-07 (P9).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(publisher): single-writer in-process nonce counter",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-06T21:21:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fa81796a89f3f2a81119317a16a20abce407fe37",
          "body": "…IP-1559)\n\nReplaces the per-tx submit path in the daemon with a batched per-chain\nsubmitter (plan-2607-07 follow-up; supersedes the P2 lock-through-wait).\n\n- Sequential admission: read PendingNonceAt once per chain, send N, N+1, …\n  in order under a send-lock held only across the sends (not the rece\n[…]\nack on admission failure, receipt timeout, and\n  transient/terminal receipt classification. gofmt/vet/-race green.\n\nRefs FOR-317, plan-2607-07.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(publisher): batched per-chain submitter (sequential admission, E…",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-06T19:04:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "80489b8951a325db0eb79f763df85f436feef016",
          "body": "…k) [P3]\n\nPublicBucketGetter issues anonymous GETs; pointing it at R2_URL (the SigV4\nS3-API endpoint) of a credentialed bucket returns 403, which surfaced as a\ngeneric error and an infinite queue-redelivery loop. Remove the silent\nGRANT_STORE_URL -> R2_URL fallback and reject GRANT_STORE_URL == R2_U\n[…]\nL at\nconfig validation with a clear message. GRANT_STORE_URL must be the anonymous\npublic-read bucket domain.\n\nRefs FOR-317, plan-2607-07 (P3).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(publisher): require distinct GRANT_STORE_URL (drop R2_URL fallbac…",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-06T12:36:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a909a79b2d53a01a2c39d652d5a52fc3963375ad",
          "body": "…ants\n\nAddresses the plan-2607-07 review block (P1/P5/P13) on the publisher service.\n\n- P1 (High): split revert classification. Transient reverts (SizeMustIncrease,\n  InvalidConsistencyProof, MinGrowthNotMet) — the on-chain state advancing under\n  us between read and submit — now yield StatusRetry (\n[…]\nal-success statuses.\n\nTests: revert-retryable classification, gas/receipt config validation.\ngofmt/vet/test green.\n\nRefs FOR-317, plan-2607-07.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(publisher): transient revert retry, per-message ack, config const…",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-06T01:26:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a3639f20698ff2288814ed1fd47d0a6079b299a2",
          "body": "New arbor services/publisher — the one-shot publish core + daemon that\nanchors sealed v3 checkpoints on-chain, per plan-2607-02 (multi-forest,\nmulti-chain; supersedes plan-0033 Phase 3's single-contract design).\n\n- One-shot core (publish.go): checkpoint key -> ResolveForestContract from\n  public R2 \n[…]\n cover key parsing,\n  revert classification, and config validation; gofmt/vet clean.\n\nRefs FOR-317, plan-2607-02, ADR-0034, ADR-0046, ADR-0047.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(publisher): FOR-317 multi-forest checkpoint publisher service",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T20:43:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c66baa16e32ead9e7f9dba429945b20073025820",
          "body": "test(publishproof): captured-grant wire-encoding vector (FOR-328)",
          "is_bot": false,
          "headline": "Merge pull request #35 from forestrie/robin/for-328-captured-grant",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T20:17:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "347b847ec64a2e16310d8822ebd976541c4b1a7b",
          "body": "test(publishproof): multi-massif grant-leaf rollover fixture (FOR-329)",
          "is_bot": false,
          "headline": "Merge pull request #34 from forestrie/robin/for-329-multimassif-rollover",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T20:17:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5b3c66940a945af35a337636330cc06a3273bf9a",
          "body": "…29 review)\n\nReview of the first cut found the \"inclusion proof crosses the massif boundary\"\nclaim was false: for a grant in massif 1 under a separate accumulator peak, the\npath stays within massif 1, so ownerNodeGetter's cross-massif routing — the\nsecond half of the R2 fix — was exercised by no tes\n[…]\nearlier one; and take the accumulator from an independent flat-MMR\n  oracle that materialises cross-massif peaks a per-blob reader cannot hash.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(publishproof): cover ownerNodeGetter cross-massif routing (FOR-3…",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T17:51:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8ff23d59b89fdb8e3778408a025c699703a61e9c",
          "body": "Adds the golden vector whose absence let R1 through: every prior fixture built\nPublishGrant.Grant from the contract constants (gfCreate=1<<32), so the byte\nposition canopy actually emits was never fed to a real publishCheckpoint.\n\nTestCapturedGrantWireEncodingPublish drives a byte-faithful canopy au\n[…]\nract flag-position contract so a future byte-position\nregression (either side) fails in CI. Pairs with the canopy fix (FOR-328).\n\nRefs FOR-328.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(publishproof): captured-grant wire-encoding vector (FOR-328)",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T17:16:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fc0b93ddb90abad709b336779e89d3086d537beb",
          "body": "Adds the end-to-end fixture the merged R2 fix was missing: an owner authority\nlog that spans two massifs (tiny 4-leaf massif height so a handful of entries\nrolls it), with the target grant leaf in massif 1. Asserts:\n\n- FindGrantLeafMMRIndex walks past massif 0 and returns the grant leaf's global\n  m\n[…]\ncrosses the massif boundary (non-empty path read\n  through ownerNodeGetter) and reproduces an owner on-chain accumulator peak.\n\nCloses FOR-329.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(publishproof): multi-massif grant-leaf rollover fixture (FOR-329)",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T17:00:52Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fe0bdde6668f547fcd699c4952ff93db1fb0e5d7",
          "body": "FOR-317 (slices 1-2): multi-forest resolution + publish assembly from public R2",
          "is_bot": false,
          "headline": "Merge pull request #33 from forestrie/robin/for-317-publisher-resolve",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T15:58:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eeffae3a7219a620e14f32d83f90761a039dcf96",
          "body": "Post-review polish for the multi-massif grant leaf fix: a present idtimestamp\nwhose committed leaf does not match the stored grant commitment now returns a\ndistinct ErrGrantLeafMismatch (an integrity failure) rather than being wrapped\nas ErrGrantLeafNotFound and swallowed by the multi-massif walk. Also refresh\nthe AssemblePublish doc comment, which still described the removed\nhead-massif-only assumption.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(publishproof): distinguish grant leaf integrity failure; refresh doc",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T15:57:35Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e9c6037275b89d5b7d15d440356ea3d0bbbadb35",
          "body": "Map the massif-local leaf ordinal to a global mmr index via the massif's\nfirst-leaf index (mc.Start.FirstIndex + local, i.e.\nurkle.LeafOrdinalToMMRIndex) instead of feeding a local ordinal into the\nglobal mmr.MMRIndex. FindGrantLeafMMRIndex walks the owner's massifs so a\ngrant that has rolled past t\n[…]\ng ownerNodeGetter\n(MassifIndexFromMMRIndex) with an IncludedRoot self-check against the owner\naccumulator. Addresses plan-2607-03 R2 / FOR-329.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(publishproof): resolve grant leaf index across owner massifs (R2)",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T15:36:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "551d0988892e2ccb1ba9f572fadab60aa8b0db06",
          "body": "Replace the linear owner-log scan with the computable lookup: ranger\nassigns idtimestamps in strictly increasing order at commit\n(NextIDTimestamp) and indexes every leaf under its idtimestamp\n(IndexLeaf), so leaf order equals key order and the massif v2 index leaf\ntable is binary-searchable by the g\n[…]\nd index entries exactly as the ranger committer\ndoes (fixtureLog.addEntry). The assembly e2e now exercises the indexed\npath end to end on anvil.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(publishproof): grant leaf position is computed, not scanned",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T14:16:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ba12d462cde5f4ab973e0c85da04e24a2c0168e2",
          "body": "…ants\n\nResolves the grant-material design question (plan-2607-02 slice 2): the\nPublishGrant tuple and grantIDTimestampBe come from the stored grant\ntransparent statement (COSE Sign1, grant v0 at unprotected -65538,\nsequenced idtimestamp at -65537 — zero for the root self-grant, matching\nthe live for\n[…]\n256-root contract: bootstrap, authority extend, first child-log\ncheckpoint, and a delegated extend — with no hand-built grant material\nanywhere.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(publishproof): FOR-317 slice 2 — publish assembly from stored gr…",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T14:03:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5b93ba5994df4144729def152ddcfe11951c1114",
          "body": "…n from public R2\n\nResolveForestContract(logId) -> {R, chainId, contract} per ADR-0047 /\nplan-2607-02 D1: global logId->R index (ADR-0036), then the forest\ngenesis chain binding (ADR-0034), falling back to probing the logId as a\nforest root when the index entry is absent (genesis self-indexing is\nbe\n[…]\nconformance fixture set\n(regenerate with UPDATE_RESOLVE_VECTORS=1); wiring the univocity service\ntests to the same vectors is a named follow-up.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(publishproof): FOR-317 slice 1 — multi-forest contract resolutio…",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T13:45:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6baa9c5e36ea8024f1c6fd31a916c3d6d38a0b95",
          "body": "…e-deps\n\nfix(ci): release workflow clones private deps with forestrie-cd app token",
          "is_bot": false,
          "headline": "Merge pull request #32 from forestrie/robin/for-316-release-ci-privat…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T10:51:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "55202dbc778f6fec9f0440abe74db8290da5d1b3",
          "body": "…oken\n\nSame fix as build-deploy (#30): task bootstrap clones the private\ngo-univocity repo over https and the job GITHUB_TOKEN only covers arbor.\nBoth bootstrap sites in the release workflow mint a forestrie-cd app token\nfirst. Unblocks the orchestrator release loop.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(ci): release workflow clones private deps with forestrie-cd app t…",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T10:51:51Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "58518419592671ffccb0e590047835211ed3c151",
          "body": "…eset\n\nfix(custodian): re-ensure custody keys after content-reset destroys versions",
          "is_bot": false,
          "headline": "Merge pull request #31 from forestrie/robin/for-44-ensure-key-after-r…",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T00:23:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "93b4798905d0a4b46ae7b65258b2069cc32ffb10",
          "body": "…ersions\n\nEnsureKeyForOwner hardcoded cryptoKeyVersions/1 for the public key. After a\ncontent-reset (FOR-44) the CryptoKey resources remain but every version is\ndestroyed, so ensure for a previously-known log id failed with\nKEY_DESTROY_SCHEDULED (surfaced by the system tests' fixed c0ffee log ids on\n[…]\nd and\ncreate a fresh version when none is live; extend the public-key retry to\ncover FailedPrecondition while a new version finishes generating.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(custodian): re-ensure custody keys after content-reset destroys v…",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T00:23:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0a4cac60763e0dc1e86d4954d5f2854a3222da44",
          "body": "fix(ci): clone private deps with forestrie-cd app token",
          "is_bot": false,
          "headline": "Merge pull request #30 from forestrie/robin/for-316-ci-private-dep-clone",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T00:09:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "baf44141b0ff4b48dd724f05d3824f086ac9826e",
          "body": "build-deploy has failed since the go-univocity dep landed (#28): the\nbootstrap clones private forestrie repos over https and the job's\nGITHUB_TOKEN only covers this repo. Mint a forestrie-cd app token and route\ngithub https clones through it for the bootstrap step.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(ci): clone private deps with forestrie-cd app token",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T00:08:50Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1be5d6d30c5215a5dc31ccb42386357cc7c4642b",
          "body": "feat(sealer,publishproof,custodian): checkpoint format v3 cutover (FOR-316)",
          "is_bot": false,
          "headline": "Merge pull request #29 from forestrie/robin/for-316-sealer-format-v3",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-05T00:02:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "450286b6f26891538da9c4b9859294a4d689bf55",
          "body": "Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(delegationcert): tidy module for onchain proof tests",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-04T21:55:40Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "86d83022b9dd0edb47f71d550230473dac55a9e8",
          "body": "… proof\n\nCompletes the FOR-316 Cutover C issuer gap and greens the remaining suites\n(Cutover D):\n\n- delegationcert: BuildOnchainDelegationToBeSigned constructs the contract's\n  delegation Sig_structure (domain ‖ logId ‖ mmrStart ‖ mmrEnd ‖ keyX ‖ keyY,\n  delegationVerifier.sol) with the bytes32 log \n[…]\nbootstrap and extend)\n- ranger: massifs index-v2 bloom/urkle module wiring so the full ranger\n  suite (committer, tests) builds and passes again\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(custodian,publishproof): issue and prove the on-chain delegation…",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-04T21:55:24Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f6f4149c930d88972fa66832c5e505f23ea24357",
          "body": "…ckpoint\n\nCutover C slice 2 (FOR-316, FOR-314 Outcome B): the univocity delegation\nproof travels inside the sealed checkpoint object, making the checkpoint the\ncomplete publishable artifact for the delegated path.\n\n- delegationcert: OnchainDelegationProof wire type (plan-0003) and the\n  reserved onc\n[…]\ntodian/coordinator signing the\ndelegation Sig_structure with the root key) is the remaining C work; the\nsealer treats it as optional until then.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sealer,publishproof): on-chain delegation proof rides the v3 che…",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-04T21:24:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7c364d1759db9a657df50cecde57929a7f8e6bfb",
          "body": "…n peak receipts\n\nCutover C slice 1 (FOR-316): repair the two consumers of the go-merklelog\ncheckpoint read API after the format-v3 hard cutover (massifs Cutover B), and\nopt the sealer emission into pre-signed peak inclusion receipts.\n\n- publishproof r2read: GetCheckpoint drops the codec param; seal\n[…]\ntoring\n  self-service inclusion receipts in the v3 seal (plan-0033 locked decision)\n- stress test (integration tag) updated to the v3 read shape\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sealer,publishproof): adopt v3-only checkpoint read API, pre-sig…",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-04T21:09:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "42efee13e861ff456fc7dfdc1bff8ca42d4f9034",
          "body": "Replace the v2 MMRState Sign1 path with the format-v3 emission: read the\nlast checkpoint via DecodeCheckpointReceipt (baseState size = proof\ntree-size-2), build the consistency proof prev->curSize, and\nSignCheckpointReceipt with the delegated COSE signer. putCheckpoint's\noptimistic-concurrency read \n[…]\ne\nlabel-1000 cert injection is dropped here. Sealer *tests* are RED until\nCutover D updates them to v3 — production code compiles and emits v3.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sealer): emit checkpoint format v3 (hard cutover, part A)",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-04T19:53:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0cb9fac696f5d5b84d41afe48934d6b2c37365a6",
          "body": "Option A (single source): the receipt profile lives in go-merklelog\nmassifs. publishproof keeps its calldata-shaped [32]byte types for the\non-chain ABI and delegates DetachedPayload / SigStructure / consistency\nproof + checkpoint receipt encode/decode to massifs via thin type\nadapters. No behaviour change; tracer bullet + round-trips green.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(publishproof): delegate format-v3 receipt codec to go-merklelog",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-04T19:14:10Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "28e4c75b4d601e1fe729d42e07be51341da926e9",
          "body": "Legacy plan-NNNN ids are frozen; new plans use plan-YYMM-NN-<slug>.\nForward-only. See agentfiles workflow/rules/planning.md.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(plans): add date-cohort plan numbering banner",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-04T19:08:38Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d52bfa20662f0ae8f88ccfa54a23984416685030",
          "body": "…(#28)\n\n* feat(publishproof): FOR-316 format-v3 raw-concat detached payload\n\nAlign the Go detached payload with the merged FOR-321 contract: replace\nConsistencyCommitment (sha256 of the packed accumulator) with\nDetachedPayload returning the raw concatenation of the accumulator peaks\n(no hashing), ma\n[…]\norestrie unprotected label for the delegation proof\nwith the sealer change.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "FOR-316 (slices 1-2): publishproof format-v3 payload + receipt codec …",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-04T18:41:57Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "42773fa991dd5c7de09b03b04db895c08387625b",
          "body": "* feat(publishproof): FOR-315 grant leaf commitment and publishCheckpoint calldata\n\nNew shared package services/pkgs/publishproof. Reuses go-univocity/grant\nfor the LibLogState double-SHA256 leaf commitment (pinned against the\ncross-language leaf vectors) and encodes/decodes publishCheckpoint\ncallda\n[…]\noundry is\ninstalled so the anvil tracer-bullet test runs instead of skipping.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "FOR-315: publishproof shared Go package (#26)",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-04T18:36:21Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7834440bd93de073cafdcb8323dabac1d3f46e57",
          "body": "release:build-push must invoke :ranger:build not release:ranger:build.",
          "is_bot": false,
          "headline": "fix(release): call service build tasks from root namespace (#21)",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-04T18:35:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e06c8d32a880c923598535945ec55664d4b0bcc9",
          "body": "Ledger-b bumps all five arbor services to semver; univocity must exist\nin GAR at the release tag or forestrie-b pulls fail (FOR-253 R7).\n\nCo-authored-by: Cursor <cursoragent@cursor.com>",
          "is_bot": false,
          "headline": "fix(release): build and push univocity in semver release loop",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-02T17:44:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "42ba44b23278bd75e5befac9f2a8c4476ec4247c",
          "body": "FOR-253: release fragment carries pullable GAR tag for ledger-b bump.\nCo-authored-by: Cursor <cursoragent@cursor.com>",
          "is_bot": false,
          "headline": "feat(release): include dockerTag in orchestrator release fragment",
          "author_name": "Robin Bryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-02T17:43:53Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "fc070c0df79f5c1bbe56e4760ce2ad8320005015",
          "body": "Use highest semver git tag (not latest GitHub Release) for patch bump;\nskip tag/release steps when orchestrator retries after partial success.",
          "is_bot": false,
          "headline": "fix(release): bump from git tags and idempotent tag create (#23)",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-02T12:29:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2ed40bb164f952a642cad6b1432b15d37085d45c",
          "body": "release:build-push must invoke :ranger:build not release:ranger:build.",
          "is_bot": false,
          "headline": "fix(release): call service build tasks from root namespace (#22)",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-02T12:16:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "932e27eb126a1535b03138d1a7fcc6fbb07893cb",
          "body": "Task SERVICE is a go-task var, not a shell env var; fixes orchestrator\ndispatch release when building semver images.",
          "is_bot": false,
          "headline": "fix(release): use task var in release build-push echo (#20)",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-02T12:10:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d138f5593ea823c4ac8582730b04222efb1b2ad7",
          "body": "Accept ADR-0043 inputs, build from main with patch-bump semver,\nupload release-fragment.jsonc, and create GitHub Release.\n\nCo-authored-by: Cursor <cursoragent@cursor.com>",
          "is_bot": false,
          "headline": "feat(release): add orchestrator workflow_dispatch release path (#19)",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-07-02T11:56:17Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "675f8cefa368cbab6e304f58b5c995138450cc01",
          "body": "Publish semver images only; lane-b GitOps bumps move to the\nrelease-orchestrator promotion gate.\n\nCo-authored-by: Cursor <cursoragent@cursor.com>",
          "is_bot": false,
          "headline": "feat(release): drop ledger-b PR job from release.yaml (FOR-254) (#18)",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-06-30T13:29:26Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2c098d4326e479084e78629da84633e2c97b1ba5",
          "body": "Tighten release workflow to v*.*.* tags with validation, pass VERSION\nto builds, and centralise release build/push in task release:build-push.\nContinuous main pushes keep main-<sha>-<run> tags via build-deploy.\n\nCo-authored-by: Cursor <cursoragent@cursor.com>",
          "is_bot": false,
          "headline": "feat(release): standardise arbor images on semver tags (FOR-255) (#17)",
          "author_name": "robinbryce",
          "author_login": "robinbryce",
          "committed_at": "2026-06-30T13:07:06Z",
          "body_truncated": false,
          "is_coding_agent": true
        }
      ],
      "releases_count": 20,
      "commits_last_year": 579,
      "latest_release_at": "2026-07-24T13:34:53Z",
      "latest_release_tag": "v0.1.24",
      "releases_from_tags": false,
      "days_since_last_push": 2,
      "active_weeks_last_year": 29,
      "days_since_latest_release": 3,
      "mean_days_between_releases": 0.7
    },
    "community": {
      "has_readme": true,
      "has_license": false,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 37,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "github.com/forestrie/arbor",
          "exists": true,
          "license": null,
          "keywords": [],
          "ecosystem": "go",
          "matches_repo": true,
          "registry_url": "https://pkg.go.dev/github.com/forestrie/arbor",
          "is_deprecated": false,
          "latest_version": "v0.1.24",
          "repository_url": "https://github.com/forestrie/arbor",
          "versions_count": 24,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": null,
          "latest_published_at": "2026-07-24T13:04:31Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 3
        }
      ]
    },
    "popularity": {
      "forks": 1,
      "stars": 0,
      "watchers": 0,
      "fork_history": {
        "days": [
          {
            "date": "2026-07-09",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 1,
        "total_forks": 1
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0,
        "collected_at": null
      },
      "open_issues_and_prs": 1
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [
        "services/custodian/src/go.mod",
        "services/pkgs/delegatekeys/go.mod",
        "services/pkgs/delegationcert/go.mod",
        "services/pkgs/logid/go.mod",
        "services/pkgs/logredact/go.mod",
        "services/pkgs/publishproof/go.mod",
        "services/pkgs/s3storage/go.mod",
        "services/publisher/src/go.mod",
        "services/ranger/src/go.mod",
        "services/scout/src/go.mod",
        "services/sealer/src/go.mod",
        "services/sharder/go.mod",
        "services/signer/src/go.mod",
        "services/univocity/src/go.mod"
      ],
      "largest_source_bytes": 31405,
      "source_files_sampled": 302,
      "oversized_source_files": 0,
      "agent_instruction_files": [
        ".cursor/rules/branch-naming.mdc",
        ".cursor/rules/commit-conventions.mdc",
        ".cursor/rules/docs-workflow.mdc",
        ".cursor/rules/go-comments.mdc",
        ".cursor/rules/linear-mcp-forestrie.mdc",
        ".cursor/rules/types-single-responsibility.mdc",
        "AGENTS.md",
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 4169
    },
    "dependencies": {
      "manifests": [],
      "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": [],
      "dependencies": [
        {
          "name": "k8s.io/api",
          "manifest": "services/sharder/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.34.1"
        },
        {
          "name": "k8s.io/apimachinery",
          "manifest": "services/sharder/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.34.1"
        },
        {
          "name": "k8s.io/client-go",
          "manifest": "services/sharder/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.34.1"
        },
        {
          "name": "sigs.k8s.io/controller-runtime",
          "manifest": "services/sharder/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.22.3"
        }
      ],
      "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": 1,
        "merged_prs": 80,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 3
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "robinbryce",
          "commits": 333,
          "avatar_url": "https://avatars.githubusercontent.com/u/4013001?v=4"
        },
        {
          "type": "User",
          "login": "fluxcdbot",
          "commits": 246,
          "avatar_url": "https://avatars.githubusercontent.com/u/53427796?v=4"
        }
      ],
      "contributors_sampled": 2,
      "top_contributor_share": 0.575
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "build-deploy.yml",
        "go-test.yml",
        "release.yaml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "go.sum"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 7,
            "reason": "23 out of 30 merged PRs checked by a CI test -- score normalized to 7",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 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": 0,
            "reason": "license file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 10,
            "reason": "GitHub workflow tokens follow principle of least privilege",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 0,
            "reason": "29 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "4af072e25c9518340a1c876906aaae52d24a331b",
        "ran_at": "2026-07-28T02:00:22Z",
        "aggregate_score": 3.8,
        "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-25T18:36:09Z",
      "oldest_open_prs": [
        {
          "number": 67,
          "created_at": "2026-07-15T13:07:43Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-25T18:27:58Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/forestrie/arbor",
    "host": "github.com",
    "name": "arbor",
    "owner": "forestrie"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 55,
      "inputs": {
        "security": 38,
        "vitality": 90,
        "community": 12,
        "governance": 55,
        "engineering": 67
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "excellent",
        "name": "Vitality",
        "value": 90,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 84,
            "inputs": {
              "commits_last_year": 579,
              "human_commit_share": 1,
              "days_since_last_push": 2,
              "active_weeks_last_year": 29
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 2 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 2
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "29/52 weeks with commits",
                "points": 20.1,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 29
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "579 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 579
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 20,
              "latest_release_tag": "v0.1.24",
              "releases_from_tags": false,
              "days_since_latest_release": 3,
              "mean_days_between_releases": 0.7
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "20 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 20
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 3 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 3
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~0.7 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 0.7
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "maintained",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": null,
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": 2,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 2 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 2
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "critical",
        "name": "Community & Adoption",
        "value": 12,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 1,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "1 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "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": "critical",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 25,
            "inputs": {
              "has_readme": true,
              "has_license": false,
              "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": "no license file detected",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "license_absent",
                    "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": "moderate",
        "name": "Sustainability & Governance",
        "value": 55,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 24,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 2,
              "top_contributor_share": 0.575
            },
            "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 57% of commits",
                "points": 9.6,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 57
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "2 contributors",
                "points": 2.7,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "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": "moderate",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 69,
            "inputs": {
              "merged_prs": 80,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 3
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "80/83 decided PRs merged",
                "points": 36.9,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 80,
                      "decided": 83
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 42,
            "inputs": {
              "followers": 0,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "forestrie",
              "public_repos": 19,
              "account_age_days": 370
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "0 followers of forestrie",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 0,
                      "login": "forestrie"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "19 public repos, account ~1 yr old",
                "points": 11.5,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 19
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 1
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "github.com/forestrie/arbor"
              ],
              "ecosystems": "go",
              "any_deprecated": false,
              "min_days_since_publish": 3
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on go",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "go"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 3 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 3
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "24 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 24
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 67,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 62,
            "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": "3 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "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": "23 out of 30 merged PRs checked by a CI test -- score normalized to 7",
                "points": 14,
                "status": "partial",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "good",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 75,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "at_risk",
        "name": "Security",
        "value": 38,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Packaging, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "packaging",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 38,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 3.8
            },
            "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": "23 out of 30 merged PRs checked by a CI test -- score normalized to 7",
                "points": 1.8,
                "status": "partial",
                "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/30 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 not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "GitHub workflow tokens follow principle of least privilege",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "29 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 1
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "good",
        "name": "AI Readiness",
        "value": 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": 1,
              "agent_instruction_files": [
                ".cursor/rules/branch-naming.mdc",
                ".cursor/rules/commit-conventions.mdc",
                ".cursor/rules/docs-workflow.mdc",
                ".cursor/rules/go-comments.mdc",
                ".cursor/rules/linear-mcp-forestrie.mdc",
                ".cursor/rules/types-single-responsibility.mdc",
                "AGENTS.md",
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 4169
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": ".cursor/rules/branch-naming.mdc, .cursor/rules/commit-conventions.mdc, .cursor/rules/docs-workflow.mdc, .cursor/rules/go-comments.mdc, .cursor/rules/linear-mcp-forestrie.mdc, .cursor/rules/types-single-responsibility.mdc, AGENTS.md, CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".cursor/rules/branch-naming.mdc, .cursor/rules/commit-conventions.mdc, .cursor/rules/docs-workflow.mdc, .cursor/rules/go-comments.mdc, .cursor/rules/linear-mcp-forestrie.mdc, .cursor/rules/types-single-responsibility.mdc, AGENTS.md, 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": "100 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 100,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 66,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "go.sum"
              ],
              "has_dockerfile": true,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0.73,
              "toolchain_manifests": [
                "services/custodian/src/go.mod",
                "services/pkgs/delegatekeys/go.mod",
                "services/pkgs/delegationcert/go.mod",
                "services/pkgs/logid/go.mod",
                "services/pkgs/logredact/go.mod",
                "services/pkgs/publishproof/go.mod",
                "services/pkgs/s3storage/go.mod",
                "services/publisher/src/go.mod",
                "services/ranger/src/go.mod",
                "services/scout/src/go.mod",
                "services/sealer/src/go.mod",
                "services/sharder/go.mod",
                "services/signer/src/go.mod",
                "services/univocity/src/go.mod"
              ],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "services/custodian/src/go.mod, services/pkgs/delegatekeys/go.mod, services/pkgs/delegationcert/go.mod (toolchain convention, no task runner)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "toolchain_convention",
                    "params": {
                      "files": "services/custodian/src/go.mod, services/pkgs/delegatekeys/go.mod, services/pkgs/delegationcert/go.mod"
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "Go (statically typed)",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Go"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "Dockerfile, lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Dockerfile, lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "73 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 73,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "primary_language": "Go",
              "largest_source_bytes": 31405,
              "source_files_sampled": 302,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Go (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Go"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/302 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 302,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-28T02:00:41.131276Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/f/forestrie/arbor.svg",
  "full_name": "forestrie/arbor",
  "license_state": "absent",
  "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 agregadasGo.