Öffentliches Register
Software-GesundheitsberichtSchema 0.26.0 · Metriken 1.13.0 · 2026-07-22 03:06 UTC

codespeak-dev / twip

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

GoApache-2.0★ 0 Sterne⑂ 0 Forksseit Juni 2026Auf GitHub ansehen ↗

codespeak-dev/twip erreicht einen Gesundheitsindex von 49 von 100 und liegt damit im Bereich Gefährdet. Am stärksten schneidet es bei Vitality (69/100) ab, am schwächsten bei Community & Adoption (24/100). Zuletzt vor 4 Tagen aktualisiert. 2 Mitwirkende tragen den Großteil der jüngsten Arbeit.

49
gesamt / 100
Gefährdet

Software-Gesundheitsindex

Metriken werden auf einer Skala von 1–100 in gewichtete Kategorien gruppiert. Der Gesamtwert beginnt als ihr Mittel; sobald öffentliche Evidenz die Richtlinie für Hochrisikojurisdiktionen auslöst, wird die Bewertung angepasst und erhält die Obergrenze 49 (Gefährdet). AI Readiness liegt außerhalb.

49
Exzellent85-100Vorbildlich; erfüllt im Wesentlichen alle geprüften Kriterien
Gut70-84Gesund; geringfügige Lücken
Mittel50-69Akzeptabel mit deutlichen Lücken; Überprüfung empfohlen
Gefährdet30-49Erhebliche Schwächen; eine Übernahme erfordert Vorsicht
Kritisch1-29Schwerwiegende Probleme (aufgegeben, nur ein Maintainer, keine Hygiene)
VitalitätCommunity &VerbreitungNachhaltigkeit &GovernanceEngineering-QualitätSicherheitAI Readiness

Bewertungsprofil

Jede Achse ist eine Kategorie. Die Form zählt mehr als der Durchschnitt — ein gesundes Projekt füllt die gesamte Fläche, während ein Profil aus Spitzen und Kratern bedeutet, dass Stärke in einer Dimension Risiken in einer anderen verdeckt.

Eigentümerschaft

CodeSpeakOrganisation
29 Follower12 öffentliche Reposseit Juni 2025

Dieses Repository wird von einer Organisation getragen — geteilte, rechenschaftspflichtige Trägerschaft, die jeden einzelnen Maintainer überdauern kann.

Paket-Ökosysteme

RegistryPaketVersionDownloads / MonatVersionenZuletzt veröffentlicht
Gogithub.com/codespeak-dev/twipv0.4.7-15vor 4 Tagen

Metriken nach Kategorie

Vitalität

Lebt das Projekt — wird Code geschrieben und werden Releases ausgeliefert?

69Mittel · 22 % des Gesamtindex
Wie die Bewertung erfolgt
36/36Push-Aktualität — letzter Push vor 4 Tagen
4.2/36Commit-Rhythmus — 6/52 Wochen mit Commits
16.6/18Commit-Volumen — 70 Commits im letzten Jahr
0/10OpenSSF Scorecard: Maintained — project was created within the last 90 days. Please review its contents carefully
Verwendete Eingangsdaten
commits_last_year70
human_commit_share1
days_since_last_push4
active_weeks_last_year6
Wie die Bewertung erfolgt
16.2/27Liefert Releases aus — 15 Versions-Tags (keine GitHub-Releases)
36/36Release-Aktualität — letztes Release vor 4 Tagen
27/27Release-Rhythmus — ein Release etwa alle 2,8 Tage
0/10OpenSSF Scorecard: Signed-Releases — keine Daten
Verwendete Eingangsdaten
releases_count15
latest_release_tagv0.4.7
releases_from_tagsja
days_since_latest_release4
mean_days_between_releases2,8
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): OpenSSF Scorecard: Signed-Releases. Die verbleibenden Gewichte wurden renormalisiert.

Community & Verbreitung

Hat das Projekt Nutzer, Downloads, Aufmerksamkeit und ein einladendes Umfeld für Beitragende?

24Kritisch · 18 % des Gesamtindex
Wie die Bewertung erfolgt
0/60Stars — 0 Stars
0/25Forks — 0 Forks
0/15Watcher — 0 Watcher
Verwendete Eingangsdaten
forks0
stars0
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Wie die Bewertung erfolgt
22.5/22.5README
22.5/22.5Lizenz — anerkannte Lizenz (Apache-2.0)
0/18CONTRIBUTING-Leitfaden
0/13.5Verhaltenskodex
0/7.2Issue-Vorlage
0/6.3PR-Vorlage
Verwendete Eingangsdaten
has_readmeja
has_licenseja
has_contributingnein
has_issue_templatenein
has_code_of_conductnein
has_pull_request_templatenein

Nachhaltigkeit & Governance

Überdauert das Projekt die Menschen, die es tragen — Bus-Faktor, Reaktionsfähigkeit, Trägerschaft und Paketpflege?

67Mittel · 24 % des Gesamtindex
Wie die Bewertung erfolgt
25.2/54Bus-Faktor — 2 Beitragende decken die Hälfte aller Commits ab
13.8/22.5Commit-Verteilung — wichtigste beitragende Person verfasste 39 % der Commits
5.4/13.5Breite der Beitragenden — 4 Beitragende
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Verwendete Eingangsdaten
bus_factor2
contributors_sampled4
top_contributor_share0,386
Wie die Bewertung erfolgt
46.8/46.8Issue-Lösungsquote — 100 % der Issues geschlossen
38.2/38.3PR-Annahme — 4/4 entschiedene PRs gemergt
0/15OpenSSF Scorecard: Code-Review — Found 1/23 approved changesets -- score normalized to 0
Verwendete Eingangsdaten
merged_prs4
open_issues0
closed_issues2
issue_closed_ratio1
closed_unmerged_prs0
Wie die Bewertung erfolgt
30/30Organisatorische Trägerschaft — im Besitz einer Organisation
0/20Verifizierte Domain
10.6/25Reichweite des Inhabers — 29 Follower von codespeak-dev
10.3/25Kontohistorie — 12 öffentliche Repos, Kontoalter ca. 1 Jahre
Verwendete Eingangsdaten
followers29
owner_typeOrganization
is_verified
owner_logincodespeak-dev
public_repos12
account_age_days391

Paketpflege

100Exzellent
Wie die Bewertung erfolgt
25/25Veröffentlicht & auflösbar — 1 Paket(e) auf go
35/35Veröffentlichungsaktualität — letzte Veröffentlichung vor 4 Tagen
20/20Versionshistorie — 15 veröffentlichte Versionen
20/20Nicht veraltet — aktiv, nicht veraltet oder zurückgezogen
Verwendete Eingangsdaten
packagesgithub.com/codespeak-dev/twip
ecosystemsgo
any_deprecatednein
min_days_since_publish4

Engineering-Qualität

Sind grundlegende Engineering- und Dokumentationspraktiken vorhanden?

44Gefährdet · 20 % des Gesamtindex
Wie die Bewertung erfolgt
0/24CI-Workflows
24/24Tests vorhanden
0/16Linter-Konfiguration
0/9.6Pre-Commit-Hooks
0/6.4.editorconfig
0/20OpenSSF Scorecard: CI-Tests — 0 out of 3 merged PRs checked by a CI test -- score normalized to 0
Verwendete Eingangsdaten
has_cinein
has_testsja
has_editorconfignein
has_linter_confignein
has_precommit_confignein
Wie die Bewertung erfolgt
30/30README
25/25Dokumentationsverzeichnis
0/15Dokumentations-/Homepage-Site
10/10Repository-Beschreibung
0/10Topics
10/10Wiki
Verwendete Eingangsdaten
topics
has_wikija
homepage
has_readmeja
has_docs_dirja
has_descriptionja

Sicherheit

Sind die sichtbaren Sicherheits- und Lieferkettenpraktiken belastbar, ohne ungeklärte Exposition gegenüber Hochrisikojurisdiktionen?

30Gefährdet · 16 % des Gesamtindex

Sicherheitslage

30Gefährdet
Wie die Bewertung erfolgt
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — 0 out of 3 merged PRs checked by a CI test -- score normalized to 0
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 1/23 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
0/10Dangerous-Workflow — keine Daten
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Lizenz — license file detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
0/5Packaging — keine Daten
5/5Pinned-Dependencies — all dependencies are pinned
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — keine Daten
0/7.5Token-Permissions — keine Daten
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Verwendete Eingangsdaten
sourceopenssf_scorecard
checks_evaluated14
scorecard_versionv5.5.0
checks_inconclusive4
scorecard_aggregate3
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): dangerous_workflow, packaging, signed_releases, token_permissions. Die verbleibenden Gewichte wurden renormalisiert.

AI Readiness

Wie gut ist das Repository dafür ausgestattet, mit KI-Coding-Agenten entwickelt und gepflegt zu werden? Ein unabhängiges, experimentelles Badge — Gewicht 0,0, es wird eigenständig ausgewiesen und verändert den Gesamt-Gesundheitswert nicht.

68Mittel · 0 % des Gesamtindex
Wie die Bewertung erfolgt
0/45Agentenanweisungen — keine CLAUDE.md / AGENTS.md / Editor-Regeln
0/15Maschinenlesbare Doku (llms.txt)
40/40Lesbare Commit-Historie — 63 von 70 menschlichen Commits benennen ihre Absicht (strukturierter Betreff oder erläuternder Text)
Verwendete Eingangsdaten
has_llms_txtnein
legible_history_share0,9
agent_instruction_files
agent_instruction_max_bytes
Wie die Bewertung erfolgt
12.6/18Bootstrap mit einem Befehl — go.mod (Toolchain-Konvention, kein Task-Runner)
22/22Automatisierte Tests
0/11Lint-/Format-Konfiguration
11/11Statische Typprüfung — Go (statisch typisiert)
10/10Reproduzierbare Umgebung — lockfile
10/10Belegte Agentenpraxis — 35 der letzten 70 Commits von Agenten verfasst oder ihnen zugeschrieben
0/8Automatisierte Wartung — keine automatisierten Abhängigkeits-Updates beobachtet
10/10OpenSSF Scorecard: Pinned-Dependencies — all dependencies are pinned
Verwendete Eingangsdaten
has_nixnein
has_testsja
lockfilesgo.sum
has_dockerfilenein
typed_languageja
bootstrap_files
has_devcontainernein
has_linter_confignein
typecheck_configs
agent_commit_share0,5
toolchain_manifestsgo.mod
dependency_bot_commit_share0
Wie die Bewertung erfolgt
45/45Typprüfbarer Code — Go (statisch typisiert)
55/55Handhabbare Dateigrößen — 0/70 Quelldateien über 60 KB
Verwendete Eingangsdaten
primary_languageGo
largest_source_bytes26.159
source_files_sampled70
oversized_source_files0

Eckdaten

0GitHub-Sterne
4Mitwirkende
70Commits, letzte 12 Monate
4Tage seit letztem Push
15Releases
2Bus-Faktor
0offene Issues
GoPaket-Ökosysteme

Warnungen zur Datenerhebung

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

Weitere Details

OpenSSF Scorecard 3.0 / 10
3.0Gesamtwert

Unabhängige, werkzeugneutrale Sicherheitsbewertung durch das quelloffene OpenSSF Scorecard. Jede Prüfung honoriert eine Sicherheits-Praxis, nicht das Werkzeug eines bestimmten Anbieters. Prüfungen, die Scorecard nicht ermitteln konnte, sind mit k. A. markiert und vom Sicherheitswert ausgeschlossen (nie als null gezählt).Scorecard v5.5.0 · 2026-07-22 03:06 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
0CI-Tests0 out of 3 merged PRs checked by a CI test -- score normalized to 0
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 1/23 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
k. A.Dangerous-Workflowno workflows found
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
k. A.Packagingpackaging workflow not detected
10Pinned-Dependenciesall dependencies are pinned
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
k. A.Signed-Releasesno releases found
k. A.Token-PermissionsNo tokens found
10Vulnerabilities0 existing vulnerabilities detected
Direkte Abhängigkeiten 1
RegistryPaketVersionsvorgabeManifest
Gogithub.com/spf13/cobrav1.10.2go.mod
Alle Abhängigkeiten nicht erhoben

Der aufgelöste Abhängigkeitssatz konnte für diesen Bericht nicht erhoben werden: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

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

Bewertungen sind Signale, keine Garantien. Sie spiegeln öffentlich sichtbare Praxis auf GitHub wider — kein Code-Audit und keine Sicherheitsgarantie.

Fehlende Daten werden ausgeschlossen und die Gewichte neu normiert, nie als null bewertet. Die Methodik ist versioniert und offen: Metriken v1.13.0, Schema v0.26.0 — vollständige Methodik · Metriken-Wiki.

Wie ein einzelnes Ergebnis im Gesamtregister steht: aggregierte StatistikenGo.