Öffentliches Register
Software-GesundheitsberichtSchema 0.26.0 · Metriken 1.13.0 · 2026-07-22 19:08 UTC

nathanramoscfa / roadmodel

Recommends the right AI model, platform, and settings for any prompt — grounded in public benchmarks and per-category ratings. BYO-key CLI, MCP server, and web app.

Python · TypeScriptApache-2.0★ 1 Stern⑂ 1 Forkseit Mai 2026Auf GitHub ansehen ↗

nathanramoscfa/roadmodel erreicht einen Gesundheitsindex von 61 von 100 und liegt damit im Bereich Mittel. Am stärksten schneidet es bei Engineering Quality (86/100) ab, am schwächsten bei Security (41/100). Zuletzt heute aktualisiert. Ein einzelner Mitwirkender trägt den Großteil der jüngsten Arbeit.

61
gesamt / 100
Mittel

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.

61
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

Nathan Ramos, CFAPersönliches Konto
25 Follower21 öffentliche Reposseit Juni 2021

Dieses Repository gehört einem persönlichen Konto. Ein Projekt mit nur einem Eigentümer trägt ein höheres Kontinuitätsrisiko als ein organisationsgetragenes.

Paket-Ökosysteme

RegistryPaketVersionDownloads / MonatVersionenZuletzt veröffentlichtTags
PyPIroadmodel0.2.29-34vor 0 Tagenaianthropiccligeminillmmodel-selectionopenai

Metriken nach Kategorie

Vitalität

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

76Gut · 22 % des Gesamtindex
Wie die Bewertung erfolgt
36/36Push-Aktualität — letzter Push vor 0 Tagen
7.6/36Commit-Rhythmus — 11/52 Wochen mit Commits
18/18Commit-Volumen — 391 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_year391
human_commit_share0,83
days_since_last_push0
active_weeks_last_year11
Wie die Bewertung erfolgt
27/27Liefert Releases aus — 36 Releases veröffentlicht
36/36Release-Aktualität — letztes Release vor 0 Tagen
27/27Release-Rhythmus — ein Release etwa alle 1,9 Tage
8/10OpenSSF Scorecard: Signed-Releases — 5 out of the last 5 releases have a total of 5 signed artifacts.
Verwendete Eingangsdaten
releases_count36
latest_release_tagv0.2.29
releases_from_tagsnein
days_since_latest_release0
mean_days_between_releases1,9

Community & Verbreitung

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

43Gefährdet · 18 % des Gesamtindex
Wie die Bewertung erfolgt
0/60Stars — 1 Stars
0/25Forks — 1 Forks
0/15Watcher — 0 Watcher
Verwendete Eingangsdaten
forks1
stars1
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)
18/18CONTRIBUTING-Leitfaden
13.5/13.5Verhaltenskodex
0/7.2Issue-Vorlage
6.3/6.3PR-Vorlage
Verwendete Eingangsdaten
has_readmeja
has_licenseja
has_contributingja
has_issue_templatenein
has_code_of_conductja
has_pull_request_templateja

Nachhaltigkeit & Governance

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

54Mittel · 24 % des Gesamtindex
Wie die Bewertung erfolgt
9/54Bus-Faktor — 1 Beitragende decken die Hälfte aller Commits ab
0/22.5Commit-Verteilung — wichtigste beitragende Person verfasste 100 % der Commits
1.4/13.5Breite der Beitragenden — 1 Beitragende
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Verwendete Eingangsdaten
bus_factor1
contributors_sampled1
top_contributor_share1
Wie die Bewertung erfolgt
34.9/46.8Issue-Lösungsquote — 75 % der Issues geschlossen
37.1/38.3PR-Annahme — 354/365 entschiedene PRs gemergt
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Verwendete Eingangsdaten
merged_prs354
open_issues24
closed_issues71
issue_closed_ratio0,747
closed_unmerged_prs11
Wie die Bewertung erfolgt
10/30Organisatorische Trägerschaft — persönliches (Nutzer-)Konto
0/20Verifizierte Domain — für Nutzerkonten nicht anwendbar
10.2/25Reichweite des Inhabers — 25 Follower von nathanramoscfa
19.9/25Kontohistorie — 21 öffentliche Repos, Kontoalter ca. 5 Jahre
Verwendete Eingangsdaten
followers25
owner_typeUser
is_verified
owner_loginnathanramoscfa
public_repos21
account_age_days1.854
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Verifizierte Domain. Die verbleibenden Gewichte wurden renormalisiert.

Paketpflege

100Exzellent
Wie die Bewertung erfolgt
25/25Veröffentlicht & auflösbar — 1 Paket(e) auf pypi
35/35Veröffentlichungsaktualität — letzte Veröffentlichung vor 0 Tagen
20/20Versionshistorie — 34 veröffentlichte Versionen
20/20Nicht veraltet — aktiv, nicht veraltet oder zurückgezogen
Verwendete Eingangsdaten
packagesroadmodel
ecosystemspypi
any_deprecatednein
min_days_since_publish0

Engineering-Qualität

Sind grundlegende Engineering- und Dokumentationspraktiken vorhanden?

86Exzellent · 20 % des Gesamtindex
Wie die Bewertung erfolgt
24/24CI-Workflows — 14 Workflow(s)
24/24Tests vorhanden
16/16Linter-Konfiguration — .eslintrc.json
0/9.6Pre-Commit-Hooks
0/6.4.editorconfig
20/20OpenSSF Scorecard: CI-Tests — 30 out of 30 merged PRs checked by a CI test -- score normalized to 10
Verwendete Eingangsdaten
has_cija
has_testsja
has_editorconfignein
has_linter_configja
has_precommit_confignein

Dokumentation

90Exzellent
Wie die Bewertung erfolgt
30/30README
25/25Dokumentationsverzeichnis
15/15Dokumentations-/Homepage-Site — https://roadmodel-web.vercel.app
10/10Repository-Beschreibung
0/10Topics
10/10Wiki
Verwendete Eingangsdaten
topics
has_wikija
homepagehttps://roadmodel-web.vercel.app
has_readmeja
has_docs_dirja
has_descriptionja

Sicherheit

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

41Gefährdet · 16 % des Gesamtindex

Sicherheitslage

41Gefährdet
Wie die Bewertung erfolgt
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — keine Daten
2.5/2.5CI-Tests — 30 out of 30 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
10/10Dangerous-Workflow — no dangerous workflow patterns detected
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
5/5Packaging — packaging workflow detected
0.5/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 1
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
5/5Security-Policy — security policy file detected
6/7.5Signed-Releases — 5 out of the last 5 releases have a total of 5 signed artifacts.
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0.8/7.5Vulnerabilities — 9 existing vulnerabilities detected
Verwendete Eingangsdaten
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate4,1
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): branch_protection. 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.

53Mittel · 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 — 83 von 83 menschlichen Commits benennen ihre Absicht (strukturierter Betreff oder erläuternder Text)
Verwendete Eingangsdaten
has_llms_txtnein
legible_history_share1
agent_instruction_files
agent_instruction_max_bytes
Wie die Bewertung erfolgt
0/18Bootstrap mit einem Befehl
22/22Automatisierte Tests
11/11Lint-/Format-Konfiguration — .eslintrc.json
11/11Statische Typprüfung — web/tsconfig.json
10/10Reproduzierbare Umgebung — Dockerfile, lockfile
10/10Belegte Agentenpraxis — 84 der letzten 100 Commits von Agenten verfasst oder ihnen zugeschrieben
0/8Automatisierte Wartung — keine automatisierten Abhängigkeits-Updates beobachtet
1/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 1
Verwendete Eingangsdaten
has_nixnein
has_testsja
lockfilespackage-lock.json
has_dockerfileja
typed_languagenein
bootstrap_files
has_devcontainernein
has_linter_configja
typecheck_configsweb/tsconfig.json
agent_commit_share0,84
toolchain_manifests
dependency_bot_commit_share0
Wie die Bewertung erfolgt
27/45Typprüfbarer Code — Python mit Typprüfungs-Konfiguration (web/tsconfig.json)
55/55Handhabbare Dateigrößen — 0/237 Quelldateien über 60 KB
Verwendete Eingangsdaten
primary_languagePython
largest_source_bytes51.420
source_files_sampled237
oversized_source_files0
Wie die Bewertung erfolgt
0/40API-Schema (OpenAPI/GraphQL/proto)
20/20MCP-Server
0/40Lauffähige Beispiele
Verwendete Eingangsdaten
example_dirs
has_mcp_signalja
api_schema_files

Eckdaten

1GitHub-Sterne
1Mitwirkende
391Commits, letzte 12 Monate
0Tage seit letztem Push
36Releases
1Bus-Faktor
24offene Issues
npm, PyPIPaket-Ökosysteme

Warnungen zur Datenerhebung

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • Could not fetch pypi package 'roadmodel-service' from its registry
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository
  • deps.dev does not index pypi:roadmodel@0.2.29; advisories assessed against the repository dependency graph instead

Weitere Details

OpenSSF Scorecard 4.1 / 10
4.1Gesamtwert

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 19:07 UTC

10Binary-Artifactsno binaries found in the repo
k. A.Branch-Protectioninternal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
10CI-Tests30 out of 30 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
10Dangerous-Workflowno dangerous workflow patterns detected
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
10Packagingpackaging workflow detected
1Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 1
0SASTSAST tool is not run on all commits -- score normalized to 0
10Security-Policysecurity policy file detected
8Signed-Releases5 out of the last 5 releases have a total of 5 signed artifacts.
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
1Vulnerabilities9 existing vulnerabilities detected
Direkte Abhängigkeiten 15
RegistryPaketVersionsvorgabeManifest
PyPIclick>=8.3.3pyproject.toml
PyPIroadmodel>=0.2.29,<0.3service/pyproject.toml
PyPIfastapi>=0.110service/pyproject.toml
PyPIuvicorn>=0.27service/pyproject.toml
PyPIpydantic>=2.6service/pyproject.toml
npm@google/genai^2.6.0web/package.json
npm@supabase/ssr^0.10.3web/package.json
npm@supabase/supabase-js^2.106.0web/package.json
npm@upstash/ratelimit^2.0.8web/package.json
npm@upstash/redis^1.38.0web/package.json
npmlucide-react^0.511.0web/package.json
npmnext^15.3.2web/package.json
npmreact^19.1.0web/package.json
npmreact-dom^19.1.0web/package.json
npmzod^3.25.28web/package.json
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": 3620,
      "has_wiki": true,
      "homepage": "https://roadmodel-web.vercel.app",
      "languages": {
        "CSS": 973,
        "Shell": 142540,
        "Python": 1109485,
        "PLpgSQL": 17050,
        "Dockerfile": 813,
        "JavaScript": 5482,
        "TypeScript": 615065
      },
      "pushed_at": "2026-07-22T17:59:20Z",
      "created_at": "2026-05-07T16:58:09Z",
      "owner_type": "User",
      "updated_at": "2026-07-22T17:59:44Z",
      "description": "Recommends the right AI model, platform, and settings for any prompt — grounded in public benchmarks and per-category ratings. BYO-key CLI, MCP server, and web app.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "Apache-2.0",
      "default_branch": "main",
      "license_spdx_raw": "Apache-2.0",
      "primary_language": "Python",
      "significant_languages": [
        "Python",
        "TypeScript"
      ]
    },
    "owner": {
      "blog": null,
      "name": "Nathan Ramos, CFA",
      "type": "User",
      "login": "nathanramoscfa",
      "company": null,
      "location": null,
      "followers": 25,
      "avatar_url": "https://avatars.githubusercontent.com/u/86393277?v=4",
      "created_at": "2021-06-24T03:26:51Z",
      "is_verified": null,
      "public_repos": 21,
      "account_age_days": 1854
    },
    "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.2.29",
          "kind": "patch",
          "published_at": "2026-07-22T17:37:36Z"
        },
        {
          "tag": "v0.2.28",
          "kind": "patch",
          "published_at": "2026-07-21T22:03:55Z"
        },
        {
          "tag": "v0.2.27",
          "kind": "patch",
          "published_at": "2026-07-19T21:49:41Z"
        },
        {
          "tag": "v0.2.26",
          "kind": "patch",
          "published_at": "2026-07-19T15:45:00Z"
        },
        {
          "tag": "v0.2.25",
          "kind": "patch",
          "published_at": "2026-07-17T00:32:55Z"
        },
        {
          "tag": "v0.2.24",
          "kind": "patch",
          "published_at": "2026-07-16T16:47:41Z"
        },
        {
          "tag": "v0.2.23",
          "kind": "patch",
          "published_at": "2026-07-16T14:34:20Z"
        },
        {
          "tag": "v0.2.22",
          "kind": "patch",
          "published_at": "2026-07-16T04:49:45Z"
        },
        {
          "tag": "v0.2.21",
          "kind": "patch",
          "published_at": "2026-07-16T03:52:56Z"
        },
        {
          "tag": "v0.2.20",
          "kind": "patch",
          "published_at": "2026-07-05T05:46:54Z"
        },
        {
          "tag": "v0.2.19",
          "kind": "patch",
          "published_at": "2026-07-05T02:00:08Z"
        },
        {
          "tag": "v0.2.18",
          "kind": "patch",
          "published_at": "2026-07-04T19:29:25Z"
        },
        {
          "tag": "v0.2.17",
          "kind": "patch",
          "published_at": "2026-07-04T18:51:22Z"
        },
        {
          "tag": "v0.2.16",
          "kind": "patch",
          "published_at": "2026-07-04T16:02:53Z"
        },
        {
          "tag": "v0.2.15",
          "kind": "patch",
          "published_at": "2026-07-04T03:22:53Z"
        },
        {
          "tag": "v0.2.14",
          "kind": "patch",
          "published_at": "2026-07-03T23:25:30Z"
        },
        {
          "tag": "v0.2.13",
          "kind": "patch",
          "published_at": "2026-07-03T13:48:46Z"
        },
        {
          "tag": "v0.2.12",
          "kind": "patch",
          "published_at": "2026-07-02T04:38:26Z"
        },
        {
          "tag": "v0.2.11",
          "kind": "patch",
          "published_at": "2026-06-29T04:24:31Z"
        },
        {
          "tag": "v0.2.10",
          "kind": "patch",
          "published_at": "2026-06-29T02:40:49Z"
        },
        {
          "tag": "v0.2.9",
          "kind": "patch",
          "published_at": "2026-06-15T01:01:22Z"
        },
        {
          "tag": "v0.2.8",
          "kind": "patch",
          "published_at": "2026-06-15T00:16:05Z"
        },
        {
          "tag": "v0.2.7",
          "kind": "patch",
          "published_at": "2026-06-13T23:39:07Z"
        },
        {
          "tag": "v0.2.6",
          "kind": "patch",
          "published_at": "2026-06-13T21:43:39Z"
        },
        {
          "tag": "v0.2.5",
          "kind": "patch",
          "published_at": "2026-06-06T04:27:09Z"
        },
        {
          "tag": "v0.2.4",
          "kind": "patch",
          "published_at": "2026-06-04T05:00:54Z"
        },
        {
          "tag": "v0.2.3",
          "kind": "patch",
          "published_at": "2026-06-01T02:20:04Z"
        },
        {
          "tag": "v0.2.2",
          "kind": "patch",
          "published_at": "2026-05-31T15:46:55Z"
        },
        {
          "tag": "v0.2.1",
          "kind": "patch",
          "published_at": "2026-05-31T13:59:36Z"
        },
        {
          "tag": "v0.3.0-phase-3",
          "kind": "prerelease",
          "published_at": "2026-05-20T15:53:16Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-05-17T00:21:14Z"
        },
        {
          "tag": "v0.1.2-pypi",
          "kind": "prerelease",
          "published_at": "2026-05-16T03:43:03Z"
        },
        {
          "tag": "v0.1.1-pypi",
          "kind": "prerelease",
          "published_at": "2026-05-15T05:14:23Z"
        },
        {
          "tag": "v0.1.0-pypi",
          "kind": "prerelease",
          "published_at": "2026-05-15T03:57:01Z"
        },
        {
          "tag": "v0.0.0-r1",
          "kind": "prerelease",
          "published_at": "2026-05-15T03:48:58Z"
        },
        {
          "tag": "v0.1.0",
          "kind": "minor",
          "published_at": "2026-05-09T01:47:48Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "abfe10fed33b3b85daaf7f8193e193f0ad16e99a",
          "body": "… pick (#487)\n\nRoot cause of the self-contradictory \"Fable 5 is the strongest model your\ndeclared access can run; Claude Fable 5 was outside your access and was not\nrecommendable\" rationale — a DETERMINISTIC AccessGuard rewrite, not the engine:\n\n- The engine emits \"Claude Fable 5\" (maker prefix) but\n[…]\n root cause.\n\nRegression tests: is_accessible(\"Claude Opus\") is True; enforce() leaves a\nmaker-prefixed accessible pick untouched.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(service): AccessGuard no longer self-substitutes a maker-prefixed…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-22T17:59:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0dd79c26ac5bfce0bdfb8c6309558da768bc890c",
          "body": "* chore(service): bump roadmodel floor to >=0.2.29\n\nPulls the 0.2.29 rationale fix (no self-contradictory \"returned pick is\noutside your access\" narration) into the deployed service.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n* chore: re-trigger CI after PyPI 0.2.29 propagation\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(service): bump roadmodel floor to >=0.2.29 (#485)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-22T17:44:07Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f49acb6c3d5204b96b4cff4ded7739eb72756bc2",
          "body": "…ss (0.2.29) (#484)\n\nThe <availability-context> substitution example literally used \"Fable 5\" as its\nunavailable-model example, so when the engine picked Fable 5 it parroted the\nexample verbatim — producing the self-contradictory rationale seen in prod\n(\"Fable 5 is the strongest fit ... Fable 5 was \n[…]\n rationales, contradiction gone. Version 0.2.29;\nmodel-selector.md regenerated. Service floor bump follows after the PyPI publish.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: rationale never calls the returned pick unavailable/outside-acce…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-22T17:33:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9bf2693e1f69a67d31065164811f26ec56c60300",
          "body": "Pulls the 0.2.28 engine into the deployed service: the RUN->EFFORT rationale\nrename (\"Why this effort\") + the Opus 4.8 frontier-anchor fix. Separate PR\nafter the PyPI publish so the Vercel preview can resolve the version.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(service): bump roadmodel floor to >=0.2.28 (#482)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-21T22:09:18Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "bb6a6952d041a29eb5255c6305e1b9a7893fc914",
          "body": "…r (0.2.28) (#481)\n\nStage 2 of the /recommend declutter + the ladder fix.\n\nWhy this effort (RUN -> EFFORT):\n- The recommender answers WHAT to run + with which settings, not HOW to run\n  it. The third labelled RATIONALE segment is repurposed from RUN: (funding /\n  how-to-invoke) to EFFORT: — a justif\n[…]\nersion 0.2.28; docs/model-selector.md regenerated. Service floor bump to\n>=0.2.28 follows in a separate PR after the PyPI publish.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: rationale 'Why this effort' (RUN->EFFORT) + Opus frontier ancho…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-21T22:00:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7ba575e81f5088b4175345900046745e15c57192",
          "body": "Added mention of 2.1.216's sandbox.filesystem.disabled setting to the claude-code method's best-for text, extending the existing versioned change log there. Versions 2.1.211-2.1.215 were already covered in the current best-for content and produced no additional edits. No changes to <thinking-context\n[…]\n no-op: --forward-subagent-text flag and CLAUDE_CODE_FORWARD_SUBAGENT_TEXT env var already documented in existing best-for text.\n\nCo-authored-by: roadmodel-bot <roadmodel-bot@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Automated Claude Code refresh: 2026-07-21 (#477)",
          "author_name": "roadmodel-cron-bot[bot]",
          "author_login": "roadmodel-cron-bot[bot]",
          "committed_at": "2026-07-21T17:43:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f49107e05951ffe460bee1786c0db85b103b7d0e",
          "body": "…ackup (#476)\n\nroadmodel answers WHAT to run + with which settings, not HOW to run it —\nthe user knows how to run the model. Stage 1 (frontend-only) of the\ndeclutter:\n\n- WhyDisclosure: drop the engine's third \"run\" rationale segment (\"How to\n  run it\": funding/how-to-invoke) from the \"Why {model}?\" \n[…]\n assert the \"How to run it\" heading + text are gone.\n\nFocus stays on model, platform, effort, and thinking — not run instructions.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(web): declutter /recommend output — drop \"how to run it\", trim b…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-21T01:20:12Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "87a74aa52652343ef16630891b0f3a3237afebf3",
          "body": "…=0) (#470)\n\ngpt-5* at default effort reasons ~33s and can empty the output budget; minimal\n(tb=0 -> reasoning.effort=minimal per #469) runs ~7s, the validated fast/cheap\nanon config. (The harness itself shipped via #469's index carry-over.)\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "tooling: run gpt-5 eval engines at minimal reasoning (thinking_budget…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-20T03:33:51Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d2edbd6665a3782cda02ed3f1ad24cf07c327910",
          "body": "…#474)\n\nCompletes the eval-backed engine cutover (anon canary verified in prod).\nresolveRecommenderEngine's frontier branch now returns gpt-5-mini on the\nOpenAI key (force_provider openai-gpt-5-mini) instead of gemini-2.5-pro —\nthe 2026-07-19 differential eval (scripts/eval_recommend_engines.py) gav\n[…]\nc.ts: assert the new frontier\n  engine / generated-by label\n- engine-overrides.ts: note both tiers now share the gpt-5-mini engine\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(web): flip signed-in frontier recommender engine to GPT-5 mini (…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-20T02:59:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "97fdc256a0a6b510e4b9243f43df50b9a7eaba89",
          "body": "…er) (#472)\n\nEval-backed engine move (differential harness): GPT-5 mini has the best\ninstruction-adherence (1.0 no-cost-demotion vs Gemini 0.83-0.92), is structurally\nflawless, and is ~3x cheaper with OpenAI automatic prefix caching (~$0.005/call).\n\n- service: add 'openai-gpt-5-mini' to _PROVIDER_HI\n[…]\ngpt-5-mini to ENGINE_RATES.\n\nCanary-first: this flips only the anon tier. Verify cost + adherence in prod,\nthen flip the frontier.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(recommend): canary the recommender engine to GPT-5 mini (anon ti…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-19T21:56:15Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "65c7349fb9fd51ba7f5a87cabdc99d48a9b3059a",
          "body": "Carries the OpenAI provider reasoning.effort fix (#469) to PyPI so the service\ncan use GPT-5 mini as a recommender engine. Bumps 0.2.26 -> 0.2.27 (pyproject +\n__init__ + packaging test). Service floor bump lands in a follow-up after publish\n(the service Vercel preview resolves roadmodel from PyPI).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(release): roadmodel 0.2.27 (#471)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-19T21:45:18Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "73f3240cb8871fcfa39ad072511c849f15e0563a",
          "body": "…size (#468)\n\nThe per-call engine-cost ledger used STATIC_PROMPT_TOKENS=20000, but the real\nheader+selector+tier-cost prompt measures ~39,526 tokens (google\nusage_metadata.prompt_token_count, 2026-07). So audit_log.cost_usd — and the\ndaily spend-guard (web/lib/spend-guard.ts) that returns 503 at the\n[…]\nince Gemini implicit caching is present but unreliable per\nthe probe). Real cached-token capture from the provider is a follow-up.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(web): correct engine-cost estimate to the measured ~39.5k prompt …",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-19T20:34:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "406272a260b3b5dfcc12f6c80fc39ace15fc0b73",
          "body": "…text (#469)\n\nOpenAI reasoning models (gpt-5*) count reasoning tokens against\nmax_output_tokens. The provider set max_output_tokens but never capped\nreasoning, so on a real recommend call the reasoning consumed the ENTIRE budget\nand returned NO visible text (observed: gpt-5-mini 32s, empty output) —\n[…]\natic prefix caching). Temperature stays unforwarded\n(reasoning models reject it); Gemini-only thinking_config keys are never sent.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(providers): cap reasoning.effort on gpt-5* models so they return …",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-19T20:13:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "837ba73383ba63748c9d0516cc854a0052245340",
          "body": "No changes detected. The current selector's OpenAI/Codex reasoning-effort content already matches <docs_facts> exactly: the thinking-context OpenAI bullet enumerates minimal/low/medium/high/xhigh (noting the plan-mode `none` variant), and the output mapping covers minimal→Off, low→Low, medium→Medium\n[…]\nsity vocabularies which are out of scope for the reasoning-effort narrative and were intentionally not surfaced in the selector.\n\nCo-authored-by: roadmodel-bot <roadmodel-bot@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Automated Codex refresh: 2026-07-19 (#465)",
          "author_name": "roadmodel-cron-bot[bot]",
          "author_login": "roadmodel-cron-bot[bot]",
          "committed_at": "2026-07-19T18:29:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4c9e6260a233b0e6a665329e41fb9db4285ac4aa",
          "body": "…ill (#464)\n\nThe rounded-full accent pills on the /recommend matrix wrapped long labels\n(\"ChatGPT (web / desktop)\", \"Claude Code · Extra high\") inside the balloon on\nnarrow columns, hurting readability. Drop the pill chrome (rounded bg + padding)\nand render the platform as plain accent-colored subti\n[…]\next with leading-snug,\nso a long label flows to a clean second line instead of a two-line balloon. No\ndata hidden; works on touch.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(web): render pick/backup platform as plain text, not a wrapping p…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-19T17:56:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "dc1b0f205d395129b4e23b33b13bcae491a1cf96",
          "body": "Processed Claude Code CHANGELOG versions 2.1.210–2.1.215. All five entries are Claude Code polish (bug fixes, tool-call elapsed-time counter, `--forward-subagent-text` flag, `/fork`/`/subtask`/`/resume` background sessions, EndConversation tool, Podman daemon-redirect prompts, `/verify` and `/code-r\n[…]\nntion the live elapsed-time counter on long-running tool calls and the Write/NotebookEdit/Glob permission-rule startup warnings.\n\nCo-authored-by: roadmodel-bot <roadmodel-bot@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Automated Claude Code refresh: 2026-07-19 (#463)",
          "author_name": "roadmodel-cron-bot[bot]",
          "author_login": "roadmodel-cron-bot[bot]",
          "committed_at": "2026-07-19T17:35:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "324d4c517cfdcfd556a5da284fdd36daa4dee86b",
          "body": "Adds a /docs section: effort is a separate axis from model choice; roadmodel\nkeeps it high and lowers it only when it saves real cost, so each pick can run\nat full effort while differing by model. Documents the Settings control\n(Automatic / Always maximum / Scale to save budget) and notes the backup follows\nthe same setting.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(web): explain the Reasoning effort setting (#461)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-19T16:27:42Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "71903f8bf6688564e05cdb7e765b0abb57edcb86",
          "body": "* chore(service): floor roadmodel[recommend]>=0.2.26\n\n0.2.26 is now on PyPI, so the service can require it — this is what actually\ncarries the backup backstop + OpenAI-API display fix to prod (they ship via the\npackage, not service code). Split from the release PR because bumping the floor\nbefore pu\n[…]\nore: retrigger CI (PyPI 0.2.26 index propagation)\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(service): floor roadmodel[recommend]>=0.2.26 (#460)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-19T15:51:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0afd8d0ae5efa6c14e0e2511211fa1f6cb97fc3c",
          "body": "Carries the merged package changes to PyPI so the recommender service can pick\nthem up (they reach prod only via release, not merge):\n- Backup backstop: benched / region-blocked cross-provider backups rejected\n  deterministically (+ cost.model_jurisdiction / cost.model_id_of).\n- OpenAI direct API re\n[…]\nLLOW-UP PR after 0.2.26 is on PyPI —\nbumping it here fails the service's Vercel preview (uv can't resolve an\nunpublished version).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(release): roadmodel 0.2.26 (#459)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-19T15:41:24Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2b0039a785ba78984fec928d0ee9c05cc4b0097c",
          "body": "* feat(recommend): consumption-headroom effort axis (keep effort maxed when it costs nothing)\n\nReasoning EFFORT and capability TIER are separate axes, but the\nbudget-priority ladder scaled both down together for the Cost pick. Scaling\neffort only helps when effort actually costs the user something —\n[…]\nict[str,str]) with _resolve_id's str|None return.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(recommend): consumption-headroom effort axis (#457)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-19T06:48:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8247c87ba414b37f1170dfa4133de3a3ec52942e",
          "body": "… cross-provider backups (#456)\n\n* fix(recommend): deterministic jurisdiction + availability backstop on cross-provider backups\n\nThe Step 7 BACKUP is only kept as-is when it is genuinely usable. The\nsame-maker case was always enforced deterministically, but the\navailability (Step 0a) and jurisdictio\n[…]\nmat test_backup_guard.py (CI ruff version reflow)\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(recommend): deterministic jurisdiction + availability backstop on…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-19T06:37:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6ab6e24fb9343957252a179d255faa4da1777f01",
          "body": "Processed CHANGELOG version 2.1.214. Extended the `<method id=\"claude-code\">` best-for text to note the 2.1.214 additions: the EndConversation tool (agent-initiated session end for abusive/jailbreak cases) and Podman/docker daemon-redirect permission prompts. No thinking-context reconciliation neede\n[…]\nnt. No max-mode-context change (no Claude Code Max-Mode equivalent shipped). Cursor-owned `supports-models` attribute untouched.\n\nCo-authored-by: roadmodel-bot <roadmodel-bot@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Automated Claude Code refresh: 2026-07-18 (#455)",
          "author_name": "roadmodel-cron-bot[bot]",
          "author_login": "roadmodel-cron-bot[bot]",
          "committed_at": "2026-07-18T18:07:36Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "81160b90986e0dd991388b88cb67b1891b71fd4b",
          "body": "…sive app default (#445) (#453)\n\nForward migration setting the profiles.allowed_jurisdictions COLUMN DEFAULT to\ninclude 'cn', matching the app default flipped in #452 (web\nDEFAULT_PROFILE.allowed_jurisdictions). DEFAULT ONLY — no backfill, since\nexisting rows hold each user's explicit selection and \n[…]\negacy infra/migrations/ is frozen\n(no api_providers/model_availability migrations); infra/supabase/migrations/ is\nthe live Supabase-tracked dir.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(db): align profiles.allowed_jurisdictions default with cn-inclu…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-18T16:32:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "50e6ad21ebc7d83be14e9b82cd94f4f672ddd40f",
          "body": "…stricted (#445) (#452)\n\nTwo coupled Settings changes so the access filter (#451) matches user intent:\n\n1. Flip the default: \"Restrict to low-risk jurisdictions\" now ships OFF, so\n   Chinese open-weight models (DeepSeek, GLM via z.ai) are available by\n   default. DEFAULT_PROFILE.allowed_jurisdiction\n[…]\nt; the app always\nsends allowed_jurisdictions on onboarding so it's never the effective value —\naligning the DB default is a cosmetic follow-up.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(web): jurisdiction default includes cn + hide cn vendors when re…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-18T15:23:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ea3e65c391559c055ef133a8f2ce590d44534bee",
          "body": "…ls (#445) (#451)\n\nWhen the user declares any funding, recommendations must only surface models\nthey can actually run. Two layers, both service-side (no package release):\n\n1. Bias: build_user_context appends a HARD \"Access restriction\" allowlist of\n   the accessible model NAMES (models reachable via\n[…]\nccessible, honest pay-per-token notes) instead of Fable 5 / Sonnet /\nComposer. 17 new unit tests; ruff + mypy --strict + 77 service tests green.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(service): restrict recommendations to the user's accessible mode…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-17T21:43:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7334de9730c797f36f2cce40c55f1cc509452042",
          "body": "Extended the claude-code access-method `best-for` to note the 2.1.212 additions: `/fork` for background-session copies, `/subtask` for the in-session subagent, the `/resume` picker, per-session WebSearch and subagent caps, and long-running MCP auto-backgrounding. Scopes 1 (thinking-context) and 2 (m\n[…]\nS_WRAPPER`, and rendering fixes — none materially change Claude Code's positioning fact set relative to the existing `best-for`.\n\nCo-authored-by: roadmodel-bot <roadmodel-bot@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Automated Claude Code refresh: 2026-07-17 (#450)",
          "author_name": "roadmodel-cron-bot[bot]",
          "author_login": "roadmodel-cron-bot[bot]",
          "committed_at": "2026-07-17T18:17:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2dce61473c34c1a1571e2ac4307fb04193c73f4d",
          "body": "…ription\") (#444) (#448)\n\nPost-deploy prod probe surfaced a guard escape: \"This uses the ChatGPT\nsubscription via the Codex CLI\" carries no \"your\", so the possessive claim\npatterns missed it. Add a verb+\"the\" alternation (uses/on/via/through/with/by\nthe ... subscription|plan|pool); the honest \"requi\n[…]\nscription or API\nkey\" phrasing stays unmatched (article \"a\", no verb+\"the\"). Regression tests\npin the exact prod string and the honest phrasing.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(service): catch possessive-free funded claims (\"the ChatGPT subsc…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-17T14:04:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "13e279e40a06db6fa73e9e73b3aefb67b0a52088",
          "body": "…s (#444) (#447)\n\nThe engine intermittently narrates funding the user never declared (\"This\nruns on your claude.ai Max subscription\") even though the per-user context\nsays \"None declared\" / \"do not assume\". Enforce it in code, like the\nTHINKING=N/A override (#188) and the BACKUP guard: when the pick\n[…]\nxt is injected; anon/bundled path untouched; selection never changed.\n\nRider: z.ai renders as \"z.ai\" in the funding doc, not the \"Zai\" fallback.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(service): deterministic funded-platform honesty guard on run-note…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-17T04:40:06Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "41d8ac05d04cf6e03ca11cd77abc23ca00db7961",
          "body": "Bumps the service floor to the release that carries the 2026-07-15 catalog\nrefresh (40 models; grok-4.3 retained as provider-direct via xai-api). The\nselector + catalog.json ship inside the wheel, so the deployed service only\npicks these models up once its floor forces the new release at build time.\n[…]\nheck 13 pins\nroadmodel[recommend]>=0.2.x,<0.3); roadmodel 0.2.25 is live on PyPI (wheel +\nsdist, trusted-publishing attestations).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(service): require roadmodel[recommend]>=0.2.25 (#443)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-16T22:53:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "57209e0b85736822e7f4d6e27260f8c575f23cec",
          "body": "…-direct (#442)\n\nShips the 2026-07-15 catalog refresh (#427) to PyPI. The selector and\ncatalog.json ride inside the wheel, so a release is what carries these models\nto the CLI, MCP read_catalog, and the recommender service.\n\n- Catalog → 40 models: adds Claude Sonnet 5, GPT-5.6 Sol/Terra/Luna, GPT-5.\n[…]\n, so this cannot recur.\n\nVerified: full suite 492 passed, ruff clean, verify-macos --fast green, wheel\nbuilds as roadmodel-0.2.25.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: roadmodel 0.2.25 — 40-model catalog + grok-4.3 kept provider…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-16T22:39:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e4cfbabfb4911ce3ea8870b01d75bf2744beaa51",
          "body": "* Automated catalog refresh: 2026-07-15\n\nCost-scale refresh 2026-07-15: added new models visible on Cursor's pricing page — Claude Sonnet 5 ($3/$15, High), GPT-5.6 Sol ($5/$30, Very High), GPT-5.6 Terra ($2.50/$15, High), GPT-5.6 Luna ($1/$6, Low), GPT-5.2 Codex ($1.75/$14, Medium), GPT-5.1 Codex Ma\n[…]\nCo-authored-by: roadmodel-bot <roadmodel-bot@users.noreply.github.com>\nCo-authored-by: Nathan Ramos <nathan.ramos.github@gmail.com>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": true,
          "headline": "Automated catalog refresh: 2026-07-15 (#427)",
          "author_name": "roadmodel-cron-bot[bot]",
          "author_login": "roadmodel-cron-bot[bot]",
          "committed_at": "2026-07-16T22:29:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "47c355050b0d09695da5ed4afa736ffe2af19600",
          "body": "Codex reasoning-effort conformance touch-up.\n- <thinking-context> OpenAI bullet: no vocabulary change (already enumerates minimal/low/medium/high/xhigh, matching the docs' `reasoning_effort` set); added a short trailing note that Codex's plan-mode reasoning-effort variant additionally accepts `none`\n[…]\ne synonym for the 'xhigh' config token in the OpenAI mapping bullet, per the scope instructions — docs_facts only lists 'xhigh'.\n\nCo-authored-by: roadmodel-bot <roadmodel-bot@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Automated Codex refresh: 2026-07-16 (#441)",
          "author_name": "roadmodel-cron-bot[bot]",
          "author_login": "roadmodel-cron-bot[bot]",
          "committed_at": "2026-07-16T19:11:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "020b5ac81d4993778a4526e71be19a3b41c73d7e",
          "body": "Updated the Claude Code method best-for in <access-methods> to mention the 2.1.211 addition of the `--forward-subagent-text` flag and `CLAUDE_CODE_FORWARD_SUBAGENT_TEXT` environment variable for including subagent text and thinking in stream-json output. Reviewed versions 2.1.207–2.1.211: all other \n[…]\nare out-of-catalog anyway; existing default-permission-mode Manual note in claude-code best-for already covers 2.1.200 defaults.\n\nCo-authored-by: roadmodel-bot <roadmodel-bot@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Automated Claude Code refresh: 2026-07-16 (#437)",
          "author_name": "roadmodel-cron-bot[bot]",
          "author_login": "roadmodel-cron-bot[bot]",
          "committed_at": "2026-07-16T18:17:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5576b158951fe6f48b6e8e2c4addd786dff77bd8",
          "body": "…rs (0.2.24) (#435)\n\n* feat(mcp): ship the per-surface settings-display rules to offline consumers (0.2.24)\n\nThe selector emits platform-neutral axes (MAX MODE / THINKING /\nORCHESTRATION). Turning those into a surface's REAL controls lives in\nrecommend._structured_settings and is deliberately NOT in\n[…]\ninclude list broke package-smoke on every Python.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(mcp): ship per-surface settings-display rules to offline consume…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-16T16:44:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "149f4d6d24ba5c633180a253d1f8e3dd38896730",
          "body": "…p (0.2.23) (#434)\n\nUsing roadmodel across many projects meant per-project installs and a\nplanning/ folder exported (and re-exported on every catalog change) into\neach repo. That scales with project count and is pure toil.\n\nThe MCP server already solves it — `read_catalog` serves the whole\nselector \n[…]\n/--force/--dry-run; actionable errors when the mcp extra or\nthe `claude` CLI is missing (prints the exact command to run instead).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(cli): add `roadmodel setup-mcp` — one-command, machine-wide setu…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-16T14:30:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "195e769c90b3155009b50d96127b006908ed7a09",
          "body": "* chore(service): require roadmodel[recommend]>=0.2.22\n\nroadmodel 0.2.22 made the provider SDKs an opt-in `recommend` extra. The\nservice serves live recommendations, so it must pull that extra — pin\n`roadmodel[recommend]>=0.2.22,<0.3` so the deployed service installs\nanthropic/openai/google-genai. N\n[…]\nd-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n* chore: retrigger service deploy (0.2.22 PyPI propagation)\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(service): require roadmodel[recommend]>=0.2.22 (#433)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-16T05:01:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1a0d7e88e70a79a49a6b732148c938fbfb078c24",
          "body": "…22) (#432)\n\nBase `pip install roadmodel` no longer forces anthropic/openai/\ngoogle-genai — the only hard runtime dep is now click. Those three SDKs\nmove to a `recommend` optional-extra, needed ONLY for `roadmodel\nrecommend` (live API calls). The offline planning-kit workflow\n(export-kit, catalog, c\n[…]\nlls `.[recommend]` (mirrors prod).\n\nService floor bump to `roadmodel[recommend]` follows in a separate PR\nafter 0.2.22 is on PyPI.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(packaging): make provider SDKs an opt-in [recommend] extra (0.2.…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-16T04:46:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2434e905cf299fbd7c3d5a85be96e97bdec3b909",
          "body": "….json (#431)\n\nCloses the gap that left Fable 5 benched in the offline CLI + planning\nkit for two weeks after the runtime layer autonomously un-benched it\n(2026-07-02). The autonomous un-bench only ever updated the runtime\npath (Supabase → web /api/recommend); the bundled static\n<availability-contex\n[…]\n kit still needs a package release to pick the change up\n(offline is offline), but the human no longer edits the selector by hand.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(availability): auto-sync static fallback from model-availability…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-16T04:07:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1b9540d7509b8a052576536b01d67c76d5b352bc",
          "body": "Requires the release that ships the un-benched static availability\nfallback (#428/#429, roadmodel 0.2.21 on PyPI) so the deployed service\ncarries the corrected bundled selector.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(service): bump roadmodel floor to >=0.2.21 (#430)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-16T04:00:49Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "dab7fba92eb3587f87f7e29ae4b57e4b743feff0",
          "body": "…ck (#429)\n\nShips #428 (empty <availability-context> cold-start fallback) to the CLI\nand planning-kit consumers. Selector-data change only; the runtime\nauthoritative path was already correct since 2026-07-02.\n\nBumps pyproject.toml + __init__.py + test_packaging.py pin; CHANGELOG entry.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: roadmodel 0.2.21 — un-bench Fable 5 in bundled static fallba…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-16T03:47:02Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "bc824acf2c2afcdb2021e8ca7791359bec6bec93",
          "body": "…#428)\n\nThe runtime availability layer autonomously un-benched Fable 5 on\n2026-07-02 (grounded AI verification cleared the export-control bar,\nconf 0.93 / 5 sources; #341), so prod /api/recommend recommends it\nagain. But the bundled <availability-context> cold-start fallback in\ndocs/model-selector.t\n[…]\nf-heals) while still validating any\nids that are present.\n\nPropagates to the bundle on the next PyPI release + service floor bump.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(selector): un-bench Fable 5 in the static availability fallback (…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-16T03:29:06Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "beab0016ef31cf62b491b23b6a8986837b72b597",
          "body": "…cron) (#419)\n\nCursor delisted its entire xAI section on 2026-07-14, so the Opus refresh\ncorrectly drops the \"Grok 4.3\" row from docs/model-tier-cost-scale.md. But\ngrok-4.3 stayed in SELECTOR_TO_COST_SCALE_NAME, so merge_catalog's cost-scale\noverlay hard-failed (\"no table row found for 'Grok 4.3'\").\n[…]\ned (post-Opus state) the overlay raises\nno fatal flag and grok-4.3 stays in the snapshot price map; full suite green\n(456 passed).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(catalog): exempt delisted grok-4.3 from cost-scale sync (unblock …",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-15T20:04:03Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7e7f0278a0bce9c9115ba3c6a3243dd5b5100c9a",
          "body": "…s (#420)\n\nThe Claude Code effort docs list a row's models as \"Sonnet 5, Opus 4.8, and\nOpus 4.7\" (Oxford comma). parse_effort_table split on \" and \" only, mangling\nthat into the bogus model name \"Sonnet 5, Opus 4.8,\" which the tracker then\nflagged as a brand-new model. Dedup used `gh issue list --se\n[…]\nce gate PASS, macOS verify --fast PASS, full suite\n457 passed; new dedup matches the existing dup title via REST (proven offline).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(cc-tracker): parse Oxford-comma model lists; stop daily dup issue…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-15T19:59:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6f909b365e272271bd5311f22e9041d6f3a3a818",
          "body": "…codex/deepseek) (#425)\n\nThe Gemini, Codex, and DeepSeek refresh crons dedup their \"docs introduced\nmodel / level / effort\" tracking issues with `gh issue list --search\n'... in:title'`. GitHub's search index lags, so the search returned empty\nmid-run and a fresh DUPLICATE was filed almost every day \n[…]\n three YAMLs parse; the new exact-title dedup matches the live\nGemini dup title offline (would skip); no `--search` dedup remains.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(trackers): dedup new-model issues via REST + exact title (gemini/…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-15T19:53:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2258b1b5ff47fa55086f6f6e35156c1ad53b2a38",
          "body": "… 3.2 (#424)\n\nThe pre-push hook (added in #391) crashed on every push where git config\nroadmodel.prepushphases is unset (the default): line 57 expanded a bare\n\"${phase_args[@]}\" under `set -u`, and macOS /usr/bin/env bash is 3.2, where an\nempty-array \"${arr[@]}\" raises \"unbound variable\". Every push\n[…]\n ref on stdin with no prepushphases config;\nit cleared line 57 and ran verify-macos.sh --fast to a clean pass instead of\ncrashing.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(githooks): guard empty phase_args so pre-push works on macOS bash…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-15T19:47:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a582fb559496f62738b775e5e4d4da9444aee14e",
          "body": "… builds (#423)\n\nCI's `type-check` (mypy --strict src update) has been red repo-wide: the\ninstalled pyarrow ships no py.typed marker, so `import pyarrow.parquet` in\nupdate/update_models.py raises import-untyped, and the read_table\n`# type: ignore[no-untyped-call]` is then flagged unused. This blocke\n[…]\nitions (pyarrow stubs\npresent, and pyarrow unresolved so the override forces Any): Success both ways.\nFull test suite: 456 passed.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(ci): treat pyarrow as untyped so mypy --strict passes on stubless…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-15T19:33:39Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a1a690e641066cf8d63df6b8753ca3aba526696a",
          "body": "Processed Claude Code CHANGELOG version 2.1.205. The release is editorial/bugfix-focused (auto-mode transcript-tampering rule, `Claude Browser` MCP name reservation, `/doctor` becoming a full setup checkup, various fixes). None of the changes add new effort/thinking levels, orchestration primitives,\n[…]\ns 4.8,. This tracker only FLAGS new models; do NOT add them to selector model lists here. Open an issue for the catalog refresh.\n\nCo-authored-by: roadmodel-bot <roadmodel-bot@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Automated Claude Code refresh: 2026-07-09 (#407)",
          "author_name": "roadmodel-cron-bot[bot]",
          "author_login": "roadmodel-cron-bot[bot]",
          "committed_at": "2026-07-09T19:02:29Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b0bb9244f4333145d3b73454df5fa80a8d925cc6",
          "body": "Reviewed Claude Code CHANGELOG entries 2.1.204 and 2.1.203. Both releases are bug fixes and reliability improvements (background session recovery, MCP roots/list, session token handling, `claude agents` polish, VSCode remote-control toggle) with no material changes to Claude Code's effort dial, thin\n[…]\ns 4.8,. This tracker only FLAGS new models; do NOT add them to selector model lists here. Open an issue for the catalog refresh.\n\nCo-authored-by: roadmodel-bot <roadmodel-bot@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Automated Claude Code refresh: 2026-07-08 (#404)",
          "author_name": "roadmodel-cron-bot[bot]",
          "author_login": "roadmodel-cron-bot[bot]",
          "committed_at": "2026-07-08T18:28:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8f92e89189d10dc154c542e43e9e94749655aa5d",
          "body": "Reinforced the OpenAI/Codex reasoning-effort description against the config-reference docs (`reasoning_effort`: minimal/low/medium/high/xhigh):\n- Added an explicit clarification in the <thinking-context> Output mapping that OpenAI's scale tops out at `xhigh`, so no OpenAI level maps to `Max` (which \n[…]\nd to codex-cli's best-for; if these deserve first-class surfacing, a future prompt-scope expansion should cover them explicitly.\n\nCo-authored-by: roadmodel-bot <roadmodel-bot@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Automated Codex refresh: 2026-07-07 (#400)",
          "author_name": "roadmodel-cron-bot[bot]",
          "author_login": "roadmodel-cron-bot[bot]",
          "committed_at": "2026-07-07T19:56:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3e4f852cb934784f3a88bc84498862bb84553b0f",
          "body": "Processed Claude Code 2.1.202. In scope: the release adds a `/config` \"Dynamic workflow size\" setting (small/medium/large agent counts, advisory only) that touches the Claude Code Ultracode surface. Extended the claude-code `<method>` `best-for` with a parenthetical noting the 2.1.202 advisory guide\n[…]\ns 4.8,. This tracker only FLAGS new models; do NOT add them to selector model lists here. Open an issue for the catalog refresh.\n\nCo-authored-by: roadmodel-bot <roadmodel-bot@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Automated Claude Code refresh: 2026-07-07 (#399)",
          "author_name": "roadmodel-cron-bot[bot]",
          "author_login": "roadmodel-cron-bot[bot]",
          "committed_at": "2026-07-07T19:13:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2722fff4f8fb88f7282b17a57a2d4799f21fcd76",
          "body": "…io (#391)\n\nroadmodel is a public repo, so its Linux GitHub Actions minutes are free\n(covered by the public-repo discount). macOS runners are NOT covered and\nwere the only paid Actions minutes on this project — driven by the 10 macOS\njobs per run in phase-verify.yml (every push + PR) and 3 in verify\n[…]\n add workflow_dispatch to re-verify\nmain on demand.\n\nCONTRIBUTING.md documents the pre-push hook, its bypasses, and the rationale.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(ci): move paid macOS verification off Actions to local Mac Stud…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-06T18:13:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3c89d4e9089555f861b611587cbc0dafc38e7b62",
          "body": "Scope 3 (best-for on <method id=\"claude-code\">): folded in 2.1.197's introduction of Claude Sonnet 5 as Claude Code's new default model with a native 1M-token context window — a materially new positioning fact for the Claude Code surface. Scopes 1 and 2 unchanged: <thinking-context> already reconcil\n[…]\ns 4.8,. This tracker only FLAGS new models; do NOT add them to selector model lists here. Open an issue for the catalog refresh.\n\nCo-authored-by: roadmodel-bot <roadmodel-bot@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Automated Claude Code refresh: 2026-07-05 (#394)",
          "author_name": "roadmodel-cron-bot[bot]",
          "author_login": "roadmodel-cron-bot[bot]",
          "committed_at": "2026-07-05T18:14:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "05b9d7e12ec8c236579683285da0a99d5f3b946b",
          "body": "…dropping rows) (#390)\n\nEvery caller does `void writeAudit(...)` and returns the response immediately,\nso on Vercel the function could be torn down after the response but BEFORE the\nSupabase insert committed — silently DROPPING audit rows. Observed live: across\nseveral rapid /api/recommend diag requ\n[…]\nbest-effort void. The test-sink path is unchanged.\nFixes every call site (recommend + roadmap routes, withRateLimit) in one place.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(web): flush fire-and-forget audit writes with Next `after` (stop …",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-05T15:52:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "65724c30b94c86f4592653384193bd27f53467ad",
          "body": "…+ floor >=0.2.20 (#389)\n\nWires the cross-provider backup substitution (roadmodel 0.2.20) end to end:\n- funding.resolve_allowed_jurisdictions(context): the forwarded allowed set or\n  the baseline the selector already uses.\n- recommend() + recommend_ladder() forward it to recommend_structured /\n  rec\n[…]\nss_provider_backup).\n- test fakes accept allowed_jurisdictions (the signature-contract line already\n  landed with the package PR).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(service): forward allowed_jurisdictions for backup substitution …",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-05T05:49:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8a13a5ea6dfdaea34927238ff8f876bd75dff051",
          "body": "…] (#388)\n\n* feat(recommend): cross-provider backup SUBSTITUTION (0.2.20)\n\nThe 0.2.19 same-provider backup guard DROPPED a same-maker backup (e.g.\nFable 5 -> Opus 4.8, both Anthropic) because the package couldn't see the\nuser's jurisdiction. Realize 0.2.17 \"option A\" — substitute a cross-provider\nfa\n[…]\n service wiring\nland in the follow-up service PR.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(recommend): cross-provider backup SUBSTITUTION (0.2.20) [package…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-05T05:43:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "247a3a2c5e31e11dc6c49b42b36156ad06e8885d",
          "body": "…s #2) (#387)\n\n* fix(service): stop overriding Cursor Thinking=On back to N/A (unbreaks #2)\n\nroadmodel 0.2.17 (#2) made _structured_settings emit Cursor thinking as\n\"On\" on purpose — Cursor's frontier models reason; the dial it exposes is\nMax Mode. But the service's _normalize_no_thinking still list\n[…]\ndate stale #188 comment (Cursor moved to package)\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(service): stop overriding Cursor Thinking=On back to N/A (unbreak…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-05T05:32:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c8f2f799795e0259846ea780fac587e903d9bed7",
          "body": "Ships the deterministic same-provider backup guard (#385) to prod on\nredeploy. roadmodel 0.2.19 is published to PyPI.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(service): require roadmodel>=0.2.19 (#386)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-05T02:03:37Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "735ad08564b0bff8869970446c0109412ef29fdf",
          "body": "…385)\n\n* feat(recommend): deterministic same-provider BACKUP guard (draft)\n\n#4 made the Step 7 cross-provider backup rule HARD in PROMPT prose only;\nGemini can still emit a same-maker backup (observed in prod: Fable 5 ->\nOpus 4.8, both Anthropic — zero resilience). Add a deterministic guard,\nmirrori\n[…]\nd. Follow-up\nbumps the service floor to >=0.2.19.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(recommend): deterministic same-provider BACKUP guard (0.2.19) (#…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-05T01:56:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1621f76654aaa63f5ad8bbd9e221accc8de24b00",
          "body": "… svc+web] (#383)\n\nWire the single-call Cost/Balanced/Quality ladder (roadmodel 0.2.18) through\nthe service and the web edge. Ships DARK behind RECOMMEND_LADDER_ENABLED with\nthe per-priority fan-out as instant rollback.\n\nService:\n- models.py: LadderResponse (tier-keyed picks + tier-distinctness guar\n[…]\nt 3x for the ladder (vs 3x/3x for the fan-out).\n- mock-recommend/ladder: E2E mock so the path runs end-to-end when the flag is on.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(recommend): ladder endpoint + flag-gated single-call edge [#1/#3…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-04T19:34:03Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e55462f25240e95eb7a7c41b4b41b89ba21a2080",
          "body": "…kg] (#382)\n\nAdd a selector \"ladder mode\" + package plumbing that emits the whole\nCost/Balanced/Quality ladder in ONE response, replacing three independent\nper-priority calls that could collapse onto the same model (Balanced =\nQuality = Opus 4.8). Quality is chosen first (no budget cap); Balanced an\n[…]\n.18 (additive, backward-compatible; within the service's\n>=0.2.17,<0.3 floor). Single-prompt + roadmap-annotation modes unchanged.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(selector): single-call tier-ladder recommender (0.2.18) [#1/#3 p…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-04T19:26:13Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4ea6d0173b2da1f57e6d65909dc7e19969309314",
          "body": "Bumps the service floor so the backup cross-provider hard rule (#375) and\nthe Cursor Thinking=On display reframe (#376) reach prod on redeploy.\nroadmodel 0.2.17 is published to PyPI.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(service): require roadmodel>=0.2.17 (#381)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-04T19:01:08Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a861e95df7c54fc2b889d8c74bfc09c0a062f501",
          "body": "…l (#378)\n\nThe \"Per 1k\" column was the model's blended API token rate stamped onto\nevery platform row. Because the funding-rank table is ONE model across\nplatforms, that number is identical on every row — which implies\nplatforms charge different token rates when they don't. It's also\noutright mislea\n[…]\n (per1kCost / sharedApiRate /\nhasPoolBilledRow) into lib/cost-format.ts with a unit spec, matching the\nrepo's lib/ + spec pattern.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(recommend): make 'cost by platform' honest — per-1k is model-leve…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-04T18:52:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fe21e2cea48246e23c4b6e57f209d740e96b4ce7",
          "body": "…splay) (#379)\n\nBundles the two selector-package changes that reach prod only via a\nPyPI release:\n- #375 BACKUP hard cross-provider requirement (Step 7).\n- #376 Cursor picks read Thinking=On + Max Mode (_structured_settings).\n\nBumps version in pyproject.toml + __init__.py, pins it in\ntests/test_packaging.py, and adds the CHANGELOG entry. A follow-up bumps\nthe service floor to roadmodel>=0.2.17.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: roadmodel 0.2.17 (backup cross-provider + Cursor thinking di…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-04T18:47:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d9e94e40826ee8f9019b26c74bb5f86d93654017",
          "body": "… (#376)\n\nCursor's frontier models always reason, but the IDE exposes no\nthinking-level dial, so the selector emits THINKING=N/A for Cursor.\nSurfaced raw, a Cursor pick read \"Thinking: N/A\" beside an em-dash\nEffort — implying it had no controllable settings at all.\n\nReframe it at the display layer i\n[…]\nn the selector vocabulary\nmeans the daily effort/thinking conformance cron (which pins Cursor's\nTHINKING=N/A) can never revert it.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(recommend): Cursor picks read Thinking=On + Max Mode, not N/A + —…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-04T18:03:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9d56d885a53f486ccefcdead3fbce3b27f13023e",
          "body": "… (#375)\n\nThe backup exists so a single provider's outage or access block can't\ntake out both picks — but Step 7 only said \"prefer a model from a\nDIFFERENT provider/family\", a soft preference that let same-family\nbackups through (e.g. Fable 5 primary -> Opus 4.8 backup, both\nAnthropic). Rewrite it a\n[…]\nkup_step_requires_different_provider) that guards\nthe hard language and rejects the old soft phrasing. Regenerated the\n.md mirror.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(selector): make BACKUP a hard cross-provider requirement (Step 7)…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-04T17:55:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8bc2e9df90d65e8b0aa363ae4d4282890dde409d",
          "body": "The DEFAULT badge was absolutely positioned (right-2.5 top-2.5) and\nreserved no space, so the uppercase column label ran under it on narrow\ncolumns (\"BALANCED\"/\"QUALITY\"). Put the label and badge in one in-flow\nrow with justify-between so the badge can never overlap the label at any\nviewport width or column position.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(recommend): stop DEFAULT badge overlapping the column label (#374)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-04T17:48:15Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "492955138fb78428b662293042ae79c2291f7684",
          "body": "…gh\" (#372)\n\nClaude Code has no separate orchestration dial — Ultracode is the top of its one\nEffort ladder (folded into the effort value by roadmodel >=0.2.16). Add\n\"orchestration\" to HIDDEN_SETTING_KEYS so the row never renders, including for any\nstale/cached record that still carries the key (imm\n[…]\nsplay the `xhigh` effort step as \"Extra high\" to match Claude\nCode's own /effort label (Low/Medium/High/Extra high/Max/Ultracode).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(recommend): hide any orchestration row + label XHigh as \"Extra hi…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-04T16:12:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "70ca238153f4e0aba11cb67ea087c3d1b8d8aeca",
          "body": "…rt) (#373)\n\nRedeploys roadmodel-api onto 0.2.16 so /recommend presents Claude Code's single\nEffort ladder (Ultracode as the top value) with no separate Orchestration row.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(service): require roadmodel>=0.2.16 (Ultracode folded into Effo…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-04T16:07:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "50b6f52cc6a6736e300c9fa9854e5f5a7a7032c9",
          "body": "…stration row (0.2.16) (#371)\n\nClaude Code exposes ONE effort dial (Low/Medium/High/XHigh/Max/Ultracode, where\nUltracode = xhigh + Dynamic Workflows) plus a separate Thinking toggle — it has\nno standalone \"orchestration\" control. The 0.2.15 change surfaced ORCHESTRATION\nas its own settings row, whic\n[…]\nd for Quality/demanding) so the Cost/Balanced/\nQuality effort tiers stay distinct after folding. Bumps roadmodel 0.2.15 -> 0.2.16.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(recommend): fold Ultracode into the Effort ladder, drop the Orche…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-04T15:50:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "365a46011ae0937c72ddd307c4d1975f5d7b4a61",
          "body": "…h mock) (#370)\n\nThe per-platform cost table lists the SAME recommended model across platforms,\nso its \"Model\" column just repeated one name three times and stole the width\nthe \"Your cost\" column needs — forcing it to wrap 2-3 lines and pushing the\ndetail panel below the fold. Show the Model column \n[…]\n\n\nCard bottom at 960px with a real 3-row personalized table: 922px -> 856px\n(mock ~828px), so the picks + detail fit one viewport.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(recommend): drop redundant Model column from the cost table (matc…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-04T04:34:33Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d9682ca3eb5774911c8ee9356daebad573ad2a7e",
          "body": "…ingful (#369)\n\n* fix(recommend): drop matrix rows where every pick's value is non-meaningful\n\nA settings dimension whose value is off/absent for ALL three picks (e.g.\n\"Max Mode: Off / — / —\" when no pick is on a Max-Mode surface) added a noise\nrow the mock omits and pushed the result below the fold\n[…]\nMode ON to keep exercising the humanization path.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(recommend): drop matrix rows where every pick's value is non-mean…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-04T04:25:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ca7ed71992fbc7a95f2e9934615907636a06907e",
          "body": "…k) (#368)\n\nThe result was taller than the mock and spilled below the fold at ~960px. Two\ncauses: (1) generous page-level spacing (py-8, text-2xl title, gap-6) and (2)\nthe benchmark chips lived in the always-visible left column, adding ~120px.\n\n- Tighten the vertical rhythm to the mock's compact sca\n[…]\nt 960px dropped 948px -> 863px (mock ~828px), so the picks\n+ detail fit one viewport with only the optional drawer below the fold.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(recommend): compact the result so it fits one viewport (match moc…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-04T04:09:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "12b296dad9a6fb373f9c0bf4afcc937727d861f3",
          "body": "Redeploys roadmodel-api onto 0.2.15 so /recommend surfaces the Claude Code\nORCHESTRATION dial as a settings dimension — the Orchestration row in the\ncomparison matrix. Merge only AFTER 0.2.15 is published to PyPI.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(service): require roadmodel>=0.2.15 (Orchestration setting) (#367)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-04T03:27:29Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "28741675930709646b94567b0c2de94a92add1a4",
          "body": "…nsion (0.2.15) (#366)\n\nThe comparison-matrix mock shows an Orchestration row (Standard / Ultracode),\nbut the recommender captured ORCHESTRATION only to drop it. Add it to\n_OPTIONAL_KEYS so a meaningful value (Ultracode / PerPrompt) is surfaced, and\nhave _structured_settings emit an `orchestration` \n[…]\n\nstill parses. The web matrix already renders any settings key, so no frontend\nchange is needed. Bumps roadmodel 0.2.14 -> 0.2.15.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(recommend): surface Claude Code ORCHESTRATION as a settings dime…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-04T03:12:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8c61957df5215fefb9a6d6052c06cde875d9bd5d",
          "body": "…ck) (#365)\n\nAt the ~960px split-screen widths the page is actually viewed at, the matrix\nand the selected-pick detail STACKED — the `lg` (1024px) breakpoint didn't\nfire, so it looked nothing like the mock's compact side-by-side layout. Match\nthe mock's own `.body-split`: side-by-side (1.42fr / 1fr)\n[…]\nable), the \"Balanced is the best value\" insight clause, and\nthe cost cell rendering the amount + a muted funding-source sub-label.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(recommend): keep matrix + detail side-by-side at ~960px (match mo…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-04T03:00:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "115f29853071d58677214a1af59e2d7f7fe7e856",
          "body": "…t (#364)\n\nBump the service floor to the 0.2.14 release (concise rationale + budget\nobjective that lowers the Cost pick's tier/effort even at $0-funded), and\nalign the per-user funding-context Cost posture with it: differentiate by\nCAPABILITY TIER and EFFORT when a whole family is $0-funded (price i\n[…]\nhan holding the frontier $0 model — the fix for Cost==Quality on\nclaude.ai Max. Balanced states it lands between Cost and Quality.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(service): roadmodel>=0.2.14 + Cost posture steers by tier+effor…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-03T23:35:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "edf4c71a318ded6c53545dbe420d0fc6d910ad57",
          "body": "…lumn (#363)\n\nThe selected Cost/Balanced/Quality column showed only a ring around its header\nplus lightly-tinted cells — not the mock's one clean, continuous box. Rebuild\nthe highlight to mirror mockups/recommend-redesign.html: an accent border on\nthe header top+sides (transparent bottom so it flows\n[…]\nthe rows into one ordered list so the last row can close\nthe box regardless of which optional rows (settings, Backup) are present.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(recommend): continuous rounded outline for the selected matrix co…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-03T23:31:03Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8fa2ab0281cd470316c6d8a388121a8f09e01b5d",
          "body": "… (0.2.14) (#362)\n\nBudget priority collapsed to the frontier model for all three tiers when a\nuser funds a whole family at $0 (claude.ai Max): list price is flat across\nevery candidate, so the old \"keep the $0 model\" rule held the top model for\nCost/Balanced/Quality alike. Steer the `cheap` posture \n[…]\nSK/PICK/RUN) at one crisp ~15-25 word sentence so the\n\"Why this model?\" panel renders compactly. Bumps roadmodel 0.2.13 -> 0.2.14.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(recommend): Cost picks lower tier+effort at $0, concise rationale…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-03T23:08:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "49dc1dccc046e33d1cab655448535550e6f43187",
          "body": "#358's full-width stacked matrix fixed the empty space but read sparse and\nspread-out, losing the mock's compact side-by-side feel. This restores compact\nside-by-side and removes the empty column by FILLING it instead of stacking:\n\n- LEFT column = comparison matrix + a reference block (S->D scale + \n[…]\nting key carries the scale + benchmarks.\n\nFull Playwright suite green (130 passed); verified with verbose rationale by screenshot.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(recommend): compact side-by-side layout + filled left column (#361)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-03T22:20:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "03ce850473ac3b949f968ea922abc3e06a544d31",
          "body": "Side-by-side \"matrix + rating key | detail\" left a large empty left column when\nthe rationale was long — the detail panel was much taller than the matrix. The\nmock only looked balanced because its sample rationale was short; real Gemini\nrationales are verbose, so the columns never matched and the le\n[…]\n so the two stay balanced at any length.\n\nFull Playwright suite green (130 passed); verified with verbose rationale by screenshot.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(recommend): stack the pick detail below a full-width matrix (#358)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-03T19:27:52Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "98f55f858fc36cf402f027a37848cefc3870d6c0",
          "body": "…cohesive detail (#357)\n\nThe shipped redesign dropped several things from the approved mockup, leaving the\nresults cramped and unbalanced (a big empty gap under the matrix, no insight):\n\n- Add the funded-$0 insight strip (shown when every pick is $0 to the user;\n  best-effort funding-source extracti\n[…]\nhy-box with\n  the cost floating outside it).\n\nFull Playwright suite green (130 passed); verified against the mockup by screenshot.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(recommend): restore mockup fidelity — insight strip, rating key, …",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-03T19:00:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a485bef73f9825da9a19c88a4b99b6326d4b01c6",
          "body": "Reconciled `<thinking-context>` with docs_facts and expanded the claude-code method's best-for to reflect Claude Code CHANGELOG entries 2.1.196–2.1.200. Notable additions in best-for: effort-level fallback rule (highest supported at or below requested); Option+T/Alt+T, alwaysThinkingEnabled, and MAX\n[…]\ns 4.8,. This tracker only FLAGS new models; do NOT add them to selector model lists here. Open an issue for the catalog refresh.\n\nCo-authored-by: roadmodel-bot <roadmodel-bot@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Automated Claude Code refresh: 2026-07-03 (#356)",
          "author_name": "roadmodel-cron-bot[bot]",
          "author_login": "roadmodel-cron-bot[bot]",
          "committed_at": "2026-07-03T18:23:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f620e74da1541621e12b0496311d8b7eb594ee0f",
          "body": "Bumps the service's roadmodel floor to 0.2.13 so the redeploy installs the\nstructured-rationale selector (#349, now on PyPI). Changing service/ triggers\nthe roadmodel-api Vercel deploy, which pip-installs 0.2.13; /healthz then\nreports roadmodel_version 0.2.13.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(service): require roadmodel >=0.2.13 (structured rationale) (#354)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-03T13:55:26Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2e796aef4602c71f0bd06695d45f9408898db3f4",
          "body": "Ships the structured-rationale selector change (#349): RATIONALE is emitted as\nthree labelled segments (TASK / PICK / RUN) and recommend_structured parses them\nbest-effort into a rationale_sections payload field. The single RATIONALE field\nstays required and its parse_response regex / _REQUIRED_KEYS\n[…]\ncommendResponse.\n\n- version 0.2.12 -> 0.2.13 (pyproject + __init__)\n- CHANGELOG 0.2.13 entry\n- pin test_packaging expected version\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(release): roadmodel 0.2.13 (#353)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-03T04:34:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cd0c9aab351ed585743785cc497ed969bdb3e71c",
          "body": "filterByJurisdiction read each cost row's `model`, but SessionCostEstimate rows\ncarry the model under `model_name` — so a jurisdiction-restricted model was\ncorrectly excluded as a PICK yet still surfaced as a cost-table alternative. The\nredesign made this visible (the cost table renders in the selec\n[…]\nTightens the onboarding restrict-path test to assert the excluded model appears\nNOWHERE (pick or cost table), regressing the leak.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(recommend): jurisdiction-filter cost-table rows by model_name (#352)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-03T04:26:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "95a10bbd65d1217cf9052baf8402e29bee8133ef",
          "body": "…rationale (#350)\n\n* feat(recommend): redesign output as a comparison matrix + sub-headed rationale\n\nReplaces the three stacked PriorityCards (which overflowed the viewport and read\nas duplicate containers) with a single comparison matrix — Cost / Balanced /\nQuality as COLUMNS, shared attributes (Yo\n[…]\nrison matrix +\ndetail sit higher in the viewport.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(recommend): redesign output as a comparison matrix + sub-headed …",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-03T04:20:21Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9a3494cd84681d5d3a950ba4f9e9964475e77dee",
          "body": "…end redesign (#349)\n\nThe selector now emits its RATIONALE as three labelled segments —\n\"TASK: … PICK: … RUN: …\" — so the web \"Why this model?\" panel can render\nsub-headings instead of splitting one prose string. The change is additive\nand best-effort so it can never turn a good recommendation into \n[…]\nhing prod still needs a roadmodel release + service redeploy (per the\nrecommender release pipeline); this PR is code + tests only.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(recommend): structured rationale (task/pick/run) for the /recomm…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-03T04:13:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a7fecf6a528bb84717569d877c3f8337f0fbd921",
          "body": "Reconciled <thinking-context> with docs_facts: added Sonnet 5 to the Claude Code full-range effort list (low/medium/high/xhigh/max), the max-above-xhigh model set, and the default-high enumeration alongside Opus 4.6, Opus 4.8, Fable 5, and Sonnet 4.6. Updated <method id=\"claude-code\"> best-for to me\n[…]\ns 4.8,. This tracker only FLAGS new models; do NOT add them to selector model lists here. Open an issue for the catalog refresh.\n\nCo-authored-by: roadmodel-bot <roadmodel-bot@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Automated Claude Code refresh: 2026-07-02 (#346)",
          "author_name": "roadmodel-cron-bot[bot]",
          "author_login": "roadmodel-cron-bot[bot]",
          "committed_at": "2026-07-02T17:45:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b3c45acf07094fdcd858eaf3192106eb0b10457b",
          "body": "…ilability (#343)\n\nStep 3 (final) of the Phase 4.9 B5 cutover. Bumps the service floor to the\n0.2.12 release that adds recommend_structured's `availability_authoritative`\nparam, and drops the temporary `_RS_SUPPORTS_AUTHORITATIVE` feature-detect guard\n(+ its test) — the floor now guarantees the para\n[…]\nlability-context> fallback.\n\nBLOCKED until roadmodel 0.2.12 is published to PyPI (CI installs the pinned\nfloor). Draft until then.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(service): require roadmodel>=0.2.12; activate authoritative ava…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-02T04:42:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4a33a2d0eaf7615eec83664994e9524802f87f2b",
          "body": "Cutover release that activates the authoritative runtime availability override\n(Phase 4.9 B5, #339): recommend_structured/recommend/build_prompt accept\navailability_authoritative, and <availability-context> becomes a fail-closed\ncold-start fallback. Publishing this + bumping the service floor is wha\n[…]\nurther releases.\n\n- version 0.2.11 -> 0.2.12 (pyproject + __init__)\n- CHANGELOG 0.2.12 entry\n- pin test_packaging expected version\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(release): roadmodel 0.2.12 (#342)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-02T04:34:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e9fa5a10e5a57c576e882e08929c55557bc9b12b",
          "body": "…(#341)\n\nCo-authored-by: roadmodel-bot <roadmodel-bot@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(availability): probe-detected availability change (2026-07-02) …",
          "author_name": "roadmodel-cron-bot[bot]",
          "author_login": "roadmodel-cron-bot[bot]",
          "committed_at": "2026-07-02T03:10:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d90659da0a98beb684f03be5894915ec4c1dd968",
          "body": "… (#340)\n\nThe [verify] adjudication line printed only the decision reason; a dry-run showed\nthe un-bench decision but not the sources behind it. Append up to 5 evidence_urls\nfrom the AI verdict so a run log shows the grounded basis for each bench/hold/\nun-bench (useful because an un-bench deletes the entry, so the sources aren't\npersisted in the JSON).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(availability): log cited evidence_urls in the probe verify sweep…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-02T02:06:42Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "65348798620b03576da956fddbf09cca4a21ff6e",
          "body": "… a release (Phase 4.9 B5) (#339)\n\nMake the runtime availability layer the source of truth so a RESTORED model is\nrecommended again with no package release, while the bundled <availability-context>\nbecomes a fail-closed cold-start fallback (used only when the availability service\nis unreachable).\n\n-\n[…]\neds one cutover release (roadmodel + service floor bump + web\ndeploy); after it, un-benching is fully autonomous and release-free.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(availability): authoritative runtime override — un-bench without…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-02T00:29:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "55800656521f3490e1533ba0b38c941fcf3b2706",
          "body": "…337)\n\nAdd an AI web-search verification step (update/verify_availability.py) that gates\nthe un-bench direction of the daily availability probe. The cheap US-keyed 1-token\nprobe is trusted to BENCH a model (fail-safe) but no longer trusted to UN-BENCH one\non its own: every currently-restricted entry\n[…]\n).\nStage 2 (separate) makes the runtime layer authoritative so a restored model is\nactually recommended without a package release.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(availability): AI-grounded autonomous un-bench (Phase 4.9 B5) (#…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-07-02T00:04:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5caa0b7a77429860aa21ad22845e23267240e882",
          "body": "…(#336)\n\nCo-authored-by: roadmodel-bot <roadmodel-bot@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(availability): probe-detected availability change (2026-07-01) …",
          "author_name": "roadmodel-cron-bot[bot]",
          "author_login": "roadmodel-cron-bot[bot]",
          "committed_at": "2026-07-01T21:39:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a719d303d8ec3216a8e6f1d231020b3a600ab777",
          "body": "Pin the service to roadmodel 0.2.11 so the redeploy picks up the Max\nreasoning-effort output level (#324). Completes the release pipeline: PyPI\npublish -> service floor bump -> redeploy. Verify via healthz roadmodel_version.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(service): require roadmodel>=0.2.11 (#325)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-06-29T04:30:43Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "aae819b9aace8c449136932b9b5ea13e72075cae",
          "body": "…(#324)\n\nThe selector's structured THINKING field was a stale 6-state enum\n(Off/Low/Medium/High/XHigh/N/A) that capped at XHigh — so the recommender could\nnot surface Claude Code's top `/effort` level (`max`), even though roadmodel's\nown effort tracker lists `max` for Opus 4.7/4.8/Fable 5. Result: o\n[…]\n (pyproject + __init__ + packaging pin + CHANGELOG).\nReaches prod via PyPI release + service floor bump (same pipeline as 0.2.10).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(recommend): add Max reasoning-effort output level (above XHigh) …",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-06-29T04:15:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cc07430ec43e0ced63f6e80b3faeae46609f39b1",
          "body": "Pin the service to the just-published roadmodel 0.2.10 so the redeploy picks up\nthe bundled selector-prompt changes (budget-priority steering #319 + funding-\naware Cost #321). Completes the recommender release pipeline: PyPI publish ->\nservice floor bump -> redeploy. Verify via healthz roadmodel_version.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(service): require roadmodel>=0.2.10 (#323)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-06-29T02:46:51Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "988e20ff384b2d6b6d99418a079af848fc8bd4e8",
          "body": "Cut 0.2.10 so the budget-priority selector-prompt changes reach prod (the\nrecommender package is bundled at build time and only ships via a PyPI release\n+ service floor bump, not on merge — #319/#321 have been running service-side\nonly). This release bundles the updated <objective>:\n\n- Budget-priori\n[…]\ntisfied). Tag v0.2.10 + the gated workflow_dispatch\npublish follow on merge; then the service floor bumps to >=0.2.10 + redeploys.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(release): roadmodel 0.2.10 (#322)",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-06-29T02:09:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "eb7bd1bb39be9a116bd9130e802568315a0d12c4",
          "body": "…rt (#321)\n\nFor a user who already funds a capable model at $0 (e.g. Opus via Claude Max),\n\"Cost\" was switching to a cheaper-TIER model (GPT-5.4) by generic list price —\nwhich RAISES their real cost, since the cheaper-tier model is unfunded\n(pay-per-token) while their best model is free. List-price \n[…]\nestion: why Cost picked GPT-5.4 over Opus-at-lower-effort.\nBuilds on #319 (budget steers selection) and #320 (three-card surface).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(recommend): make Cost funding-aware — hold a $0 model, lower effo…",
          "author_name": "Nathan Ramos, CFA",
          "author_login": "nathanramoscfa",
          "committed_at": "2026-06-28T21:31:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        }
      ],
      "releases_count": 36,
      "commits_last_year": 391,
      "latest_release_at": "2026-07-22T17:37:36Z",
      "latest_release_tag": "v0.2.29",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 11,
      "days_since_latest_release": 0,
      "mean_days_between_releases": 1.9
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 100,
      "has_issue_template": false,
      "has_code_of_conduct": true,
      "has_pull_request_template": true
    },
    "ecosystem": {
      "packages": [
        {
          "name": "roadmodel",
          "exists": true,
          "license": null,
          "keywords": [
            "ai",
            "anthropic",
            "cli",
            "gemini",
            "llm",
            "model-selection",
            "openai",
            "Development Status :: 3 - Alpha",
            "Environment :: Console",
            "Intended Audience :: Developers",
            "License :: OSI Approved :: Apache Software License",
            "Operating System :: OS Independent",
            "Programming Language :: Python :: 3",
            "Programming Language :: Python :: 3 :: Only",
            "Programming Language :: Python :: 3.11",
            "Programming Language :: Python :: 3.12",
            "Programming Language :: Python :: 3.13",
            "Topic :: Software Development",
            "Topic :: Utilities"
          ],
          "ecosystem": "pypi",
          "matches_repo": true,
          "registry_url": "https://pypi.org/project/roadmodel/",
          "is_deprecated": false,
          "latest_version": "0.2.29",
          "repository_url": "https://github.com/nathanramoscfa/roadmodel",
          "versions_count": 34,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": "2026-05-15T03:48:45.267990Z",
          "latest_published_at": "2026-07-22T17:37:24.996900Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 0
        }
      ]
    },
    "popularity": {
      "forks": 1,
      "stars": 1,
      "watchers": 0,
      "fork_history": {
        "days": [
          {
            "date": "2026-05-18",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 1,
        "total_forks": 1
      },
      "star_history": null,
      "open_issues_and_prs": 51
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": true,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "web/tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 51420,
      "source_files_sampled": 237,
      "oversized_source_files": 0,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "pyproject.toml",
        "service/pyproject.toml",
        "tests/requirements.txt",
        "update/requirements.txt",
        "web/package.json"
      ],
      "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": [
        "npm",
        "pypi"
      ],
      "dependencies": [
        {
          "name": "click",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=8.3.3"
        },
        {
          "name": "roadmodel",
          "manifest": "service/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.2.29,<0.3"
        },
        {
          "name": "fastapi",
          "manifest": "service/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.110"
        },
        {
          "name": "uvicorn",
          "manifest": "service/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.27"
        },
        {
          "name": "pydantic",
          "manifest": "service/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=2.6"
        },
        {
          "name": "@google/genai",
          "manifest": "web/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.6.0"
        },
        {
          "name": "@supabase/ssr",
          "manifest": "web/package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.10.3"
        },
        {
          "name": "@supabase/supabase-js",
          "manifest": "web/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.106.0"
        },
        {
          "name": "@upstash/ratelimit",
          "manifest": "web/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.0.8"
        },
        {
          "name": "@upstash/redis",
          "manifest": "web/package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.38.0"
        },
        {
          "name": "lucide-react",
          "manifest": "web/package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.511.0"
        },
        {
          "name": "next",
          "manifest": "web/package.json",
          "ecosystem": "npm",
          "version_constraint": "^15.3.2"
        },
        {
          "name": "react",
          "manifest": "web/package.json",
          "ecosystem": "npm",
          "version_constraint": "^19.1.0"
        },
        {
          "name": "react-dom",
          "manifest": "web/package.json",
          "ecosystem": "npm",
          "version_constraint": "^19.1.0"
        },
        {
          "name": "zod",
          "manifest": "web/package.json",
          "ecosystem": "npm",
          "version_constraint": "^3.25.28"
        }
      ],
      "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": 27,
        "merged_prs": 354,
        "open_issues": 24,
        "closed_ratio": 0.747,
        "closed_issues": 71,
        "closed_unmerged_prs": 11
      },
      "bus_factor": 1,
      "bot_contributors": 2,
      "top_contributors": [
        {
          "type": "User",
          "login": "nathanramoscfa",
          "commits": 374,
          "avatar_url": "https://avatars.githubusercontent.com/u/86393277?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "auto-remediate.yml",
        "claude.yml",
        "phase-verify.yml",
        "probe-availability.yml",
        "recommend-soak.yml",
        "release.yml",
        "sync-availability.yml",
        "tests.yml",
        "update-claude-code.yml",
        "update-codex.yml",
        "update-deepseek.yml",
        "update-gemini.yml",
        "update-models.yml",
        "verify-pypi.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [
        ".eslintrc.json"
      ],
      "has_editorconfig": false,
      "has_linter_config": true,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "package-lock.json"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": null,
            "reason": "internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 0,
            "reason": "project has 0 contributing companies or organizations -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 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": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 1,
            "reason": "dependency not pinned by hash detected -- score normalized to 1",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 10,
            "reason": "security policy file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": 8,
            "reason": "5 out of the last 5 releases have a total of 5 signed artifacts.",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 1,
            "reason": "9 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "abfe10fed33b3b85daaf7f8193e193f0ad16e99a",
        "ran_at": "2026-07-22T19:07:59Z",
        "aggregate_score": 4.1,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": true,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-22T18:33:17Z",
      "oldest_open_prs": [
        {
          "number": 318,
          "created_at": "2026-06-27T19:40:17Z",
          "last_comment_at": "2026-06-27T19:40:21Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 326,
          "created_at": "2026-06-29T17:13:15Z",
          "last_comment_at": "2026-06-29T17:13:19Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 327,
          "created_at": "2026-06-29T18:47:09Z",
          "last_comment_at": "2026-06-29T18:47:13Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 328,
          "created_at": "2026-06-29T19:44:22Z",
          "last_comment_at": "2026-06-29T19:44:26Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 329,
          "created_at": "2026-06-30T16:55:01Z",
          "last_comment_at": "2026-06-30T16:55:05Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 332,
          "created_at": "2026-07-01T16:58:44Z",
          "last_comment_at": "2026-07-01T16:58:48Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 335,
          "created_at": "2026-07-01T19:43:37Z",
          "last_comment_at": "2026-07-01T19:43:41Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 344,
          "created_at": "2026-07-02T16:47:05Z",
          "last_comment_at": "2026-07-02T16:47:09Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 348,
          "created_at": "2026-07-02T19:40:27Z",
          "last_comment_at": "2026-07-02T19:40:30Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 360,
          "created_at": "2026-07-03T20:23:30Z",
          "last_comment_at": "2026-07-03T20:23:33Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 380,
          "created_at": "2026-07-04T18:08:32Z",
          "last_comment_at": "2026-07-04T18:08:36Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 392,
          "created_at": "2026-07-05T17:16:29Z",
          "last_comment_at": "2026-07-05T17:16:33Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 397,
          "created_at": "2026-07-07T18:08:28Z",
          "last_comment_at": "2026-07-07T18:08:30Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 402,
          "created_at": "2026-07-08T17:37:32Z",
          "last_comment_at": "2026-07-08T17:37:36Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 410,
          "created_at": "2026-07-10T18:30:33Z",
          "last_comment_at": "2026-07-10T18:30:37Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 413,
          "created_at": "2026-07-11T18:02:03Z",
          "last_comment_at": "2026-07-11T18:02:09Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 415,
          "created_at": "2026-07-11T20:13:59Z",
          "last_comment_at": "2026-07-11T20:14:03Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 418,
          "created_at": "2026-07-14T18:11:10Z",
          "last_comment_at": "2026-07-14T18:11:14Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 449,
          "created_at": "2026-07-17T17:20:20Z",
          "last_comment_at": "2026-07-17T17:20:24Z",
          "last_comment_author": "vercel"
        },
        {
          "number": 454,
          "created_at": "2026-07-18T17:05:34Z",
          "last_comment_at": "2026-07-18T17:05:37Z",
          "last_comment_author": "vercel"
        }
      ],
      "last_merged_pr_at": "2026-07-22T17:59:19Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 63,
          "created_at": "2026-05-19T03:06:20Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 65,
          "created_at": "2026-05-19T03:06:47Z",
          "last_comment_at": "2026-06-12T04:13:20Z",
          "last_comment_author": "nathanramoscfa"
        },
        {
          "number": 69,
          "created_at": "2026-05-19T03:29:12Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 81,
          "created_at": "2026-05-19T17:33:43Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 99,
          "created_at": "2026-05-20T18:16:51Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 148,
          "created_at": "2026-06-01T03:19:31Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 185,
          "created_at": "2026-06-05T14:39:38Z",
          "last_comment_at": "2026-06-06T04:35:10Z",
          "last_comment_author": "nathanramoscfa"
        },
        {
          "number": 188,
          "created_at": "2026-06-05T14:39:42Z",
          "last_comment_at": "2026-06-06T04:35:11Z",
          "last_comment_author": "nathanramoscfa"
        },
        {
          "number": 189,
          "created_at": "2026-06-05T14:39:44Z",
          "last_comment_at": "2026-06-06T04:35:12Z",
          "last_comment_author": "nathanramoscfa"
        },
        {
          "number": 201,
          "created_at": "2026-06-06T23:35:50Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 210,
          "created_at": "2026-06-07T15:37:11Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 211,
          "created_at": "2026-06-07T15:37:21Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 254,
          "created_at": "2026-06-12T20:18:29Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 260,
          "created_at": "2026-06-13T17:06:33Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 330,
          "created_at": "2026-06-30T19:38:59Z",
          "last_comment_at": "2026-07-15T19:23:21Z",
          "last_comment_author": "nathanramoscfa"
        },
        {
          "number": 331,
          "created_at": "2026-07-01T16:58:41Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 422,
          "created_at": "2026-07-15T18:07:51Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 438,
          "created_at": "2026-07-16T18:59:55Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 439,
          "created_at": "2026-07-16T18:59:56Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 440,
          "created_at": "2026-07-16T18:59:57Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/nathanramoscfa/roadmodel",
    "host": "github.com",
    "name": "roadmodel",
    "owner": "nathanramoscfa"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 61,
      "inputs": {
        "security": 41,
        "vitality": 76,
        "community": 43,
        "governance": 54,
        "engineering": 86
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 76,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 62,
            "inputs": {
              "commits_last_year": 391,
              "human_commit_share": 0.83,
              "days_since_last_push": 0,
              "active_weeks_last_year": 11
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "11/52 weeks with commits",
                "points": 7.6,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 11
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "391 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 391
                    }
                  }
                ],
                "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": null,
            "notes": [],
            "value": 98,
            "inputs": {
              "releases_count": 36,
              "latest_release_tag": "v0.2.29",
              "releases_from_tags": false,
              "days_since_latest_release": 0,
              "mean_days_between_releases": 1.9
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "36 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 36
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~1.9 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 1.9
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "5 out of the last 5 releases have a total of 5 signed artifacts.",
                "points": 8,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 43,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 1,
              "stars": 1,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "1 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "1 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "excellent",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 92,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": true,
              "has_pull_request_template": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (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": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 13.5,
                "status": "met",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 6.3,
                "status": "met",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 54,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 10,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 72,
            "inputs": {
              "merged_prs": 354,
              "open_issues": 24,
              "closed_issues": 71,
              "issue_closed_ratio": 0.747,
              "closed_unmerged_prs": 11
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "75% of issues closed",
                "points": 34.9,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 75
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "354/365 decided PRs merged",
                "points": 37.1,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 354,
                      "decided": 365
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 50,
            "inputs": {
              "followers": 25,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "nathanramoscfa",
              "public_repos": 21,
              "account_age_days": 1854
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "25 followers of nathanramoscfa",
                "points": 10.2,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 25,
                      "login": "nathanramoscfa"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "21 public repos, account ~5 yr old",
                "points": 19.9,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 21
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 5
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "roadmodel"
              ],
              "ecosystems": "pypi",
              "any_deprecated": false,
              "min_days_since_publish": 0
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on pypi",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "pypi"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 0 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "34 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 34
                    }
                  }
                ],
                "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": "excellent",
        "name": "Engineering Quality",
        "value": 86,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "good",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 84,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": true,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "14 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 14
                    }
                  }
                ],
                "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": ".eslintrc.json",
                "points": 16,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".eslintrc.json"
                    }
                  }
                ],
                "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": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "excellent",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": "https://roadmodel-web.vercel.app",
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": "https://roadmodel-web.vercel.app",
                "points": 15,
                "status": "met",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": 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": 41,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Branch-Protection. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "branch_protection"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 41,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 17,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 1,
              "scorecard_aggregate": 4.1
            },
            "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": "internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "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 detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 1",
                "points": 0.5,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "5 out of the last 5 releases have a total of 5 signed artifacts.",
                "points": 6,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "9 existing vulnerabilities detected",
                "points": 0.8,
                "status": "partial",
                "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": 53,
        "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": 1,
              "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": "83 of 83 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 83,
                      "sampled": 83
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 65,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "package-lock.json"
              ],
              "has_dockerfile": true,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [
                "web/tsconfig.json"
              ],
              "agent_commit_share": 0.84,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": ".eslintrc.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".eslintrc.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "web/tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "web/tsconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "Dockerfile, lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Dockerfile, lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "84 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 84,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 1",
                "points": 1,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "good",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 82,
            "inputs": {
              "primary_language": "Python",
              "largest_source_bytes": 51420,
              "source_files_sampled": 237,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Python with type-check config (web/tsconfig.json)",
                "points": 27,
                "status": "partial",
                "details": [
                  {
                    "code": "typecheck_config_language",
                    "params": {
                      "files": "web/tsconfig.json",
                      "language": "Python"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/237 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 237,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "critical",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 20,
            "inputs": {
              "example_dirs": [],
              "has_mcp_signal": true,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "Could not fetch pypi package 'roadmodel-service' from its registry",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
    "deps.dev does not index pypi:roadmodel@0.2.29; advisories assessed against the repository dependency graph instead"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-22T19:08:19.337969Z",
  "schema_version": "0.26.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/n/nathanramoscfa/roadmodel.svg",
  "full_name": "nathanramoscfa/roadmodel",
  "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 StatistikenPyPI.