Öffentliches Register
Software-GesundheitsberichtSchema 0.27.0 · Metriken 1.13.0 · 2026-07-25 17:04 UTC

nanostack-dev / echopoint-runner

Echopoint Flow Engine

GoKeine Lizenz erkannt★ 0 Sterne⑂ 0 Forksseit Okt. 2025Auf GitHub ansehen ↗

nanostack-dev/echopoint-runner erreicht einen Gesundheitsindex von 46 von 100 und liegt damit im Bereich Gefährdet. Am stärksten schneidet es bei AI Readiness (78/100) ab, am schwächsten bei Community & Adoption (1/100). Zuletzt vor 5 Tagen aktualisiert. Ein einzelner Mitwirkender trägt den Großteil der jüngsten Arbeit.

46
gesamt / 100
Gefährdet

Software-Gesundheitsindex

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

46
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

nanostack.devOrganisation
0 Follower10 öffentliche Reposseit März 2024

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

Paket-Ökosysteme

RegistryPaketVersionDownloads / MonatVersionenZuletzt veröffentlicht
Gogithub.com/nanostack-dev/echopoint-runnerv0.35.0-41vor 5 Tagen

Metriken nach Kategorie

Vitalität

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

77Gut · 22 % des Gesamtindex
Wie die Bewertung erfolgt
36/36Push-Aktualität — letzter Push vor 5 Tagen
5.5/36Commit-Rhythmus — 8/52 Wochen mit Commits
17.6/18Commit-Volumen — 90 Commits im letzten Jahr
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Verwendete Eingangsdaten
commits_last_year90
human_commit_share1
days_since_last_push5
active_weeks_last_year8
Wie die Bewertung erfolgt
27/27Liefert Releases aus — 40 Releases veröffentlicht
36/36Release-Aktualität — letztes Release vor 5 Tagen
27/27Release-Rhythmus — ein Release etwa alle 3,3 Tage
0/10OpenSSF Scorecard: Signed-Releases — Project has not signed or included provenance with any releases.
Verwendete Eingangsdaten
releases_count40
latest_release_tagv0.35.0
releases_from_tagsnein
days_since_latest_release5
mean_days_between_releases3,3

Community & Verbreitung

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

1Kritisch · 18 % des Gesamtindex
Wie die Bewertung erfolgt
0/60Stars — 0 Stars
0/25Forks — 0 Forks
0/15Watcher — 0 Watcher
Verwendete Eingangsdaten
forks0
stars0
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Wie die Bewertung erfolgt
0/22.5README
0/22.5Lizenz — keine Lizenzdatei erkannt
0/18CONTRIBUTING-Leitfaden
0/13.5Verhaltenskodex
0/7.2Issue-Vorlage
0/6.3PR-Vorlage
Verwendete Eingangsdaten
has_readmenein
has_licensenein
has_contributingnein
has_issue_templatenein
has_code_of_conductnein
has_pull_request_templatenein

Nachhaltigkeit & Governance

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

46Gefährdet · 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
0/46.8Issue-Lösungsquote — keine Issues oder keine Daten
26.9/38.3PR-Annahme — 26/37 entschiedene PRs gemergt
0/15OpenSSF Scorecard: Code-Review — Found 0/4 approved changesets -- score normalized to 0
Verwendete Eingangsdaten
merged_prs26
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs11
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Issue-Lösungsquote. Die verbleibenden Gewichte wurden renormalisiert.
Wie die Bewertung erfolgt
30/30Organisatorische Trägerschaft — im Besitz einer Organisation
0/20Verifizierte Domain
0/25Reichweite des Inhabers — 0 Follower von nanostack-dev
12.3/25Kontohistorie — 10 öffentliche Repos, Kontoalter ca. 2 Jahre
Verwendete Eingangsdaten
followers0
owner_typeOrganization
is_verified
owner_loginnanostack-dev
public_repos10
account_age_days867

Paketpflege

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

Engineering-Qualität

Sind grundlegende Engineering- und Dokumentationspraktiken vorhanden?

65Mittel · 20 % des Gesamtindex
Wie die Bewertung erfolgt
24/24CI-Workflows — 2 Workflow(s)
24/24Tests vorhanden
16/16Linter-Konfiguration — .golangci.yml
0/9.6Pre-Commit-Hooks
0/6.4.editorconfig
14/20OpenSSF Scorecard: CI-Tests — 3 out of 4 merged PRs checked by a CI test -- score normalized to 7
Verwendete Eingangsdaten
has_cija
has_testsja
has_editorconfignein
has_linter_configja
has_precommit_confignein

Dokumentation

45Gefährdet
Wie die Bewertung erfolgt
0/30README
25/25Dokumentationsverzeichnis
0/15Dokumentations-/Homepage-Site
10/10Repository-Beschreibung
0/10Topics
10/10Wiki
Verwendete Eingangsdaten
topics
has_wikija
homepage
has_readmenein
has_docs_dirja
has_descriptionja

Sicherheit

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

31Gefährdet · 16 % des Gesamtindex

Sicherheitslage

31Gefährdet
Wie die Bewertung erfolgt
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
1.8/2.5CI-Tests — 3 out of 4 merged PRs checked by a CI test -- score normalized to 7
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/4 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
0/2.5Lizenz — license file not detected
7.5/7.5Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
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
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — Project has not signed or included provenance with any releases.
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0/7.5Vulnerabilities — 26 existing vulnerabilities detected
Verwendete Eingangsdaten
sourceopenssf_scorecard
checks_evaluated18
scorecard_versionv5.5.0
checks_inconclusive0
scorecard_aggregate3,1

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.

78Gut · 0 % des Gesamtindex
Wie die Bewertung erfolgt
45/45Agentenanweisungen — AGENTS.md, CLAUDE.md
0/15Maschinenlesbare Doku (llms.txt)
40/40Lesbare Commit-Historie — 90 von 90 menschlichen Commits benennen ihre Absicht (strukturierter Betreff oder erläuternder Text)
Verwendete Eingangsdaten
has_llms_txtnein
legible_history_share1
agent_instruction_filesAGENTS.md, CLAUDE.md
agent_instruction_max_bytes789
Wie die Bewertung erfolgt
12.6/18Bootstrap mit einem Befehl — go.mod (Toolchain-Konvention, kein Task-Runner)
22/22Automatisierte Tests
11/11Lint-/Format-Konfiguration — .golangci.yml
11/11Statische Typprüfung — Go (statisch typisiert)
10/10Reproduzierbare Umgebung — Dockerfile, lockfile
10/10Belegte Agentenpraxis — 70 der letzten 90 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
lockfilesgo.sum
has_dockerfileja
typed_languageja
bootstrap_files
has_devcontainernein
has_linter_configja
typecheck_configs
agent_commit_share0,778
toolchain_manifestsgo.mod
dependency_bot_commit_share0
Wie die Bewertung erfolgt
45/45Typprüfbarer Code — Go (statisch typisiert)
55/55Handhabbare Dateigrößen — 0/139 Quelldateien über 60 KB
Verwendete Eingangsdaten
primary_languageGo
largest_source_bytes53.521
source_files_sampled139
oversized_source_files0
Wie die Bewertung erfolgt
0/40API-Schema (OpenAPI/GraphQL/proto)
0/20MCP-Server
40/40Lauffähige Beispiele — examples
Verwendete Eingangsdaten
example_dirsexamples
has_mcp_signalnein
api_schema_files

Eckdaten

0GitHub-Sterne
1Mitwirkende
90Commits, letzte 12 Monate
5Tage seit letztem Push
40Releases
1Bus-Faktor
0offene Issues
GoPaket-Ökosysteme

Warnungen zur Datenerhebung

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

Weitere Details

OpenSSF Scorecard 3.1 / 10
3.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-25 17:04 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
7CI-Tests3 out of 4 merged PRs checked by a CI test -- score normalized to 7
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/4 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
0Licenselicense file not detected
10Maintained30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
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
0Security-Policysecurity policy file not detected
0Signed-ReleasesProject has not signed or included provenance with any releases.
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
0Vulnerabilities26 existing vulnerabilities detected
Direkte Abhängigkeiten 8
RegistryPaketVersionsvorgabeManifest
Gogithub.com/brianvoe/gofakeit/v7v7.15.0go.mod
Gogithub.com/docker/dockerv28.3.3+incompatiblego.mod
Gogithub.com/google/uuidv1.6.0go.mod
Gogithub.com/rs/zerologv1.34.0go.mod
Gogithub.com/spf13/cobrav1.8.1go.mod
Gogithub.com/stretchr/testifyv1.11.1go.mod
Gogithub.com/testcontainers/testcontainers-gov0.39.0go.mod
Gogithub.com/theory/jsonpathv0.10.1go.mod
Alle Abhängigkeiten nicht erhoben

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

JSON-Rohbericht maschinenlesbar
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 555,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "Go": 667536,
        "Dockerfile": 438
      },
      "pushed_at": "2026-07-20T03:14:23Z",
      "created_at": "2025-10-25T02:11:29Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-20T03:14:21Z",
      "description": "Echopoint Flow Engine",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": null,
      "default_branch": "main",
      "license_spdx_raw": null,
      "primary_language": "Go",
      "significant_languages": [
        "Go"
      ]
    },
    "owner": {
      "blog": null,
      "name": "nanostack.dev",
      "type": "Organization",
      "login": "nanostack-dev",
      "company": null,
      "location": null,
      "followers": 0,
      "avatar_url": "https://avatars.githubusercontent.com/u/162839586?v=4",
      "created_at": "2024-03-09T21:01:46Z",
      "is_verified": null,
      "public_repos": 10,
      "account_age_days": 867
    },
    "license": {
      "state": "absent",
      "spdx_id": null,
      "raw_spdx": null,
      "file_present": false,
      "scorecard_found": false,
      "profile_has_license": false
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.35.0",
          "kind": "minor",
          "published_at": "2026-07-20T03:14:54Z"
        },
        {
          "tag": "v0.34.0",
          "kind": "minor",
          "published_at": "2026-07-19T03:14:09Z"
        },
        {
          "tag": "v0.33.0",
          "kind": "minor",
          "published_at": "2026-07-04T17:47:45Z"
        },
        {
          "tag": "v0.32.0",
          "kind": "minor",
          "published_at": "2026-07-04T17:46:50Z"
        },
        {
          "tag": "v0.31.0",
          "kind": "minor",
          "published_at": "2026-06-29T18:41:08Z"
        },
        {
          "tag": "v0.30.0",
          "kind": "minor",
          "published_at": "2026-06-29T18:27:00Z"
        },
        {
          "tag": "v0.29.0",
          "kind": "minor",
          "published_at": "2026-06-28T14:25:48Z"
        },
        {
          "tag": "v0.28.0",
          "kind": "minor",
          "published_at": "2026-06-20T15:06:15Z"
        },
        {
          "tag": "v0.27.0",
          "kind": "minor",
          "published_at": "2026-06-20T03:01:20Z"
        },
        {
          "tag": "v0.26.0",
          "kind": "minor",
          "published_at": "2026-06-20T03:01:09Z"
        },
        {
          "tag": "v0.25.0",
          "kind": "minor",
          "published_at": "2026-06-18T17:12:36Z"
        },
        {
          "tag": "v0.24.0",
          "kind": "minor",
          "published_at": "2026-06-09T00:07:04Z"
        },
        {
          "tag": "v0.23.0",
          "kind": "minor",
          "published_at": "2026-06-08T22:26:39Z"
        },
        {
          "tag": "v0.22.0",
          "kind": "minor",
          "published_at": "2026-06-08T17:48:29Z"
        },
        {
          "tag": "v0.21.0",
          "kind": "minor",
          "published_at": "2026-06-08T17:44:12Z"
        },
        {
          "tag": "v0.20.0",
          "kind": "minor",
          "published_at": "2026-06-08T17:25:38Z"
        },
        {
          "tag": "v0.19.0",
          "kind": "minor",
          "published_at": "2026-06-08T12:51:15Z"
        },
        {
          "tag": "v0.18.0",
          "kind": "minor",
          "published_at": "2026-06-08T11:16:35Z"
        },
        {
          "tag": "v0.17.0",
          "kind": "minor",
          "published_at": "2026-06-08T03:57:35Z"
        },
        {
          "tag": "v0.16.0",
          "kind": "minor",
          "published_at": "2026-06-08T03:50:07Z"
        },
        {
          "tag": "v0.15.0",
          "kind": "minor",
          "published_at": "2026-06-05T01:13:27Z"
        },
        {
          "tag": "v0.14.0",
          "kind": "minor",
          "published_at": "2026-06-05T01:10:25Z"
        },
        {
          "tag": "v0.13.0",
          "kind": "minor",
          "published_at": "2026-06-04T22:29:28Z"
        },
        {
          "tag": "v0.12.0",
          "kind": "minor",
          "published_at": "2026-06-03T21:27:55Z"
        },
        {
          "tag": "v0.11.0",
          "kind": "minor",
          "published_at": "2026-06-02T19:42:41Z"
        },
        {
          "tag": "v0.10.3",
          "kind": "patch",
          "published_at": "2026-04-24T14:22:58Z"
        },
        {
          "tag": "v0.10.2",
          "kind": "patch",
          "published_at": "2026-03-18T18:52:45Z"
        },
        {
          "tag": "v0.10.1",
          "kind": "patch",
          "published_at": "2026-03-18T18:16:05Z"
        },
        {
          "tag": "v0.10.0",
          "kind": "minor",
          "published_at": "2026-03-18T17:30:53Z"
        },
        {
          "tag": "v0.9.0",
          "kind": "minor",
          "published_at": "2026-02-06T02:18:54Z"
        },
        {
          "tag": "v0.8.0",
          "kind": "minor",
          "published_at": "2026-02-05T05:02:34Z"
        },
        {
          "tag": "v0.7.0",
          "kind": "minor",
          "published_at": "2026-02-02T16:11:47Z"
        },
        {
          "tag": "v0.6.1",
          "kind": "patch",
          "published_at": "2026-01-25T06:04:58Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2026-01-21T05:09:38Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2026-01-21T03:50:09Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-01-15T04:41:09Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2025-12-05T04:47:45Z"
        },
        {
          "tag": "v0.2.1",
          "kind": "patch",
          "published_at": "2025-11-11T04:43:11Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2025-10-28T03:52:05Z"
        },
        {
          "tag": "v0.1.0",
          "kind": "minor",
          "published_at": "2025-10-25T04:00:15Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "574955ece8c7f5d45271b3f3e3a16e112f7ee4d7",
          "body": "Move internal/ephemeral -> pkg/ephemeral so external consumers (echopoint-cli)\ncan execute an ephemeral package in-process via ephemeral.Run(pkg) instead of\nshelling out to the echopoint-runner binary. Pure package move + import-path\nupdate; no behaviour change. cmd/runner keeps using it.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(ephemeral): promote ephemeral to pkg/ephemeral (public) (#39)",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-20T03:14:15Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1cb3d68ccec90b16ff3d967284d8722480820992",
          "body": "Nested module executions were built without the dynamic-variable resolver,\nso {{$runId}}, {{$uuid}}, etc. inside a module's request nodes rendered\nliterally. Module-generated names (e.g. the setup-org module's product name)\nwere therefore identical across runs, making any flow that creates named\nres\n[…]\ne child ExecuteFlowDefinition call. Adds a regression test asserting a\nmodule request node resolves {{$runId}} to the run's value.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(engine): propagate dynamic vars into module executions (#38)",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-19T03:12:26Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3ebb41181a4cad13317b1473c731a77b42de6cc1",
          "body": "…+ dynamicvars parity\n\nfeat: greenfield runner core (pkg/core)",
          "is_bot": false,
          "headline": "Merge #35: feat(core) — greenfield runner (pkg/core) + optimizations …",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-04T17:47:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1f8167a72b29492fa9949e13919674a431f1267e",
          "body": "refactor(runner): collapse spi alias facade + remove dead code",
          "is_bot": false,
          "headline": "Merge #34: refactor(runner) — collapse spi facade + remove dead code",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-04T17:46:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "db739b78b9f4591c81985c5805424393730e688d",
          "body": "…tVar)\n\nModule transparently exposes everything the child flow outputs, addressed by the\nchild's node id. Confirms the intended contract: no per-module output selection;\na downstream node reads a module's child output as {{module.child.output}}.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BUV1chzzCLRQJ4mw8vEnMF",
          "is_bot": false,
          "headline": "test(core): lock module output addressing (moduleNode.childNode.outpu…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-04T17:37:03Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "30b5f7f3d91ecbe7f28fcfbdf84c50352cb6fff0",
          "body": "…nner)\n\nThe greenfield dynamicvars had shrunk to a 5-generator stdlib stub; the old\nrunner shipped ~55 gofakeit-backed generators with deterministic per-execution\nseeding and a discovery catalog. Ported the full set into pkg/core/dynamicvars:\n\n- ~55 generators across time/identity/contact/address/fi\n[…]\n. Tests cover breadth, determinism, args, and the catalog.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BUV1chzzCLRQJ4mw8vEnMF",
          "is_bot": false,
          "headline": "feat(core): restore full dynamic-variable catalog (parity with old ru…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-04T15:23:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "32fd3d302e5dcd6c0fb1f9b68779656a5069c337",
          "body": "Per review, the ~7% loop/module gain did not justify adding derived state and a\ndual scheduler code path to the intentionally pure-data flow package. The other\nfive Fable-round optimizations (dotted-path walker, byte template rewrite, one-\nboxing-per-node, decode-once values, scheduler micro-wins) all stay.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BUV1chzzCLRQJ4mw8vEnMF",
          "is_bot": false,
          "headline": "revert(core): drop topology-at-parse (opt #11) — keep flow pure data",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-02T21:57:49Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "483b1299e41f89d4d1d04c40f582c6cac3b2201a",
          "body": "A model-driven perf review prototyped and measured six further wins beyond the\nround-7 floor; each reviewed for correctness and re-verified here (race tests +\nlint green, benchmarks reproduced).\n\n8.  Dotted-path fast walker. value.Get walks bare \"node.key\" paths member-by-\n    member with zero alloc\n[…]\nginal\nbaseline, WideDiamond n=256: time -87%, allocs -86%.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BUV1chzzCLRQJ4mw8vEnMF",
          "is_bot": false,
          "headline": "perf(core): six more engine optimizations (Fable-driven review)",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-02T21:47:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4ad3757a89233e258fc42c2aa9a1c2016d50a173",
          "body": "Profiling the full-coverage benchmarks to exhaustion surfaced three more wins,\nafter which the top allocations are all inherent per-node work (config decode,\nJSONPath eval, output boxing).\n\n5. Lean scheduler state. Per run the scheduler allocated nine maps. done+failed\n   merge into one state map; d\n[…]\n88%, allocs -82%.\nFull suite green (-race), lint 0 issues.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BUV1chzzCLRQJ4mw8vEnMF",
          "is_bot": false,
          "headline": "perf(core): three more engine optimizations to the inherent-work floor",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-02T19:22:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8ce0225ef609aef21c601a7d93e9306d6563d818",
          "body": "…ions\n\nExtend the benchmark harness to every node kind and a kitchen-sink graph:\nVarChain (pure engine, no HTTP), BranchFanout (routing + cascade-skip), Modules\n(sub-flow recursion), Poll, DelayChain, and Complex (request+branch+loop+module+\nassert combined).\n\nProfiling the new graphs surfaced two m\n[…]\n82% (139k->26k).\n\nFull suite green (-race), lint 0 issues.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BUV1chzzCLRQJ4mw8vEnMF",
          "is_bot": false,
          "headline": "perf(core): full node-coverage benchmarks + two more engine optimizat…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-02T18:04:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "443bb58bc51424e0e56a97d68f3ec49172e8874b",
          "body": "Add engine/bench_test.go: stress graphs (wide diamond, deep chain, loop, SSE)\ndriven by an instant in-memory HTTPDoer to isolate engine overhead, plus a\nrealistic httptest (\"wiremock\") end-to-end bench.\n\nProfiling surfaced two wins:\n\n1. Incremental input view. runNode rebuilt the entire output store\n[…]\ne), lint 0 issues. README documents the harness + results.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BUV1chzzCLRQJ4mw8vEnMF",
          "is_bot": false,
          "headline": "perf(core): benchmark harness + O(n^2)->O(n) engine optimizations",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-02T17:41:33Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1ad39b21758b308cbbf2ef77b8942a99fe9735f0",
          "body": "Covers the mental model, package layout, execution lifecycle, node catalog,\nassertions/outputs/templating, result + error-code taxonomy, how to extend\n(add a node/operator/output), runtime/middleware/observer, and the invariants.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BUV1chzzCLRQJ4mw8vEnMF",
          "is_bot": false,
          "headline": "docs(core): human-readable README for the flow runner",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-02T17:15:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d3902b72af3351c9361d3424d4c876e2c75ecba5",
          "body": "Adversarial per-finding verification (workflow) confirmed 5 of 8; F6 deferred\n(premature per repo guidance), F7/F8 rejected (match old runner / intentional).\n\n- F1 numeric truncation (regression): assert.toFloat routed through value.Int(),\n  which truncates floats (1.9->1), so gt/lt/gte/lte/between \n[…]\nnner code+node,\nindependent root runs after sibling fails.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BUV1chzzCLRQJ4mw8vEnMF",
          "is_bot": false,
          "headline": "fix(core): resolve verified review findings F1-F5",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-02T16:48:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e6525b5801e71324cd51252bf599ce856dfa3872",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BUV1chzzCLRQJ4mw8vEnMF",
          "is_bot": false,
          "headline": "docs(core): note flat-event boundary for sub-flow nodes",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-02T00:21:58Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "515c3345a27600182dbd5d86e5be41012bca8fba",
          "body": "…rtions\n\n- Add shared jsonOrString helper; request bodies and SSE event data now\n  decide the null/number/empty corner cases in one place (drop parseBody,\n  parseSseData).\n- Poll: map a hit deadline to a coded POLL_TIMEOUT error (pollErr helper),\n  and record the passing exit condition on NodeResult\n[…]\ns: assert poll/sse expose their self-evaluated assertions.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BUV1chzzCLRQJ4mw8vEnMF",
          "is_bot": false,
          "headline": "refactor(core): unify JSON-or-raw fallback and surface self-eval asse…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-01T23:49:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f73663b4e561fcb8376a9e56234eafa4e934a284",
          "body": "…ests\n\nFable findings:\n- failed nodes keep their produced outputs (NodeResult.Outputs set on failure) —\n  a UI can show the body that failed an assertion.\n- module passes its 'inputs' into the child flow (was hardcoded empty); flow's\n  declared 'inputs' now act as defaults overridden by the passed i\n[…]\nys-node-failure-doesn't-fail-flow\n  (locked contract), loop max_iterations, sse stop_on_assertion_failure=false,\n  flow.Parse/Validate table test.\n\n58 test funcs; go test -race clean; golangci-lint 0.",
          "is_bot": false,
          "headline": "feat(core): wire dead paths + observability/correctness fixes + gap t…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-01T23:31:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2278184e4b9204bb8a2a9a31b01c1266c6b4127a",
          "body": "…ype leak) + Register panics on dup\n\nFable extensibility finding: engine.walkModules and flow.Validate hand-unmarshaled\nModuleCfg/BranchCfg shapes in a second package (the two 'zero per-node-type logic'\nviolations). Now:\n- node.FlowReferencer{ReferencedFlows()} and node.Router{RouteTargets()} are\n  \n[…]\n-type knowledge).\n- A new composite/routing node gets validation free by implementing the interface.\n- node.Register panics on a duplicate kind (a wiring bug, caught at load).\n\ngreen; golangci-lint 0.",
          "is_bot": false,
          "headline": "refactor(core): capability interfaces for validation (kill per-node-t…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-01T23:23:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7443e8e4a08a7347d379a70fbed7106d94d34600",
          "body": "Fable review, helper/duplication findings:\n- assert: drop dead IsKnown+known map; drop AnyFailed (== !AllPassed).\n- node: drop unused UserErr; build coded errors on spi.UserError (so\n  spi.AsUserError sees them) instead of a parallel CodedError/ErrUser; use\n  spi.DynamicResolver instead of a duplica\n[…]\nool for validation; RunFlow drops its always-nil\n  error (returns *result.FlowResult).\n- sse: errors now carry the underlying cause (%v).\n- dynamicvars: add tests (were none).\n\ngreen; golangci-lint 0.",
          "is_bot": false,
          "headline": "refactor(core): helper-smell sweep + dedup onto spi",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-01T23:11:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "82e9a55319820708955f4a99bc86e924aa4da8aa",
          "body": "…licit Provided flag\n\nFindings from a Fable 5 review:\n- value.Get bracket-quotes bare paths -> hyphenated node ids ('create-user.id')\n  and header keys ('headers.content-type') are addressable (RFC-9535 dot\n  shorthand rejects them). Confirmed regression test added.\n- tmpl resolves refs via the node\n[…]\ncause Assert happened to be non-null.\n- decode/template errors -> coded INVALID_NODE_CONFIG (were RUNNER_ERROR).\n- documented the loop/poll body outer-template capture caveat.\n\ngreen; golangci-lint 0.",
          "is_bot": false,
          "headline": "fix(core): jsonpath hyphen bug + unify template/assertion paths + exp…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-01T22:45:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d1ce6b5ac7447a5943ba3eccf8edf0cd08bb9bdb",
          "body": "…, poll body-error, sse stop reasons\n\nAdds behavior tests for documented cases: diamond/parallel join (c reads two\npredecessors), loop continue_on_error (failing iteration captured, loop\ncontinues), poll POLL_BODY_FAILED (body errors vs merely unsatisfied), sse\ncompletion_event + max_events stop reasons. 45 test funcs; go test -race clean;\ngolangci-lint 0.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "test(core): behavior coverage — parallel join, loop continue-on-error…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-01T20:41:11Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5fdd3158bd074a1cfeb75d31c397c31a6a859269",
          "body": "Before executing, the engine walks the module reference graph (resolving\nbody_flow_id) to detect cycles and unresolvable flows with no side effects —\nFLOW_VALIDATION_FAILED, zero nodes run. Tests: A->B->A cycle caught upfront,\nunknown-flow reference. lint 0.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(core): upfront module-cycle + unknown-flow validation",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-01T20:37:32Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ee31fd4c33b72307ee1f8cd83142f565c5b8003e",
          "body": "- request node: per-node timeout_ms (bounds the HTTP call via ctx).\n- Timeout middleware test (50ms delay under a 1ms deadline -> node fails).\n- direct unit tests for the leaf packages: value (accessors/jsonpath/Map.Value/\n  marshal), tmpl (ref/{{{raw}}}/{{$dyn}}/unresolved-literal/nil-resolver),\n  \n[…]\n38 test funcs total; go test -race clean; golangci-lint 0.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(core): per-request timeout + unit tests across leaf packages",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-01T20:20:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b2e2a85f1c945d57e3d964c1b94a27e7639748b7",
          "body": "- Observer: engine.WithObserver attaches a func(Event) that receives\n  flow.started / node.started / node.completed|failed / flow.completed|failed for\n  the top-level flow (sub-flow runs are silent). Wired through run/step.\n- Middleware: engine.WithMiddleware wraps every node's run-and-assert unit\n \n[…]\nrtion; Retry re-runs a flaky node until it passes.\nlint 0.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(core): execution events (observer) + retry/timeout middleware",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-01T19:54:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e6806a00aec7e4ee1f6b3d0c333cd5ae1f02dd82",
          "body": "value.Get now backs on theory/jsonpath (the old runner's lib): bare paths\n('body.id') get a '$.' prefix for convenience; full jsonpath ('$.items[*].id',\n'$.users[?@.role==\"admin\"]') works — filters, wildcards, multi-match (returns a\nlist). refRoot (assert/branch ref validation) stops at '.' or '[' s\n[…]\nsyntax validates its true root. Filter test added. lint 0.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(core): RFC-9535 jsonpath for value.Get",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-01T15:17:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6fb8a543781b9a8fdb0d51a4ea81f41c8c644b25",
          "body": "flow.Validate checks structural invariants with no side effects: every edge\nreferences a declared node, and every branch case/default target is a real\nsuccessor edge. The engine runs it before scheduling; a violation yields\nFLOW_VALIDATION_FAILED in the result. Tests: branch-target-without-edge,\nedge-to-unknown-node. lint 0.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(core): upfront flow validation (edges + branch targets)",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-01T15:10:40Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "48e938c68ba3eb9e5beac6da3a480235e59a63ea",
          "body": "tmpl resolves {{$name:args}} via a runtime resolver (node.Runtime.Vars), threaded\nthrough the engine before decode; nil resolver leaves them verbatim. New\ndynamicvars.Generators (uuid/hex/email/timestamp/int) satisfies node.Resolver and\nis wired into DefaultRuntime. Proven with a fake deterministic resolver. lint 0.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(core): dynamic variables {{$gen:args}}",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-01T15:04:17Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4a82df377211ff23eddbcca2d1a1e3105c4a6831",
          "body": "request -> REQUEST_FAILED; poll -> POLL_FAILED/POLL_BODY_FAILED/\nPOLL_CONDITION_NOT_MET; loop -> LOOP_FAILED; sse -> SSE_FAILED. Node failures now\nsurface a stable code on their NodeResult (was generic USER_ERROR). green; lint 0.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(core): node-specific error codes",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-01T14:47:15Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "35e88d970a6004b643ce87533cd0f267042b1345",
          "body": "…ses, skip reasons\n\nRunFlow now returns *result.FlowResult (per-node status/outputs/error-code/\nassertion-results + a Success flag) instead of aborting on the first node error.\nThe engine records a failure and keeps scheduling:\n\n- failed node -> recorded with its code (ASSERTION_FAILED, MODULE_*, ..\n[…]\nip-reason, assertion-code capture. green; golangci-lint 0.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(core): result model — FlowResult, failure-continue, run_when pha…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-01T14:42:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6fbac24715873de8fd8579c854e45d0d97348a86",
          "body": "Per design review: assert and branch no longer carry a 'target'. They evaluate\nover the input context directly, addressing any already-executed node by\nfully-qualified path (flow inputs by name, 'nodeID.key' for node outputs) — so an\nassertion/condition can reference MULTIPLE prior nodes (cross-node\n[…]\ne guard, request status assertion.\ngreen; golangci-lint 0.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(core): drop target from assert/branch; enrich request response",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-01T01:30:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7ee2bee62eea150742d60c840dd49a726a7516f9",
          "body": "Clearer, less jargon-y name for the per-node output store (was 'bus'). The\nengine variable is storeOutputs; the tmpl type is Store.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "refactor(core): rename bus -> storeOutputs / tmpl.Store",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-07-01T00:50:06Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "549dcf6175b761d7f22c12c8632d3f415291f5c5",
          "body": "node.CodedError + UserErr/UserErrf/CodeOf/IsUser: user errors carry a stable\ncode (REQUEST_FAILED, ASSERTION_FAILED, ...) while still satisfying\nerrors.Is(err, ErrUser). Foundation for the per-node result model + error-code\nparity; nodes adopt coded errors as the engine result model lands.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(core): coded-error foundation for the result model",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-30T20:57:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b5880ff3047805f1b827b899c836a5ff6ee01b70",
          "body": "sse: connect to a text/event-stream, parse events (data/event/comment, multi-\nline data), run the node's assertions per event, and stop on completion event /\nmax_events / timeout / eof / assertion failure. Non-2xx connect fails as a user\nerror. Self-evaluating (Assert:None).\n\nAll 9 node kinds now po\n[…]\nssert, loop,\npoll, branch, sse. 18 tests; golangci-lint 0.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(core): sse node — all 9 node kinds ported",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-30T20:53:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d311081d9acc903fb5faa0b41f269a7cea92b044",
          "body": "- node.Result gains Routed: routing nodes name the successor(s) taken.\n- Scheduler becomes run-or-skip: a routing node marks the edges it routed away\n  from as dead; any node left with no live incoming edge is skipped, cascading\n  down its subtree. Root + normally-fed nodes unaffected (all existing \n[…]\nf 9 node kinds (only sse remains). green; golangci-lint 0.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(core): branch node + engine routing/skip-cascade",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-30T20:44:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "010883584dea1f8ad62d31a4438596b03479851c",
          "body": "- assert operators: complete the 14-operator matrix (not_contains, starts_with,\n  ends_with, regex, empty, not_empty, gte, lte, between) + IsKnown; table test.\n- loop node: foreach over a templated list, inline body per item with item/index\n  injected, aggregate results/count, max_iterations cap, co\n[…]\n (remaining: branch + engine routing, sse). green; lint 0.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(core): full operator matrix + loop (foreach) node",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-30T20:37:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7a095c0f86b2de94df0da7a61378aeedf58dc9bf",
          "body": "- Run signature gains 'in value.Value' — the node's input context (flow inputs +\n  upstream outputs, by path), the typed replacement for old ExecutionContext\n  Inputs/FlowInputs. Most nodes ignore it.\n- set_variable: boxes engine-resolved variable templates; assertions/outputs run\n  over the compute\n[…]\ns/fail.\n\n6 of 9 node kinds ported. green; golangci-lint 0.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(core): node input context + set_variable + assert nodes",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-30T20:30:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "dae9506a40246b94c09707e36d6e9cb3855a6299",
          "body": "- Outputs nest under node id (results accessed by path uniformly, incl a child\n  flow's outputs); value.Map.Value() boxes a map for path access.\n- SubflowRunner gains RunInline for embedded body flows.\n- poll node: re-runs an inline body until its assertions (exit conditions) pass\n  or the attempt/d\n[…]\nost-step. Proven by\n  retry-until-done + exhaustion tests.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(core): nested outputs + poll node (self-evaluating loop)",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-30T20:23:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "139b334652826381ca4b1ef192d9ccf4a34bc746",
          "body": "… bus\n\nEngine resolves templates per node (lazy decode-after-resolve) so a node reads\nupstream outputs; nodes still receive fully-typed, resolved config. New tmpl\npackage ({{ref}} interpolation + {{{ref}}} whole-value). Proven by an\nauth-then-call test: login token flows into the next request's auth header.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(core): inter-node templating — {{node.key}} resolved against the…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-30T20:05:50Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "26708f52b26af29f852642d15ffeed578f2da084",
          "body": "…ion-only engine\n\nNew pkg/core/* built alongside the existing engine (nothing in pkg/node|engine\ntouched). Proves the target shape end to end; reuses pkg/spi as the wire leaf.\n\n- value: the Value boundary type — the single place `any` lives, behind typed\n  accessors (Get/Str/Int/List/Raw).\n- node: t\n[…]\nFC-9535 jsonpath, run_when phases, the other 6 node kinds.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(core): greenfield runner scaffold — typed node seam + orchestrat…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-30T19:13:28Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1407cc828928d13be221103f22e3b3c3bce2236a",
          "body": "…ad code\n\nechopoint adapts to the new API on its next runner bump; until then it keeps\nbuilding against the pinned v0.28.0.\n\n- Drop the node/extractors/executionevents back-compat alias layer that\n  re-exported spi types under second names. spi is now the single source of\n  truth, referenced directl\n[…]\nained).\n\nbuild / vet / test green; golangci-lint 0 issues.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "refactor(runner): collapse spi alias facade + remove duplication & de…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-29T19:46:57Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a088bc6ff75a04b4650df99c0139370339e6ff83",
          "body": "Remove symbols with zero callers across the runner, ../echopoint, and\n../echopoint-cli (no reflection / string-dispatch). Verified with grep\nbefore each removal.\n\nRemoved:\n- pkg/engine/observer.go: MultiObserver type + 4 methods (kept NoopObserver,\n  synchronizedObserver)\n- pkg/extractors: BodyReade\n[…]\nen (248 tests); golangci-lint clean on\ntouched packages.\n\n\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(runner): remove verified-dead code (Phase A) (#33)",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-29T18:40:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d3696dc422cae3dccd922ade0f3bd1afac8512b9",
          "body": "…rge lint)",
          "is_bot": false,
          "headline": "chore(merge): split node init + share count output-key const (post-me…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-29T18:25:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c06b0a4137428d8cf25e360b3e6dfb886b196b27",
          "body": "…tors",
          "is_bot": false,
          "headline": "merge: #32 operators dead-code cleanup + typed/decode-validated opera…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-29T18:22:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cc11160d975c8517978f724394265812f9aea2a7",
          "body": "# Conflicts:\n#\tpkg/node/registry.go\n#\tpkg/node/types.go\n#\tpkg/spi/kind.go",
          "is_bot": false,
          "headline": "merge: #30 sse-consumer node",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-29T18:21:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bd14b9a995a9418e5bc47a7a9f5d90da0a603f82",
          "body": "# Conflicts:\n#\tpkg/node/registry.go\n#\tpkg/node/types.go\n#\tpkg/spi/kind.go",
          "is_bot": false,
          "headline": "merge: #29 branch (if/switch) node + conditional engine routing",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-29T18:19:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6ff82fceb79c608a10037646c62036394fdb2e05",
          "body": "# Conflicts:\n#\tpkg/node/registry.go\n#\tpkg/node/types.go\n#\tpkg/spi/kind.go",
          "is_bot": false,
          "headline": "merge: #28 assert / validate node",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-29T18:16:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cb4404171ae89f142d20805bddb75d993459e64d",
          "body": "# Conflicts:\n#\tpkg/node/registry.go\n#\tpkg/node/types.go\n#\tpkg/spi/kind.go",
          "is_bot": false,
          "headline": "merge: #27 poll-until node",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-29T18:14:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "992e409fb301b1fbed1da727e11e486ab88589cd",
          "body": "# Conflicts:\n#\tpkg/node/registry.go\n#\tpkg/node/types.go\n#\tpkg/spi/kind.go",
          "is_bot": false,
          "headline": "merge: #26 loop (foreach) node",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-29T18:12:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c87b0284005db01ca6a3af8d8801a8c4199a5318",
          "body": null,
          "is_bot": false,
          "headline": "merge: #25 set-variable node",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-29T18:09:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "45753d0dcb12bf8cde22dd5b8d08b94451568277",
          "body": null,
          "is_bot": false,
          "headline": "merge: #31 common assertion + output system (stack base)",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-29T18:09:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "08909518ed285089cf92ee3397b6c125314c2b07",
          "body": "…tors\n\nThe operators package carried two parallel implementations: a dead, more-typed\nOO layer (Operator interface, ValueType enum, 13 typed operator structs +\nfactories) that had ZERO non-test callers, shadowing the live stringly-typed\nComparator registry (Compare). The two even disagreed on equals\n[…]\nrder).\n- Pin the equals==string-equality contract + IsKnown set with table tests.\n\nNo wire change: AssertionResult.Operator stays a string on the wire; operator\ntype strings (\"equals\", ...) unchanged.",
          "is_bot": false,
          "headline": "refactor(operators): drop dead OO layer; type + decode-validate opera…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-29T17:06:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6e8ab039e137f9b11e0eed5717609251fb5e36ee",
          "body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_011aHVMLgy41oRoVj65nXqnZ",
          "is_bot": false,
          "headline": "chore(go): bump Go toolchain to 1.26.2",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-28T14:24:08Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c99fcea023908df0eb7099cbf66e7d775e92c374",
          "body": "Add a `loop` node kind that iterates a body sub-flow once per item in a\nresolved array (foreach). Each iteration injects the current item and\nzero-based index into the child flow inputs (default keys `item`/`index`,\noverridable via `item_var`/`index_var`) and the per-iteration final outputs\nare aggr\n[…]\ne node. The execution context is honored for cancellation.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(node): loop (foreach) node",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-28T11:49:57Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e7323a904c7219e53c259a5d060cc0bbeb85693c",
          "body": "SetVariableExecutionResult now implements AssertionContextProvider:\nAssertionContext() returns extractors.NewValueResponseContext over the\ncomputed variables map (the node Outputs). This lets the uniform\nengine-level assertion/output pass evaluate user assertions over a\nset-variable node's resolved \n[…]\nled with ASSERTION_FAILED, flow fails) through the engine.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "refactor(node): set-variable assertions via shared engine seam",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-28T11:49:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cfa537091d27dd8d575f5835fee70712f0d2d53e",
          "body": "Rebased onto feat/common-assertion-output and simplified the assert node to\nconsume the single shared assertion/output evaluation seam instead of its own\nprivate duplication:\n\n- Execute now only resolves the target value and returns an\n  AssertExecutionResult exposing it via AssertionContext()\n  (ex\n[…]\nAILED); updated the engine integration test\n  accordingly.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "refactor(node): thin assert node onto shared engine-level assertion seam",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-28T11:48:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6be81f7b51e9c53791b707336c73cb88bff0d7fb",
          "body": "Add a new \"sse\" node kind that connects to a text/event-stream endpoint,\nconsumes Server-Sent Events over time, and runs the node's assertions\nagainst each event's parsed data with a cross-event accumulator.\n\nUnlike the buffered single-shot request node, this node streams: events\nare processed as th\n[…]\nshared one-line edits to kind.go / types.go /\nregistry.go.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(node): sse-consumer node",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-28T11:44:57Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e8ecc6d1786390d05758d4d99e306c1e47b39e55",
          "body": "Add a \"poll\" node kind (TypePoll) that re-runs an inline body sub-flow on\nan interval until its exit-condition assertions all pass on a single\nattempt, or it exhausts its max-attempts / timeout budget. This is the\ncanonical async-API testing pattern: kick off a job, then poll until\nstatus == done be\n[…]\n carrying the last AssertionResults + a stable error code.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(node): poll-until node",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-28T11:44:37Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "bdba460851892a8d61ac5c033c680afd454ffd49",
          "body": "Delete the branch node's private valueResponseContext adapter and use the\nshared extractors.NewValueResponseContext for evaluating case conditions\nagainst the resolved branch target value. The shared adapter provides the\nsame body/parsed_body capabilities the branch conditions rely on.\n\nBranch routi\n[…]\nass does not\napply to routing nodes (no double-assertion).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "refactor(node): branch node consumes shared value-context seam",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-28T11:44:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9a150df290d4ffe3c738bb38221b942b229886d9",
          "body": "The omitted-target default (\"assert over inputs\") was non-functional through\nthe real FlowEngine. The engine populates ctx.Inputs only from refs declared\nin InputSchema, which AssertNode derives solely from Data.Target templates; an\nomitted target yields [] refs, so the engine assembles an empty ctx\n[…]\nthe old unit\ntest to reflect FlowInputs-default semantics.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "fix(node): assert node default asserts over FlowInputs, not empty Inputs",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-28T11:43:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "59b32c2d9620a78412a59fb990c29448f92abae9",
          "body": "Adds a first-class \"assert\" node that runs the standard BaseNode.Assertions\nlist (plus output extractors) against an in-memory value rather than an HTTP\nresponse. This closes the key gap for an API-flow testing product: validating\ndata produced by earlier nodes (transforms, modules, branches), not j\n[…]\n: no engine change. Registered via the node-kind registry.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(node): assert node — validate upstream/derived data",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-28T11:43:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5d875dfefe32842ca3092b4cb01aeec09dd75384",
          "body": "Add a pure \"set_variable\" node kind that computes named outputs from\nupstream node outputs and flow inputs via template resolution, without\nperforming any HTTP call. It is used to assemble request payloads, derive\nheaders, and reshape values between nodes in an API flow.\n\nData is a `variables` map o\n[…]\nresult with SET_VARIABLE_FAILED and returns (result, err).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(node): set-variable transform node",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-28T11:43:06Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "79db6495f7cbf598fea20c2c88b2dc94fac70a4a",
          "body": "BUG 1 (pkg/engine/execution.go): a diamond join reachable from a taken arm\nbut whose InputSchema templated an output from the routed-away (skipped) arm\nwas run into validateInputs, which hard-failed the whole flow with\nNODE_INPUT_VALIDATION_FAILED. Now, before running a ready on_success node, if\nany\n[…]\nal branch->target edge, failing flow validation otherwise.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "fix(node): graceful skip on cross-arm diamond + validate branch targets",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-28T11:42:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "12fc17ac2c885e722010586915f13fa792a2160c",
          "body": "Adds a \"branch\" node kind for value-based routing: it evaluates ordered\nconditions over upstream data and selects exactly ONE downstream successor\nto run, skipping the others. This complements RunWhen (which only gates on\nsuccess/failure) with true if/switch routing for API-flow testing.\n\nNode:\n- Da\n[…]\nree-subtree\ncascade; all existing engine tests still pass.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "feat(node): branch (if/switch) node + conditional engine routing",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-28T11:42:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "dc81fa48831402abad04bc6b72556e8490745996",
          "body": "Introduce a single assertion + output-extraction system the engine drives\nuniformly for every node, replacing per-node re-implementations.\n\n- pkg/extractors/value_context.go: NewValueResponseContext — an in-memory\n  ResponseContext over an arbitrary value (parsed=value, raw=json.Marshal),\n  the sing\n[…]\no drop their per-node\nassertion/value-context duplication.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018BnQs98DQaLeJT5Fs3NkCE",
          "is_bot": false,
          "headline": "refactor(node): common engine-level assertion + output evaluation",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-28T11:34:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6be6c34e622a184d3b7fc65cb268f1e48139535f",
          "body": "…#23)",
          "is_bot": false,
          "headline": "fix(engine): classify module-graph validation failures as UserError (…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-20T15:05:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9600e9e5d8c8de883dcb7afffc5302328d90a0ea",
          "body": "Enable golangci-lint's modernize suite (new(expr), any, slices/maps/min-max,\n...). No code changes — repo already has 0 modernize findings; this enforces\nmodern Go going forward.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: enable modernize linter (#21)",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-20T03:00:28Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5df20be6d1fd681fcb3cb2f5e3581b4cb879c5b9",
          "body": "A module node that fails because of the referenced flow's definition\n(missing flow_id, a module cycle, or a flow that fails to parse/validate)\nreturned a plain error. The node executor treats any non-UserError as a\ngenuine runner fault and logs it at error level, so an invalid flow\ndefinition — e.g.\n[…]\nxt are preserved.\n\n\nClaude-Session: https://claude.ai/code/session_01VPShbqtFtSXE91bNZagnb3\n\nCo-authored-by: Alexis Gardin <me@alexisgardin.com>\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(engine): classify module flow definition failures as UserError (#22)",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-20T03:00:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4a4eb521f18da64b424b646986a4942647643ca6",
          "body": "…s for real faults (#20)\n\nSeparate failures caused by the flow author or their target system from genuine\nrunner faults, so customer-side errors stop tripping error-level logs and are\nsurfaced cleanly in the result instead of as raw Go errors.\n\n- pkg/spi: add UserError (Code, Message, Cause) — an ex\n[…]\n NOT reclassified yet: assertion/output-validation failures\nin other node types — they remain at error until they adopt UserError.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(errors): classify user-caused execution failures, keep error log…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-18T17:11:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ce37d12cd12046270399f13bf5a70c0fb7d055b6",
          "body": "…e) (#19)\n\nv0.23.0 shipped pkg/spi as a facade that aliased *out* to node/extractors/\nexecutionevents. This inverts it: the contract types are now DEFINED in pkg/spi\n(which imports only stdlib — a true L0 leaf), and the source packages re-export\nthem as back-compat aliases. spi is now the single sou\n[…]\ner of docs/runner-api-redesign.md (the capability\nSPIs for operators/extractors and the registry-driven parse remain future work).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(runner): make pkg/spi the L0 contract leaf (invert the facad…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-09T00:06:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8cbd651bbeb2b60c48e51018f1c8786d3e82b2b7",
          "body": "Introduces pkg/spi as the single, stable contract surface downstream control\nplanes bind to (echopoint's openapi.yaml x-go-type, SSE decoders). It re-exports\nthe wire-facing types via Go *type aliases*, so spi.Kind is byte-for-byte the\nsame type as node.Type — wire-stable and behavior-identical:\n\n  \n[…]\nerts the\ndependency so spi becomes the L0 leaf (this facade flips at that point).\nAdditive only — no existing runner code changes.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(runner): add pkg/spi public contract package (#18)",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-08T22:26:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "67b90a647a936c562d4ec40e38c1bf157770a75b",
          "body": "…n (#17)\n\nReplace the two node-type switches with a registry, so adding a node kind is\none RegisterNodeKind call (decoder + skipped-result factory) plus the node's\nExecute — no edits to UnmarshalNode or the engine's skip construction.\nBehavior-identical; no public type renames (generated-client safe\n[…]\nults via node.NewSkippedResult (type\n  switch removed).\n- Tests: built-in decode + RunWhen default, NewSkippedResult, custom kind.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(runner): node-kind registry — add a node type by registratio…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-08T17:47:41Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "776e4df3916e479a5a4381ee717e11fac371a08a",
          "body": "…hase B) (#16)\n\nMake assertion operators and extractors extensible by registration instead of\nediting core switches — the redesign's Phase B, behavior-identical and with no\npublic type renames (generated-client safe).\n\nOperators:\n- pkg/operators gains a Comparator registry (Register/Compare) plus th\n[…]\nxtractor is a pure registry lookup with the per-type switch removed.\n\nTests for both registries. Full suite + golangci-lint green.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(runner): capability registries for operators + extractors (P…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-08T17:43:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3f55f76f79046486bcc4bff617f0ac4e731b9b00",
          "body": "… A (#15)\n\nAdds a composable middleware layer around node execution (the redesign's home\nfor cross-cutting concerns), the last Phase-A item from the API redesign doc.\n\n- engine: Middleware = func(NodeExecutor) NodeExecutor, applied per node in\n  runNode (outermost first); Options/ExecuteOptions.Midd\n[…]\nimeout layers a deadline on the\n  caller's ctx). + tests.\n\nAdditive only; no transport opts in yet, so no behavior change in prod.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(runner): executor middleware (retry / timeout) — completes Phase…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-08T17:24:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "172a0cd90517593ea1ef14e38995c046a72659f1",
          "body": "…er (#14)\n\nTwo of the redesign's Phase-A items (docs/runner-api-redesign.md), both\nadditive — no transport behavior change unless a caller opts in.\n\ncontext.Context (real value: cancellation/deadlines reach nodes):\n- ExecutionContext gains a Ctx field (+ Context() accessor defaulting to\n  context.Ba\n[…]\ncancellation aborts a long delay; Builder produces a runnable\nflow; merge/module-resolver units. Full suite + golangci-lint green.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(runner): thread context.Context through execution + fluent Build…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-08T12:50:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0b8182a1354356bf908f217ac59e97a76082aa9e",
          "body": "…#13)\n\nThe engine was already shared, but the orchestration around it (input merge,\nreferenced-flow module resolver, engine wiring) was copy-pasted in every\ntransport. Add pkg/runner.Run as the one source of truth and route the\nin-repo transports through it.\n\n- pkg/runner: Run(flowDef, inputs, opts.\n[…]\n),\nremoving its own copy so the runner stays the source of truth for node/flow\nexecution and echopoint stays a pure control plane.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(runner): add pkg/runner.Run as the single execution entrypoint (…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-08T11:15:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b6f59dfe869dab4bb748008b93069aeb7e3fc7a6",
          "body": "* refactor(runner): remove dead pkg/compatibility and pkg/assertions\n\nBoth were imported only by their own tests (verified). Compatibility is\nderived from extractor self-declaration; the assertion structs were unused\nscaffolding superseded by pkg/operators + node assertion eval.\n\nCo-Authored-By: Cla\n[…]\nalues so a rename can't silently break consumers.\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": "refactor(runner): remove dead code + golden-lock skip reasons (#12)",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-08T03:56:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b86e27d5adb5be58ac5ed3cda5fb2e0a4e3f01db",
          "body": "* feat(engine): skip downstream nodes with a named reason on failure\n\nWhen an on_success node fails, downstream dependents could never run but were\ndropped silently (no result, no event) — the control plane saw nothing.\n\n- Record a SKIPPED result for every blocked downstream on_success node, and emi\n[…]\nname shadowed ok var to satisfy govet shadow lint\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(engine): skip downstream nodes with a named reason on failure (#11)",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-08T03:49:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "050f4b26fca3577a48e346db5f5fc84d7f7b485b",
          "body": "refactor: typed shapes, generics, and operator unification",
          "is_bot": false,
          "headline": "Merge pull request #10 from nanostack-dev/refactor/runner-code-quality",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-05T01:12:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "84243945b65be3cb68fb10d32a4737870f59de5f",
          "body": "feat(node): record per-assertion results in request execution",
          "is_bot": false,
          "headline": "Merge pull request #8 from nanostack-dev/feat/record-assertion-results",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-05T01:09:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b4091a4c3095c42f87b191cd6fec13c26e1215de",
          "body": "Mechanical sweep (287 occurrences). No behaviour change — full test suite and\ngolangci-lint pass.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "style: replace interface{} with the any alias repo-wide",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-05T01:04:23Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "caf37165b409d1927d5a5329b20c5a1489134db9",
          "body": "Execute brushed the funlen ceiling and the 10-arg response-backed error build was\nrepeated three times. Extract the response tail (assert -> extract -> validate ->\nbuild) into processResponse, collapsing the repeated error build into a captured\nclosure. Adds direct tests for the success and assertion-failure paths (pkg/node\ncoverage 27% -> 36%).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(node): extract processResponse from Execute + cover it",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-05T01:03:28Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f2eb954604e321330e94809467d7179466f1254b",
          "body": "applyOperator was a stringly-typed switch covering 8 of the 14 operators the\ncompatibility matrix declares (pkg/compatibility) — an author could create a\nstartsWith/regex/gte assertion the runtime then rejected as 'unknown operator'.\nReplace the switch with a dispatch table keyed by the shared\nopera\n[…]\nient to match the wire format (string expected vs typed\nactual). Adds tests for every newly-supported operator + unknown-operator.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(node): type assertion operators + close the evaluator gap",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-05T01:01:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7fed6d07cbb909aa624859377864156cf7f20fc4",
          "body": "…tructs\n\nProgress-event payloads were assembled as map[string]interface{} literals with\nstringly-typed keys (a typo'd key compiled fine). Model them as typed structs\nwhose json tags are the wire contract; RunnerProgressEvent.Payload and enqueue\nnow take 'any'. Emitted JSON is unchanged — added wire-\n[…]\nhe omitempty behaviour for assertion_results, and the\nsuccess/failure variants. First tests for internal/runtime (was 0% covered).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(runtime): replace hand-built event payload maps with typed s…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-05T00:58:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fec0d43a27a99f95ce68d051b2d77d06d0c20eff",
          "body": "…As[T]\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(node): replace 6 result-cast helpers with generic As[T]/Must…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-05T00:55:07Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "da63aab095e0934274441bd66a82329c23e76e39",
          "body": "…ng method\n\nEvaluate had zero production callers and EvaluateDetailed returned a\n(actual, passed, err) tuple that runAssertions re-assembled into an\nAssertionResult with a `passed && err==nil` dance. Replace both with a single\nEvaluate(ctx) AssertionResult: the assertion builds its own outcome record and\nrunAssertions just assigns the index and decides node failure. One method, no\ntuple, single source of truth.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(node): collapse assertion evaluation into one result-returni…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-05T00:42:41Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "570f47bb5c32cdeddd2e6971eaa0d4ce6cae34e2",
          "body": "Previously runAssertions returned only the first failure as an error and\nrecorded nothing on success, so per-assertion outcomes were invisible in the\nrun output. Capture every assertion outcome (index, extractor, operator,\nexpected, actual, passed, error) on RequestExecutionResult.AssertionResults\na\n[…]\nent_reporter includes assertion_results on the progress event\n- tests: pass/fail/extractor-error recording + payload serialization\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(node): record per-assertion results in request execution",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-05T00:29:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8586e7448c1a3a1419f62141077e5ae6d47322c9",
          "body": "* feat(dynamicvars): {{$name}} fake-data template variables\n\nAdd a {{$...}} namespace for generated fake data in flow templates (URL,\nheaders, body), so flows can produce unique/realistic test data instead of\nhardcoded values that collide across re-runs.\n\n- pkg/dynamicvars: a generator registry owni\n[…]\n.test /\nE.164 wrappers on email/phone. Use gofakeit directly for every generator for\nnow. Regenerate the reference doc.\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(dynamicvars): {{$name}} fake-data template variables (#7)",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-04T22:27:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "df47b2fc7a0722c4f4726595a3e13325c3d18320",
          "body": "…se errors (#5)\n\n* fix(runner): default request timeout, send string bodies raw, log parse errors\n\nThree fixes surfaced running real flows on the ephemeral runner:\n\n- Request node timeout of 0 (the common unset case) produced an instant 0ms\n  context deadline (\"context deadline exceeded\" before the \n[…]\nputTypeAny and fieldTimestamp constants (goconst)\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(runner): default request timeout, send string bodies raw, log par…",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-03T21:27:03Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c9d1be21b20a717b17315007eddd63e378fba7a9",
          "body": "The GitHub Action downloads runner binaries from GitHub release assets\n(echopoint-runner_<ver>_<os>_<arch>.{tar.gz,zip}), but releases shipped no\nbinaries — only a Docker image was built. Add a goreleaser config matching\nthe action's archive naming (linux/darwin/windows x amd64/arm64, no\nwindows/arm\n[…]\nuting the\nalready-published v0.1.0 and failing every release. Use the highest semver\ntag instead and guard against tag collisions.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: add goreleaser config and fix release versioning",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-02T19:41:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "670c1c3128a580571fa40f60f16b3e68051855cd",
          "body": "Adds a one-shot `ephemeral` subcommand that executes a single execution\npackage from stdin/file and writes the result, without claiming jobs,\nsending heartbeats, posting progress, or requiring an API key. Used by\n`echopoint flows run` and the GitHub Action to run flows on a CI worker.\n\nMigrates the \n[…]\nnner behaviour; `ephemeral` is the new\nmode. Stable exit codes: 1 for failed flow / serve error, 3 for\nAPI/runner/contract errors.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add ephemeral package execution mode",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-06-02T19:34:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c109bdfe7480c69ce32a36e8943e20d801062f0b",
          "body": "Snapshot main as a single initial v1 commit authored by devnanostack.",
          "is_bot": false,
          "headline": "chore: initial v1 snapshot",
          "author_name": "devnanostack",
          "author_login": "devnanostack",
          "committed_at": "2026-05-11T17:33:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 40,
      "commits_last_year": 90,
      "latest_release_at": "2026-07-20T03:14:54Z",
      "latest_release_tag": "v0.35.0",
      "releases_from_tags": false,
      "days_since_last_push": 5,
      "active_weeks_last_year": 8,
      "days_since_latest_release": 5,
      "mean_days_between_releases": 3.3
    },
    "community": {
      "has_readme": false,
      "has_license": false,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 12,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "github.com/nanostack-dev/echopoint-runner",
          "exists": true,
          "license": null,
          "keywords": [],
          "ecosystem": "go",
          "matches_repo": true,
          "registry_url": "https://pkg.go.dev/github.com/nanostack-dev/echopoint-runner",
          "is_deprecated": false,
          "latest_version": "v0.35.0",
          "repository_url": "https://github.com/nanostack-dev/echopoint-runner",
          "versions_count": 41,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": null,
          "latest_published_at": "2026-07-20T03:14:15Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 5
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 0,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0,
        "collected_at": null
      },
      "open_issues_and_prs": 2
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [
        "go.mod"
      ],
      "largest_source_bytes": 53521,
      "source_files_sampled": 139,
      "oversized_source_files": 0,
      "agent_instruction_files": [
        "AGENTS.md",
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 789
    },
    "dependencies": {
      "manifests": [
        "go.mod"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "go"
      ],
      "dependencies": [
        {
          "name": "github.com/brianvoe/gofakeit/v7",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v7.15.0"
        },
        {
          "name": "github.com/docker/docker",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v28.3.3+incompatible"
        },
        {
          "name": "github.com/google/uuid",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.6.0"
        },
        {
          "name": "github.com/rs/zerolog",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.34.0"
        },
        {
          "name": "github.com/spf13/cobra",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.8.1"
        },
        {
          "name": "github.com/stretchr/testify",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.11.1"
        },
        {
          "name": "github.com/testcontainers/testcontainers-go",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.39.0"
        },
        {
          "name": "github.com/theory/jsonpath",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.10.1"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 2,
        "merged_prs": 26,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 11
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "devnanostack",
          "commits": 90,
          "avatar_url": "https://avatars.githubusercontent.com/u/283686842?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "go.yml",
        "release.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [
        ".golangci.yml"
      ],
      "has_editorconfig": false,
      "has_linter_config": true,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "go.sum"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 7,
            "reason": "3 out of 4 merged PRs checked by a CI test -- score normalized to 7",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/4 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": 0,
            "reason": "license file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 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": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": 0,
            "reason": "Project has not signed or included provenance with any releases.",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 0,
            "reason": "26 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "574955ece8c7f5d45271b3f3e3a16e112f7ee4d7",
        "ran_at": "2026-07-25T17:04:19Z",
        "aggregate_score": 3.1,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-20T03:16:51Z",
      "oldest_open_prs": [
        {
          "number": 36,
          "created_at": "2026-07-04T17:51:13Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 37,
          "created_at": "2026-07-11T13:15:14Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-20T03:14:16Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/nanostack-dev/echopoint-runner",
    "host": "github.com",
    "name": "echopoint-runner",
    "owner": "nanostack-dev"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "at_risk",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 46,
      "inputs": {
        "security": 31,
        "vitality": 77,
        "community": 1,
        "governance": 46,
        "engineering": 65
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 77,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 69,
            "inputs": {
              "commits_last_year": 90,
              "human_commit_share": 1,
              "days_since_last_push": 5,
              "active_weeks_last_year": 8
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 5 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 5
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "8/52 weeks with commits",
                "points": 5.5,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 8
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "90 commits in the last year",
                "points": 17.6,
                "status": "partial",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 90
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "releases_count": 40,
              "latest_release_tag": "v0.35.0",
              "releases_from_tags": false,
              "days_since_latest_release": 5,
              "mean_days_between_releases": 3.3
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "40 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 40
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 5 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 5
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~3.3 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 3.3
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "maintained",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": null,
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": 5,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 5 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 5
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "critical",
        "name": "Community & Adoption",
        "value": 1,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "critical",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "has_readme": false,
              "has_license": false,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "no license file detected",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "license_absent",
                    "params": {}
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 46,
        "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": "moderate",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 51,
            "inputs": {
              "merged_prs": 26,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 11
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "26/37 decided PRs merged",
                "points": 26.9,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 26,
                      "decided": 37
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/4 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 42,
            "inputs": {
              "followers": 0,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "nanostack-dev",
              "public_repos": 10,
              "account_age_days": 867
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "0 followers of nanostack-dev",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 0,
                      "login": "nanostack-dev"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "10 public repos, account ~2 yr old",
                "points": 12.3,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 10
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 2
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "github.com/nanostack-dev/echopoint-runner"
              ],
              "ecosystems": "go",
              "any_deprecated": false,
              "min_days_since_publish": 5
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on go",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "go"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 5 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 5
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "41 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 41
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 65,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "good",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 78,
            "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": "2 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": ".golangci.yml",
                "points": 16,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".golangci.yml"
                    }
                  }
                ],
                "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": "3 out of 4 merged PRs checked by a CI test -- score normalized to 7",
                "points": 14,
                "status": "partial",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "at_risk",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 45,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": null,
              "has_readme": false,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "at_risk",
        "name": "Security",
        "value": 31,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": null,
            "notes": [],
            "value": 31,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 18,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 0,
              "scorecard_aggregate": 3.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": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "3 out of 4 merged PRs checked by a CI test -- score normalized to 7",
                "points": 1.8,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/4 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 not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow 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 not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "26 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "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": "good",
        "name": "AI Readiness",
        "value": 78,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 1,
              "agent_instruction_files": [
                "AGENTS.md",
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 789
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "AGENTS.md, CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "AGENTS.md, CLAUDE.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "90 of 90 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 90,
                      "sampled": 90
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "good",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 78,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "go.sum"
              ],
              "has_dockerfile": true,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [],
              "agent_commit_share": 0.778,
              "toolchain_manifests": [
                "go.mod"
              ],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "go.mod (toolchain convention, no task runner)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "toolchain_convention",
                    "params": {
                      "files": "go.mod"
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": ".golangci.yml",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".golangci.yml"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "Go (statically typed)",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Go"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "Dockerfile, lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Dockerfile, lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "70 of the last 90 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 70,
                      "sampled": 90
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 1",
                "points": 1,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "primary_language": "Go",
              "largest_source_bytes": 53521,
              "source_files_sampled": 139,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Go (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Go"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/139 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 139,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "at_risk",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "example_dirs": [
                "examples"
              ],
              "has_mcp_signal": false,
              "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": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": "examples",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "examples"
                    }
                  }
                ],
                "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": [
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-25T17:04:34.451300Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/n/nanostack-dev/echopoint-runner.svg",
  "full_name": "nanostack-dev/echopoint-runner",
  "license_state": "absent",
  "license_spdx": null
}

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.27.0 — vollständige Methodik · Metriken-Wiki.

Wie ein einzelnes Ergebnis im Gesamtregister steht: aggregierte StatistikenGo.