Öffentliches Register
Software-GesundheitsberichtSchema 0.23.0 · Metriken 1.13.0 · 2026-07-21 16:52 UTC

nemanjan00 / qrp

A data-first, declarative, low-overhead framework for dashboards. Zero RUNTIME dependencies, zero build step — the devDependencies below are only for tests, lint, and git hooks.

JavaScript · HTMLMIT★ 0 Sterne⑂ 0 Forksseit Juli 2026Auf GitHub ansehen ↗

nemanjan00/qrp erreicht einen Gesundheitsindex von 55 von 100 und liegt damit im Bereich Mittel. Am stärksten schneidet es bei Engineering Quality (93/100) ab, am schwächsten bei Security (32/100). Zuletzt vor 4 Tagen aktualisiert. Ein einzelner Mitwirkender trägt den Großteil der jüngsten Arbeit.

55
gesamt / 100
Mittel

Software-Gesundheitsindex

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

55
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

Nemanja NedeljkovićPersönliches Konto
117 Follower233 öffentliche Reposseit Okt. 2010FlockSocial

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

Paket-Ökosysteme

RegistryPaketVersionDownloads / MonatVersionenZuletzt veröffentlichtTags
npm@nemanjan00/qrp0.7.02.68318vor 4 Tagendashboardreactiveproxydeclarativeframeworkfrontendno-buildzero-dependencydomformstable

Metriken nach Kategorie

Vitalität

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

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

Community & Verbreitung

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

32Gefährdet · 18 % des Gesamtindex
Wie die Bewertung erfolgt
0/60Stars — 0 Stars
0/25Forks — 0 Forks
0/15Watcher — 0 Watcher
Verwendete Eingangsdaten
forks0
stars0
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Wie die Bewertung erfolgt
22.5/22.5README
22.5/22.5Lizenz — anerkannte Lizenz (MIT)
0/18CONTRIBUTING-Leitfaden
0/13.5Verhaltenskodex
0/7.2Issue-Vorlage
0/6.3PR-Vorlage
Verwendete Eingangsdaten
has_readmeja
has_licenseja
has_contributingnein
has_issue_templatenein
has_code_of_conductnein
has_pull_request_templatenein
Wie die Bewertung erfolgt
45.7/80Downloads pro Monat — 2.683 Downloads/Monat über npm
0/20Abhängige in der Registry — von diesem Ökosystem nicht ausgewiesen
Verwendete Eingangsdaten
packages@nemanjan00/qrp
dependents
ecosystemsnpm
total_downloads
monthly_downloads2.683
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Abhängige in der Registry. Die verbleibenden Gewichte wurden renormalisiert.

Nachhaltigkeit & Governance

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

42Gefä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
10/10OpenSSF Scorecard: Contributors — project has 6 contributing companies or organizations
Verwendete Eingangsdaten
bus_factor1
contributors_sampled1
top_contributor_share1
Wie die Bewertung erfolgt
0/46.8Issue-Lösungsquote — keine Issues oder keine Daten
0/38.3PR-Annahme — keine entschiedenen Pull Requests oder keine Daten
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Verwendete Eingangsdaten
merged_prs0
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Issue-Lösungsquote, PR-Annahme. Die verbleibenden Gewichte wurden renormalisiert.
Wie die Bewertung erfolgt
10/30Organisatorische Trägerschaft — persönliches (Nutzer-)Konto
0/20Verifizierte Domain — für Nutzerkonten nicht anwendbar
14.9/25Reichweite des Inhabers — 117 Follower von nemanjan00
25/25Kontohistorie — 233 öffentliche Repos, Kontoalter ca. 15 Jahre
Verwendete Eingangsdaten
followers117
owner_typeUser
is_verified
owner_loginnemanjan00
public_repos233
account_age_days5.752
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Verifizierte Domain. Die verbleibenden Gewichte wurden renormalisiert.

Paketpflege

100Exzellent
Wie die Bewertung erfolgt
25/25Veröffentlicht & auflösbar — 1 Paket(e) auf npm
35/35Veröffentlichungsaktualität — letzte Veröffentlichung vor 4 Tagen
20/20Versionshistorie — 18 veröffentlichte Versionen
20/20Nicht veraltet — aktiv, nicht veraltet oder zurückgezogen
Verwendete Eingangsdaten
packages@nemanjan00/qrp
ecosystemsnpm
any_deprecatednein
min_days_since_publish4

Engineering-Qualität

Sind grundlegende Engineering- und Dokumentationspraktiken vorhanden?

93Exzellent · 20 % des Gesamtindex
Wie die Bewertung erfolgt
24/24CI-Workflows — 1 Workflow(s)
24/24Tests vorhanden
16/16Linter-Konfiguration — .eslintrc.json
0/9.6Pre-Commit-Hooks
6.4/6.4.editorconfig
0/20OpenSSF Scorecard: CI-Tests — keine Daten
Verwendete Eingangsdaten
has_cija
has_testsja
has_editorconfigja
has_linter_configja
has_precommit_confignein
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): OpenSSF Scorecard: CI-Tests. Die verbleibenden Gewichte wurden renormalisiert.

Dokumentation

100Exzellent
Wie die Bewertung erfolgt
30/30README
25/25Dokumentationsverzeichnis
15/15Dokumentations-/Homepage-Site — https://qrp.nemanja.top/
10/10Repository-Beschreibung
10/10Topics — 11 Topics
10/10Wiki
Verwendete Eingangsdaten
topicsdashboard, declarative, dom, forms, framework, frontend, no-build, proxy, reactive, table, zero-dependency
has_wikija
homepagehttps://qrp.nemanja.top/
has_readmeja
has_docs_dirja
has_descriptionja

Sicherheit

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

32Gefährdet · 16 % des Gesamtindex

Sicherheitslage

32Gefährdet
Wie die Bewertung erfolgt
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — keine Daten
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
2.5/2.5Contributors — project has 6 contributing companies or organizations
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Lizenz — license file detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
0/5Packaging — keine Daten
1.5/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 3
0/5SAST — no SAST tool detected
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — keine Daten
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
5.2/7.5Vulnerabilities — 3 existing vulnerabilities detected
Verwendete Eingangsdaten
sourceopenssf_scorecard
checks_evaluated15
scorecard_versionv5.5.0
checks_inconclusive3
scorecard_aggregate3,2
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): ci_tests, packaging, signed_releases. Die verbleibenden Gewichte wurden renormalisiert.

AI Readiness

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

67Mittel · 0 % des Gesamtindex
Wie die Bewertung erfolgt
45/45Agentenanweisungen — CLAUDE.md
0/15Maschinenlesbare Doku (llms.txt)
40/40Lesbare Commit-Historie — 86 von 100 menschlichen Commits benennen ihre Absicht (strukturierter Betreff oder erläuternder Text)
Verwendete Eingangsdaten
has_llms_txtnein
legible_history_share0,86
agent_instruction_filesCLAUDE.md
agent_instruction_max_bytes15.489
Wie die Bewertung erfolgt
0/18Bootstrap mit einem Befehl
22/22Automatisierte Tests
11/11Lint-/Format-Konfiguration — .eslintrc.json
11/11Statische Typprüfung — tsconfig.json
10/10Reproduzierbare Umgebung — lockfile
0/10Belegte Agentenpraxis — keine von Agenten verfassten Commits unter den letzten 100
0/8Automatisierte Wartung — keine automatisierten Abhängigkeits-Updates beobachtet
3/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 3
Verwendete Eingangsdaten
has_nixnein
has_testsja
lockfilespackage-lock.json
has_dockerfilenein
typed_languagenein
bootstrap_files
has_devcontainernein
has_linter_configja
typecheck_configstsconfig.json
agent_commit_share0
toolchain_manifests
dependency_bot_commit_share0
Wie die Bewertung erfolgt
27/45Typprüfbarer Code — JavaScript mit Typprüfungs-Konfiguration (tsconfig.json)
55/55Handhabbare Dateigrößen — 0/84 Quelldateien über 60 KB
Verwendete Eingangsdaten
primary_languageJavaScript
largest_source_bytes46.054
source_files_sampled84
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
118Commits, letzte 12 Monate
4Tage seit letztem Push
21Releases
1Bus-Faktor
0offene Issues
npmPaket-Ökosysteme

Warnungen zur Datenerhebung

  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository
  • deps.dev does not index npm:@nemanjan00/qrp@0.7.0; advisories assessed against the repository dependency graph instead

Weitere Details

OpenSSF Scorecard 3.2 / 10
3.2Gesamtwert

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-21 16:52 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
k. A.CI-Testsno pull request found
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
10Contributorsproject has 6 contributing companies or organizations
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
k. A.Packagingpackaging workflow not detected
3Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 3
0SASTno SAST tool detected
0Security-Policysecurity policy file not detected
k. A.Signed-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
7Vulnerabilities3 existing vulnerabilities detected
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": [
        "dashboard",
        "declarative",
        "dom",
        "forms",
        "framework",
        "frontend",
        "no-build",
        "proxy",
        "reactive",
        "table",
        "zero-dependency"
      ],
      "is_fork": false,
      "size_kb": 580,
      "has_wiki": true,
      "homepage": "https://qrp.nemanja.top/",
      "languages": {
        "CSS": 11179,
        "HTML": 61215,
        "JavaScript": 298103,
        "TypeScript": 5735
      },
      "pushed_at": "2026-07-17T00:27:50Z",
      "created_at": "2026-07-14T15:22:49Z",
      "owner_type": "User",
      "updated_at": "2026-07-17T00:27:54Z",
      "description": "A data-first, declarative, low-overhead framework for dashboards. Zero RUNTIME dependencies, zero build step — the devDependencies below are only for tests, lint, and git hooks.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "master",
      "license_spdx_raw": "MIT",
      "primary_language": "JavaScript",
      "significant_languages": [
        "JavaScript",
        "HTML"
      ]
    },
    "owner": {
      "blog": "https://nemanja.top/",
      "name": "Nemanja Nedeljković",
      "type": "User",
      "login": "nemanjan00",
      "company": "FlockSocial",
      "location": "Belgrade, Serbia",
      "followers": 117,
      "avatar_url": "https://avatars.githubusercontent.com/u/448151?v=4",
      "created_at": "2010-10-21T11:30:52Z",
      "is_verified": null,
      "public_repos": 233,
      "account_age_days": 5752
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.7.0",
          "kind": "minor",
          "published_at": "2026-07-17T00:27:34Z"
        },
        {
          "tag": "v0.6.1",
          "kind": "patch",
          "published_at": "2026-07-16T22:34:59Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2026-07-16T10:30:16Z"
        },
        {
          "tag": "v0.5.2",
          "kind": "patch",
          "published_at": "2026-07-16T09:50:20Z"
        },
        {
          "tag": "v0.5.1",
          "kind": "patch",
          "published_at": "2026-07-15T19:24:55Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2026-07-15T18:05:51Z"
        },
        {
          "tag": "v0.4.10",
          "kind": "patch",
          "published_at": "2026-07-15T18:02:48Z"
        },
        {
          "tag": "v0.4.9",
          "kind": "patch",
          "published_at": "2026-07-15T14:37:00Z"
        },
        {
          "tag": "v0.4.8",
          "kind": "patch",
          "published_at": "2026-07-15T10:24:47Z"
        },
        {
          "tag": "v0.4.7",
          "kind": "patch",
          "published_at": "2026-07-15T09:18:08Z"
        },
        {
          "tag": "v0.4.6",
          "kind": "patch",
          "published_at": "2026-07-15T08:41:53Z"
        },
        {
          "tag": "v0.4.5",
          "kind": "patch",
          "published_at": "2026-07-15T08:21:18Z"
        },
        {
          "tag": "v0.4.4",
          "kind": "patch",
          "published_at": "2026-07-15T08:14:59Z"
        },
        {
          "tag": "v0.4.3",
          "kind": "patch",
          "published_at": "2026-07-15T08:01:11Z"
        },
        {
          "tag": "v0.4.2",
          "kind": "patch",
          "published_at": "2026-07-15T01:12:44Z"
        },
        {
          "tag": "v0.4.1",
          "kind": "patch",
          "published_at": "2026-07-14T23:22:24Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-07-14T23:03:13Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-07-14T22:36:51Z"
        },
        {
          "tag": "v0.2.1",
          "kind": "patch",
          "published_at": "2026-07-14T20:02:26Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-07-14T19:15:41Z"
        },
        {
          "tag": "v0.1.1",
          "kind": "patch",
          "published_at": "2026-07-14T19:02:49Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "ea7183479bbd1581280f33be6d5428ffd9c323c9",
          "body": "Authoring Custom Elements is tangential to 'turn data into a dashboard' — more a\n'no class extends' flex than a dashboard need — so it's out, per do-one-thing-well.\nCore drops ~4.6 -> ~4.4 KB min+gzip. mount()/scoped() cover in-app component\nlifecycles; the ~50 self-contained lines (state+scope+clea\n[…]\n: removed the Custom elements demo section, the qrp-clock demo,\n  imports, highlighter keyword, and module-card mention. index.html render-checked.\n\nPer the tag rule, this is the version after v0.6.1.",
          "is_bot": false,
          "headline": "0.7.0: remove define() (custom-element registration) — BREAKING",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-17T00:27:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0c3e1cec0bfc0b0c1fb5c2a4e95830d5ee101014",
          "body": "v0.6.0 was tagged/published before commit 53f17ae (SHARP-EDGES callout in\nREADME + API reference, and the API.md regen documenting list()'s onDuplicateKey).\nPer 'anything after a tag is the next version', that's 0.6.1 — moved the\nSHARP-EDGES bullet out of the published 0.6.0 section into a new 0.6.1 section and\nbumped. Docs only; runtime identical to 0.6.0.",
          "is_bot": false,
          "headline": "0.6.1: SHARP-EDGES callout + onDuplicateKey docs (post-0.6.0-tag work)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-16T22:34:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "53f17ae6ec1d8da796942341b1986475dc102f60",
          "body": "…reference\n\nPoint readers (and coding agents reading the shipped docs) at the gotchas doc up\nfront. Added to bin/gen-api.js's preamble so API.md keeps it on regeneration, and\nto the README intro.\n\nAlso fixes a docs regression this surfaced: ListOptions had been inserted between\nlist()'s JSDoc and it\n[…]\nerface and\nDROPPED the entire ### list section (81 -> 80 exports). Moved ListOptions after\nthe function; list is back, onDuplicateKey documented, export set matches (81).\nFolds into unpublished 0.6.0.",
          "is_bot": false,
          "headline": "docs: 'read SHARP-EDGES before implementing' callout in README + API …",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-16T22:31:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0daa09dd9470160e6bced575ae2604a04a57715d",
          "body": "…f-host docs\n\nBuild:\n- dist/ is now a flat per-module minified mirror — dropped esbuild code-splitting,\n  so no shared chunk-*.js. Each module minifies in place (same names, no hashes);\n  cross-module imports stay relative (table.js -> ./qrp.js) so core is shared not\n  inlined, bundlers still tree-s\n[…]\nd sizes; CLAUDE.md build/release notes updated.\n\nAlso fixes CHANGELOG attribution: restored the 0.5.2 (ships-docs) and 0.5.1\n(guard rework) sections that prior version-shuffling had merged/mislabeled.",
          "is_bot": false,
          "headline": "0.6.0: flat dist (no chunks), list onDuplicateKey, build-optional/sel…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-16T10:30:16Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e508a5684d522c7a03c9f2a5c0add662af0d4951",
          "body": "Reviewer called it 'rare and great' — test a qrp component in a plain node --test\nscript under happy-dom, no browser. It follows from the core premise (real DOM,\nno VDOM/hydration/test-renderer) and is how qrp tests itself, but was never\nsurfaced as a selling point. Added a README section with a verified example (a\ntable going 0->3 rows on a state write via @happy-dom/global-registrator). Folds\ninto the unpublished 0.5.3 docs release.",
          "is_bot": false,
          "headline": "docs: document headless testability as a first-class plus (0.5.3)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-16T10:13:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c9ab49bfde4b0ecebfefca880a8c6a681e6768fd",
          "body": "Readers — humans and coding agents reading the shipped docs — were concluding\nfrom 'zero build / no bundler' that qrp CANNOT use a bundler. It always could;\nthe aimfox review confirmed it's a model ESM package under Vite (exports subpaths,\ntree-shaking, .d.ts). Philosophy: it's an MIT lib, use it ho\n[…]\nUDE.md: philosophy now states build-optional explicitly so future edits keep\n  the framing.\n\nDocs/metadata only, no runtime change. Ships because README + description + docs\nreach npm only on publish.",
          "is_bot": false,
          "headline": "0.5.3: reframe messaging as build-OPTIONAL (not build-forbidden)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-16T10:07:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "16f5ba4712576ba356123c19db8f921fa4860682",
          "body": "A coding agent (and humans) learn the API from what's in node_modules, so put the\nreference there: added docs/ and CHANGELOG.md to the files allowlist. The full\nAPI reference, getting-started, sharp-edges, and styling guides now travel with\nthe install — offline, no repo visit.\n\n- README doc + CHANG\n[…]\nUDE.md: package-contents note + release checklist updated (docs/ ships now;\n  *.html/docs-site.*/examples/ still don't).\n- ~30 KB added to the packed tarball (48.8 -> 78.7 kB); runtime code unchanged.",
          "is_bot": false,
          "headline": "0.5.2: ship docs/*.md + CHANGELOG in the npm package",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-16T09:50:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4f33dfb9c00a0b6e2f450c8b436e52d9e8d25348",
          "body": "…c-page dedup)\n\nThree loose ends from the review round:\n\n1. form() emitted markup (review §5): STYLING.md had the class table but not the\n   NESTING — the reviewer's labels 'sat inline until I inspected the DOM'. Added\n   the exact skeleton (bare <h3> outside .settings-section; .setting-item is\n   l\n[…]\ns. Verified all four render (headings, TOC, derived\n   aria-labels, cross-doc links resolve, live search filter) with no console\n   errors. Site-only files, not in the npm allowlist — no version bump.",
          "is_bot": false,
          "headline": "docs+site: close remaining gaps (form() markup, release checklist, do…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T19:37:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6cd00211217a587a1421ec67f7c2bfd07ce675d2",
          "body": "Patch bump: 0.5.0 (published) shipped the wall-clock runaway guard; the\nre-entrancy-depth rework (79e4179) is a runtime fix, so it needs its own version.\nMoved that CHANGELOG entry to a 0.5.1 section; 0.5.0 stays as published.",
          "is_bot": false,
          "headline": "0.5.1",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T19:24:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "264f773087e4668a0426166e6adfb32f5f3e2e87",
          "body": "Re-measured everything for 0.5.0:\n\nSizes (stale, updated): core ~3.9 -> ~4.5 KB min+gzip; whole library ~17 ->\n~20.5 KB; raw source ~12 -> ~16 KB gz. ESP32 blob rebuilt: app JS ~10.9 -> ~12.7\nKB, HTML ~15.4 -> ~17.4 KB, gzipped ~6 -> ~7 KB (react-dom ~45 KB gz is now ~6x,\nwas 7x). Test badge/count 2\n[…]\nmachine; the paint-timed suite landed on the\ndocumented table within normal jitter. Overwriting curated reference numbers with\nnoisier container/Xvfb figures would only make them worse, so they stand.",
          "is_bot": false,
          "headline": "docs: refresh sizes (benchmarks re-verified, unchanged)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T19:22:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "79e417933ba5c6e35974cf29fa84d7e81cfc8993",
          "body": "Re-running the benchmark for the size/perf refresh surfaced a false-positive in\n0.4.10's loop guard: updateOneNs fires one cell's effect ~22,000 times in a tight\nsynchronous loop, and the 1000-runs-per-second rate guard tore it down at 1001.\nA legitimately HOT reactive path (bulk writes, animation, \n[…]\n in practice.\n\n- new test: 5000 sequential updates to one effect never trip the guard\n- existing A<->B runaway + phase:'loop' report still pass\n- d.ts/SHARP-EDGES/CHANGELOG updated; API.md regenerated",
          "is_bot": false,
          "headline": "fix(core): runaway guard detects re-entrancy depth, not wall-clock rate",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T19:22:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9d8c351a780ba8fbd272cce549306d1db95e9ded",
          "body": "Bump for this round's new module + features. 0.4.10 (published) keeps only what\nshipped in it — the runaway-effect guard and the two createHttp fixes. The new\ndatagrid module (a new public subpath) makes this a minor bump; datagrid,\ncollection.filtered(), behaviors scope auto-teardown, query({arrays}), and the\nmarker console.error escalation move under the 0.5.0 heading.",
          "is_bot": false,
          "headline": "0.5.0",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T18:05:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ca57b95c59955c06a414c97ab4c77b6a952608ff",
          "body": "…PI, site\n\n- README + CLAUDE.md: datagrid module entry; behaviors scope auto-registration;\n  collection.filtered(); http pluggable fetch.\n- CHANGELOG 0.4.10: datagrid, collection.filtered, behavior auto-teardown,\n  query({arrays}), marker console.error.\n- docs/SHARP-EDGES: query({arrays}) note (repl\n[…]\n (13 modules, 81 exports — adds datagrid).\n- index.html: datagrid module card + import map; footer stats (259 tests, ~4.5 KB\n  core). Verified index.html + api.html render datagrid, no console errors.",
          "is_bot": false,
          "headline": "docs: datagrid + round-four fixes across README, CLAUDE, CHANGELOG, A…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T18:02:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4f9b6af7207f756f15da80c75bfae34cff48d067",
          "body": "…ogs error\n\nThree review edges (§7, §11, §2):\n\n- §7: portal/dismissable/trapFocus/anchored now onDispose-register their undo, so\n  building them inside scoped()/mount() means dispose() alone tears down effects\n  AND behaviors — no hand-tracking. Undos stay returned and are now idempotent.\n- §11: que\n[…]\ned (unchanged).\n- §2: a bare parent.append(when()/list()) now logs at console.error (was warn) so\n  headless/CI catches it (most harnesses fail on console.error); the in-DOM\n  breadcrumb is unchanged.",
          "is_bot": false,
          "headline": "fix: behaviors auto-register teardown; query() array params; marker l…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T18:02:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "61195b6e751a0669a9a4767e02195e04cceb6e31",
          "body": "…aging)\n\nReview §11 called a headless dataGrid 'the single highest-leverage addition' for\nqrp's audience — the batteries every admin table rebuilds: row selection\n(select-all + indeterminate, keyed so it survives sort/filter/page churn and\nrow-object replacement on refetch), column visibility, page-\n[…]\nthe\n  .d.ts), gen-api MODULES, and test/types.ts\n- tests: selection + keyed-survives-refetch + filtered select-all, column\n  visibility, page-size reset, windowed pager clamping, explicit-page honored",
          "is_bot": false,
          "headline": "feat(datagrid): headless data-grid state machine (selection/columns/p…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T18:02:46Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "87e6f0618eeedaa895e9512ac2a13f66b036887a",
          "body": "…ll links)\n\n- §0: README linked docs/*.md, CHANGELOG, examples/ — none ship in the npm\n  tarball, so an npm reader hit dead links. Converted to absolute GitHub URLs\n  (work on both npmjs.com and GitHub).\n- §1: SHARP-EDGES 'Routing & URL' — navigate with a real <a href>, not\n  onclick+navigate() (pre\n[…]\nve loader is now safe inside effects (the untracked fix).\n\nVerified sharp.html renders: new Routing section, 6 TOC entries, 11 cross-doc\nlinks resolve to api.html, no raw .md links, no console errors.",
          "is_bot": false,
          "headline": "docs: address review's doc findings (SHARP-EDGES callouts + npm-tarba…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T17:46:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "224a1d9b97f18561821c67e3d1fe28d8d6794f4b",
          "body": "…h is never partial)\n\nReview §5 flagged validate().value 'dropping keys not in the schema' (v0.4.8),\nranked the highest-value fix. It does not reproduce: walk() has built `out` from\n{ ...data } since before v0.4.8, so undeclared keys already pass through (declared\nones coerced) — verified against th\n[…]\n test mirroring the exact scenario (a no-rule\nfield surviving alongside coercion), plus explicit 'carries ALL keys' wording in\nthe module doc + .d.ts (pass { strict: true } to reject undeclared keys).",
          "is_bot": false,
          "headline": "validate: lock in + document that value carries undeclared keys (patc…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T17:46:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1686c1c1af82840f310e0a9be9c00a3e3559b358",
          "body": "… fetch seam\n\nTwo fixes surfaced by a real Vite/TS rewrite driving qrp as an npm dep.\n\n1. CRITICAL: the reactive in-flight counter's `loading.pending += 1` reads\n   pending. Issuing a request synchronously inside an effect() (the normal\n   refetch-on-filter-change pattern) subscribed that effect to \n[…]\nests or wrapped (retry/dedupe) without patching\n   globalThis.fetch.\n\nTests: a request inside an effect no longer re-runs it via pending; a custom\nfetch overrides the global. d.ts + CHANGELOG updated.",
          "is_bot": false,
          "headline": "http: stop createHttp leaking the loader dep into caller effects; add…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T17:35:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fde5b7d75c5ef18d8f1791043e2d802919899dd2",
          "body": "An effect that (transitively) writes state it reads looped forever: the classic\nfootgun is a loader called from an effect that sets state the same effect\ndepends on. Synchronously it recursed until the stack overflowed; with an async\nloader it spun an unbounded fetch loop ending in net::ERR_INSUFFIC\n[…]\nt option + phase 'loop'; API.md regenerated.\n- tests: runaway is stopped+reported; 50 legit re-runs never trip the guard.\n- docs/SHARP-EDGES.md + CLAUDE.md + CHANGELOG: document the guard and the fix.",
          "is_bot": false,
          "headline": "core: runaway-effect guard (loop detection) — 0.4.10",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T16:45:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f667721cea84904d30e07be28efc0fac84c517bd",
          "body": "…ss-links\n\n- styling.html renders docs/STYLING.md live (same dogfooded md renderer as\n  api/start); sharp.html does the same for docs/SHARP-EDGES.md (which the guide\n  already linked but had no rendered target).\n- generalize resolveHref across all doc pages: cross-doc .md links now map to\n  their re\n[…]\ning at the site root.\n- unified doc-page nav (Home · Guide · API · Styling · Demos · GitHub); added\n  Styling to the main site nav. Verified: all 4 pages render, no raw .md links,\n  no console errors.",
          "is_bot": false,
          "headline": "site: render STYLING (and SHARP-EDGES) on the website + unify doc cro…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T15:07:58Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5e0e7f8214803fedc44706ad0f5eb094f7adf35e",
          "body": "Documents the styling seam the 'helpers, not styled components' stance implies:\nthe three approaches (own CSS, the qrp.css token baseline + light/dark theming,\nor a CSS framework via class passthrough), the --qrp-* design tokens, and a\nreference of every semantic class the batteries emit (grounded in the source,\nincl. the forms classes' un-prefixed quirk). Linked from README + guide + CLAUDE.",
          "is_bot": false,
          "headline": "docs: add STYLING.md (bring-your-own CSS / qrp.css tokens / frameworks)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T14:59:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a32624ad7baa57e5bc4f77f2e61bb96c151d5c56",
          "body": null,
          "is_bot": false,
          "headline": "docs: CHANGELOG 0.4.9 (sideEffects)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T14:37:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b62594b4f0edc0a64b3926bf509364a70de8685f",
          "body": null,
          "is_bot": false,
          "headline": "0.4.9",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T14:37:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5b66dda31c30ced238ce5c173bc9596c44b62f42",
          "body": "Marks all JS side-effect-free so a consumer's bundler (webpack especially, which\nrequires the flag) drops unused re-exports — importing one util from the barrel\nno longer drags the rest in (verified: memoize-only import = 843 B, no\nvalidate/loadScript/limit/debounce). CSS kept side-effectful (**/*.css) since a\nCSS import injects styles.",
          "is_bot": false,
          "headline": "build: add sideEffects for reliable consumer tree-shaking",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T14:36:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "429f87b6cd649d7ef98708870c5f534e25de9353",
          "body": "Nav lagged the reorder: now Guide · ESP32 · Composition · Performance · Reactivity\n· Table · Data · Modules · API · GitHub — in section order, differentiators first.\nAdded the missing Composition link; every in-page anchor resolves.",
          "is_bot": false,
          "headline": "site: nav order matches new section flow (+ add Composition, drop stale)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T14:16:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3e8f417f566249c4eb65bd15f65d0ae5e1a740ca",
          "body": "Marketing order: reactivity is table stakes (assumed), so the differentiators go\nfirst — esp32 (tiny) → composition (simple) → performance (categorically fast:\n'change one field, touch one node') → reactivity (the how). Moved the perf\nsection's scattered helpers (perfData/perfSection/vsRow/perfHeadline) together\nwith its append so they define before use. Verified render + order, no errors.",
          "is_bot": false,
          "headline": "site: lead with differentiators — Performance now sits above Reactivity",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T13:06:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "da95b909c8c8fb0ff67d47d7b38adcf9a0e1efcd",
          "body": "esp32 (the 'wow' hook) → composition (how you actually build) reads as a stronger\none-two before the primitives deep-dive. Section unchanged, just reordered.",
          "is_bot": false,
          "headline": "site: move Composition section directly below the ESP32 demo",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T12:54:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b3688d3be96817d14fb2f5d0e9ca1c0ce113a433",
          "body": "…nctions\n\nShows the 'components are just functions' payoff concretely: a Card() wrapping\nField()s (each wrapping an input) plus a Toggle() factory, composed into a live\nAccount settings card with two-way bind + a save + a live state readout. Verified\nin Chromium (edit name, flip toggle, save), zero console errors.",
          "is_bot": false,
          "headline": "site: add live Composition section — a real card+form from factory fu…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T12:43:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "de231f84e82ff3f59e66b91c0abc8a8a846c2949",
          "body": "Teaches the 'helpers, not components' payoff the guide was missing: a component\nis just a function returning DOM; a factory takes props (values or thunks/state)\nand returns an el() tree. Covers composition, the one-node-one-place reuse\ngotcha (why factories/thunks exist), free scope-owned cleanup + onDispose, and\nwhen to reach for scoped()/define(). Renumbered 'Where to go next' to §9.",
          "is_bot": false,
          "headline": "docs(guide): add 'Reusable components (the factory pattern)' section",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T12:41:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f502ee63a6eef29abae291145cd3eaba70abd290",
          "body": null,
          "is_bot": false,
          "headline": "chore: gitignore profiles/ (local profiler captures, never commit)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T12:35:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0157332325f398bf8eefd6ef9785e6fe910ae40d",
          "body": "…ustom domain)",
          "is_bot": false,
          "headline": "docs: point live-demo links + homepage to https://qrp.nemanja.top/ (c…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T12:34:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b15ea0c1342a224c235b571ec1a1084722adb9b9",
          "body": null,
          "is_bot": false,
          "headline": "0.4.8",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T10:24:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "52188b7b36c20e65761a6cb54033de62ee527219",
          "body": null,
          "is_bot": false,
          "headline": "docs: CHANGELOG 0.4.8 + test badges (243)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T10:24:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a1f8c262c851ed89b24b405825cbbb64f29976a5",
          "body": "The one unsupported marker position — parent.append(marker) — failed as a silent\n[object Object] text node (shipped exactly this: a whole tab pane rendering as\n[object Object], invisible to navigation-only smoke tests). Markers now carry a\ntoString() that console.warns and returns a '[qrp when() — r\n[…]\ndiagnoses at the call site.\nCan't fire in normal use (qrp routes markers via the renderable symbol before any\nString coercion). +test (happy path silent; misuse warns+breadcrumb). SHARP-EDGES\nupdated.",
          "is_bot": false,
          "headline": "feat(core): markers self-diagnose a bare DOM append (P2)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T10:24:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2c4fb6bb922ef284bf227b79939219cf33d1387e",
          "body": null,
          "is_bot": false,
          "headline": "0.4.7",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T09:18:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "700229f87b9c4c22ba75e10cedd8ae76bd9d899c",
          "body": null,
          "is_bot": false,
          "headline": "docs: CHANGELOG 0.4.7 + test badges (242)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T09:18:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e2bcd1e6d1cb316043ffb0d3f52bcc0f219b9603",
          "body": "…plementations\n\nCloses the one seam where when/list were privileged: the normalizer special-cased\ntheir brands, so a userland switchOn/virtualList needed a host element. Now child\nposition dispatches on Symbol.for('qrp.renderable') — any object with\n[renderable](parent) renders like when/list, with \n[…]\nts it without importing. +test: a userland switchOn nested inside a\nfirst-party when, no wrapper, no stranding. Docs: exported symbol +\nQrpRenderable type, CLAUDE 'small core, everything else a peer'.",
          "is_bot": false,
          "headline": "feat(core): expose the renderable protocol — when/list become peer im…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T09:17:50Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0a9b621b1988395869933d17cbf2a65289671f11",
          "body": null,
          "is_bot": false,
          "headline": "0.4.6",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T08:41:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2866a067479cd1545cc00e27eb27692b44d0f400",
          "body": null,
          "is_bot": false,
          "headline": "docs: CHANGELOG 0.4.6 + test badges (241)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T08:41:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6bad92c479b4a3ae898c97b9524d03f4cd958ab1",
          "body": "…M on dispose (P0)\n\nFound adopting 0.4.x: a when()/list() nested in a parent marker's branch stranded\nits DOM when the parent switched (both tabs' content stacking). Cause: the parent\nonly tracks the nodes present when IT mounted the branch; a nested marker that\nre-rendered since inserted nodes the \n[…]\n unaffected (clear() already wipes; the removes are no-ops there).\n\nWrapper divs are no longer needed as the safe idiom for nested markers. +2 tests\n(nested when->when, when->list grow/switch/return).",
          "is_bot": false,
          "headline": "fix(core)!: nested-marker teardown leak — a marker removes its own DO…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T08:41:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b17b8732e5e114f699297749d9e5f58a267ee112",
          "body": null,
          "is_bot": false,
          "headline": "0.4.5",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T08:21:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b604b5cb4bf2c470218f86ab963fb3b2be182f59",
          "body": null,
          "is_bot": false,
          "headline": "docs: CHANGELOG 0.4.5 + test badges (239)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T08:21:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1a495ca7d752ab053965e5cb1d60f349ce7b56df",
          "body": "The two must-have table batteries, done without regressing the static fast path:\n- fields may be a THUNK () => Column[] — a reactive column set (visibility\n  toggle, role-gated). Header + each row's cells become reactive regions that\n  re-render on change; row ELEMENTS are reused. Static arrays keep\n[…]\n Row click toggles it (interactive cells excluded); also\n  node.toggleRow(key) + reactive node.expanded. + qrp.css .qrp-expand.\n+5 tests (incl. row-reuse across column change, interactive-cell guard).",
          "is_bot": false,
          "headline": "feat(table): dynamic (reactive) columns + expandable rows (§9.6)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T08:20:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b6c500d50518a99c1ea61d43b79d95279d98dfa5",
          "body": null,
          "is_bot": false,
          "headline": "0.4.4",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T08:14:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "663d2505fc8a5ee341821e3880a376231acd23a6",
          "body": null,
          "is_bot": false,
          "headline": "docs: CHANGELOG 0.4.4 + test-count badges (236)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T08:14:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2807623d89d13922c7b9bd4018644fea1cb90404",
          "body": "Full control of a th's content (select-all box, filter icon…); its own clicks\nstopPropagation so they don't trigger the column sort. Overrides label. +test.",
          "is_bot": false,
          "headline": "feat(table): custom header content via field.header(column) (§9.6)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T08:14:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "906cd4735e936cb4ec5e99b63999aee9a93d6e50",
          "body": "The ~70-lines-per-page pager (prev/windowed-pages/next, clamp, hide at ≤1 page)\nand 'Showing X–Y of Z' summary the port rewrote every time — now stock helpers\nover a table().view (or any collection), reactive. + qrp.css baseline styles\n(.qrp-pager/.qrp-summary). +4 tests.",
          "is_bot": false,
          "headline": "feat(table): tablePager + tableSummary batteries (§9.6)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T08:13:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "967b94d28dd4773c306479e8f74aec8a09d188cc",
          "body": "Persist table filters/sort/page to the URL without a page rebuild: setQuery\nmerges/replaces query params (nullish removes, array repeats), defaults to\nreplace+merge, and rides the same-pattern keep-alive so currentRoute.query\nupdates reactively with no remount. +test.",
          "is_bot": false,
          "headline": "feat(router): setQuery() — query-only URL updates without remount (§4.3)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T08:11:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2d51c674a4a605bb84afa97f5ecbf875744aa05c",
          "body": "…name})\n\nThe 2nd handler arg was the opaque internal runner. Now it's a stable context:\n{ phase } — 'create' (first run) vs 'update' (a reactive re-run) — plus 'name'\nfrom effect(fn, { name }), for crash-report attribution/triage. +test asserts.",
          "is_bot": false,
          "headline": "feat(onEffectError): documented context { phase, name } + effect(fn,{…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T08:10:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6ef425ce88074f8e544a96ecf3e7813b07205d92",
          "body": "…ount appends return (§2.2)\n\n- toNodes() now materializes when()/list() markers via a fragment, so a marker\n  RETURNED from a when branch, a list render, a mount component, or a reactive\n  hole renders instead of stringifying to [object Object]. Only a bare non-qrp\n  parent.appendChild(marker) is un\n[…]\nso the\n  append-to-view style doesn't double. Done inside the mount scope so a returned\n  marker's effects are owned.\n- docs: when()/mount d.ts + SHARP-EDGES updated (no longer limitations). +6 tests.",
          "is_bot": false,
          "headline": "fix(core): markers render when returned (not just as el children) + m…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T08:08:03Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0e40aba47040adf2626d68b9a7c9e46cf632ca03",
          "body": null,
          "is_bot": false,
          "headline": "0.4.3",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T08:01:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "20966d4e25a40a0e0ace1ac36783706e09964a8a",
          "body": "…empty (round-three findings)\n\nFrom the production port adopting 0.4.2 (deleted both hand-rolled validators):\n- validate(schema, data, { strict }) — opt-in reject keys not in the schema,\n  recursively (default permissive, so pass-through patches keep working).\n- present-but-empty '' is now validated\n[…]\n — now deletable.\n\nAlso: add CHANGELOG.md (breaking/behavioral changes marked, newest first) — the\nport flagged three consecutive silent semantic fixes; this closes that. Linked\nfrom README. +2 tests.",
          "is_bot": false,
          "headline": "feat(validate)!: strict unknown-key rejection + validate present-but-…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T08:01:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6538f6376d2f97f2bd0c6360d52dfba8c532897f",
          "body": null,
          "is_bot": false,
          "headline": "0.4.2",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T01:12:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fc8702046b7859c52894a4c1698965348f5562cf",
          "body": "…inding)\n\nThe production port could NOT adopt validate() because its real validation sites\ncoerce ('5'→5, 'true'→true) and send the coerced patch to the server; check-only\nwould have changed the wire format. Now validate() coerces form strings toward\neach rule's declared type and returns { errors, v\n[…]\nend as the patch. Nested fields coerce too.\n\nBREAKING: validate() returns { errors, value } instead of an errors array\n(validate is one release old; pre-1.0). Docs/site/types updated. +coercion tests.",
          "is_bot": false,
          "headline": "feat(validate)!: coerce + return { errors, value } (round-two field f…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-15T01:12:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "22586768445c75575d51770074b50b59c793861a",
          "body": null,
          "is_bot": false,
          "headline": "0.4.1",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T23:22:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "63cfe8c028e1d1d4dc3aa3d717b5831e7da95123",
          "body": "0.4.0 shipped dist/utils/ WITHOUT debounce/limit/validate/load-script: build.js's\nENTRIES was a hand-maintained list and the new util files were never added, so\nthe exports './utils/*' deep subpaths pointed at files not in the tarball (the\numbrella '@nemanjan00/qrp/utils' worked; '.../utils/debounce\n[…]\n\n- build guard: assert every package.json exports subpath resolves to a built\n  dist file; fail the build (→ prepack → publish) otherwise.\n\ndist/utils now has all 8 files; verifyExportsResolve passes.",
          "is_bot": false,
          "headline": "fix(build)!: derive dist entries from filesystem + guard exports resolve",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T23:22:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1b3d0e892130cd6a9c03d5c23452ecb84c7df982",
          "body": "The utils overview prose was stale — it listed only the original helpers, not\nlimit/debounce/throttle/validate/loadScript or memoize's ttl/invalidate (the\nper-export entries were present; only the intro undersold them). Note the barrel\nimport for both modules and the scoped() modal caveat for behaviors. Regenerated.",
          "is_bot": false,
          "headline": "docs: refresh utils/behaviors module overviews in API.md",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T23:18:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "050e4d1dfd12134c0a54998bc7eef3cb13f5ea99",
          "body": "…utils/routing snippets)\n\n- site: live 'Dashboard utilities' section — a debounced search (keystrokes fire\n  every time; the search waits for a pause), verified in Chromium. Highlighter +\n  importmap updated for the new utils.\n- README: value-keyed when() tab example; new snippets for debounce/limit/\n  validate, responseType, currentRoute/scoped/onEffectError; keep-alive note.",
          "is_bot": false,
          "headline": "site,readme: showcase 0.4 features (debounce demo, value-keyed when, …",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T23:11:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c472d135db61d1ad195620aea0765075672c7e89",
          "body": "… KB library)\n\nNew exports (currentRoute, onEffectError, scoped; validate, loadScript,\nlimit/debounce, memoize ttl) grew the core to ~3.9 KB min+gzip and the whole\nlibrary to ~16.8 KB. README badge/copy, index.html meta/hero/footer updated.\nBenchmarks re-verified: single-cell still ~0.8 us / 1 node of 40,002; suite\nratios unchanged within noise — no table change needed.",
          "is_bot": false,
          "headline": "docs: update size claims to measured 0.4.0 figures (~3.9 KB core, ~17…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T23:07:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b02926a12717ad695fdf0e07ac78d7e372c884f7",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump test-count badges to 225",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T23:03:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1a4cbe83a4abd494d67079b7b5b4516ec925a7cc",
          "body": null,
          "is_bot": false,
          "headline": "0.4.0",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T23:03:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ae030cc73c4f16814fbb4cb0bcb6c7943da25109",
          "body": "- docs/SHARP-EDGES.md: the handful of behaviors worth knowing once (raw-array\n  mutation, node-lives-once, marker-as-child, value-keyed when, unique list keys,\n  scoped() for handler-built UI, http reject shape, SPA serving) — reflecting the\n  CURRENT post-fix state, not the report's pre-fix list. Linked from README +\n  Getting Started.\n- README/CLAUDE.md/site utils listings updated (validate, loadScript, memoize\n  ttl). API.md regenerated.",
          "is_bot": false,
          "headline": "docs: add SHARP-EDGES.md + sync README/CLAUDE/site for new utils (§8.2)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T23:02:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4ada320501607f98c17241fc105a7358c9e860e4",
          "body": "… §6.2)\n\n- utils/validate.js: tiny declarative schema validator (required/type/min/max/\n  enum/pattern/custom check/nested fields) → [{path,message}]. Pairs with forms;\n  the zero-build answer to joi/zod for PATCH payloads.\n- utils/load-script.js: inject a UMD/global <script> once (deduped), reactiv\n[…]\n — the honest hatch for Chart.js et al. under an\n  import-map app.\n- behaviors/anchored: { matchWidth } sizes the floating element to its trigger\n  (dropdown-spans-input).\n+4 tests, API.md 76 exports.",
          "is_bot": false,
          "headline": "feat(utils,behaviors): validate, loadScript, anchored matchWidth (§7,…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T23:01:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "895d7cb62ba893d2da7064df6396c827e9b9a668",
          "body": "The generator listed supporting types by NAME only — the gap that shipped the\ndisclosure() bug (readers assumed d.open was a boolean, not a method). Now it\ncaptures each exported interface/type's FULL definition (brace-matched), incl.\nundocumented ones (second pass), and emits them as code blocks under a\n'Supporting types' heading. Bumped the api.html/start.html markdown renderers to\nh4 + styled it. Disclosure's { state:{open}, toggle(), open(), close() } shape\nnow visible.",
          "is_bot": false,
          "headline": "docs(gen)!: inline supporting-type definitions in API.md (§8.1)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T22:59:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "80eeca1ac7e1eac8353d5d7057f6172d150c531e",
          "body": "- memoize: options.ttl expires entries (post-resolve for promises); the returned\n  fn gains .invalidate(...args) (one key) / .invalidate() (all). Covers the\n  refetch-with-TTL + bus-driven-invalidation pattern hand-rolled in the port.\n- lru: add clear().\n- scoped(fn) -> { value, dispose }: build UI \n[…]\nutside a render (a modal from an\n  onclick) with owned effects instead of ownerless leaks (§6.1). ESP32 demo's\n  scan modal now uses it — its when()/list() effects tear down with the modal.\n\n+4 tests.",
          "is_bot": false,
          "headline": "feat: memoize ttl+invalidate, lru.clear, scoped() sugar (§7, §6.1)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T22:56:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0b509670698f32883b497e664d08ca2a6db27058",
          "body": "BREAKING (behavioral): when a navigation matches the SAME route pattern (a\nparam/query change — e.g. switching :tab on /users/:pk/:tab), the router no\nlonger tears down and remounts the page. In-pane state (form edits, scroll,\nexpanded rows) survives and the handler reacts through the reactive currentRoute;\nno refetch churn. A different pattern still fully remounts. Pass\nrouter(..., { remount: true }) to restore always-remount.\n\n+2 tests.",
          "is_bot": false,
          "headline": "feat(router)!: keep-alive on same-pattern navigation (§4.2)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T22:52:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9869aafe3f93b263ca075d4d90728510e4827d85",
          "body": "…c, §5.1b)\n\n- table: custom render() cells are now reactive — re-run when the row's item is\n  replaced (refetch), so action cells reflect fresh state instead of the item\n  they were built with. (Was: built once per key.)\n- forms: form() renders the FIELDS spec, not Object.keys(settings) — a field\n  \n[…]\njects created, bound two-way) and seeds defaults\n  along the path. With no fields, keeps the reactive-key-set fallback.\n\nBREAKING: form() structure is now fields-driven when fields is given. +6 tests.",
          "is_bot": false,
          "headline": "feat(table,forms)!: reactive render cells + fields-driven forms (§2.3…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T22:51:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "604513728342351e59c0b79fdb342d3a3e4dfca9",
          "body": null,
          "is_bot": false,
          "headline": "test(list): cyclic-object rebind terminates (loop safety regression)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T22:47:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cba5465b9f2b15b57e0dace84ed85005a17c0005",
          "body": "… §2.4)\n\nBREAKING (behavioral): a row whose key survives a refetch now reflects the fresh\nobject instead of the one captured when the row was built. The merge is a\nDEPTH-LIMITED recursion (REBIND_DEPTH=8): it recurses into nested plain objects\nso their proxy identity is preserved (a captured `const \n[…]\nic subtrees fall back to reference assignment. Same-identity rows still\nupdate in place through their own bindings.\n\nAnswers the reviewer's §2.3 staleness trap and the nested-object concern. +3 tests.",
          "is_bot": false,
          "headline": "feat(list)!: rebind surviving rows via bounded recursive merge (§2.3,…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T22:46:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "05d5b1afc56b8a91f1c3bc276bf635f2871191a8",
          "body": "… (§2.1)\n\nBREAKING: when() now re-renders the branch when the condition's VALUE changes\n(Object.is), not only when truthiness flips. This makes value-switches work\ndirectly — when(() => state.tab, tab => TABS[tab]()) re-renders on every tab,\nthe pattern that previously shipped a bug (stuck on the fi\n[…]\nue change rebuilds.\n\nMigration: code relying on when() NOT rebuilding across distinct truthy values\nshould key on a boolean instead (when(() => !!x, ...)). Boolean conditions are\nunaffected. +2 tests.",
          "is_bot": false,
          "headline": "feat(when)!: value-keyed rendering — re-render when the value changes…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T22:42:02Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a72052769746f32ed8434f9a00534bfc51d6cfe7",
          "body": "…1/§2.2)\n\nCompletes the 'skip the behavior change, document the gotcha' half for the two\nthat shipped bugs in the field report: when() swaps on truthiness not value\n(so it won't switch between truthy tabs — branch per value), and markers are\nonly valid as el()/html children. Regenerated API.md.",
          "is_bot": false,
          "headline": "docs: loudly document when() truthiness trap + marker-child rule (§2.…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T22:38:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "95a8fb084395cc71c9ac9eeac31fd91aed2bba69",
          "body": null,
          "is_bot": false,
          "headline": "0.3.0",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T22:36:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "202831e5223bb69e9bce3c52068f1b294b4e4bbe",
          "body": "…pe, utils limit/debounce/throttle, forms style passthrough\n\nAdditive changes from a production port's punch list (no breaking semantics):\n\n- core: onEffectError(handler) — central hook fired before a throwing effect's\n  error propagates (wire Sentry etc.); today a throwing binding is only visible\n \n[…]\nal), types-suite usage, API.md regenerated (73 exports),\nREADME/site/CLAUDE.md synced. Skipped (need design, would break behavior):\nwhen() value-keying, list()/table render-cell rebind, nested routes.",
          "is_bot": false,
          "headline": "feat: field-report P0s — onEffectError, currentRoute, http responseTy…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T22:36:50Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d8153a6c58ace5273d19ff17ca22a0eeaf7317a5",
          "body": null,
          "is_bot": false,
          "headline": "chore: gitignore local field notes (never commit/publish)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T22:23:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bb2078b973ceb1a30a706233b2f0ab5a3b1efb11",
          "body": "…ast)\n\nThe old toasts demo sent a static html snippet — it didn't show the actual\ntrick. Now 'Delete last' emits a toast whose content is a live el() node with\na working Undo button; the node travels over the bus (bus.emit('warning', node))\nand the toast layer renders it, handler and all. Undo restores the item and\nfires a success toast. Builds a fresh node per emit (a DOM node lives in one\nplace). Reframes the section as 'Renderables over the bus'.",
          "is_bot": false,
          "headline": "site: demo sending a live DOM node over the event bus (Undo action to…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T20:32:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ee3caee84528c85ee6514d832436d41c61286c33",
          "body": "…orners\n\n- sparkline: derive() the history min/max ONCE per tick instead of every one\n  of the 40 bars re-scanning the whole array twice (was 80 scans to move 40\n  bars — the opposite of the fine-grained pitch). Now one scan feeds 40 bindings.\n- modal: make close/pick local to each openScan() so they close over that\n  invocation, not a module-scoped reassigned handle — the pattern stays correct\n  if copied for a second modal. Compose the three behaviors' teardowns into one.",
          "is_bot": false,
          "headline": "examples(esp32): tighten the two spots exemplary code shouldn't cut c…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T20:24:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ec42b8f86d1c954f14376402ee3dadd53ac86003",
          "body": "- docs/GETTING-STARTED.md: a ten-minute, zero-to-dashboard tutorial covering\n  the five core ideas (state/effect, el, derive, when, list) then a full small\n  dashboard, with a 'where to go next' map into the module docs.\n- start.html: renders the guide live with the same qrp markdown renderer as\n  a\n[…]\n in api.html/start.html (link-in-text-block).\n- wire links: README header + Install note, index.html nav + hero 'Get\n  started' CTA, api.html nav.\n- CLAUDE.md: document the guide + start.html pattern.",
          "is_bot": false,
          "headline": "docs: add Getting Started guide + rendered start.html page",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T20:17:08Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a1a679b73d550a95e3fb35999c8ddf79771a4fe7",
          "body": null,
          "is_bot": false,
          "headline": "0.2.1",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T20:02:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "57334a7be17992f75f106dfd4e0282f8c2100924",
          "body": "Leftover from the original form-only demo; the reworked live dashboard is\n~6 KB gzipped, as the panel next to it already states.",
          "is_bot": false,
          "headline": "site: fix stale ESP32 flash size in code comment (~4 KB -> ~6 KB)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T20:01:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5622b43d40f7e85dfd3b7f1b036e636d6cf9ccf2",
          "body": "Audited all three pages (site, api.html, esp32 dashboard) with Lighthouse.\n\nAccessibility -> 100:\n- forms: field() now associates its <label> with the control via for/id\n  (only for labelable INPUT/SELECT/TEXTAREA, not the radio-group wrapper) —\n  fixes the Lighthouse select-name/label failures at t\n[…]\nO -> 100: meta description on the esp32 dashboard.\n\nFinal: site 98/100/100/100 (2 perf pts are the intentional raw-source load),\napi 100/100/100/100, esp32 100/100/100/100 — for a client-rendered SPA.",
          "is_bot": false,
          "headline": "a11y + perf: Lighthouse 100 on api & esp32, 98/100/100/100 on site",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T19:57:44Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8dac45759bd807b914764116211e8c40e0507443",
          "body": "A static settings form is the weakest pitch for a reactive framework, so make\nthe demo show what only reactivity can do:\n- live telemetry (temp/humidity/rssi/heap) streaming into bindings + sparkline\n- LED toggle + brightness slider that write to the device\n- config form that rewrites itself via whe\n[…]\nKB gzipped blob\n- reframe README + site section (live dashboard, not a form); iframe gets a title\n\nFixes the qrp gotcha of mixing native append() with when()/list() markers\n(build the tree with el()).",
          "is_bot": false,
          "headline": "examples(esp32): rework into a live reactive dashboard + WiFi-scan modal",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T19:38:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "032c8a0146d289e246b600f849f78ec9afd0469c",
          "body": "… & site\n\n- examples/esp32/: form() as a full device config UI, bundled + minified +\n  gzipped into a ~4 KB PROGMEM blob served from flash. PlatformIO project\n  (platformio.ini + src/main.cpp), build.js (bundle->minify->inline->gzip->\n  PROGMEM header), self-contained dashboard.html doubles as the l\n[…]\n extreme case' section after the hero — main.cpp serve snippet\n  beside a live iframe of the actual dashboard; nav link added.\n- fix README keyed-list sample: () => view.items() (items() is a method).",
          "is_bot": false,
          "headline": "examples: add ESP32 self-hosted settings dashboard + wire into README…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T19:24:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f5c5c80c6499e0fcba83e11a0fad899992e5f13f",
          "body": null,
          "is_bot": false,
          "headline": "0.2.0",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T19:15:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "80672759ab7ce63666b50cda1e983d63d46cf998",
          "body": "- bin/build.js: esbuild bundle+splitting per subpath -> dist/ (shared core\n  chunk), minified. npm run build; also prepack so pack/publish rebuild it.\n- package.json: exports.default -> dist/*.js, exports.types -> hand-written\n  .d.ts; files ships dist + .d.ts + css, NOT raw source; esbuild devDep.\n\n[…]\n correct all size claims to measured figures: core ~3.7 KB min+gzip\n  (was quoting ~12 KB raw-gzip), whole library ~15 KB; honest raw-source\n  clause in README. Update CLAUDE.md (docs+build pipeline).",
          "is_bot": false,
          "headline": "build: ship minified, code-split dist/ on npm (~3.7 KB min+gzip core)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T19:13:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e32e6f7653001a4c895b6ea7c36ae75b4aba1da3",
          "body": null,
          "is_bot": false,
          "headline": "0.1.1",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T19:02:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3970b677ebc87be173531a11c516a54c434c6131",
          "body": "- npm version + license badges, npm link in quick-links\n- LICENSE (MIT) + license field in package.json + License section",
          "is_bot": false,
          "headline": "readme: npm badge + link; add MIT license",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T19:02:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b8f140c42beaa094eaddd88936edc26e585942a2",
          "body": "- package.json: scoped name, exports map (clean subpaths + types), files\n  allowlist, publishConfig.access=public, repo/homepage/keywords/author\n- README + generated API.md + site + examples: import from @nemanjan00/qrp[/sub]\n- demo HTML pages gain a <script type=\"importmap\"> so the bare specifiers\n\n[…]\noped specifiers so docs stay single-sourced\n\nqrp was taken on npm; scoped keeps the brand. Verified: all demo pages boot\nunder the import maps, typecheck + lint clean, npm pack ships 47 runtime files.",
          "is_bot": false,
          "headline": "publish: rename package to @nemanjan00/qrp, wire clean subpath imports",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T19:00:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "910bdc1b7fea47d9bd02254f72f778c5af5784b5",
          "body": "Runs on push to master/main and every PR, matrix over Node 22 & 24\n(node --test glob needs Node >= 21). Adds a CI status badge to the README.",
          "is_bot": false,
          "headline": "ci: add GitHub Actions workflow (lint + typecheck + test)",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T18:47:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8683e88d410f4ba9a315e6beead59ded20627df6",
          "body": "- assets/qrp-logo.svg: wordmark (r in accent) + QRP radio-wave mark,\n  matched to the site palette (#0a0d12 / #ffb23e / #34d399)\n- centered header: shields.io badges (deps/build/size/tests/types),\n  live-demo + API + quick-jump links\n- emoji icons on every section heading; proto row lists onceOnly",
          "is_bot": false,
          "headline": "readme: add logo, badges, section icons, live-demo links",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T18:46:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "64f419bcde72272ec6dbd0531fe3b8aa7647fcf5",
          "body": "The proto module (wrapMethod/delegate/onceOnly) shipped and tested but never\nappeared on the marketing site — not even as a module card. Add a live\nwrapMethod demo (idempotent prototype patch, the userscript trick) and the\nmissing grid card.",
          "is_bot": false,
          "headline": "site: add Prototypes section + module card for the proto module",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T18:40:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b74088c4f3ddd318cf02578a0713721c53801b5f",
          "body": "- add bin/gen-api.js: parse .d.ts doc-comments -> docs/API.md\n- backfill @module overviews across satellite .d.ts so curated prose\n  (html escaping guarantee, forms FieldSpec/types, http error shape) lives\n  in one place and flows through the generator\n- enrich qrp/index.d.ts: list() thunk source contract, effect/derive edge\n  cases, el() prop-rule subsection, scope-vs-mount guidance\n- wire npm run docs",
          "is_bot": false,
          "headline": "docs: generate API.md from .d.ts single source",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T18:37:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "10b26d4d927cd0b393e0967f64467b8c86580934",
          "body": "- api.html: a browsable API reference — sticky sidebar TOC, filterable search,\n  styled tables/code — rendered at runtime from docs/API.md by a compact\n  Markdown→DOM renderer built with qrp itself (el/list/state, no md library).\n  The site DERIVES from the markdown: one place to update, no duplicat\n[…]\number + the minified\n  context, not the flattering stale figure.\n\n- CLAUDE.md: documented the types/docs setup and the JSDoc-as-single-source\n  north star (generate .d.ts + md from JSDoc — next step).",
          "is_bot": false,
          "headline": "API reference page (renders docs/API.md live) + accurate size numbers",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T18:22:07Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1658fe32a56140934bba630cc1f2e2a0abc26160",
          "body": "Ship types for the whole surface, hand-written next to each ESM module so\nimporting \"./qrp/index.js\" resolves ./qrp/index.d.ts — no @types package, no\nbuild step, no change to how qrp is loaded.\n\n- .d.ts for qrp, html, forms, collection, table, http, events, toasts, browser,\n  each behaviors/* and u\n[…]\nerence — every export, signature, and a usage snippet\n  per module, plus the escaping guarantee and a TypeScript section.\n\ntypecheck passes; lint clean; 192 tests. .eslintignore excludes the .ts test.",
          "is_bot": false,
          "headline": "Add TypeScript declarations (.d.ts) for every module + API reference",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T18:14:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c82c909757c0ae9dfde824f5b839032a3f347a5b",
          "body": "Same class as the markup-demo fix, in the section whose lede promises \"disposes\nthe previous route's scope on navigation.\" It did the opposite: it hand-rolled\noutlet.replaceChildren() + mount() inside an effect and never kept the disposable\nmount() returns — so every tab click stranded the previous \n[…]\ne outlet) — which is exactly\nwhat the real router() does on navigation. Verified in Chromium: switching\nthrough all routes leaves exactly one view in the outlet (no accumulation), zero\nconsole errors.",
          "is_bot": false,
          "headline": "Router demo: dispose the mount handle instead of hand-rolling + leaking",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T18:02:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "eb894b9a65eb07eb1a0989f5a98315609b7fcb54",
          "body": "1. Removed the duplicate storable-templates section — #templates (Grace Hopper)\n   and #storable (card list) demoed the same feature. Kept the richer #storable\n   (list() + add-row).\n\n2. Markup demo now uses when() for the tab switch instead of a hand-rolled\n   IIFE + effect + replaceChildren — dogf\n[…]\nno longer contradicts the numbers below it.\n\nVerified in Chromium: one templates section, one viewport meta, badges/footer at\n192, markup when()-switch works, theme swatch reacts, zero console errors.",
          "is_bot": false,
          "headline": "Fix the remaining five site issues from review",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T18:00:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0961cca28a9772165110e4805f0296668eab0833",
          "body": "1. Perf chart no longer drops the two worst numbers. It now shows all EIGHT ops\n   the README shows — including create 10k (1.3×) and clear 10k (1.8×), the one\n   I explicitly called the honest weak spot. Omitting it after naming it was the\n   kind of thing that taints the numbers you did show. 1.8×\n[…]\nse to GitHub on narrow screens, the\n   table scrolls horizontally in its own box, and section/bar/code spacing scales\n   down. Verified at 390px: zero horizontal page overflow.\n\n192 tests still green.",
          "is_bot": false,
          "headline": "Site perf/table/responsive fixes from review",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T17:51:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e774392bb07fc764c98154eab0c8be8a3a68506a",
          "body": "A 1000× claim invites a fight; answer the top-comment objections before they're\nraised, in both places people look:\n\n- flushSync: answered in react-compare.html AND the README. flushSync doesn't\n  add work — it stops batching from smearing the reconcile across a later frame\n  so it can be timed. Con\n[…]\ned. That walk is the ~800µs. The number\n  defends itself.\n\n\"You wrote slow React\" (per-row stores narrow it) folded in as the second\nanswered objection. No code changes; docs/comments only. 192 tests.",
          "is_bot": false,
          "headline": "Preempt the two objections to the 1000× number",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T17:28:16Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5a20fbd89c3f35fe7b77d865ef5ecabe40c2d7ed",
          "body": "…ity pass\n\nAddresses a review of the README/site — every ask was to replace an assertion\nwith evidence:\n\n- MEASURED the virtual-DOM claim. Vendored React 18 (production) and a fair\n  memoized+keyed 10k-row table (examples/react-compare.html). Same single-cell\n  update, same MutationObserver: qrp ~0.\n[…]\ns 8ms paint → ~10% reactivity).\n\n- clear() 1.8× called out as the honest weak spot.\n\nSite perf shows qrp-vs-React bars. .eslintignore excludes examples/vendor/\n(the React production build). 192 tests.",
          "is_bot": false,
          "headline": "Measure the categorical claim (React), XSS test file, README credibil…",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T17:24:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e6c8362499e46029c2f795702c22a77258143140",
          "body": "Site (index.html):\n- Performance section now LEADS with the categorical stat — \"1 DOM node touched\n  of 40,002\" when you change one field in a 10k-row table — big, with the honest\n  framing (~0.8µs, no diff, no re-render, O(1); the win is vs virtual-DOM, not\n  vs hand-written vanilla). Full suite ba\n[…]\nment\n(1 node of 40,002, ~0.8µs) and an explicit honest footnote — it's a win over\nvirtual-DOM frameworks, NOT over hand-optimized vanilla (270–460ns), and we say\nso. Full paint-timed suite kept below.",
          "is_bot": false,
          "headline": "Marketing site: single-cell headline + demo every feature; README perf",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T17:14:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "48a74050ef9b7e83d42c9de854fd825a9e832c2a",
          "body": "- Reactive text holes now update the existing text node's data IN PLACE (both\n  qrp core and html) instead of remove+insert. Changing one cell in a 10,000-row\n  table touches exactly 1 DOM node (was 3), and is faster (1.3µs → 0.8µs). The\n  effect closure already holds the node reference — no lookup,\n[…]\n it.\n\n- Removed utils/round-robin.js and utils/weighted-pool.js — load-balancer\n  helpers that don't serve dashboards. \"Do one thing well.\" utils is now\n  memoize / lru / cache / paginate.\n\n185 tests.",
          "is_bot": false,
          "headline": "In-place text updates; single-cell benchmark; cut load-balancer utils",
          "author_name": "Nemanja Nedeljkovic",
          "author_login": "nemanjan00",
          "committed_at": "2026-07-14T17:10:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        }
      ],
      "releases_count": 21,
      "commits_last_year": 118,
      "latest_release_at": "2026-07-17T00:27:34Z",
      "latest_release_tag": "v0.7.0",
      "releases_from_tags": true,
      "days_since_last_push": 4,
      "active_weeks_last_year": 1,
      "days_since_latest_release": 4,
      "mean_days_between_releases": 0.2
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 42,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "@nemanjan00/qrp",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "dashboard",
            "reactive",
            "proxy",
            "declarative",
            "framework",
            "frontend",
            "no-build",
            "zero-dependency",
            "dom",
            "forms",
            "table"
          ],
          "ecosystem": "npm",
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/@nemanjan00/qrp",
          "is_deprecated": false,
          "latest_version": "0.7.0",
          "repository_url": "https://github.com/nemanjan00/qrp",
          "versions_count": 18,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 2683,
          "first_published_at": "2026-07-14T19:00:34.180000Z",
          "latest_published_at": "2026-07-17T00:27:41.501000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 4
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 0,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0
      },
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 46054,
      "source_files_sampled": 84,
      "oversized_source_files": 0,
      "agent_instruction_files": [
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 15489
    },
    "dependencies": {
      "manifests": [
        "package.json"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm"
      ],
      "dependencies": [],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 0,
        "merged_prs": 0,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "nemanjan00",
          "commits": 118,
          "avatar_url": "https://avatars.githubusercontent.com/u/448151?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [
        ".eslintrc.json"
      ],
      "has_editorconfig": true,
      "has_linter_config": true,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "package-lock.json"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 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": null,
            "reason": "no pull request found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 6 contributing companies or organizations",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 0,
            "reason": "project was created within the last 90 days. Please review its contents carefully",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 3,
            "reason": "dependency not pinned by hash detected -- score normalized to 3",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "no SAST tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 7,
            "reason": "3 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "ea7183479bbd1581280f33be6d5428ffd9c323c9",
        "ran_at": "2026-07-21T16:52:08Z",
        "aggregate_score": 3.2,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/nemanjan00/qrp",
    "host": "github.com",
    "name": "qrp",
    "owner": "nemanjan00"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 55,
      "inputs": {
        "security": 32,
        "vitality": 68,
        "community": 32,
        "governance": 42,
        "engineering": 93
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "moderate",
        "name": "Vitality",
        "value": 68,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 55,
            "inputs": {
              "commits_last_year": 118,
              "human_commit_share": 1,
              "days_since_last_push": 4,
              "active_weeks_last_year": 1
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 4 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 4
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "1/52 weeks with commits",
                "points": 0.7,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 1
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "118 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 118
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 88,
            "inputs": {
              "releases_count": 21,
              "latest_release_tag": "v0.7.0",
              "releases_from_tags": true,
              "days_since_latest_release": 4,
              "mean_days_between_releases": 0.2
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "21 version tags (no GitHub releases)",
                "points": 16.2,
                "status": "partial",
                "details": [
                  {
                    "code": "version_tags_no_releases",
                    "params": {
                      "count": 21
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 4 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 4
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~0.2 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 0.2
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 32,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "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
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "moderate",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 57,
            "inputs": {
              "packages": [
                "@nemanjan00/qrp"
              ],
              "dependents": null,
              "ecosystems": "npm",
              "total_downloads": null,
              "monthly_downloads": 2683
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "2,683 downloads/month across npm",
                "points": 45.7,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 2683,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 42,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 20,
            "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 6 contributing companies or organizations",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "critical",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution, PR acceptance. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution",
                    "pr_acceptance"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 1,
            "inputs": {
              "merged_prs": 0,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 0
            },
            "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": "no decided pull requests or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_decided_prs_or_data",
                    "params": {}
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 62,
            "inputs": {
              "followers": 117,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "nemanjan00",
              "public_repos": 233,
              "account_age_days": 5752
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "117 followers of nemanjan00",
                "points": 14.9,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 117,
                      "login": "nemanjan00"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "233 public repos, account ~15 yr old",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 233
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 15
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "@nemanjan00/qrp"
              ],
              "ecosystems": "npm",
              "any_deprecated": false,
              "min_days_since_publish": 4
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on npm",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 4 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 4
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "18 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 18
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "excellent",
        "name": "Engineering Quality",
        "value": 93,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "excellent",
            "name": "Engineering practices",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 88,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": true,
              "has_linter_config": true,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "1 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": ".eslintrc.json",
                "points": 16,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".eslintrc.json"
                    }
                  }
                ],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 6.4,
                "status": "met",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "excellent",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "topics": [
                "dashboard",
                "declarative",
                "dom",
                "forms",
                "framework",
                "frontend",
                "no-build",
                "proxy",
                "reactive",
                "table",
                "zero-dependency"
              ],
              "has_wiki": true,
              "homepage": "https://qrp.nemanja.top/",
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": "https://qrp.nemanja.top/",
                "points": 15,
                "status": "met",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": "11 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 11
                    }
                  }
                ],
                "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": 32,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): CI-Tests, Packaging, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "ci_tests",
                    "packaging",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 32,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 15,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 3,
              "scorecard_aggregate": 3.2
            },
            "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": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 6 contributing companies or organizations",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 3",
                "points": 1.5,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "no SAST tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "3 existing vulnerabilities detected",
                "points": 5.2,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 3
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 67,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.86,
              "agent_instruction_files": [
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 15489
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "CLAUDE.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "86 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 86,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 57,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "package-lock.json"
              ],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [
                "tsconfig.json"
              ],
              "agent_commit_share": 0,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": ".eslintrc.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".eslintrc.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "tsconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "no agent-authored commits among the last 100",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_authored_commits",
                    "params": {
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 3",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "good",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 82,
            "inputs": {
              "primary_language": "JavaScript",
              "largest_source_bytes": 46054,
              "source_files_sampled": 84,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "JavaScript with type-check config (tsconfig.json)",
                "points": 27,
                "status": "partial",
                "details": [
                  {
                    "code": "typecheck_config_language",
                    "params": {
                      "files": "tsconfig.json",
                      "language": "JavaScript"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/84 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 84,
                      "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",
    "deps.dev does not index npm:@nemanjan00/qrp@0.7.0; advisories assessed against the repository dependency graph instead"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-21T16:52:13.105613Z",
  "schema_version": "0.23.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/n/nemanjan00/qrp.svg",
  "full_name": "nemanjan00/qrp",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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

Wie ein einzelnes Ergebnis im Gesamtregister steht: aggregierte Statistikennpm.