Public record
Software health reportschema 0.27.0 · metrics 1.13.0 · 2026-07-27 05:01 UTC

atelico / gdstyle

A fast, opinionated linter and formatter for GDScript (Godot 4.x), in Rust.

RustMIT★ 48 stars⑂ 2 forkssince May 2026View on GitHub ↗

atelico/gdstyle holds a health index of 59 out of 100, placing it in the Moderate band. It scores highest on Engineering Quality (81/100) and lowest on Security (37/100). It was last updated 13 days ago. A single contributor accounts for most of its recent work.

59
overall / 100
Moderate

Software health index

Metrics are grouped into weighted categories on one standardized 1–100 scale. Overall starts as their weighted mean; when public evidence triggers the High-Risk Jurisdiction Policy, the rating is adjusted and receives an At risk ceiling of 49. AI Readiness sits outside the overall score.

59
Excellent85-100Exemplary; meets essentially all checked criteria
Good70-84Healthy; minor gaps
Moderate50-69Acceptable with notable gaps; review recommended
At risk30-49Significant weaknesses; adoption warrants caution
Critical1-29Severe problems (abandoned, single-maintainer, no hygiene)
VitalityCommunity &AdoptionSustainability &GovernanceEngineeringQualitySecurityAI Readiness

Score profile

Each axis is a category. The shape matters more than the average — a healthy subject fills the whole shape, while a spike-and-crater profile means strength in one dimension is masking risk in another.

Ownership

Studio AtelicoOrganization
2 followers15 public repossince Apr 2024

This repository is backed by an organization — shared, accountable stewardship that can outlive any single maintainer.

Package ecosystems

RegistryPackageVersionDownloads / moVersionsLast publishTags
crates.iogdstyle0.2.4851313 days agoformattergamedevgdscriptgodotlintercommand-line-utilitiesdevelopment-tools

Metrics by category

Vitality

Is the project alive — is code being written and are releases shipping?

65Moderate · 22% of overall
How it's scored
28.8/36Push recency — last push 13 days ago
4.2/36Commit cadence — 6/52 weeks with commits
15.3/18Commit volume — 50 commits in the last year
0/10OpenSSF Scorecard: Maintained — project was created within the last 90 days. Please review its contents carefully
Inputs used
commits_last_year50
human_commit_share1
days_since_last_push13
active_weeks_last_year6
How it's scored
27/27Ships releases — 13 releases published
36/36Release recency — latest release 13 days ago
27/27Release cadence — a release every ~4.8 days
0/10OpenSSF Scorecard: Signed-Releases — Project has not signed or included provenance with any releases.
Inputs used
releases_count13
latest_release_tagv0.2.4
releases_from_tagsno
days_since_latest_release13
mean_days_between_releases4.8

Community & Adoption

Does the project have users, downloads, attention, and a welcoming setup for contributors?

51Moderate · 18% of overall
How it's scored
27.1/60Stars — 48 stars
0/25Forks — 2 forks
0/15Watchers — 1 watchers
Inputs used
forks2
stars48
watchers1
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history

Community health

92Excellent
How it's scored
22.5/22.5README
22.5/22.5License — recognized license (MIT)
18/18CONTRIBUTING guide
13.5/13.5Code of conduct
0/7.2Issue template
6.3/6.3PR template
Inputs used
has_readmeyes
has_licenseyes
has_contributingyes
has_issue_templateno
has_code_of_conductyes
has_pull_request_templateyes
How it's scored
25.8/80Monthly downloads — 85 downloads/month across crates
0/20Registry dependents — not reported by this ecosystem
Inputs used
packagesgdstyle
dependents
ecosystemscrates
total_downloads256
monthly_downloads85
Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.

Sustainability & Governance

Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?

57Moderate · 24% of overall
How it's scored
9/54Bus factor — 1 contributor(s) cover half of all commits
0.5/22.5Commit distribution — top contributor authored 98% of commits
2.7/13.5Contributor breadth — 2 contributors
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Inputs used
bus_factor1
contributors_sampled2
top_contributor_share0.98
How it's scored
46.8/46.8Issue resolution — 100% of issues closed
38.2/38.3PR acceptance — 13/13 decided PRs merged
0/15OpenSSF Scorecard: Code-Review — Found 1/27 approved changesets -- score normalized to 0
Inputs used
merged_prs13
open_issues0
closed_issues15
issue_closed_ratio1
closed_unmerged_prs0
How it's scored
30/30Ownership backing — organization-owned
0/20Verified domain
3.4/25Owner reach — 2 followers of atelico
13.2/25Track record — 15 public repos, account ~2 yr old
Inputs used
followers2
owner_typeOrganization
is_verified
owner_loginatelico
public_repos15
account_age_days818
How it's scored
25/25Published & resolvable — 1 package(s) on crates
35/35Publish recency — latest publish 13 days ago
20/20Version history — 13 published versions
20/20Not deprecated — active, not deprecated or yanked
Inputs used
packagesgdstyle
ecosystemscrates
any_deprecatedno
min_days_since_publish13

Engineering Quality

Are baseline engineering and documentation practices in place?

81Good · 20% of overall
How it's scored
24/24CI workflows — 2 workflow(s)
24/24Tests present
0/16Linter config
0/9.6Pre-commit hooks
0/6.4.editorconfig
20/20OpenSSF Scorecard: CI-Tests — 13 out of 13 merged PRs checked by a CI test -- score normalized to 10
Inputs used
has_ciyes
has_testsyes
has_editorconfigno
has_linter_configno
has_precommit_configno

Documentation

100Excellent
How it's scored
30/30README
25/25Documentation directory
15/15Documentation / homepage site — https://github.com/atelico/gdstyle
10/10Repository description
10/10Topics — 5 topics
10/10Wiki
Inputs used
topicsformatter, gdscript, godot, linter, rust
has_wikiyes
homepagehttps://github.com/atelico/gdstyle
has_readmeyes
has_docs_diryes
has_descriptionyes

Security

Are visible security and supply-chain practices strong, without unresolved high-risk jurisdiction exposure?

37At risk · 16% of overall
How it's scored
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
2.5/2.5CI-Tests — 13 out of 13 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 1/27 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5License — license file detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
5/5Packaging — packaging workflow detected
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
5/5Security-Policy — security policy file detected
0/7.5Signed-Releases — Project has not signed or included provenance with any releases.
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
6/7.5Vulnerabilities — 2 existing vulnerabilities detected
Inputs used
sourceopenssf_scorecard
checks_evaluated18
scorecard_versionv5.5.0
checks_inconclusive0
scorecard_aggregate3.7

AI Readiness

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.

54Moderate · 0% of overall
How it's scored
0/45Agent instructions — no CLAUDE.md / AGENTS.md / editor rules
0/15Machine-readable docs (llms.txt)
40/40Legible commit history — 49 of 50 human commits state their intent (structured subject or explanatory body)
Inputs used
has_llms_txtno
legible_history_share0.98
agent_instruction_files
agent_instruction_max_bytes
How it's scored
12.6/18One-command bootstrap — Cargo.toml, gdstyle-gdext/Cargo.toml (toolchain convention, no task runner)
22/22Automated tests
0/11Lint / format config
11/11Static type checking — Rust (statically typed)
10/10Reproducible environment — lockfile
0/10Demonstrated agent practice — no agent-authored commits among the last 50
0/8Automated maintenance — no automated dependency updates observed
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Inputs used
has_nixno
has_testsyes
lockfilesCargo.lock
has_dockerfileno
typed_languageyes
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configs
agent_commit_share0
toolchain_manifestsCargo.toml, gdstyle-gdext/Cargo.toml
dependency_bot_commit_share0
How it's scored
45/45Type-checkable code — Rust (statically typed)
44/55Manageable file sizes — 4/20 source files over 60KB
Inputs used
primary_languageRust
largest_source_bytes201,150
source_files_sampled20
oversized_source_files4
How it's scored
0/40API schema (OpenAPI/GraphQL/proto)
0/20MCP server
40/40Runnable examples — examples
Inputs used
example_dirsexamples
has_mcp_signalno
api_schema_files

Key facts

48GitHub stars
2contributors
50commits, last 12 months
13days since last push
13releases
1bus factor
0open issues
crates.iopackage ecosystems

Data collection warnings

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • Could not fetch crates package 'gdstyle-gdext' from its registry
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

More detail

Star and fork history 0 ★ / 2 ⇿
0Stars
2Forks
7Releases

When each star and fork was added, collected from GitHub and bucketed by day. Cumulative growth sits directly above the daily additions it is made of, so the two read against each other: steady organic accretion looks nothing like an abrupt, short-lived burst. Where that difference is measurable, it is reported as growth authenticity.

111222212026-052026-062026-06
Major 0Minor 0Patch 7
OpenSSF Scorecard 3.7 / 10
3.7aggregate

Independent, tool-agnostic security assessment from the open-source OpenSSF Scorecard. Each check rewards a security practice, not a specific vendor's tool. Checks Scorecard could not determine are marked n/a and excluded from the security score (never counted as zero).Scorecard v5.5.0 · 2026-07-27 05:01 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
10CI-Tests13 out of 13 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 1/27 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
10Packagingpackaging workflow detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTSAST tool is not run on all commits -- score normalized to 0
10Security-Policysecurity policy file detected
0Signed-ReleasesProject has not signed or included provenance with any releases.
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
8Vulnerabilities2 existing vulnerabilities detected
Direct dependencies 9
RegistryPackageVersion constraintManifest
crates.ioclap4Cargo.toml
crates.ioserde1Cargo.toml
crates.iotoml0.8Cargo.toml
crates.iocolored2Cargo.toml
crates.ioglobset0.4Cargo.toml
crates.ioserde_json1Cargo.toml
crates.iorayon1Cargo.toml
crates.iogdstylegdstyle-gdext/Cargo.toml
crates.iogodot0.4gdstyle-gdext/Cargo.toml
All dependencies not collected

The resolved dependency set could not be collected for this report: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Raw JSON report machine-readable
{
  "data": {
    "repo": {
      "topics": [
        "formatter",
        "gdscript",
        "godot",
        "linter",
        "rust"
      ],
      "is_fork": false,
      "size_kb": 4343,
      "has_wiki": true,
      "homepage": "https://github.com/atelico/gdstyle",
      "languages": {
        "Rust": 726373,
        "GDScript": 33307
      },
      "pushed_at": "2026-07-14T02:31:44Z",
      "created_at": "2026-05-28T22:47:22Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-21T23:38:41Z",
      "description": "A fast, opinionated linter and formatter for GDScript (Godot 4.x), in Rust.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "Rust",
      "significant_languages": [
        "Rust"
      ]
    },
    "owner": {
      "blog": "https://atelico.studio",
      "name": "Studio Atelico",
      "type": "Organization",
      "login": "atelico",
      "company": null,
      "location": "United States of America",
      "followers": 2,
      "avatar_url": "https://avatars.githubusercontent.com/u/168492946?v=4",
      "created_at": "2024-04-29T23:46:55Z",
      "is_verified": null,
      "public_repos": 15,
      "account_age_days": 818
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.2.4",
          "kind": "patch",
          "published_at": "2026-07-14T02:38:00Z"
        },
        {
          "tag": "v0.2.3",
          "kind": "patch",
          "published_at": "2026-07-11T20:43:08Z"
        },
        {
          "tag": "v0.2.2",
          "kind": "patch",
          "published_at": "2026-07-11T08:22:14Z"
        },
        {
          "tag": "v0.2.1",
          "kind": "patch",
          "published_at": "2026-07-08T22:40:49Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-07-07T10:42:43Z"
        },
        {
          "tag": "v0.1.7",
          "kind": "patch",
          "published_at": "2026-06-09T18:12:45Z"
        },
        {
          "tag": "v0.1.6",
          "kind": "patch",
          "published_at": "2026-06-04T06:13:22Z"
        },
        {
          "tag": "v0.1.5",
          "kind": "patch",
          "published_at": "2026-06-03T22:47:21Z"
        },
        {
          "tag": "v0.1.4",
          "kind": "patch",
          "published_at": "2026-06-02T00:05:25Z"
        },
        {
          "tag": "v0.1.3",
          "kind": "patch",
          "published_at": "2026-06-01T08:33:57Z"
        },
        {
          "tag": "v0.1.2",
          "kind": "patch",
          "published_at": "2026-05-31T22:17:06Z"
        },
        {
          "tag": "v0.1.1",
          "kind": "patch",
          "published_at": "2026-05-31T21:41:16Z"
        },
        {
          "tag": "v0.1.0",
          "kind": "minor",
          "published_at": "2026-05-28T22:53:56Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "00a36c32aa6bc0df79151d27c952990358e1ab99",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.2.4",
          "author_name": "w4nderlust",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-14T02:31:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a6922e8c286ce4aa342cb0dc5d32ca03196a9a3f",
          "body": "…te-dict-key (#28)\n\nComment tokens inside a dictionary literal fell through to the\ncatch-all match arm and got appended to the key currently being\naccumulated, same as any other token. A comment sitting in key\nposition (right after `{` or right after an entry's comma) was\nsilently prefixed onto the \n[…]\nlater in the literal no longer matched and its\nduplicate went unreported.\n\nSkip Comment and DocComment tokens the same way Newline already is,\nso they never enter the accumulated key text.\n\nFixes #27.",
          "is_bot": false,
          "headline": "fix(quality): don't let comments corrupt tracked dict keys in duplica…",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-14T02:29:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "919ebb681cb2f4ca3ed68bdf595771ad632adf02",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.2.3",
          "author_name": "w4nderlust",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-11T20:37:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a2d2da0ab482ea549e21c7d676b70f1bbbb4131c",
          "body": "A comma or colon inside a multi-argument constructor call or subscript\nused as a dict key (e.g. Vector2i(1, 0)) was mistaken for the entry\nseparator or key/value colon, so the accumulated key text collapsed to\na trailing fragment like \"0)\" and unrelated keys sharing that fragment\nwere flagged as duplicates. Each dict frame now tracks its own paren/\nbracket depth so nested commas and colons are treated as part of the\nkey expression instead.\n\nFixes #23.",
          "is_bot": false,
          "headline": "fix(quality): track paren/bracket depth in duplicate-dict-key (#26)",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-11T20:33:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ca7c8b0f5aaa4d46daeaf755e8715465030d7227",
          "body": "…s (#25)\n\nlint_source normalizes \\r\\n/\\r to \\n before computing diagnostic byte\noffsets, but apply_fixes and extract_renames applied those offsets\ndirectly to the untouched CRLF source, drifting by one byte per\npreceding line and corrupting identifiers. Both now normalize the\nsource before using diagnostic offsets, and apply_fixes restores CRLF\nendings on the way out so on-disk line endings are unchanged.\n\nFixes #24.",
          "is_bot": false,
          "headline": "fix(fixer): preserve CRLF offsets and line endings when applying fixe…",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-11T20:33:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6f604214f4709b89e205127535ed3a41442efaa6",
          "body": "Two new formatting rules (format/brace-spacing, format/call-paren-spacing),\nthe include config for force-linting excluded paths, and editor-plugin parity\nfor exclude/include. See RELEASE_NOTES.md.",
          "is_bot": false,
          "headline": "chore(release): 0.2.2",
          "author_name": "w4nderlust",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-11T08:15:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c9d599c71bbf53eea68dd409533b0c097be81c2f",
          "body": "The editor plugin's native backend walked the project with a hardcoded\n`addons` skip (`_find_gd_files`), ignoring the config's `exclude`/`include`\nentirely, so in-editor lint/format disagreed with the CLI (and couldn't be\ntold to lint a first-party addon).\n\nMove the file-collection logic (`PathFilte\n[…]\nst, so the editor\nhonors `exclude`/`include` exactly like the CLI. `_find_gd_files` stays only\nas the CLI-backend fallback.\n\nNo behavior change for the CLI: it uses the same collector, just relocated.",
          "is_bot": false,
          "headline": "fix(plugin): honor exclude/include when collecting project files",
          "author_name": "w4nderlust",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-11T08:12:01Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "90c29260f59c62f393af204270e144960dc70be6",
          "body": "An `include` list carves specific paths back out of a broad `exclude` (e.g.\nexclude `addons` but include `addons/my_plugin`). Include always wins over\nexclude, regardless of order.\n\nThe walkers descend into excluded non-hidden directories when any include is\nconfigured, carrying an inherited-exclusion flag so only force-included paths\nsurvive and their excluded siblings don't leak back in. Hidden dirs stay\npruned. check, fmt, and scene collection share one PathFilter.\n\nCloses #19",
          "is_bot": false,
          "headline": "feat(config): add `include` to force-lint paths excluded by `exclude`",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-11T07:56:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "16a2563074c51203c0bbd674555f31de79875be7",
          "body": "… parens\n\nAdds two safe-fixable, default-on formatting rules from the official Godot\nstyle guide:\n\n- format/brace-spacing: single-line dict literals get `{ ... }` padding\n  (enum bodies, empty dicts, and multi-line dicts excluded; nesting handled).\n- format/call-paren-spacing: no space between a cal\n[…]\nord parens and lambda `func (...)` untouched).\n\nAlso collapses a pre-existing `if let … else { return None }` in\n`break_comment_line` to `strip_prefix(\"# \")?` to satisfy CI's newer clippy.\n\nCloses #20",
          "is_bot": false,
          "headline": "feat(format): pad single-line dict braces and strip space before call…",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-11T07:43:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9fd97440e83f1e7b40ef7a1186655a4699964625",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.2.1",
          "author_name": "w4nderlust",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-08T22:34:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "813bf15e6327cf91d9b769447012968bfbe60d99",
          "body": "order/class-member-order is enforced by the formatter's reorder pass, so\na # gdstyle:ignore=order/class-member-order comment was previously treated\nas a plain comment and the member got reordered anyway (issue #16).\n\nMake the directive pin the member: the reorder now keeps pinned blocks at\ntheir sou\n[…]\nh members opt out. A\nfile-level ignore pins every member. Both sides share one Suppressions\nhelper so detection stays consistent.\n\nDocumented under 'Pinning a member against reordering' in the README.",
          "is_bot": false,
          "headline": "feat(order): honor per-member order/class-member-order ignore",
          "author_name": "w4nderlust",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-08T22:29:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9aa8492e8879d2c4baed835f6d3fe76f7d764e02",
          "body": "A plain `#` comment written directly above a declaration is a leading\ncomment for it, but normalize_member_spacing left plain comments glued to\nthe previous member and then inserted the canonical inter-member gap\nbetween the comment and the declaration it describes (issue #15).\n\nTrack a pending bloc\n[…]\nllowing declaration (no blank line between), absorb it into\nthat member's unit so the gap is emitted above the comment. A blank line\nbreaks the tightness, leaving standalone/section comments in place.",
          "is_bot": false,
          "headline": "fix(formatter): keep leading comments tight against their declaration",
          "author_name": "w4nderlust",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-08T22:26:09Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7eeea2dbfed2a9b677ac0f8be8b45c1a4a48798c",
          "body": "v4 runs on Node.js 20, which GitHub is deprecating on its runners (the\nrelease run for v0.2.0 already force-upgraded it to Node 24 with a\nwarning). v5 runs on Node 24 natively.",
          "is_bot": false,
          "headline": "ci: bump actions/checkout to v5",
          "author_name": "w4nderlust",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-07T20:33:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dba234ff2c28eca1eaa00f8e7e975e90b89adc59",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.2.0",
          "author_name": "w4nderlust",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-07T10:36:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "46e20e793ff0258c055b851028e400ebd5d0ffda",
          "body": "…rface\n\nRead the editor theme through the injected editor_interface member instead\nof the global EditorInterface singleton, and wrap each lookup in a helper\nthat falls back to the original hard-coded color when it is unavailable.\nget_editor_theme() exists from 4.2 and some colors (e.g.\nfont_placeholder_color on the Editor type) only from 4.3, so has_color\ngates the lookup and older 4.x keeps working on the CLI-fallback path.",
          "is_bot": false,
          "headline": "fix(plugin): guard theme colors for older Godot and use injected inte…",
          "author_name": "w4nderlust",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-07T10:32:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "50382d514d7141d682426c883eb0565255faf22b",
          "body": null,
          "is_bot": false,
          "headline": "fix(plugin): make status and diagnostic colors theme-aware",
          "author_name": "trianglebreaker",
          "author_login": "trianglebreaker",
          "committed_at": "2026-07-07T10:32:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "47dcb7b53fde27c2085b5ab551a348fef888eef5",
          "body": "The dict-key scanner only checked the top level of each literal and\njumped its cursor past nested braces, so a genuine duplicate inside a\nvalue dictionary (e.g. {\"outer\": {\"a\": 1, \"a\": 2}}) went unreported.\nReplace the single depth-tracked scan with a stack of per-dictionary\nframes: every { opens a frame and every } closes it, so keys, commas,\nand colons route to the innermost open dictionary and each nesting level\nis checked independently. Keys reused at different levels stay distinct.",
          "is_bot": false,
          "headline": "feat(quality): detect duplicate keys inside nested dictionaries",
          "author_name": "w4nderlust",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-07T10:28:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "46d8125cc53f41a65fbdfd48e5d68f3224fac629",
          "body": "check_duplicate_dict_key recorded every key-position token separately and\nnever stopped after the first, so a dotted key like Enums.E.KEY_A was\nscanned as five keys and the two '.' tokens collided into a bogus\n\"duplicate dictionary key '.'\". Accumulate the whole key expression up to\nits ':' and compare it as one unit, keeping the string-value normalization\nso mixed quote styles still collide. Genuine duplicates (including repeated\ndotted keys) are still caught.\n\nCloses #8",
          "is_bot": false,
          "headline": "fix(quality): treat dotted dict keys as a single key",
          "author_name": "w4nderlust",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-07T10:24:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d42263b6c27a38adf9443a89cbad2378d168a09e",
          "body": null,
          "is_bot": false,
          "headline": "test(quality): add issue #7 exact repro as self-comparison regression",
          "author_name": "w4nderlust",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-07T10:24:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "89c305008045dd2bdd16a06d51f191d6bd38ea96",
          "body": "check_self_comparison used a 3-token window (Identifier op Identifier),\nso a shared trailing segment such as stored_goods.label == label was\nread as label == label and flagged. Compare the full dotted chain on\neach side instead, reusing the lhs/rhs chain helpers already used by\nno-self-assign, and require each side to be a standalone operand so\npartial matches inside arithmetic don't trigger. This also newly catches\ngenuine dotted self-comparisons like obj.foo == obj.foo.\n\nFixes #7",
          "is_bot": false,
          "headline": "fix(quality): stop self-comparison firing on different dotted paths",
          "author_name": "w4nderlust",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-07T10:24:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e5e4381f2165c12d3156a9d43eb82f3a116526bd",
          "body": null,
          "is_bot": false,
          "headline": "ci: add rustfmt, clippy and test jobs for pull requests",
          "author_name": "w4nderlust",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-07T10:18:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a3e624336b4c1c2eecc9e75f6a0f32545c06a1eb",
          "body": null,
          "is_bot": false,
          "headline": "style: apply cargo fmt",
          "author_name": "w4nderlust",
          "author_login": "w4nderlust",
          "committed_at": "2026-07-07T10:18:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5841e7119ead846c3f5155ea4e7f3fb5a0c3b65f",
          "body": "Patch release for the Godot plugin settings.json file-lock warning\non Windows (#6). Bump version in Cargo.toml, gdstyle-gdext,\nplugin.cfg, and the README pre-commit rev pin to v0.1.7; rewrite\nRELEASE_NOTES.md for the new version. Also strip three stray\nem-dashes that snuck into the README's suppression docs.",
          "is_bot": false,
          "headline": "chore(release): 0.1.7",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-06-09T18:06:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c7fa21c3a35f0e9ae57abb7c83cf3c18eeee0369",
          "body": "gdstyle itself flagged the file after 35e10cb:\n- format/trailing-comma on the push_warning args (multi-line array\n  without a trailing comma).\n- quality/max-branches on _load_settings (9 vs default 8) because\n  the error-handling and guard-flag additions pushed it over.\n\nReformat the push_warning calls with the trailing comma the\nformatter expects, and extract the per-key UI-apply block into a\n_apply_loaded_settings helper so _load_settings drops back under the\nbranch limit. Behaviour unchanged.",
          "is_bot": false,
          "headline": "style(plugin): fix two lint warnings introduced by the settings fix",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-06-09T17:51:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "35e10cbbebf47f9753192432f7d04cd64ee7f2ac",
          "body": "Reported by kyleralford in #6 on Windows. Godot was throwing\n\"Unable to write to file 'settings.json', file in use, locked or\nlacking permissions\" on every project startup, and leaving an\norphan settings.json#######.tmp behind each time.\n\nRoot cause: _load_settings opens the file for READ, then assi\n[…]\n.close()\n  explicitly instead of relying on the RefCounted drop, and log\n  a push_warning when open fails so a future user reporting a\n  related issue gets a real error instead of silence.\n\nCloses #6.",
          "is_bot": false,
          "headline": "fix(plugin): don't rewrite settings.json from inside _load_settings",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-06-09T17:45:46Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0cf43e9e1fac83cac870a0695205815fc7ce99a7",
          "body": "Patch release for the inner-class ordering false positive (#5). Bump\nversion in Cargo.toml, gdstyle-gdext, plugin.cfg, and the README\npre-commit rev pin to v0.1.6; rewrite RELEASE_NOTES.md for the new\nversion.",
          "is_bot": false,
          "headline": "chore(release): 0.1.6",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-06-04T06:07:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a2d5ea156a7c98a17ac5047b3c48a21fbf5272f1",
          "body": "Reported by Shilo in #5 with an excellent root-cause analysis. An\ninner class whose first body line was a comment-only line (`#` or\n`##`) used to NOT push an Indent onto the stack — `process_indentation`\nreturned None for any comment-only line whose indent was >= current.\nThe parser's `parse_indente\n[…]\nnt is emitted before the doc\n  comment that opens an inner-class body.\n- two integration tests guarding the reported shape (single doc\n  comment) and stacked leading comments (`#` + `##`).\n\nCloses #5.",
          "is_bot": false,
          "headline": "fix(lexer): emit Indent before a comment-only line at deeper indent",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-06-04T06:04:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ace4772b06d123053efccb917936471110148e28",
          "body": "Patch release fixing the @abstract formatter duplication (#4). Bump\nversion in Cargo.toml, gdstyle-gdext, plugin.cfg and the README\npre-commit rev pin to v0.1.5; rewrite RELEASE_NOTES.md for the new\nversion.",
          "is_bot": false,
          "headline": "chore(release): 0.1.5",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-06-03T22:41:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a3a0e247bf93c464265841b1da8f94fdf37887a0",
          "body": "Address the three review items on commits 096e246 + 3d61f57:\n\n1. Five new integration tests covering manual probes that were\n   previously only verified by hand:\n   - args round-trip on unknown annotations (`@x(a, b)` text)\n   - stacked annotations preserve source order\n   - class-level + function-l\n[…]\n_ =>` skip arm explaining why pending\n   annotations are intentionally NOT flushed there (lexer artifact\n   tokens between annotation and decl are the common case; the EOF\n   flush is the safety net).",
          "is_bot": false,
          "headline": "test+docs: lock in annotation-flush behaviour, tidy review nits",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-06-03T22:34:03Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3d61f574ac11f93c72079b5028c523d669a8eec6",
          "body": "…ss/EOF\n\nFollow-up to 096e246. The original fix flushed pending unknown\nannotations as class-level when class_name / extends were encountered.\nThe same family of duplication / drop bug still applied at four other\ntop-level member kinds whose parser arms don't consume\npending_annotations: signal, enu\n[…]\nation tests covering each new flush point, and keeps the\n2 issue-#4 tests untouched as regression guards on the original fix.\nFunction-level @abstract continues to attach via parse_function as\nbefore.",
          "is_bot": false,
          "headline": "fix(parser): flush pending annotations on signal/enum/const/inner-cla…",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-06-03T22:27:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "096e24642bfd1090d66eba83d88d98b4ad8a3266",
          "body": "When the parser saw an unrecognised top-level annotation (anything other\nthan @tool / @icon / @static_unload / @warning_ignore*) it pushed it\ninto pending_annotations and waited for a var, func, static, or const\nto attach it to. If class_name and extends sat in between, the\nannotation rode forward p\n[…]\nssue-reporter shape (class-level @abstract above class_name +\n  blank line + extends + multiple blank lines + a function)\n- a regression guard that function-level @abstract still attaches.\n\nCloses #4.",
          "is_bot": false,
          "headline": "fix(parser): flush pending annotations on class_name/extends",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-06-03T22:22:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3298df357eb9a2a6fb31d4d3f198181e164ea0db",
          "body": "Adds the # gdstyle:ignore-file directive for file-scope suppression.\nBump version in Cargo.toml, gdstyle-gdext, plugin.cfg and the README\npre-commit rev pin to v0.1.4; rewrite RELEASE_NOTES.md for the new\nversion.",
          "is_bot": false,
          "headline": "chore(release): 0.1.4",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-06-01T23:58:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0da7cf5f5e4b53ed096c9e4eafeb19c7783992e5",
          "body": "Some rules — quality/max-public-methods, quality/max-class-variables,\nquality/max-inner-classes, quality/max-file-length — anchor their\ndiagnostic at the class header or line 1 of the file. With only per-\nline suppression, the only way to silence them was an inline comment\non the class header signat\n[…]\nlevel rule the user\nhit, bare form drops everything, directive works regardless of\nposition, scoped form leaves unlisted rules alone, and the per-line\ndirective still routes through its existing path.",
          "is_bot": false,
          "headline": "feat(linter): file-scope suppression via # gdstyle:ignore-file",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-06-01T23:13:57Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "92351007f959522e85ebf10043bad5219694c44f",
          "body": null,
          "is_bot": false,
          "headline": "docs(security): use w4nderlust@gmail.com as the private contact",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-06-01T09:00:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8e60cdfb60bf4f5f62b0f1e8ec2a0e8353ef06fe",
          "body": null,
          "is_bot": false,
          "headline": "Create CODE_OF_CONDUCT.md",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-06-01T08:59:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d99add20c8f44226ed94f88511e1e7688f621c8e",
          "body": "Fills out the GitHub community profile checklist. Adds:\n\n- SECURITY.md: how to report vulnerabilities privately (GitHub private\n  advisory or email), scope, and what to include in a report.\n- .github/ISSUE_TEMPLATE/bug_report.yml: structured form for bug\n  reports with the minimal-repro / command / \n[…]\nes and point\n  open-ended questions at Discussions.\n- .github/PULL_REQUEST_TEMPLATE.md: PR template with type checklist,\n  test plan, and \"Closes #N\" prompt.\n\nCode of conduct will be added separately.",
          "is_bot": false,
          "headline": "chore: add SECURITY policy, issue + PR templates",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-06-01T08:54:02Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f612e225c8ec2292e28216cf9cf886bcb66aade7",
          "body": "Patch release for the quality/unreachable-code false positive (#3).\nBump version in Cargo.toml, gdstyle-gdext, plugin.cfg and the README\npre-commit rev pin to v0.1.3; rewrite RELEASE_NOTES.md for the new\nversion.",
          "is_bot": false,
          "headline": "chore(release): 0.1.3",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-06-01T08:28:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3c9a63ec43d265ce96666a27c1b815bdc3c27129",
          "body": "…tions\n\nThe line-based scanner walked from a `return`/`break`/`continue` line\nforward looking for any same-indent non-blank line and flagged it as\nunreachable. It had no notion of multi-line statements, so the closing\n`)` of `return floori(\\n\\t\\t1.2\\n\\t)` landed at the same indent as\n`return` and go\n[…]\nine returns,\n  one with inconsistent close-paren indent)\n- backslash-continuation in a return expression\n- a true-positive guard: code after the multi-line return closes is\n  still flagged\n\nCloses #3.",
          "is_bot": false,
          "headline": "fix(quality): no-unreachable-code skips multi-line statement continua…",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-06-01T08:24:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "56a9a5ab317e4a97e4bb46cb7d2581a31af99c22",
          "body": "…eatures\n\nBoth have existed for a while (editor plugin since 0.1.0, pre-commit\nintegration since 0.1.1) but the Features list didn't mention them,\nso first-time visitors comparing tools couldn't see them without\nscrolling to the corresponding sections further down.",
          "is_bot": false,
          "headline": "docs(readme): surface Godot editor plugin and pre-commit support in f…",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-05-31T22:19:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e3620b7ddd1ab8be0ec5c3794439f90abf074b1d",
          "body": "Patch release for the formatter doc-detachment bug. Bump version in\nCargo.toml, gdstyle-gdext, plugin.cfg and the README pre-commit rev\npin to v0.1.2; rewrite RELEASE_NOTES.md for the new version (used\nverbatim by the release workflow).",
          "is_bot": false,
          "headline": "chore(release): 0.1.2",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-05-31T22:12:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "747b57c9314f42e66b042f2b8434665689f25f7e",
          "body": "…noise\n\nThe first cut of the doc-detachment fix (commit 1b5b87c) always emitted\ndedents when a comment line sat at shallower indent than the current\nblock. That correctly handled the reported case — top-level `## doc`\nbetween two functions whose previous body ended with a nested construct —\nbut intr\n[…]\nt work (the `# static func should appear...`\ncomment now attaches to its function, and PEP-8/Godot style\nsingle-blank between inner-class methods is preserved instead of being\ninflated to two blanks).",
          "is_bot": false,
          "headline": "fix(lexer): peek ahead to distinguish boundary comment from mid-body …",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-05-31T22:08:44Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1b5b87c8822a4bc9e1149267467403db064fdbfe",
          "body": "When the lexer's indentation pass hit a `#` while still inside an\nindented block, it always returned None — preserving the indent stack\neven if the comment sat at SHALLOWER indent than the current level.\nThe intent was to keep an in-body comment (same indent as the body)\nfrom popping the stack, but \n[…]\neport.\n\nReported by users hitting it on real Godot project files with\nfunction bodies ending in nested constructs (a top-level `if` after\na `match`, leaving two indent levels open at the body's tail).",
          "is_bot": false,
          "headline": "fix(lexer): emit dedents before comment lines at lower indent",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-05-31T21:54:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5b3b81e1051655ae73f18d795fcaa2b5376bb238",
          "body": "Adds a publish-crates job gated on the release job succeeding, so\n`cargo publish -p gdstyle` runs automatically once the GitHub release\nis live. Only the `gdstyle` crate is published; `gdstyle-gdext` keeps\nits publish = false marker.\n\nRequires the CARGO_REGISTRY_TOKEN secret to be set in the repo's\nActions secrets.",
          "is_bot": false,
          "headline": "ci(release): auto-publish to crates.io after release",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-05-31T21:37:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3d46047c1cf3c9a3c583a431db63f1df611ad25c",
          "body": "Bug fix for the no-self-assign false positive plus the new pre-commit\nframework hooks. Bump version in Cargo.toml, gdstyle-gdext, plugin.cfg\nand the README rev pin to v0.1.1; rewrite RELEASE_NOTES.md for the new\nversion (used verbatim by the release workflow).",
          "is_bot": false,
          "headline": "chore(release): 0.1.1",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-05-31T21:35:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "37458768c001274e8a8265c9d4c92ffae0678092",
          "body": "Add a .pre-commit-hooks.yaml at the repo root exposing two hooks for the\npre-commit framework (pre-commit.com): `gdstyle` (lint) and `gdstyle-fmt`\n(format in place). Both use `language: rust` so pre-commit installs the\nbinary via cargo on first run.\n\nUpdate the Pre-commit section of the README to lead with the framework-\nbased setup (the common case) and keep the raw `.git/hooks/pre-commit`\nscript as a no-dependency fallback.",
          "is_bot": false,
          "headline": "feat: pre-commit framework hooks",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-05-31T21:31:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5e1a06391801a0a6543b3df337e72158996ff612",
          "body": "The rule used a 3-token sliding window that only compared the identifier\non each side of `=`, so `moon.size = size * ...` was flagged as a\nself-assignment even though the LHS is the property `moon.size` and the\nRHS is the local `size`. Same issue for `self.position = position`,\nand `x = x + 1` was b\n[…]\nag when the two chains are\nidentical. Adds 7 regression tests covering the false-positive cases\nreported in the wild plus the true-positive deep-chain and\nmatching-chain cases that must still trigger.",
          "is_bot": false,
          "headline": "fix(quality): no-self-assign compares full dotted paths",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-05-31T21:22:36Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2bb16935b4fd414a85a1ff95cef5d363b177ffcb",
          "body": "…cs.rs link",
          "is_bot": false,
          "headline": "docs(readme): add crates.io / docs.rs / license / build badges and do…",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-05-29T18:17:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aaaece27b7a3634d26873ee508cfeafc53d14d6d",
          "body": "- docs/demo.{gif,mp4} -> docs/gdstyle-demo.{gif,mp4}\n- remove standalone blog header (lives on atelico.studio, not the repo)\n- README's GitHub Actions example now uses 'cargo install gdstyle' instead of\n  the per-platform tarball download",
          "is_bot": false,
          "headline": "chore(docs): rename demo assets, drop blog header, simplify CI install",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-05-29T18:12:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5795931f41a32e8a345efa872bf5e09939a51df7",
          "body": null,
          "is_bot": false,
          "headline": "docs(readme): use user-attachments URL for the autoplaying header demo",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-05-28T22:57:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ce93d659e6c5320399f95f6b7002927303f7380c",
          "body": "First public release of gdstyle, a fast opinionated linter and formatter for\nGDScript (Godot 4.x), shipped as a single Rust binary plus an optional Godot\neditor plugin.",
          "is_bot": false,
          "headline": "Initial commit: gdstyle 0.1.0",
          "author_name": "Piero Molino",
          "author_login": "w4nderlust",
          "committed_at": "2026-05-28T22:53:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 13,
      "commits_last_year": 50,
      "latest_release_at": "2026-07-14T02:38:00Z",
      "latest_release_tag": "v0.2.4",
      "releases_from_tags": false,
      "days_since_last_push": 13,
      "active_weeks_last_year": 6,
      "days_since_latest_release": 13,
      "mean_days_between_releases": 4.8
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 100,
      "has_issue_template": false,
      "has_code_of_conduct": true,
      "has_pull_request_template": true
    },
    "ecosystem": {
      "packages": [
        {
          "name": "gdstyle",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "formatter",
            "gamedev",
            "gdscript",
            "godot",
            "linter",
            "command-line-utilities",
            "development-tools"
          ],
          "ecosystem": "crates",
          "matches_repo": true,
          "registry_url": "https://crates.io/crates/gdstyle",
          "is_deprecated": false,
          "latest_version": "0.2.4",
          "repository_url": "https://github.com/atelico/gdstyle",
          "versions_count": 13,
          "total_downloads": 256,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": 85,
          "first_published_at": "2026-05-29T18:13:07.491478Z",
          "latest_published_at": "2026-07-14T02:38:34.323696Z",
          "latest_version_yanked": false,
          "days_since_latest_publish": 13
        }
      ]
    },
    "popularity": {
      "forks": 2,
      "stars": 48,
      "watchers": 1,
      "fork_history": {
        "days": [
          {
            "date": "2026-05-30",
            "count": 1
          },
          {
            "date": "2026-06-17",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 2,
        "total_forks": 2
      },
      "star_history": null,
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [
        "Cargo.toml",
        "gdstyle-gdext/Cargo.toml"
      ],
      "largest_source_bytes": 201150,
      "source_files_sampled": 20,
      "oversized_source_files": 4,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "Cargo.toml",
        "gdstyle-gdext/Cargo.toml"
      ],
      "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": [
        "crates"
      ],
      "dependencies": [
        {
          "name": "clap",
          "manifest": "Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "4"
        },
        {
          "name": "serde",
          "manifest": "Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "toml",
          "manifest": "Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.8"
        },
        {
          "name": "colored",
          "manifest": "Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "2"
        },
        {
          "name": "globset",
          "manifest": "Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.4"
        },
        {
          "name": "serde_json",
          "manifest": "Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "rayon",
          "manifest": "Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "gdstyle",
          "manifest": "gdstyle-gdext/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "godot",
          "manifest": "gdstyle-gdext/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.4"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 0,
        "merged_prs": 13,
        "open_issues": 0,
        "closed_ratio": 1,
        "closed_issues": 15,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "w4nderlust",
          "commits": 49,
          "avatar_url": "https://avatars.githubusercontent.com/u/349256?v=4"
        },
        {
          "type": "User",
          "login": "trianglebreaker",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/35484302?v=4"
        }
      ],
      "contributors_sampled": 2,
      "top_contributor_share": 0.98
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "release.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "Cargo.lock"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "13 out of 13 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 1/27 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 0,
            "reason": "project has 0 contributing companies or organizations -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 0,
            "reason": "project was created within the last 90 days. Please review its contents carefully",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 10,
            "reason": "security policy file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": 0,
            "reason": "Project has not signed or included provenance with any releases.",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 8,
            "reason": "2 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "00a36c32aa6bc0df79151d27c952990358e1ab99",
        "ran_at": "2026-07-27T05:01:40Z",
        "aggregate_score": 3.7,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": true,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-14T02:38:39Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": "2026-07-14T02:29:00Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/atelico/gdstyle",
    "host": "github.com",
    "name": "gdstyle",
    "owner": "atelico"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 59,
      "inputs": {
        "security": 37,
        "vitality": 65,
        "community": 51,
        "governance": 57,
        "engineering": 81
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "moderate",
        "name": "Vitality",
        "value": 65,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "at_risk",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 48,
            "inputs": {
              "commits_last_year": 50,
              "human_commit_share": 1,
              "days_since_last_push": 13,
              "active_weeks_last_year": 6
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 13 days ago",
                "points": 28.8,
                "status": "partial",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 13
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "6/52 weeks with commits",
                "points": 4.2,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 6
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "50 commits in the last year",
                "points": 15.3,
                "status": "partial",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 50
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "releases_count": 13,
              "latest_release_tag": "v0.2.4",
              "releases_from_tags": false,
              "days_since_latest_release": 13,
              "mean_days_between_releases": 4.8
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "13 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 13
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 13 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 13
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~4.8 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 4.8
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "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": 51,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 27,
            "inputs": {
              "forks": 2,
              "stars": 48,
              "watchers": 1,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "48 stars",
                "points": 27.1,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 48
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "2 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "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": 92,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": true,
              "has_pull_request_template": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 13.5,
                "status": "met",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 6.3,
                "status": "met",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "at_risk",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 32,
            "inputs": {
              "packages": [
                "gdstyle"
              ],
              "dependents": null,
              "ecosystems": "crates",
              "total_downloads": 256,
              "monthly_downloads": 85
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "85 downloads/month across crates",
                "points": 25.8,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 85,
                      "ecosystems": "crates"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 57,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 12,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 2,
              "top_contributor_share": 0.98
            },
            "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 98% of commits",
                "points": 0.5,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 98
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "2 contributors",
                "points": 2.7,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "excellent",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "merged_prs": 13,
              "open_issues": 0,
              "closed_issues": 15,
              "issue_closed_ratio": 1,
              "closed_unmerged_prs": 0
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "100% of issues closed",
                "points": 46.8,
                "status": "met",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "13/13 decided PRs merged",
                "points": 38.2,
                "status": "met",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 13,
                      "decided": 13
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 1/27 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 47,
            "inputs": {
              "followers": 2,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "atelico",
              "public_repos": 15,
              "account_age_days": 818
            },
            "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": "2 followers of atelico",
                "points": 3.4,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 2,
                      "login": "atelico"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "15 public repos, account ~2 yr old",
                "points": 13.2,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 15
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 2
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "gdstyle"
              ],
              "ecosystems": "crates",
              "any_deprecated": false,
              "min_days_since_publish": 13
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on crates",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "crates"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 13 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 13
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "13 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 13
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "good",
        "name": "Engineering Quality",
        "value": 81,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 68,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "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": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "13 out of 13 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "excellent",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "topics": [
                "formatter",
                "gdscript",
                "godot",
                "linter",
                "rust"
              ],
              "has_wiki": true,
              "homepage": "https://github.com/atelico/gdstyle",
              "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/atelico/gdstyle",
                "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": "5 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 5
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "at_risk",
        "name": "Security",
        "value": 37,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": null,
            "notes": [],
            "value": 37,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 18,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 0,
              "scorecard_aggregate": 3.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": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "13 out of 13 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 1/27 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "2 existing vulnerabilities detected",
                "points": 6,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 2
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 54,
        "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.98,
              "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": "49 of 50 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 49,
                      "sampled": 50
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 56,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "Cargo.lock"
              ],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0,
              "toolchain_manifests": [
                "Cargo.toml",
                "gdstyle-gdext/Cargo.toml"
              ],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "Cargo.toml, gdstyle-gdext/Cargo.toml (toolchain convention, no task runner)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "toolchain_convention",
                    "params": {
                      "files": "Cargo.toml, gdstyle-gdext/Cargo.toml"
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "Rust (statically typed)",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Rust"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "no agent-authored commits among the last 50",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_authored_commits",
                    "params": {
                      "sampled": 50
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 89,
            "inputs": {
              "primary_language": "Rust",
              "largest_source_bytes": 201150,
              "source_files_sampled": 20,
              "oversized_source_files": 4
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Rust (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Rust"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "4/20 source files over 60KB",
                "points": 44,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 20,
                      "oversized": 4
                    }
                  }
                ],
                "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",
    "Could not fetch crates package 'gdstyle-gdext' from its registry",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-27T05:01:52.754959Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/a/atelico/gdstyle.svg",
  "full_name": "atelico/gdstyle",
  "license_state": "standard",
  "license_spdx": "MIT"
}

Scores are signals, not warranties. They reflect publicly visible practices on GitHub — not a code audit, and not a security guarantee.

Missing data is excluded and weights renormalized, never scored as zero. Methodology is versioned and open: metrics v1.13.0, schema v0.27.0 — full methodology · metrics wiki.

How one result sits in the wider record: aggregate statisticscrates.io.