Öffentliches Register
Software-GesundheitsberichtSchema 0.27.0 · Metriken 1.13.0 · 2026-07-28 10:08 UTC

wso2 / open-cloud-datacenter

Open cloud datacenter initiative

HCLApache-2.0★ 7 Sterne⑂ 12 Forksseit Feb. 2026Auf GitHub ansehen ↗

wso2/open-cloud-datacenter erreicht einen Gesundheitsindex von 66 von 100 und liegt damit im Bereich Mittel. Am stärksten schneidet es bei Vitality (85/100) ab, am schwächsten bei AI Readiness (26/100). Zuletzt vor 1 Tag aktualisiert. Ein einzelner Mitwirkender trägt den Großteil der jüngsten Arbeit.

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

66
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

WSO2Organisation
1.731 Follower383 öffentliche Reposseit Dez. 2010

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

Metriken nach Kategorie

Vitalität

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

85Exzellent · 22 % des Gesamtindex
Wie die Bewertung erfolgt
36/36Push-Aktualität — letzter Push vor 1 Tagen
11.1/36Commit-Rhythmus — 16/52 Wochen mit Commits
18/18Commit-Volumen — 173 Commits im letzten Jahr
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Verwendete Eingangsdaten
commits_last_year173
human_commit_share1
days_since_last_push1
active_weeks_last_year16

Release-Disziplin

100Exzellent
Wie die Bewertung erfolgt
27/27Liefert Releases aus — 34 Releases veröffentlicht
36/36Release-Aktualität — letztes Release vor 4 Tagen
27/27Release-Rhythmus — ein Release etwa alle 6,3 Tage
0/10OpenSSF Scorecard: Signed-Releases — keine Daten
Verwendete Eingangsdaten
releases_count34
latest_release_tagterraform/v0.1.9
releases_from_tagsnein
days_since_latest_release4
mean_days_between_releases6,3
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?

58Mittel · 18 % des Gesamtindex
Wie die Bewertung erfolgt
12.6/60Stars — 7 Stars
8.7/25Forks — 12 Forks
0/15Watcher — 1 Watcher
Verwendete Eingangsdaten
forks12
stars7
watchers1
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Wie die Bewertung erfolgt
22.5/22.5README
22.5/22.5Lizenz — anerkannte Lizenz (Apache-2.0)
18/18CONTRIBUTING-Leitfaden
13.5/13.5Verhaltenskodex
7.2/7.2Issue-Vorlage
6.3/6.3PR-Vorlage
Verwendete Eingangsdaten
has_readmeja
has_licenseja
has_contributingja
has_issue_templateja
has_code_of_conductja
has_pull_request_templateja

Nachhaltigkeit & Governance

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

60Mittel · 24 % des Gesamtindex
Wie die Bewertung erfolgt
9/54Bus-Faktor — 1 Beitragende decken die Hälfte aller Commits ab
7.3/22.5Commit-Verteilung — wichtigste beitragende Person verfasste 68 % der Commits
9.5/13.5Breite der Beitragenden — 7 Beitragende
3/10OpenSSF Scorecard: Contributors — project has 1 contributing companies or organizations -- score normalized to 3
Verwendete Eingangsdaten
bus_factor1
contributors_sampled7
top_contributor_share0,677
Wie die Bewertung erfolgt
27.1/46.8Issue-Lösungsquote — 58 % der Issues geschlossen
36.1/38.3PR-Annahme — 167/177 entschiedene PRs gemergt
15/15OpenSSF Scorecard: Code-Review — all changesets reviewed
Verwendete Eingangsdaten
merged_prs167
open_issues21
closed_issues29
issue_closed_ratio0,58
closed_unmerged_prs10
Wie die Bewertung erfolgt
30/30Organisatorische Trägerschaft — im Besitz einer Organisation
0/20Verifizierte Domain
23.3/25Reichweite des Inhabers — 1.731 Follower von wso2
25/25Kontohistorie — 383 öffentliche Repos, Kontoalter ca. 15 Jahre
Verwendete Eingangsdaten
followers1.731
owner_typeOrganization
is_verified
owner_loginwso2
public_repos383
account_age_days5.697

Engineering-Qualität

Sind grundlegende Engineering- und Dokumentationspraktiken vorhanden?

58Mittel · 20 % des Gesamtindex
Wie die Bewertung erfolgt
24/24CI-Workflows — 2 Workflow(s)
0/24Tests vorhanden
0/16Linter-Konfiguration
0/9.6Pre-Commit-Hooks
0/6.4.editorconfig
12/20OpenSSF Scorecard: CI-Tests — 10 out of 15 merged PRs checked by a CI test -- score normalized to 6
Verwendete Eingangsdaten
has_cija
has_testsnein
has_editorconfignein
has_linter_confignein
has_precommit_confignein

Dokumentation

90Exzellent
Wie die Bewertung erfolgt
30/30README
25/25Dokumentationsverzeichnis
15/15Dokumentations-/Homepage-Site — https://github.com/wso2/open-cloud-datacenter
10/10Repository-Beschreibung
10/10Topics — 2 Topics
0/10Wiki
Verwendete Eingangsdaten
topicsasgardeo, choreo
has_wikinein
homepagehttps://github.com/wso2/open-cloud-datacenter
has_readmeja
has_docs_dirja
has_descriptionja

Sicherheit

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

67Mittel · 16 % des Gesamtindex
Wie die Bewertung erfolgt
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — keine Daten
1.5/2.5CI-Tests — 10 out of 15 merged PRs checked by a CI test -- score normalized to 6
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
7.5/7.5Code-Review — all changesets reviewed
0.8/2.5Contributors — project has 1 contributing companies or organizations -- score normalized to 3
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Lizenz — license file detected
7.5/7.5Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
0/5Packaging — keine Daten
5/5Pinned-Dependencies — all dependencies are pinned
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — keine Daten
7.5/7.5Token-Permissions — GitHub workflow tokens follow principle of least privilege
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Verwendete Eingangsdaten
sourceopenssf_scorecard
checks_evaluated15
scorecard_versionv5.5.0
checks_inconclusive3
scorecard_aggregate6,7
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): branch_protection, 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.

26Kritisch · 0 % des Gesamtindex
Wie die Bewertung erfolgt
0/45Agentenanweisungen — keine CLAUDE.md / AGENTS.md / Editor-Regeln
0/15Maschinenlesbare Doku (llms.txt)
40/40Lesbare Commit-Historie — 88 von 100 menschlichen Commits benennen ihre Absicht (strukturierter Betreff oder erläuternder Text)
Verwendete Eingangsdaten
has_llms_txtnein
legible_history_share0,88
agent_instruction_files
agent_instruction_max_bytes
Wie die Bewertung erfolgt
0/18Bootstrap mit einem Befehl
0/22Automatisierte Tests
0/11Lint-/Format-Konfiguration
0/11Statische Typprüfung
0/10Reproduzierbare Umgebung
10/10Belegte Agentenpraxis — 68 der letzten 100 Commits von Agenten verfasst oder ihnen zugeschrieben
0/8Automatisierte Wartung — keine automatisierten Abhängigkeits-Updates beobachtet
10/10OpenSSF Scorecard: Pinned-Dependencies — all dependencies are pinned
Verwendete Eingangsdaten
has_nixnein
has_testsnein
lockfiles
has_dockerfilenein
typed_languagenein
bootstrap_files
has_devcontainernein
has_linter_confignein
typecheck_configs
agent_commit_share0,68
toolchain_manifests
dependency_bot_commit_share0
Wie die Bewertung erfolgt
0/45Typprüfbarer Code — HCL ohne Typprüfungs-Konfiguration
0/55Handhabbare Dateigrößen — keine Quelldateien erkannt
Verwendete Eingangsdaten
primary_languageHCL
largest_source_bytes
source_files_sampled0
oversized_source_files0
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Handhabbare Dateigrößen. Die verbleibenden Gewichte wurden renormalisiert.
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

7GitHub-Sterne
7Mitwirkende
173Commits, letzte 12 Monate
1Tage seit letztem Push
34Releases
1Bus-Faktor
21offene Issues
Paket-Ökosysteme

Warnungen zur Datenerhebung

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Weitere Details

Stern- und Fork-Verlauf 0 ★ / 12 ⇿
0Sterne
12Forks
27Releases

Wann jeder Stern und Fork hinzugefügt wurde, von GitHub erfasst und nach Tagen gruppiert. Das kumulierte Wachstum steht direkt über den täglichen Zugängen, aus denen es besteht, sodass beide gegeneinander lesbar sind: stetiger organischer Zuwachs sieht ganz anders aus als ein abrupter, kurzlebiger Ausschlag. Wo dieser Unterschied messbar ist, wird er als Wachstumsauthentizität ausgewiesen.

246810121222026-022026-042026-06
Major 0Minor 8Patch 16
OpenSSF Scorecard 6.7 / 10
6.7Gesamtwert

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-28 10:08 UTC

10Binary-Artifactsno binaries found in the repo
k. A.Branch-Protectioninternal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
6CI-Tests10 out of 15 merged PRs checked by a CI test -- score normalized to 6
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
10Code-Reviewall changesets reviewed
3Contributorsproject has 1 contributing companies or organizations -- score normalized to 3
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
k. A.Packagingpackaging workflow not detected
10Pinned-Dependenciesall dependencies are pinned
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
k. A.Signed-Releasesno releases found
10Token-PermissionsGitHub workflow tokens follow principle of least privilege
10Vulnerabilities0 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": [
        "asgardeo",
        "choreo"
      ],
      "is_fork": false,
      "size_kb": 5404,
      "has_wiki": false,
      "homepage": "https://github.com/wso2/open-cloud-datacenter",
      "languages": {
        "HCL": 371036,
        "Shell": 25622,
        "Smarty": 7856,
        "Go Template": 4789
      },
      "pushed_at": "2026-07-27T09:22:47Z",
      "created_at": "2026-02-02T05:22:04Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-27T04:59:22Z",
      "description": "Open cloud datacenter initiative",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "Apache-2.0",
      "default_branch": "main",
      "license_spdx_raw": "Apache-2.0",
      "primary_language": "HCL",
      "significant_languages": [
        "HCL"
      ]
    },
    "owner": {
      "blog": "https://wso2.com",
      "name": "WSO2",
      "type": "Organization",
      "login": "wso2",
      "company": null,
      "location": "787 Castro Street, Mountain View, CA 94041",
      "followers": 1731,
      "avatar_url": "https://avatars.githubusercontent.com/u/533043?v=4",
      "created_at": "2010-12-22T08:54:38Z",
      "is_verified": null,
      "public_repos": 383,
      "account_age_days": 5697
    },
    "license": {
      "state": "standard",
      "spdx_id": "Apache-2.0",
      "raw_spdx": "Apache-2.0",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "terraform/v0.1.9",
          "kind": "other",
          "published_at": "2026-07-24T04:47:13Z"
        },
        {
          "tag": "terraform/v0.1.8",
          "kind": "other",
          "published_at": "2026-07-13T05:55:24Z"
        },
        {
          "tag": "terraform/v0.1.7",
          "kind": "other",
          "published_at": "2026-06-30T10:31:05Z"
        },
        {
          "tag": "terraform/v0.1.6",
          "kind": "other",
          "published_at": "2026-06-30T08:27:45Z"
        },
        {
          "tag": "terraform/v0.1.5",
          "kind": "other",
          "published_at": "2026-06-26T04:17:50Z"
        },
        {
          "tag": "terraform/v0.1.4",
          "kind": "other",
          "published_at": "2026-06-22T05:16:12Z"
        },
        {
          "tag": "terraform/v0.1.3",
          "kind": "other",
          "published_at": "2026-06-18T12:18:14Z"
        },
        {
          "tag": "terraform/v0.1.2",
          "kind": "other",
          "published_at": "2026-05-29T10:47:24Z"
        },
        {
          "tag": "terraform/v0.1.1",
          "kind": "other",
          "published_at": "2026-05-29T05:53:07Z"
        },
        {
          "tag": "terraform/v0.1.0",
          "kind": "other",
          "published_at": "2026-05-28T10:22:30Z"
        },
        {
          "tag": "v0.8.3",
          "kind": "patch",
          "published_at": "2026-05-25T15:02:33Z"
        },
        {
          "tag": "v0.8.2",
          "kind": "patch",
          "published_at": "2026-05-25T10:49:26Z"
        },
        {
          "tag": "v0.8.1",
          "kind": "patch",
          "published_at": "2026-05-25T05:15:42Z"
        },
        {
          "tag": "v0.8.0",
          "kind": "minor",
          "published_at": "2026-05-19T06:16:11Z"
        },
        {
          "tag": "v0.7.9",
          "kind": "patch",
          "published_at": "2026-05-18T15:11:19Z"
        },
        {
          "tag": "v0.7.8",
          "kind": "patch",
          "published_at": "2026-05-15T10:28:07Z"
        },
        {
          "tag": "v0.7.7",
          "kind": "patch",
          "published_at": "2026-05-15T04:00:00Z"
        },
        {
          "tag": "v0.7.6",
          "kind": "patch",
          "published_at": "2026-05-06T07:40:02Z"
        },
        {
          "tag": "v0.7.5",
          "kind": "patch",
          "published_at": "2026-04-28T13:55:26Z"
        },
        {
          "tag": "v0.7.4",
          "kind": "patch",
          "published_at": "2026-04-21T08:50:02Z"
        },
        {
          "tag": "v0.7.3",
          "kind": "patch",
          "published_at": "2026-04-21T05:20:12Z"
        },
        {
          "tag": "v0.7.2",
          "kind": "patch",
          "published_at": "2026-04-17T11:41:20Z"
        },
        {
          "tag": "v0.7.1",
          "kind": "patch",
          "published_at": "2026-04-16T05:55:38Z"
        },
        {
          "tag": "v0.7.0",
          "kind": "minor",
          "published_at": "2026-04-16T03:32:30Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2026-04-10T11:37:11Z"
        },
        {
          "tag": "v0.5.8",
          "kind": "patch",
          "published_at": "2026-04-09T09:33:16Z"
        },
        {
          "tag": "v0.5.7",
          "kind": "patch",
          "published_at": "2026-04-07T17:48:40Z"
        },
        {
          "tag": "v0.5.6",
          "kind": "patch",
          "published_at": "2026-04-03T05:21:06Z"
        },
        {
          "tag": "v0.5.5",
          "kind": "patch",
          "published_at": "2026-04-02T07:38:30Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2026-03-31T08:31:53Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-03-30T05:15:38Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-03-27T17:15:18Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-03-27T01:59:56Z"
        },
        {
          "tag": "v0.1.0",
          "kind": "minor",
          "published_at": "2026-03-13T04:48:11Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "25cb78eacee2ae426e3171b1113f24f1f46bb586",
          "body": null,
          "is_bot": false,
          "headline": "fix: update the precondition check and namespace quota divided nonzeoro",
          "author_name": "sathindudezoysa",
          "author_login": "sathindudezoysa",
          "committed_at": "2026-07-27T04:59:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d0f580e76be15c0348ed240a77775abae313b8e2",
          "body": null,
          "is_bot": false,
          "headline": "fix: the auto split namespaces getting near zero resources",
          "author_name": "sathindudezoysa",
          "author_login": "sathindudezoysa",
          "committed_at": "2026-07-27T04:59:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2e8d4b2c7eb567e57e4dc4852a19a373388dba49",
          "body": "…project quota limits",
          "is_bot": false,
          "headline": "fix: set default namespace limits and set unit validation check with …",
          "author_name": "sathindudezoysa",
          "author_login": "sathindudezoysa",
          "committed_at": "2026-07-27T04:59:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "73ded4dd7b2d608de63cf5ec7d2bca5db7eefefa",
          "body": null,
          "is_bot": false,
          "headline": "fix: add preflight validation for namespace resource quotas",
          "author_name": "sathindudezoysa",
          "author_login": "sathindudezoysa",
          "committed_at": "2026-07-27T04:59:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "67b3d7fe516f5af519fde5be4fd5903724e3b4d4",
          "body": "CodeRabbit reads its configuration only from the repository's default\nbranch, so base_branches must be set here on main. Without it, CodeRabbit\nuses dashboard defaults and reviews only the default branch, skipping\npull requests targeting the long-lived controlplane, terraform,\noperators, and terrafo\n[…]\nis supersedes the per-branch .coderabbit.yaml files added earlier;\nthey live on non-default branches and are therefore never read.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Enable CodeRabbit on non-default branches",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-06-26T04:58:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "142a6ae7d5d547dad9c47f6340ff82c3fe67e13d",
          "body": "The repository PR template was the generic WSO2-product template\n(Certification, Marketing, Training, FindSecurityBugs, a JDK/DB/browser\ntest matrix, ...). Almost none of it applies to this repo's products —\nthe Go control plane, the Terraform module catalog, or the operators —\nso contributors faced\n[…]\ner-repo names).\n\nGitHub serves the PR template only from the default branch, so this\nsingle file governs PRs against every branch.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Replace the legacy PR template with a lean one",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-06-11T08:12:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "73db130de358640948c900fcd78da90d03e2a4f9",
          "body": "Add short dcctl and cloud-ui VNet-creation clips to the entry-point README, laid out side by side so the two demos stay compact.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add CLI and console demo clips to the README",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-30T12:13:45Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "686e76842e7aaf3dd6cacaa7ed7e4e4fdb72e271",
          "body": "Repurpose the deprecated main branch as the repository's front door.\nGitHub renders this branch's README first, so it now opens with a\nbranch-navigation map and the OCD roadmap instead of Terraform module\nusage (which belongs on the terraform branch).\n\n  - ASCII diagram + table mapping the terraform\n[…]\nES.md for detail.\n\nmain carries no code; the previous Terraform-flavored README content\nremains available on the terraform branch.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Make main the repo entry point and roadmap",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-30T09:22:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1cbfa40f8e0ddb1b9d3d00def3abeb4bc875043d",
          "body": "Add structured issue forms under .github/ISSUE_TEMPLATE so issues\nare filed with consistent, triage-ready fields:\n\n  - 01-bug: area, description, repro steps, severity, version\n  - 02-improvement: area, current limitation, suggested improvement\n  - 03-task: area, description, related issues\n  - 04-e\n[…]\nform auto-applies its Type/* label. The broader label taxonomy\nis managed in repository settings, not in this change.\n\nCloses #127\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add GitHub issue form templates",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-30T04:56:33Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "81062c591e091a824e592e890fee17abf62f01a5",
          "body": "Four fixes from automated review:\n\n* dc-controlplane-services: cloud-ui probe path is now configurable\n  via cloudui_health_path. Default stays /healthz because the wso2\n  cloud-ui image's nginx.conf serves it; consumers that ship a stock\n  nginx-unprivileged image (no /healthz) override to /.\n\n* dc\n[…]\nts.\n\n* dc-controlplane: vm_storage_class_override is trimspace'd before\n  the empty-string check so a whitespace-only override no longer\n  wins precedence and propagates an invalid storage class name.",
          "is_bot": false,
          "headline": "Address CodeRabbit feedback on PR #107",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-27T03:23:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3f6672f2174fb2b3390c2a0f64880e98d75962b2",
          "body": "Convert the dc-controlplane RKE2 cluster to a 3-node HA layout with\nkube-vip serving the apiserver VIP, and bring the cloud-ui Deployment\n+ Service + Ingress into the dc-controlplane-services module so a\ncluster rebuild restores routing without waiting for the cloud-ui CI\nworkflow.\n\nStorage:\n\n* Crea\n[…]\ns\n  >= 1.7.\n\n* Apply trimspace() to user_data + storage_class_name override\n  checks in workloads/k8s-cluster so whitespace-only inputs fall\n  through to defaults instead of masking as real overrides.",
          "is_bot": false,
          "headline": "Add 3-node HA dc-controlplane + cloud-ui in TF",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-27T03:23:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5c3b20ae132f0230d94d15c0574fa6d30a1e68c1",
          "body": "…ole binding for_each",
          "is_bot": false,
          "headline": "Fix same network multi attachemnts + static principal+index key for r…",
          "author_name": "iamtrazy",
          "author_login": "iamtrazy",
          "committed_at": "2026-05-25T15:02:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "82661f446182d20418ed0dc33b8f79414efa644d",
          "body": null,
          "is_bot": false,
          "headline": "Fix description with uuid instead of email",
          "author_name": "iamtrazy",
          "author_login": "iamtrazy",
          "committed_at": "2026-05-25T10:48:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9a12ae12bea06d601d62cbb22681d57234ab5e90",
          "body": null,
          "is_bot": false,
          "headline": "Add user_principal_id and user_id support for tenant role bindings",
          "author_name": "iamtrazy",
          "author_login": "iamtrazy",
          "committed_at": "2026-05-25T10:48:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "63caf20827baf5d28480fc7e3295b48480216694",
          "body": null,
          "is_bot": false,
          "headline": "Address code rabbit issue regarding userdata template",
          "author_name": "iamtrazy",
          "author_login": "iamtrazy",
          "committed_at": "2026-05-25T05:14:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "67a7e1f8ea8de48947734b9b882e030b93b4c31b",
          "body": null,
          "is_bot": false,
          "headline": "Addressing code rabbit concerns",
          "author_name": "iamtrazy",
          "author_login": "iamtrazy",
          "committed_at": "2026-05-25T05:14:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f66b284a28ab000608371b64fa5b9be30e4baa9a",
          "body": "… tenants",
          "is_bot": false,
          "headline": "Feat: DHCP support for storage network + restricted images access for…",
          "author_name": "iamtrazy",
          "author_login": "iamtrazy",
          "committed_at": "2026-05-25T05:14:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "91ee1ffafd8c7ebe144867f42935f07d6d00970d",
          "body": null,
          "is_bot": false,
          "headline": "Fix: bug when using harvester cluster name instead of id",
          "author_name": "iamtrazy",
          "author_login": "iamtrazy",
          "committed_at": "2026-05-25T05:14:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fdddf3581607be9d86f9b3f177bfc4467a3cede7",
          "body": "Two fixes from the review on the OCD PR:\n\n  * main.tf: base64-decode harvester_kubeconfig_b64 before storing\n    it in the kubernetes_secret data field. The kubernetes provider\n    auto-base64-encodes whatever string is passed into data, so the\n    live Secret was holding base64-of-base64 — the webh\n[…]\nin description said\n    \"ValidatingWebhookConfiguration\" but the module creates a\n    MutatingWebhookConfiguration. Word-fix only.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Address CodeRabbit review on dc-webhook module",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-19T06:15:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f89a6ad73be61c8b9822bea0787862f968d7a2b9",
          "body": "KubeVirt admission webhook that pins VM NIC MAC addresses for tenants\nwhose workloads sit behind a kube-ovn LB. Without MAC pinning,\nKubeVirt regenerates NIC MACs on VM restart, which breaks\nsticky-by-MAC connections that depend on a stable backend.\n\nThe module covers:\n  * Deployment + Service for t\n[…]\n's\nenvironments/<env>/02-dc-webhooks layer instantiates this module\nper-environment with the appropriate kubeconfig and image SHA.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add dc-webhook module",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-19T06:15:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "49e9eab3cf988b23468eb56d84680bb1622e5ad0",
          "body": "A batch of dc-controlplane-services module changes that surfaced\nwhile verifying a real-world consumer's plan. Together they push\nevery per-environment knob out of consumer layers and into the\nmodule, so consumers only pass parameters going forward.\n\nChanges:\n\n  * Eight BFF input variables (bff_clie\n[…]\n terraform validate clean; terraform plan\nagainst a representative dev environment shows only intentional\nchanges; apply succeeds.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Land BFF, VPC, hostname, env-order and lifecycle fixes",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-19T06:15:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e58680e1cc75d709e6781363f14d67b1a353eed6",
          "body": "Introduce a self-signed RSA-4096 certificate (1-year validity) via the\nhashicorp/tls provider. The cert covers dcapi.lk.internal.wso2.com and\n*.lk.internal.wso2.com. A kubernetes.io/tls Secret (dc-api-tls) is\ncreated in dc-system and referenced by the Ingress tls block so\nnginx-ingress serves HTTPS on port 443.\n\nPort-80 rules are preserved unchanged. No new variables are required.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add TLS termination to dc-api ingress",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-19T06:15:40Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2f931c065aa19c25671ff70d21cb2c9cee377158",
          "body": null,
          "is_bot": false,
          "headline": "Introduce support to provision RKE2 clusters with dynamic harvester",
          "author_name": "iamtrazy",
          "author_login": "iamtrazy",
          "committed_at": "2026-05-18T14:37:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "04c160cf16ace509ac793dc3d4fc216cf9bedbb0",
          "body": "Bind tenant SAs to harvesterhci.io:csi-driver for RWX",
          "is_bot": false,
          "headline": "Merge pull request #98 from wso2/fix/97-csi-driver-clusterrolebinding",
          "author_name": "Deependra Ariyadewa",
          "author_login": "gnudeep",
          "committed_at": "2026-05-15T10:17:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4d942a597f9fbd92d7b667a57b63120cf672dcd6",
          "body": "PR #96 added a custom harvester-cloud-provider-rwx ClusterRole and\ntwo namespaced RoleBindings to cover networkfilesystems + longhorn\nvolumes. End-to-end testing on kasun-test-cluster after that landed\nshowed RWX PVCs went Bound but pods failed to mount with\n`Failed to get NetworkFS ...: not found`.\n[…]\n logs quiet\non already-provisioned tenants. Namespace deletion explicitly removes\nthe ClusterRoleBinding since cluster-scoped resources are not GC'd\nwhen their tenant namespace is removed.\n\nCloses #97",
          "is_bot": false,
          "headline": "Bind tenant SAs to harvesterhci.io:csi-driver for RWX",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-15T10:10:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "96db11551a95e31da82f9e4382c36e3810f89f0f",
          "body": null,
          "is_bot": false,
          "headline": "fix: typo in comment - coderabbit",
          "author_name": "iamtrazy",
          "author_login": "iamtrazy",
          "committed_at": "2026-05-15T06:50:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7593a6683d904c7d745ca1c0c36c32ed8c3dbaba",
          "body": null,
          "is_bot": false,
          "headline": "fix: remove label platform role from default namespace",
          "author_name": "iamtrazy",
          "author_login": "iamtrazy",
          "committed_at": "2026-05-15T06:50:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "416557c14cdca2d021c51ea5ee9edb48c8eb367e",
          "body": null,
          "is_bot": false,
          "headline": "fix: addrss coderabbit issues",
          "author_name": "iamtrazy",
          "author_login": "iamtrazy",
          "committed_at": "2026-05-15T06:50:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ba18d94f0b5a4612a36e2f7dec4f0f53d25f0cf0",
          "body": null,
          "is_bot": false,
          "headline": "fix: management/tenant-module quota management + vm module enhancements",
          "author_name": "iamtrazy",
          "author_login": "iamtrazy",
          "committed_at": "2026-05-15T06:50:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3dddc058ca07466f771724fd2b3c21ecf02890da",
          "body": "The harvester-csi-driver running on guest RKE2 clusters probes\nnetworkfilesystems.harvesterhci.io and volumes.longhorn.io on the\nhost Harvester cluster at startup. On a Forbidden response it\nsilently disables RWX support and only advertises SINGLE_NODE_WRITER,\nso every subsequent RWX CreateVolume fa\n[…]\nnamespace, backfills them in the init pass\nfor already-provisioned namespaces, and removes them in\non_deleted_namespace. All operations use the existing idempotent\n`kubectl apply` pattern.\n\nCloses #95",
          "is_bot": false,
          "headline": "Grant tenant cloud-provider SAs RWX RBAC on Harvester",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-15T03:59:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ed820b15c09815f0ee714dad93f970dfbb0bd2ac",
          "body": "Two findings from CodeRabbit on PR #93:\n\n1. Avoid fixed runtime files under path.module\n   The helm kubeconfig and dc-runner values files used hardcoded names\n   in the module source dir, which would collide if the module is\n   instantiated more than once or two applies share a checkout. Append\n   a\n[…]\n--values) so values containing\n   spaces don't break the command line. Destroy guards no-op via an\n   if [[ -z … ]] short-circuit.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Address CodeRabbit review on helm CLI bypass",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-10T13:04:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e5a9c5f92f047742c63b29d4f42f541ab4a5b038",
          "body": "The TF helm provider repeatedly fails when posting the ARC controller's\nrelease Secret through Rancher 2.14's cluster-router proxy with\n\"http: request body too large\" — even with public-api-body-limit and\nthe rancher Ingress proxy-body-size both raised to 50Mi/50m. The\ncluster-router has its own har\n[…]\n hashicorp/local and hashicorp/null providers in versions.tf\n  - destroy-time helm uninstall provisioners with on_failure=continue\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Bypass helm provider with helm CLI for ARC chart install",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-10T13:04:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "32a4e6c2fa7fe583335a35f60b0313d5bccb1444",
          "body": "Add PostgreSQL liveness probe so Kubernetes can restart a hung or\ndeadlocked Postgres process; readiness alone only gates traffic.\n\nAdd pod-security.kubernetes.io/enforce=privileged label to the\narc-runners namespace so dind runner pods are not silently blocked\nby PSA admission on clusters with non-default security policies.\nThe dind container mode is preserved as the runner may need Docker\nbuild capabilities in future workflows.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(dc-controlplane-services): address CodeRabbit review",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-06T05:01:32Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "33c7b3f1dca73920813fc1eade56c7c78ff684ad",
          "body": "tenant-space requires kubernetes.harvester via configuration_aliases.\ndc-controlplane must declare it in required_providers and forward it\nto module \"project\" via the providers meta-argument.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Wire kubernetes.harvester provider through dc-controlplane",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-06T05:01:32Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e25677b1e4001342ecc93abc29997f0888396532",
          "body": "Rancher injects cattle.io/status, lifecycle.cattle.io/create.namespace-auth,\nand field.cattle.io/publicEndpoints automatically. kube-vip injects\nkube-vip.io/loadbalancerIPs and kube-vip.io/vipHost on the ingress LB\nservice. Without lifecycle ignore_changes, terraform plan always shows\nthese as diffs to remove even though the apply is a no-op.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Ignore Rancher/kube-vip managed annotations on k8s resources",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-06T05:01:32Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2a1bb84cae6c42b1ca4059f07cb17073f01f1fb2",
          "body": "- Fix invalid trim() call: use trimspace() in credential_namespace\n  validation (trim() requires two args; trimspace() strips whitespace)\n- Drop namespaces from dc-api-deployer Role: namespaces is cluster-\n  scoped and silently ineffective inside a namespace-scoped Role\n- Add validation block to log_level variable: enforce the four allowed\n  values so typos fail at plan time instead of propagating to the\n  ConfigMap\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Address CodeRabbit review on dc-controlplane-services",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-06T05:01:32Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3355d9fc6a64da7642f5d4e6e2ff6787415f947b",
          "body": "dc-controlplane: wraps the RKE2 cluster, Harvester NAD, and LB\nIPPool for the DC-API control plane. Includes the kubectl patch\nthat sets selector.scope on the IPPool (workaround until the\nHarvester provider exposes the field declaratively).\n\ndc-controlplane-services: wraps all workloads that run on \n[…]\nster — PostgreSQL StatefulSet, DC-API Deployment and\nIngress, ARC controller + runner scale set, and all Kubernetes\nsecrets. Environment layers become thin callers with no inline\nresource definitions.",
          "is_bot": false,
          "headline": "Add dc-controlplane and dc-controlplane-services modules",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-06T05:01:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "61b04a55858dcba6abf9e1bd29b389f9d4c6ec6b",
          "body": "Add VM image and storage management to the bootstrap module:\nnew variables for image source URL, disk size, and storage class;\ncloud-init template extended with additional packages and disk\nsetup; outputs expose the provisioned image ID for downstream\nlayers.\n\nImprove the namespace-credential-provisioner reconcile script to\nhandle edge cases and surface clearer error messages on failure.",
          "is_bot": false,
          "headline": "Extend bootstrap and reconcile modules",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-06T05:01:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fa14460d931f4d5fd87646c09d3fc05f91739cd9",
          "body": "Cloud-init user_data carries SSH authorized keys, bootstrap tokens,\nand other credentials. Without sensitive = true, the value is emitted\nin plain text during terraform plan and stored without redaction in\nstate.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Mark user_data variable as sensitive",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-05T16:40:47Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "87996c727af13b9205b5229a2dd9a4e5d0ccb7c7",
          "body": "Wraps tenant-space + workloads/k8s-cluster into a single opinionated\nmodule for provisioning a Rancher project, its DC-API VM namespace,\nthe Harvester NAD and IPPool for that namespace, and a managed RKE2\ncluster with the Harvester cloud provider attached. Consumers pass\nmachine pool definitions and\n[…]\nter\nLonghorn-backed VM disks; without them, both controllers lose their\nleases and crashloop every ~80 seconds during initial cluster\nbring-up.\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add dc-controlplane management module",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-05T16:40:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "673126d1e4266ad205622b5015efcf55b5486909",
          "body": "Two reconciler hardening fixes for the namespace-credential-provisioner:\n\n1. Cluster watch race with namespace watch\n   When a cluster is created in close succession with its tenant\n   namespace, the cluster event can arrive before the namespace watch\n   has minted the cloud-provider ServiceAccount \n[…]\nredentials provisioned. Skip them in both the watch\n   loop and the reconciler-restart sweep, alongside the existing\n   network-namespace skip.\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Wait for SA token and skip infrastructure namespaces",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-05T16:27:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "acde3cbe79c2eb4ee3e21564e8f2668873241236",
          "body": "Move cloud image download into the module via image_url,\nimage_name, and image_display_name variables. ubuntu_image_id\nis kept as an optional brownfield escape hatch when the image\nalready exists in the cluster.\n\nAdd storage class management: creates harvester-longhorn-2r as\nthe cluster default (con\n[…]\nfy the server certificate,\nand add a wait loop for the supervisor port before joining.\nAdd LB port 9345 listener for RKE2 HA supervisor join.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(bootstrap): add image and storage management",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-04T06:57:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "bdf2c0fe0646b1a4ab1474a853400678ad9181a2",
          "body": "Add validation block to credential_namespace to reject empty or\nwhitespace-only values before plan/apply.\n\nAdd check block for coredns_patch_vars_set so that setting\npatch_coredns = true without both rancher_lb_ip and rancher_hostname\nfails early with a clear error instead of silently rendering an empty\nhosts entry in the CoreDNS Corefile.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Address CodeRabbit review on harvester-integration module",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-04T06:57:59Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "588e6a2b5b1da653e5cf8b2c6334659dcbab8f17",
          "body": "The SA and token Secret for the cloud credential were hardcoded to\nkube-system. Brownfield deployments that created these resources in\na different namespace (e.g. default) would see a forced replacement\non every apply due to the namespace drift.\n\nExpose credential_namespace (default: kube-system) so consumers can\npin the value to match their existing state.\n\nCloses #82",
          "is_bot": false,
          "headline": "Add credential_namespace variable to harvester-integration",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-05-04T06:57:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "291c8a35140588d2f23ada81f5b18074fe4dfaa9",
          "body": "Kubernetes auto-adds kubernetes.io/metadata.name to every namespace\non creation. The rancher2 provider does not manage this label but\ndetects it as drift, producing a spurious remove-label diff on every\nplan run.\n\nAdding it to lifecycle ignore_changes on both rancher2_namespace.this\nand rancher2_namespace.network suppresses the noise permanently without\naffecting any managed label.\n\nCloses #79\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Ignore kubernetes.io/metadata.name label drift in namespaces",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-28T13:55:01Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "567f84d1e94bf0c4e1ac399bca940aa685e31606",
          "body": "Replace the fine-grained per-API-group rules with a wildcard grant\ncovering all Kubernetes resources, subresources (*/scale, pods/exec,\npods/log), and non-resource URLs. This is the same permission set as\nthe built-in cluster-admin ClusterRole.\n\nRancher cluster lifecycle operations (delete, reconfigure) are\nenforced at the Rancher management-plane level independently of\nthis Kubernetes RBAC role.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Broaden cluster-contributor to full cluster-admin-equivalent access",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-28T13:37:26Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9590fea384401f2ae1749c5198ccf5e5061c2a87",
          "body": "Introduces a cluster-scoped role template that grants SRE teams full\nkubectl operational access to downstream RKE2 clusters without\nRancher management-plane permissions. Members can deploy, scale,\nexec, stream logs, and manage workload config but cannot delete or\nreconfigure the cluster from the Ran\n[…]\nility. Explicitly excludes node mutation, RBAC\nmutation, and namespace lifecycle operations, which remain with the\nplatform team.\n\nCloses #78\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add cluster-contributor role for SRE operational access",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-28T13:37:26Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "184e145c75448745cc534ff60ffbc39ba5f137d4",
          "body": "Introduces the project-contributor RoleTemplate for Rancher projects.\nThe role allows namespace and project member management (full CRUD on\nnamespaces and projectroletemplatebindings), read-only access to the\nproject resource itself to prevent quota modification or deletion, and\nread-only visibility\n[…]\nand Claude Code artefacts to .gitignore\nto keep module-level lock files and personal editor configs out of the\nmodule repository.\n\nCloses #75\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add project-contributor role with batch workload access",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-28T11:26:42Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a94b203affc3058fb9bed814e6d2dd50efe1520c",
          "body": null,
          "is_bot": false,
          "headline": "feat(vm): add brownfield override variables",
          "author_name": "Akini Karunarathne",
          "author_login": "Akini98",
          "committed_at": "2026-04-28T05:17:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "974efa83d62f6d94cc7bae1ef57768f09c011ac0",
          "body": "Adds README for namespace-credential-provisioner documenting the\nmodule's purpose, deployment sequence relative to harvester-integration\nand tenant-space, and usage example.\n\nUpdates docs/architecture.md:\n- Adds namespace-credential-provisioner (Phase 2e) to the dependency\n  graph between rbac (Phas\n[…]\nxes harvester-cloud-credential README: replaces non-existent\nkubeconfig output entry with the actual service_account_name output.\n\nCloses #73\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Bundle namespace-credential-provisioner into management setup phase",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-28T05:07:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b61386fee27c4a4831a86d529de1151e56d2e3a5",
          "body": "Extends the namespace-credential-provisioner reconciler to create\nper-namespace VM-access credentials alongside cloud-provider creds:\n  - SA harvester-vm-access-<ns> with harvesterhci.io:edit RoleBinding\n    in the tenant namespace, edit in harvester-public for shared images\n  - harvester-vm-kubecon\n[…]\n.\n\nUpdates READMEs for vm, k8s-cluster, and harvester-cloud-credential\nmodules with inline kubeconfig pattern and usage examples.\n\nCloses #71\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add VM access kubeconfig provisioning and consumer onboarding docs",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-27T10:00:57Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4ad8797a693a1f98a057ddb00d69208696b6c422",
          "body": "On init, check whether the SA token secret already exists before\ncalling on_added_namespace. Distinguishes NotFound (provision) from\ntransient kubectl errors (skip with warning, retry on watch event).\nOnly marks the namespace processed when provisioning succeeds.\n\nAlso adds:\n- vlan_id uniqueness val\n[…]\n4)\n- harvester_api_server variable to tenant-space for VM access kubeconfig\n- Removes \"or empty\" wording from vlan_id description\n\nCloses #69\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Skip already-provisioned namespaces on reconciler restart",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-27T04:57:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9d502de9f7e3617fc7db4a81bf51289295cc83a6",
          "body": "Guard against an empty string being passed as the network namespace\noverride — coalesce accepts \"\" as truthy so validation is the right\nfix, consistent with other string variables in this module.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add non-empty validation for network_namespace_name",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-21T08:49:39Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "42349d5e50d56fa96ebc0b9307617120ffad9584",
          "body": "- vlan_id is now list(number); each entry creates a harvester_network\n  via for_each so networks can be added/removed independently\n- Auto-route path (no vyos_endpoint) supports multiple VLANs; VyOS\n  path still requires exactly one VLAN (precondition enforced)\n- network_namespace_name override lets\n[…]\nwnfield\n  harvester_network resources with non-default names\n- network_name output replaced by network_names map keyed by VLAN ID\n\nCloses #67\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Support multiple VLAN networks per tenant space",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-21T08:49:39Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "71d351dd66dd4f73e9803f1c0e2ac8cf361fe41c",
          "body": null,
          "is_bot": false,
          "headline": "Address CodeRabbit review",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-21T06:39:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "75b04a8c678e085f9071b58e2b50f78c76313f18",
          "body": null,
          "is_bot": false,
          "headline": "Add flag to control default namespace creation",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-21T06:39:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "72cb731b6d05a75a957ba74445f2ef02de825d3c",
          "body": "Checkov CKV_K8S_21 flags resources placed in the default namespace.\nMove the rancher-cloud-credential ServiceAccount and its token Secret\nto kube-system, which is the conventional namespace for infrastructure-\nlevel service accounts.\n\nThe ClusterRoleBinding subject namespace reference is derived from\nthe ServiceAccount metadata, so no separate change is needed there.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Move cloud credential SA and token to kube-system namespace",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-21T05:19:18Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "83033f835e512b6124ca68826eaa579fbde202c9",
          "body": "Exposes the Harvester Kubernetes API server URL extracted from\nthe kubeconfig so downstream layers can pass it to the\nharvester-cloud-credential module without hardcoding the VIP.\n\nMarked sensitive because it derives from the kubeconfig input.\nReturns null when create_cloud_credential = false.\n\nCloses #57\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add harvester_api_server output to harvester-integration module",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-21T05:19:18Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c64fe870fddfc18f5d0154d31d14b0c479577c67",
          "body": "When vlan_id is set without vyos_endpoint, use route_mode=auto so the\nupstream router (DigiOps / physical switch) handles DHCP and routing.\nThe manual route_mode with deterministic 10.0.0.0/8 subnetting is now\ngated on vyos_endpoint being set.\n\n- Add use_vyos local; gate tenant_subnet/tenant_gateway\n[…]\ntional\n- Relax vlan_id validation from >= 1000 to valid 802.1Q range (1–4094)\n- Update subnet_cidr/gateway_ip output descriptions (VyOS-only)\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Support auto route mode for non-VyOS VLAN networks in tenant-space",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-21T05:05:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f1b43b93d109df80912a8a6cf2f78981b017d2f5",
          "body": "- tenant-space/variables.tf: vyos_endpoint and vyos_api_key were\n  declared twice after the create_network_namespace commit merged\n  them in alongside pre-existing copies from the decouple branch.\n- vyos-tenant/outputs.tf: subnet_cidr output was declared twice,\n  once as the canonical output and once as an alias added earlier.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Remove duplicate variable and output declarations",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-21T05:05:31Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "730ce9b918eea20a154d8da24fd47fd264a89b05",
          "body": "The vyos provider was listed unconditionally, forcing every caller to\nconfigure it even when vyos_endpoint is null and no VyOS resources are\ncreated. The provider is only needed by the child vyos-tenant module,\nwhich declares its own required_providers — Terraform picks it up\ntransitively without it being declared in the parent.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Remove vyos from tenant-space required_providers",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-21T05:05:31Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "59dbfb577ec59bcfaaac587d98a82d0a12439386",
          "body": "tenant-space:\n- Add create_network_namespace (bool, default false) to pre-provision\n  the <project_name>-net namespace before a VLAN is assigned. The\n  network namespace is created when create_network_namespace = true OR\n  when vlan_id is set (backward compat: existing callers with vlan_id\n  are una\n[…]\narvester_network moving from the vyos-tenant child module address to\nthe tenant-space address — a targeted import is required on first apply.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add create_network_namespace flag; fix harvester_network ownership",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-21T05:05:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ff093ce961533f2e57752dec7d51725779e7c4f6",
          "body": "Previously, setting vlan_id always invoked the vyos-tenant module,\nmaking it impossible to create a network namespace + harvester_network\nwithout VyOS config calls.\n\nNow vlan_id and vyos_endpoint are independent gates:\n- vlan_id only: creates network namespace + harvester_network (for\n  environments\n[…]\no the network\nnamespace (used by the namespace credential provisioner), and fixes\na pre-existing missing newline in variables.tf.\n\nCloses #63\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Decouple VyOS integration from network namespace in tenant-space",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-21T05:05:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5c35e894cfdcdecb8049b6db46c00c23ef380fd5",
          "body": "- Change harvesterconfig Secret type from non-standard \"secret\" to\n  \"Opaque\" to match Kubernetes convention and avoid potential\n  filtering by Rancher controllers\n- Skip Terminating namespaces in the initial pass by reading\n  deletionTimestamp from the jq pipeline; prevents failed kubectl\n  apply calls against namespaces in the process of being deleted\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix secret type and skip Terminating namespaces at startup",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-21T04:39:16Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "47e427aed0b19e0e34ec65f1d8b09a87747c4845",
          "body": "- Remove token-presence early return in on_added_namespace so all\n  SA/RBAC resources are re-applied idempotently on every ADDED event,\n  repairing drift caused by deleted ServiceAccounts or RoleBindings\n- Mark namespaces/clusters as processed only after the handler\n  succeeds; transient failures (n\n[…]\nt\n- Replace `func || true` with `func || log \"...exited with error\"` so\n  watch-loop failures are visible in logs instead of silently ignored\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix reconciler idempotency and error handling",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-21T04:39:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c19f412ec899b43421e2b319858d67515406baeb",
          "body": "The net-read RoleBinding creation was failing with:\n  user ... is attempting to grant RBAC permissions not currently held\n\nKubernetes RBAC escalation prevention blocks a subject from granting\npermissions it doesn't hold. Fix by adding the escalate verb to the\nrolebindings rule — the approved mechani\n[…]\nrovider (cloudprovider\nSA binding) and view (net-read binding). Restricting to a single name\nprevented the second binding from being created.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add escalate verb and broaden clusterroles bind in provisioner RBAC",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-21T04:39:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "00b8461e10f9a18ee9cd63e7778bec083acc54be",
          "body": "Replace the substring kubeconfig body search with an exact annotation\nmatch when finding harvesterconfig-* secrets to delete on namespace\nremoval. The previous contains(\"namespace: \" + $ns) check would match\nprefix namespaces (e.g. \"team-a\" incorrectly matching \"team-a2\").\n\nAdd platform.wso2.com/cre\n[…]\nsource-namespace annotation to the\nsecret at creation time so the deletion path can do a precise lookup\nwithout decoding the kubeconfig body.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix stale-secret cleanup to use exact annotation match",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-21T04:39:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ca59d867ad991607ba3a40a48778b16931f9ad5e",
          "body": "Adds modules/management/namespace-credential-provisioner — a Kubernetes\nDeployment that runs a reconciler script to automate harvesterconfig\nsecret management across tenant lifecycle events.\n\nWhat it does:\n- Watches Harvester namespaces; on new tenant namespace provisions a\n  ServiceAccount (harvest\n[…]\ne includes configmaps get (kube-root-ca.crt for CA\ncert), patch/update on serviceaccounts/secrets/rolebindings for\nkubectl apply idempotency.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add namespace credential provisioner module",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-21T04:39:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "034f12ec0b6bacf59fb7c17f33ae6ffbd1d72022",
          "body": "Downstream layers that provision RKE2 clusters need the\ncattle-global-data:cc-xxxx ID for the k8s-cluster module.\nReturns null when create_cloud_credential = false so brownfield\nenvironments that manage the credential outside Terraform are\nnot affected.\n\nCloses #55\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Expose cloud_credential_id from harvester-integration module",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-17T11:37:40Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "db8282a7afd73e12f907ee570c219660fbfe78a3",
          "body": "Callers can now pass node_password, ssh_authorized_keys, and\nntp_server instead of composing raw cloud-init YAML. The module\ngenerates a full RKE2-ready cloud-init (packages, IPVS kernel\nmodules, sysctl, NTP) via templatefile.\n\nuser_data remains a full override. ssh_user (existing variable)\nis reused as the username in the generated chpasswd.list entry.\n\nCloses #53\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add node_password and ssh_authorized_keys to k8s-cluster module",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-17T11:37:20Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9ca3818c6f0b8a7821153ac37e346c811531ebd1",
          "body": "Callers can now pass `password`, `ssh_authorized_keys`, and\n`default_user` instead of composing raw cloud-init YAML. The\nmodule generates a correct chpasswd.list-based cloud-init using\na templatefile, avoiding heredoc indentation pitfalls.\n\n`user_data` remains a full override — when set, the new\nvariables are ignored entirely. `default_user` defaults to\n\"ubuntu\" but can be changed for non-Ubuntu images.\n\nCloses #53\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add password and ssh_authorized_keys to vm module",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-17T11:37:20Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e8f209f14e8d1e5552a6e628168666ff7aec9471",
          "body": "The dynamic resource_quota on rancher2_namespace.this was wrong:\nit assigned the full project quota to every namespace, which would\nprevent users from adding more namespaces and causes double\nenforcement. The project-level quota is already the ceiling —\nRancher enforces it across all namespaces without a per-namespace\nResourceQuota object. Remove the block and document why.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Revert per-namespace quota block from tenant-space module",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-16T05:55:07Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "dcf23cf9bcad9614b28bb7a36e779d5247bb5254",
          "body": "The vyos-tenant submodule requires both variables but tenant-space\nwas not declaring or passing them. Add vyos_endpoint and\nvyos_api_key as optional (default null) variables to tenant-space\nand pass them through to the module \"vyos_tenant\" call.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Thread vyos_endpoint and vyos_api_key through tenant-space module",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-16T05:55:07Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "91a445e1ecb8a08736a61d399f702dd9723af67e",
          "body": "Rancher does not reliably propagate namespace_default_limit to\nnamespaces created via the API. Without an explicit resource_quota\nblock on the rancher2_namespace resource, the namespace ResourceQuota\ncan end up with limits.cpu=0 / limits.memory=0, which blocks all\nVM creation with \"exceeded quota\".\n\n[…]\nat\nmirrors the project's per-namespace limits whenever cpu_limit is set.\n\nAlso fix a cosmetic syntax error (missing newline) in variables.tf.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Explicitly set namespace resource quota in tenant-space module",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-16T05:55:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "066762c17b683aac7f5d2d10cf563d549ffbb93a",
          "body": "Move network-attachment-definitions read from vm-creator (cluster)\nto vm-manager (project). Keeping it cluster-scoped let tenants list\nNADs in all namespaces, exposing other tenants' networks and platform\ninfrastructure in the VM creation network dropdown.\n\nWith it project-scoped, the Harvester UI o\n[…]\nrom\nthe tenant's own project namespaces (e.g. choreo-sre-net) — no\nvisibility into default/, harvester-public/, or other tenants.\n\nCloses #51\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Scope network visibility to tenant project in RBAC roles",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-16T05:55:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b05d5efb986238245e88cf19478ed6ea784ec9a9",
          "body": "tenant-space/outputs.tf references module.vyos_tenant[0].subnet_cidr\nbut the vyos-tenant module only exposed subnet. Add subnet_cidr as\nan alias so both names resolve correctly.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add subnet_cidr output alias to vyos-tenant module",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-16T05:54:47Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c28714385193a817c99ae3d4a87996ba9e03d465",
          "body": "Rewrite all vyos_config_block_tree resources to use the\nhiranadikari/vyos provider schema:\n- path: list of strings (was a space-separated string)\n- section: jsonencode({...}) (was configs = {key = value} map)\n\nMerge the separate dhcp_dns resource into the main dhcp section —\ndns_servers is now a JSO\n[…]\nider source from thomasfinstad/vyos-rolling (~> 19.0)\nto hiranadikari/vyos (~> 0.1). Remove unused locals: vif_path,\nsubnet_base.\n\nCloses #49\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix vyos-tenant module for hiranadikari/vyos provider schema",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-16T05:54:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b4d101aad7a8d62d870caabe5704150b93e55717",
          "body": "Change thomasfinstad/vyos-rolling (~> 19.0) to hiranadikari/vyos\n(~> 0.1) — the published provider that exposes the\nvyos_config_block_tree resource used in this module. Without this,\nterraform init pulls the wrong provider and plan fails with\n\"does not support resource type vyos_config_block_tree\".\n\nCloses #49\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix vyos provider source in vyos-tenant module",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-16T05:54:47Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "fd74aae8bfec8b770f59c4c9c73ae5e9cf4a2983",
          "body": "- vlan_id (optional): when set, creates a <project_name>-net network\n  namespace and calls the vyos-tenant submodule to provision the\n  Harvester NAD, VyOS vif sub-interface, DHCP server, and NAT rule.\n  Adds harvester and vyos to required_providers.\n\n- namespaces defaults to null, resolved to [proj\n[…]\ncenter uses a different name.\n\n- network_name, subnet_cidr, gateway_ip, network_namespace outputs\n  added (all null when vlan_id is not set).\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Extend tenant-space with optional VyOS VLAN network integration",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-12T04:09:33Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "91f449c433465cd2cd9bf9b52e4e0824d6abfc9b",
          "body": "Narrow lifecycle ignore_changes from [disk] to [disk[0].auto_delete]\nso only the specific Harvester-caused drift (auto_delete flag flip on\nrootdisk post-CDROM removal) is suppressed; other disk attributes\nremain Terraform-managed.\n\nAdd validation block to management_network_name enforcing null or\nthe required namespace/name format, catching malformed values at\nplan time rather than failing at provider apply.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Address CodeRabbit review on vyos bootstrap module",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-12T04:09:07Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2c21e3203c2a26259a6015b56ff2745779430500",
          "body": "- Optional eth2 NIC via management_network_name variable. When set,\n  attaches VyOS to the Harvester management cluster network (mgmt-br)\n  so in-cluster processes (DHCP reconciler pods with hostNetwork) can\n  reach the VyOS HTTPS API at a stable IP without routing through the\n  external uplink inte\n[…]\nM resource prevents a\n  perpetual diff caused by Harvester flipping auto_delete on the\n  rootdisk after the CDROM is removed on second apply.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add optional management NIC and fix disk lifecycle in vyos module",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-12T04:09:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "24192322e7c5330fb91fb206fadf1737ef6ef9ea",
          "body": "The provider is published at registry.terraform.io/hiranadikari/asgardeo.\nThe previous source 'asgardeo/asgardeo' does not exist on the registry\nand would fail on terraform init without a dev_override.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix asgardeo provider source to hiranadikari/asgardeo",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-11T17:18:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "7613d4dc88affee6595e21ee7802e30be63510ba",
          "body": "cloud-init runs only on first boot. Any subsequent changes to\nuser_data (template reformats, key rotation, etc.) have no\nruntime effect but previously triggered an in-place VM restart.\n\nCloses #41\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Ignore cloudinit changes after VM is provisioned",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-11T16:51:45Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "39a5f2fd4f571dc504d5b861297d5f816b67e038",
          "body": "Use a template for-loop instead of indent()/join()/formatlist()\nto emit ssh_authorized_keys list items — the previous expression\nproduced 8 spaces of leading whitespace (4 from the heredoc + 6\nfrom indent), which broke cloud-init YAML parsing.\n\nAdd prose note and example variable declarations to make clear\nthat vm_password and ssh_authorized_keys are root-module variables,\nnot inputs to this module.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix cloud-init SSH key indentation and clarify variable scope",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-10T11:36:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1cc0c2a204ab1bb8c573634ecfe0659621cedc76",
          "body": "Replace the generic nginx example with a validated pattern that avoids\ntwo known issues on Ubuntu 22.04 with cloud-init 25.x:\n\n- Do not use package_update: true — it races with apt-daily timers on\n  first boot, causing silent package install failures\n- Do not use a users: block with password: — clou\n[…]\n Notes entry explaining that qemu-guest-agent is required for\nHarvester to display the guest IP for VMs on private VLAN networks.\n\nCloses #39\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Update workloads/vm README with correct cloud-init pattern",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-10T11:36:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e35b6ab0a867170a0cbb5fbbc5f7e1d7deac4ea3",
          "body": "Individual range bounds (2–510) were already validated per-variable.\nAdd a check block to enforce start_offset <= end_offset, which cannot\nbe expressed in variable validation blocks without Terraform >= 1.9.\n\nUsing check block (Terraform >= 1.5, already required) keeps the\nrequired_version constraint unchanged.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add cross-variable DHCP offset order validation",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-10T11:36:02Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e536225e0d8786938b370d50dd3e3007b2880c22",
          "body": "- bootstrap/vyos/main.tf: explicitly state the route_cidr as\n  10.0.0.0/8 in the eth1 trunk comment so it matches the resource\n- tenant-space/variables.tf: soften \"At minimum, provide one\n  namespace named after the project\" to \"It is recommended\" to\n  match the actual (non-enforced) behaviour\n- vyo\n[…]\nues for consumers\n- vyos-tenant/versions.tf: correct vyos-rolling version constraint\n  from ~> 19.1 (non-existent) to ~> 19.0 (latest series)\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Address remaining CodeRabbit comments on PR #38",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-10T11:36:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d3de050aaaf68cbbc9f02da7f50eceafc4a9ef28",
          "body": "- Remove unused rancher2 provider from versions.tf; the module\n  only uses harvester and vyos providers\n- Add validation blocks to dhcp_range_start_offset and\n  dhcp_range_end_offset: valid range 2–510, offset 1 is reserved\n  for the gateway IP\n- Consolidate dhcp_dns into a single vyos_config_block_\n[…]\n is now a unique config key\n- Replace 0.0.0.0/0 in the API setup comment with\n  <management_cidr> placeholder to avoid suggesting open access\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Address CodeRabbit review on vyos-tenant module",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-10T11:36:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7e98e3dc3759e6a10a01d4c01ace649b9b09f30a",
          "body": "Replace DigiOps references and WSO2-specific defaults with generic\nterminology so the modules are usable by any Harvester operator.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Remove internal naming from VyOS module comments and variables",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-10T11:36:02Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0eebf94162268bece096b1ac127f5f199bafcac1",
          "body": "Introduces two modules for deploying and configuring a VyOS VM as a\nprivate cloud gateway on Harvester, enabling per-tenant VLAN isolation,\nDHCP, NAT, and internet egress without DigiOps involvement per tenant.\n\nmodules/bootstrap/vyos/\n- Deploys VyOS VM with two NICs: eth0 (DigiOps uplink) and eth1 \n[…]\n NAT rules, and harvester_network resources\n- Creates harvester_network with vlan_id matching the VyOS vif tag exactly\n\nCloses #77\nCloses #78\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add VyOS multi-tenant gateway modules",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-10T11:36:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f6324ee06991f1f97db53d3a70277ea3527ebce4",
          "body": "- Rename duplicate Phase 4 (Asgardeo Auth) to Phase 5 to resolve\n  numbering conflict with the Workloads phase added in this PR\n- Update Provider Dependency Summary table: replace stale ~> 0.6.0 /\n  ~> 3.0 / ~> 8.0.0 constraints with versions from actual module\n  versions.tf files (harvester ~> 1.7,\n[…]\nasgardeo ~> 0.1)\n- Fix storage example source: update from wso2-enterprise org and\n  stale v0.1.0 tag to wso2/open-cloud-datacenter at v0.5.8\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix CodeRabbit review comments on architecture docs",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-10T11:35:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "afd0a0fef5e62d2ce503cdceda18e52f9e108010",
          "body": "…odules and fix broken references",
          "is_bot": false,
          "headline": "Update README and architecture documentation to include all missing m…",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-10T11:35:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "54757306ee37eb48c45418fbeca409654cb9d307",
          "body": "Add three new role templates to the cluster-roles module to extend the\nDC platform RBAC framework:\n\nvm-creator (cluster): minimum cluster-level read access for tenants who\ncreate VMs — VM images, network attachment definitions, and SSH keypairs\nlive outside project namespaces so project-owner alone \n[…]\nnamed after the project, ensuring\nthe namespace dropdown is populated in the Rancher/Harvester VM and RKE2\ncluster creation flow.\n\nCloses #36\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add vm-creator, vm-operator, and cluster-operator role templates",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-10T08:02:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "06c962f3941acfd573e7ac0b4a18c1def5712a29",
          "body": null,
          "is_bot": false,
          "headline": "Add optional scheduled backup support to vm module",
          "author_name": "Akini Karunarathne",
          "author_login": "Akini98",
          "committed_at": "2026-04-09T09:32:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9440407a4bbbaf140629d3a17559a62318e8e94d",
          "body": "…rs[0]\n\nFollow Kubernetes kubeconfig resolution semantics: parse current-context,\nfind the matching context, extract its cluster reference, then look up the\ncluster entry by name. This correctly handles multi-cluster kubeconfigs\nwhere the target cluster may not be the first entry.\n\nAlso add a check block validating that certificate-authority-data (embedded\nCA) is present, since file-path certificate-authority references are not\nsupported when building the portable SA kubeconfig for Rancher.",
          "is_bot": false,
          "headline": "fix: resolve kubeconfig cluster via current-context instead of cluste…",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-07T17:47:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cd4844bfd5d5ac9b62b828ac5536677346039fae",
          "body": "The Harvester UI kubeconfig embeds a Rancher-internal token that\nstandalone Rancher cannot validate against the Harvester API,\ncausing 500 errors on cloud credential creation. Generate a\ndedicated Kubernetes ServiceAccount token instead so Harvester\ncan authenticate the credential directly.\n\nAlso ad\n[…]\ne management interface.\n\nAll new SA resources are gated on create_cloud_credential to\npreserve brownfield environments (lk prod).\n\nCloses #32\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix Harvester cloud credential and IP pool VLAN selector",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-07T17:47:28Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b60b4566c3fe08db6f39ef51d0cddc6848173f34",
          "body": "- Use double quotes for chpasswd entry in cloud-init template so\n  passwords containing single quotes do not break YAML parsing\n- Gate rancher2_secret_v2.registry_auth on manage_rke_config so\n  secrets are not created for brownfield clusters that never reference\n  them\n- Tighten registries validation: require non-empty hostname (unique,\n  case-insensitive), enforce non-empty username/password when set, and\n  enforce non-empty auth_config_secret_name when set",
          "is_bot": false,
          "headline": "Address CodeRabbit review comments on PR #31",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-07T17:22:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6bc5ec54e28f6f66d481f49ad1b593d32265c500",
          "body": "regexreplace() is not available in all Terraform-compatible\nruntimes. replace() with /pattern/ regex delimiter achieves\nthe same result and has broader compatibility.",
          "is_bot": false,
          "headline": "Use replace() instead of regexreplace() for secret name",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-07T17:22:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c1d668dcd357568bdbbf520ba4d1de5d765cf581",
          "body": "- Reflect current API (provider ~> 13.1, terraform >= 1.7)\n- Document all current inputs including machine_pools fields,\n  registries (inline credentials vs brownfield secret), and etcd_s3\n- Add registry credential modes reference table and usage examples\n- Add outputs table and brownfield import instructions\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Update k8s-cluster module README",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-07T17:22:34Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5364817cbfe0650d0d13a4415625e1c1e41995f4",
          "body": "- Quote password in chpasswd list to handle special characters\n- Replace ping connectivity check with curl — more reliable through\n  firewalls that block ICMP\n- Redirect deployment echo messages to /dev/console so progress is\n  visible in Harvester VM serial console during boot, not only in\n  /var/log/rancher-install.log\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Improve cloud-init bootstrap script reliability",
          "author_name": "HiranAdikari",
          "author_login": "HiranAdikari",
          "committed_at": "2026-04-07T17:22:34Z",
          "body_truncated": false,
          "is_coding_agent": true
        }
      ],
      "releases_count": 34,
      "commits_last_year": 173,
      "latest_release_at": "2026-07-24T04:47:13Z",
      "latest_release_tag": "terraform/v0.1.9",
      "releases_from_tags": false,
      "days_since_last_push": 1,
      "active_weeks_last_year": 16,
      "days_since_latest_release": 4,
      "mean_days_between_releases": 6.3
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 87,
      "has_issue_template": true,
      "has_code_of_conduct": true,
      "has_pull_request_template": true
    },
    "ecosystem": {
      "packages": []
    },
    "popularity": {
      "forks": 12,
      "stars": 7,
      "watchers": 1,
      "fork_history": {
        "days": [
          {
            "date": "2026-02-25",
            "count": 2
          },
          {
            "date": "2026-03-03",
            "count": 1
          },
          {
            "date": "2026-03-31",
            "count": 2
          },
          {
            "date": "2026-04-22",
            "count": 1
          },
          {
            "date": "2026-05-13",
            "count": 1
          },
          {
            "date": "2026-05-28",
            "count": 1
          },
          {
            "date": "2026-06-02",
            "count": 1
          },
          {
            "date": "2026-06-10",
            "count": 1
          },
          {
            "date": "2026-06-11",
            "count": 1
          },
          {
            "date": "2026-06-12",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 12,
        "total_forks": 12
      },
      "star_history": null,
      "open_issues_and_prs": 26
    },
    "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": [],
      "toolchain_manifests": [],
      "largest_source_bytes": null,
      "source_files_sampled": 0,
      "oversized_source_files": 0,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [],
      "dependencies": [],
      "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": 5,
        "merged_prs": 167,
        "open_issues": 21,
        "closed_ratio": 0.58,
        "closed_issues": 29,
        "closed_unmerged_prs": 10
      },
      "bus_factor": 1,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "HiranAdikari",
          "commits": 109,
          "avatar_url": "https://avatars.githubusercontent.com/u/13211597?v=4"
        },
        {
          "type": "User",
          "login": "VimukthiPerera",
          "commits": 30,
          "avatar_url": "https://avatars.githubusercontent.com/u/15902071?v=4"
        },
        {
          "type": "User",
          "login": "iamtrazy",
          "commits": 12,
          "avatar_url": "https://avatars.githubusercontent.com/u/73080739?v=4"
        },
        {
          "type": "User",
          "login": "sathindudezoysa",
          "commits": 4,
          "avatar_url": "https://avatars.githubusercontent.com/u/59018854?v=4"
        },
        {
          "type": "User",
          "login": "git-repo-creation-app",
          "commits": 3,
          "avatar_url": "https://avatars.githubusercontent.com/u/216828136?v=4"
        },
        {
          "type": "User",
          "login": "Akini98",
          "commits": 2,
          "avatar_url": "https://avatars.githubusercontent.com/u/116425440?v=4"
        },
        {
          "type": "User",
          "login": "gnudeep",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/155502?v=4"
        }
      ],
      "contributors_sampled": 7,
      "top_contributor_share": 0.677
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": false,
      "ci_workflows": [
        "linter.yml",
        "terraform-scan.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": null,
            "reason": "internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 6,
            "reason": "10 out of 15 merged PRs checked by a CI test -- score normalized to 6",
            "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": 10,
            "reason": "all changesets reviewed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 3,
            "reason": "project has 1 contributing companies or organizations -- score normalized to 3",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 10,
            "reason": "all dependencies are pinned",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 10,
            "reason": "GitHub workflow tokens follow principle of least privilege",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 10,
            "reason": "0 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "25cb78eacee2ae426e3171b1113f24f1f46bb586",
        "ran_at": "2026-07-28T10:08:20Z",
        "aggregate_score": 6.7,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-27T04:59:02Z",
      "oldest_open_prs": [
        {
          "number": 21,
          "created_at": "2026-03-05T11:59:06Z",
          "last_comment_at": "2026-03-05T11:59:21Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 150,
          "created_at": "2026-06-11T04:57:42Z",
          "last_comment_at": "2026-06-11T04:57:50Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 205,
          "created_at": "2026-06-30T10:04:10Z",
          "last_comment_at": "2026-06-30T10:04:35Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 215,
          "created_at": "2026-07-03T06:26:47Z",
          "last_comment_at": "2026-07-03T06:26:53Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 230,
          "created_at": "2026-07-16T09:09:32Z",
          "last_comment_at": "2026-07-16T09:09:41Z",
          "last_comment_author": "coderabbitai"
        }
      ],
      "last_merged_pr_at": "2026-07-27T09:22:47Z",
      "ci_last_conclusion": null,
      "oldest_open_issues": [
        {
          "number": 34,
          "created_at": "2026-04-07T17:29:12Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 58,
          "created_at": "2026-04-17T11:38:31Z",
          "last_comment_at": "2026-06-16T07:32:27Z",
          "last_comment_author": "kavix"
        },
        {
          "number": 59,
          "created_at": "2026-04-17T12:14:17Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 85,
          "created_at": "2026-05-04T06:58:09Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 86,
          "created_at": "2026-05-04T06:58:10Z",
          "last_comment_at": "2026-06-16T07:32:47Z",
          "last_comment_author": "kavix"
        },
        {
          "number": 87,
          "created_at": "2026-05-04T06:58:14Z",
          "last_comment_at": "2026-06-16T07:33:19Z",
          "last_comment_author": "kavix"
        },
        {
          "number": 92,
          "created_at": "2026-05-05T17:17:27Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 109,
          "created_at": "2026-05-28T06:53:48Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 120,
          "created_at": "2026-05-29T09:43:06Z",
          "last_comment_at": "2026-05-31T03:06:34Z",
          "last_comment_author": "Akini98"
        },
        {
          "number": 131,
          "created_at": "2026-05-30T12:52:09Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 139,
          "created_at": "2026-06-02T13:02:48Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 218,
          "created_at": "2026-07-07T00:00:31Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 220,
          "created_at": "2026-07-07T00:26:16Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 223,
          "created_at": "2026-07-09T05:31:00Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 226,
          "created_at": "2026-07-10T09:55:05Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 228,
          "created_at": "2026-07-14T06:43:24Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 229,
          "created_at": "2026-07-16T06:05:24Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 231,
          "created_at": "2026-07-20T00:45:26Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 233,
          "created_at": "2026-07-22T09:52:57Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 239,
          "created_at": "2026-07-25T18:39:54Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/wso2/open-cloud-datacenter",
    "host": "github.com",
    "name": "open-cloud-datacenter",
    "owner": "wso2"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 66,
      "inputs": {
        "security": 67,
        "vitality": 85,
        "community": 58,
        "governance": 60,
        "engineering": 58
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "excellent",
        "name": "Vitality",
        "value": 85,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 75,
            "inputs": {
              "commits_last_year": 173,
              "human_commit_share": 1,
              "days_since_last_push": 1,
              "active_weeks_last_year": 16
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 1 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 1
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "16/52 weeks with commits",
                "points": 11.1,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 16
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "173 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 173
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 34,
              "latest_release_tag": "terraform/v0.1.9",
              "releases_from_tags": false,
              "days_since_latest_release": 4,
              "mean_days_between_releases": 6.3
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "34 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 34
                    }
                  }
                ],
                "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 ~6.3 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 6.3
                    }
                  }
                ],
                "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": "moderate",
        "name": "Community & Adoption",
        "value": 58,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 21,
            "inputs": {
              "forks": 12,
              "stars": 7,
              "watchers": 1,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "7 stars",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 7
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "12 forks",
                "points": 8.7,
                "status": "partial",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 12
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "1 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "excellent",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "has_issue_template": true,
              "has_code_of_conduct": true,
              "has_pull_request_template": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (Apache-2.0)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "Apache-2.0"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 13.5,
                "status": "met",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 7.2,
                "status": "met",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 6.3,
                "status": "met",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 60,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 29,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 7,
              "top_contributor_share": 0.677
            },
            "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 68% of commits",
                "points": 7.3,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 68
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "7 contributors",
                "points": 9.5,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 7
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 78,
            "inputs": {
              "merged_prs": 167,
              "open_issues": 21,
              "closed_issues": 29,
              "issue_closed_ratio": 0.58,
              "closed_unmerged_prs": 10
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "58% of issues closed",
                "points": 27.1,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 58
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "167/177 decided PRs merged",
                "points": 36.1,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 167,
                      "decided": 177
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "all changesets reviewed",
                "points": 15,
                "status": "met",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "good",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 78,
            "inputs": {
              "followers": 1731,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "wso2",
              "public_repos": 383,
              "account_age_days": 5697
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "1,731 followers of wso2",
                "points": 23.3,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 1731,
                      "login": "wso2"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "383 public repos, account ~15 yr old",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 383
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 15
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 58,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "at_risk",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 36,
            "inputs": {
              "has_ci": true,
              "has_tests": false,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "2 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "10 out of 15 merged PRs checked by a CI test -- score normalized to 6",
                "points": 12,
                "status": "partial",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "excellent",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "topics": [
                "asgardeo",
                "choreo"
              ],
              "has_wiki": false,
              "homepage": "https://github.com/wso2/open-cloud-datacenter",
              "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://github.com/wso2/open-cloud-datacenter",
                "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": "2 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 67,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "moderate",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Branch-Protection, Packaging, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "branch_protection",
                    "packaging",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 67,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 15,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 3,
              "scorecard_aggregate": 6.7
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "10 out of 15 merged PRs checked by a CI test -- score normalized to 6",
                "points": 1.5,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "all changesets reviewed",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 0.8,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "all dependencies are pinned",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "GitHub workflow tokens follow principle of least privilege",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "0 existing vulnerabilities detected",
                "points": 7.5,
                "status": "met",
                "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": 4
            },
            "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": "critical",
        "name": "AI Readiness",
        "value": 26,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.88,
              "agent_instruction_files": [],
              "agent_instruction_max_bytes": null
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "no CLAUDE.md / AGENTS.md / editor rules",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_instructions",
                    "params": {}
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "88 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 88,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "critical",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 20,
            "inputs": {
              "has_nix": false,
              "has_tests": false,
              "lockfiles": [],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0.68,
              "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": 0,
                "status": "missed",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "68 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 68,
                      "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": "all dependencies are pinned",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "critical",
            "name": "Code legibility for models",
            "note": "Excluded from scoring (no data or not applicable): Manageable file sizes. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "manageable_file_sizes"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 1,
            "inputs": {
              "primary_language": "HCL",
              "largest_source_bytes": null,
              "source_files_sampled": 0,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "HCL without a type-check config",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_typecheck_config_language",
                    "params": {
                      "language": "HCL"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "no source files detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_source_files",
                    "params": {}
                  }
                ],
                "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": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-28T10:08:39.159260Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/w/wso2/open-cloud-datacenter.svg",
  "full_name": "wso2/open-cloud-datacenter",
  "license_state": "standard",
  "license_spdx": "Apache-2.0"
}

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

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

Wie ein einzelnes Ergebnis im Gesamtregister steht: aggregierte Statistiken.