Public record
Software health reportschema 0.27.0 · metrics 1.13.0 · 2026-07-31 23:38 UTC

flarum / approval

[READ ONLY] Subtree split of Flarum approval extension.

PHPMIT★ 10 stars⑂ 11 forkssince Sep 2015View on GitHub ↗

flarum/approval holds a health index of 56 out of 100, placing it in the Moderate band. It scores highest on Sustainability & Governance (77/100) and lowest on Engineering Quality (22/100). It was last updated today. 3 contributors account for most of its recent work.

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

56
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

FlarumOrganization
798 followers53 public repossince Sep 2013

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

Package ecosystems

RegistryPackageVersionDownloads / moVersionsLast publishTags
Packagistflarum/approvalv2.0.0-rc.514,0123523 days agomoderation

Metrics by category

Vitality

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

75Good · 22% of overall
How it's scored
36/36Push recency — last push 0 days ago
9.7/36Commit cadence — 14/52 weeks with commits
12.2/18Commit volume — 22 commits in the last year
6/10OpenSSF Scorecard: Maintained — 8 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 6
Inputs used
commits_last_year22
human_commit_share0.98
days_since_last_push0
active_weeks_last_year14
How it's scored
27/27Ships releases — 33 releases published
36/36Release recency — latest release 23 days ago
19.8/27Release cadence — a release every ~48 days
0/10OpenSSF Scorecard: Signed-Releases — no data
Inputs used
releases_count33
latest_release_tagv2.0.0-rc.5
releases_from_tagsno
days_since_latest_release23
mean_days_between_releases48
Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.

Community & Adoption

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

46At risk · 18% of overall
How it's scored
15.5/60Stars — 10 stars
8.3/25Forks — 11 forks
4.3/15Watchers — 7 watchers
Inputs used
forks11
stars10
watchers7
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
How it's scored
0/22.5README
22.5/22.5License — recognized license (MIT)
18/18CONTRIBUTING guide
0/13.5Code of conduct
0/7.2Issue template
6.3/6.3PR template
Inputs used
has_readmeno
has_licenseyes
has_contributingyes
has_issue_templateno
has_code_of_conductno
has_pull_request_templateyes
How it's scored
55.3/80Monthly downloads — 14,012 downloads/month across packagist
10.5/20Registry dependents — 37 packages depend on it
Inputs used
packagesflarum/approval
dependents37
ecosystemspackagist
total_downloads479,208
monthly_downloads14,012

Sustainability & Governance

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

77Good · 24% of overall
How it's scored
36/54Bus factor — 3 contributor(s) cover half of all commits
16.2/22.5Commit distribution — top contributor authored 28% of commits
13.5/13.5Contributor breadth — 20 contributors
10/10OpenSSF Scorecard: Contributors — project has 21 contributing companies or organizations
Inputs used
bus_factor3
contributors_sampled20
top_contributor_share0.281
How it's scored
0/46.8Issue resolution — no issues or no data
31.7/38.3PR acceptance — 24/29 decided PRs merged
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Inputs used
merged_prs24
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs5
Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.
How it's scored
30/30Ownership backing — organization-owned
0/20Verified domain
20.9/25Owner reach — 798 followers of flarum
24.6/25Track record — 53 public repos, account ~12 yr old
Inputs used
followers798
owner_typeOrganization
is_verified
owner_loginflarum
public_repos53
account_age_days4,691
How it's scored
25/25Published & resolvable — 1 package(s) on packagist
35/35Publish recency — latest publish 23 days ago
20/20Version history — 35 published versions
20/20Not deprecated — active, not deprecated or yanked
Inputs used
packagesflarum/approval
ecosystemspackagist
any_deprecatedno
min_days_since_publish23

Engineering Quality

Are baseline engineering and documentation practices in place?

22Critical · 20% of overall
How it's scored
0/24CI workflows
24/24Tests present
0/16Linter config
0/9.6Pre-commit hooks
0/6.4.editorconfig
0/20OpenSSF Scorecard: CI-Tests — no data
Inputs used
has_cino
has_testsyes
has_editorconfigno
has_linter_configno
has_precommit_configno
Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.

Documentation

10Critical
How it's scored
0/30README
0/25Documentation directory
0/15Documentation / homepage site
10/10Repository description
0/10Topics
0/10Wiki
Inputs used
topics
has_wikino
homepage
has_readmeno
has_docs_dirno
has_descriptionyes

Security

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

55Moderate · 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
0/2.5CI-Tests — no data
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
2.5/2.5Contributors — project has 21 contributing companies or organizations
0/10Dangerous-Workflow — no data
7.5/7.5Dependency-Update-Tool — update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5License — license file detected
4.5/7.5Maintained — 8 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 6
0/5Packaging — no data
0/5Pinned-Dependencies — no data
0/5SAST — no SAST tool detected
5/5Security-Policy — security policy file detected
0/7.5Signed-Releases — no data
0/7.5Token-Permissions — no data
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Inputs used
sourceopenssf_scorecard
checks_evaluated12
scorecard_versionv5.5.0
checks_inconclusive6
scorecard_aggregate5.5
Excluded from scoring (no data or not applicable): ci_tests, dangerous_workflow, packaging, pinned_dependencies, signed_releases, token_permissions. Remaining weights renormalized.

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.

53Moderate · 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 — 78 of 98 human commits state their intent (structured subject or explanatory body)
Inputs used
has_llms_txtno
legible_history_share0.796
agent_instruction_files
agent_instruction_max_bytes
How it's scored
0/18One-command bootstrap
22/22Automated tests
0/11Lint / format config
11/11Static type checking — js/tsconfig.json
0/10Reproducible environment
6/10Demonstrated agent practice — 3 of the last 100 commits agent-authored or agent-credited
8/8Automated maintenance — 2 of the last 100 commits are automated dependency updates
0/10OpenSSF Scorecard: Pinned-Dependencies — no data
Inputs used
has_nixno
has_testsyes
lockfiles
has_dockerfileno
typed_languageno
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configsjs/tsconfig.json
agent_commit_share0.03
toolchain_manifests
dependency_bot_commit_share0.02
Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Pinned-Dependencies. Remaining weights renormalized.
How it's scored
27/45Type-checkable code — PHP with type-check config (js/tsconfig.json)
55/55Manageable file sizes — 0/30 source files over 60KB
Inputs used
primary_languagePHP
largest_source_bytes7,489
source_files_sampled30
oversized_source_files0

Key facts

10GitHub stars
20contributors
22commits, last 12 months
0days since last push
33releases
3bus factor
0open issues
npm, Packagistpackage ecosystems

Data collection warnings

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • No resolved dependencies carried a version and a supported ecosystem

More detail

Star and fork history 0 ★ / 11 ⇿
0Stars
11Forks
19Releases

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.

0246810121112015-122020-012024-01
Major 1Minor 8Patch 2

Each point covers 8 days.

OpenSSF Scorecard 5.5 / 10
5.5aggregate

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-31 23:38 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
n/aCI-Testsno pull request found
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
10Contributorsproject has 21 contributing companies or organizations
n/aDangerous-Workflowno workflows found
10Dependency-Update-Toolupdate tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
6Maintained8 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 6
n/aPackagingpackaging workflow not detected
n/aPinned-Dependenciesno dependencies found
0SASTno SAST tool detected
10Security-Policysecurity policy file detected
n/aSigned-Releasesno releases found
n/aToken-PermissionsNo tokens found
10Vulnerabilities0 existing vulnerabilities detected
Direct dependencies 2
RegistryPackageVersion constraintManifest
Packagistflarum/core^2.0.0-rc.5composer.json
Packagistflarum/flags^2.0composer.json
All dependencies 13

Full resolved dependency set from the GitHub dependency graph: 2 direct and 11 indirect (transitive) packages. The transitive closure is complete when the repository commits a lockfile.

RegistryPackageVersionRelation
Packagistflarum/coredirect
Packagistflarum/flagsdirect
npm@flarum/prettier-config^1.0.0indirect
npmflarum-tsconfig^2.0.0indirect
npmflarum-webpack-config^3.0.0indirect
npmprettier^2.5.1indirect
npmtypescript^4.5.4indirect
npmtypescript-coverage-report^0.6.1indirect
npmwebpack^5.104.1indirect
npmwebpack-cli^4.9.1indirect
Packagistflarum/auditindirect
Packagistflarum/tagsindirect
Packagistflarum/testingindirect
Dependency advisories not assessed

Advisory matching could not run for this report: No resolved dependencies carried a version and a supported ecosystem

Raw JSON report machine-readable
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 624,
      "has_wiki": false,
      "homepage": null,
      "languages": {
        "PHP": 42863,
        "Less": 107,
        "JavaScript": 2931,
        "TypeScript": 1437
      },
      "pushed_at": "2026-07-31T23:35:20Z",
      "created_at": "2015-09-22T08:45:04Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-31T23:36:55Z",
      "description": "[READ ONLY] Subtree split of Flarum approval extension.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "2.x",
      "license_spdx_raw": "MIT",
      "primary_language": "PHP",
      "significant_languages": [
        "PHP"
      ]
    },
    "owner": {
      "blog": "http://flarum.org",
      "name": "Flarum",
      "type": "Organization",
      "login": "flarum",
      "company": null,
      "location": null,
      "followers": 798,
      "avatar_url": "https://avatars.githubusercontent.com/u/5549034?v=4",
      "created_at": "2013-09-26T11:15:45Z",
      "is_verified": null,
      "public_repos": 53,
      "account_age_days": 4691
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v2.0.0-rc.5",
          "kind": "prerelease",
          "published_at": "2026-07-08T15:54:36Z"
        },
        {
          "tag": "v2.0.0-rc.4",
          "kind": "prerelease",
          "published_at": "2026-06-18T11:59:28Z"
        },
        {
          "tag": "v2.0.0-rc.3",
          "kind": "prerelease",
          "published_at": "2026-06-09T18:53:44Z"
        },
        {
          "tag": "v2.0.0-rc.2",
          "kind": "prerelease",
          "published_at": "2026-06-01T18:17:36Z"
        },
        {
          "tag": "v2.0.0-rc.1",
          "kind": "prerelease",
          "published_at": "2026-04-20T10:17:59Z"
        },
        {
          "tag": "v2.0.0-beta.7",
          "kind": "prerelease",
          "published_at": "2026-02-22T17:16:03Z"
        },
        {
          "tag": "v2.0.0-beta.6",
          "kind": "prerelease",
          "published_at": "2026-01-30T09:18:39Z"
        },
        {
          "tag": "2.0.0-beta.5",
          "kind": "prerelease",
          "published_at": "2025-12-20T22:37:09Z"
        },
        {
          "tag": "v2.0.0-beta.4",
          "kind": "prerelease",
          "published_at": "2025-11-25T17:56:19Z"
        },
        {
          "tag": "v2.0.0-beta.3",
          "kind": "prerelease",
          "published_at": "2025-05-02T08:13:40Z"
        },
        {
          "tag": "v2.0.0-beta.2",
          "kind": "prerelease",
          "published_at": "2025-01-17T09:04:26Z"
        },
        {
          "tag": "v2.0.0-beta.1",
          "kind": "prerelease",
          "published_at": "2024-12-11T16:54:44Z"
        },
        {
          "tag": "v1.8.2",
          "kind": "patch",
          "published_at": "2024-10-08T07:13:53Z"
        },
        {
          "tag": "v1.8.1",
          "kind": "patch",
          "published_at": "2023-11-17T17:18:22Z"
        },
        {
          "tag": "v1.8.0",
          "kind": "minor",
          "published_at": "2023-05-20T17:12:56Z"
        },
        {
          "tag": "v1.7.0",
          "kind": "minor",
          "published_at": "2023-03-10T13:07:03Z"
        },
        {
          "tag": "v1.6.1",
          "kind": "patch",
          "published_at": "2022-11-16T11:09:37Z"
        },
        {
          "tag": "v1.6.0",
          "kind": "minor",
          "published_at": "2022-11-15T11:30:14Z"
        },
        {
          "tag": "v1.5.0",
          "kind": "minor",
          "published_at": "2022-09-13T09:08:08Z"
        },
        {
          "tag": "v1.4.0",
          "kind": "minor",
          "published_at": "2022-07-13T12:13:52Z"
        },
        {
          "tag": "v1.3.0",
          "kind": "minor",
          "published_at": "2022-05-12T10:16:18Z"
        },
        {
          "tag": "v1.2.0",
          "kind": "minor",
          "published_at": "2022-01-20T10:56:10Z"
        },
        {
          "tag": "v1.1.0",
          "kind": "minor",
          "published_at": "2021-10-13T00:44:56Z"
        },
        {
          "tag": "v1.0.0",
          "kind": "major",
          "published_at": "2021-05-27T07:59:11Z"
        },
        {
          "tag": "v0.1.0-beta.16",
          "kind": "prerelease",
          "published_at": "2021-03-15T15:59:47Z"
        },
        {
          "tag": "v0.1.0-beta.15",
          "kind": "prerelease",
          "published_at": "2020-12-18T14:52:26Z"
        },
        {
          "tag": "v0.1.0-beta.14",
          "kind": "prerelease",
          "published_at": "2020-10-15T13:34:53Z"
        },
        {
          "tag": "v0.1.0-beta.13",
          "kind": "prerelease",
          "published_at": "2020-05-01T11:16:29Z"
        },
        {
          "tag": "v0.1.0-beta.8",
          "kind": "prerelease",
          "published_at": "2018-11-29T06:33:52Z"
        },
        {
          "tag": "v0.1.0-beta.7",
          "kind": "prerelease",
          "published_at": "2017-07-22T03:23:04Z"
        },
        {
          "tag": "v0.1.0-beta.6",
          "kind": "prerelease",
          "published_at": "2016-10-19T10:51:54Z"
        },
        {
          "tag": "v0.1.0-beta.5",
          "kind": "prerelease",
          "published_at": "2016-03-29T07:42:33Z"
        },
        {
          "tag": "v0.1.0-beta.3",
          "kind": "prerelease",
          "published_at": "2015-11-02T23:38:01Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "68649f8b09643ce0f0157fddf47afe1937e90780",
          "body": "…first one it found) (#4871)\n\n* feat: fail integration tests that run N+1 queries\n\nEvery request sent through the integration TestCase is now inspected for\nN+1 query patterns, and the test fails when it finds one. Extension\nauthors get the feedback while writing the feature rather than when a\nforum \n[…]\ntest is a separate process and a static flag cannot track 'first'. A\nmarker file keyed to the project and the hour serves as the shared\nsignal.\n\n---------\n\nCo-authored-by: StyleCI Bot <bot@styleci.io>",
          "is_bot": false,
          "headline": "[2.x] feat: fail integration tests that run N+1 queries (and fix the …",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-07-31T21:00:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e99e3f89694d06d4d683ccbf65f1cd2ea103c594",
          "body": "* docs: add changelog for 2.0.0-rc.5\n\n* docs: add #4806 to rc.5 changelog\n\n* docs: add #4807 to rc.5 changelog\n\n* chore: bump version and dependency constraints to 2.0.0-rc.5",
          "is_bot": false,
          "headline": "[2.x] chore: prepare 2.0.0-rc.5 (#4805)",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-07-08T15:08:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "46760d9e48419fb3b07d8768c86674be04efac06",
          "body": "…roved (#4777)\n\n* fix(approval): update tag metadata when a pending discussion is approved\n\nApproving previously-pending (private) content left flarum/tags' discussion_count and last-posted metadata stale, since tags deliberately skips private discussions. Handle it inside flarum/approval as an opti\n[…]\nPostWasApproved event and refreshes the affected tags through their public model API, so flarum/tags stays unaware of approval.\n\nFixes #4776\n\n* chore(approval): use \"*\" for flarum/tags dev-requirement",
          "is_bot": false,
          "headline": "[2.x] fix(tags): update tag metadata when a pending discussion is app…",
          "author_name": "Link Robins",
          "author_login": "karl-bullock",
          "committed_at": "2026-07-08T08:43:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "15edd818fa3fc7f1d381c3cd99f541317c4a5c86",
          "body": "When the first post of a discussion is approved, the discussion itself is\napproved (see UpdateDiscussionAfterPostApproval). Record that as its own\ndiscussion.approved audit action, alongside the existing post.approved,\nwhen flarum/audit is enabled. Label shipped in the approval locale.\n\nAlso slim the audit RegisteredActionsTest to audit-owned actions only; each\nextension is responsible for registering and testing its own actions.",
          "is_bot": false,
          "headline": "feat(approval): log discussion approval in the audit log (#4748)",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-06-17T12:38:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "66f0d42dffcbaa11ab63087d339ae190fcda0459",
          "body": null,
          "is_bot": false,
          "headline": "chore: prep 2.0.0-rc.4 (#4741)",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-06-16T10:05:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "93d30f136bfc0977db6ab9a0595e28974f4f43cf",
          "body": "… coverage (#4711)\n\n* [1.x] Add first-party Audit extension (#4704)\n\n* [1.x] Add first-party Audit extension\n\nAdds flarum/audit, a first-party audit log extension, to the monorepo.\n\nIt records moderation and administration actions (user, discussion, post,\nsetting, permission, extension lifecycle and\n[…]\nons_first_post_id_foreign during the approve flow (MySQL/SQLite tolerated it). Point it at the seeded post.\n\n* chore: add composer link to docs\n\n---------\n\nCo-authored-by: StyleCI Bot <bot@styleci.io>",
          "is_bot": false,
          "headline": "[2.x] Audit extension 2.x migration, integration split, and GDPR/core…",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-06-12T01:16:39Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "03cc5b5bfb6412d021748048ed3ca74ba3179dde",
          "body": "* chore: prep rc.3\n\n* chore: bump composer reqs",
          "is_bot": false,
          "headline": "chore: prep `2.0.0-rc.3` (#4698)",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-06-09T12:39:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1351b95b1ec65d4cf6043e19f19aefbd8abdcdc4",
          "body": null,
          "is_bot": false,
          "headline": "chore: prep rc2 (#4676)",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-05-30T22:29:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f50138b351694dabbebd9741e01b4694ff141e88",
          "body": null,
          "is_bot": false,
          "headline": "chore: prep rc.1 (#4581)",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-04-17T12:43:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "640cd8cdfb47d5998315014f85ed210a20db66fe",
          "body": "* prep for beta.8\n\n* chore: update changelog for beta.8 (#4480, #4481)",
          "is_bot": false,
          "headline": "[2.x] prep for beta.8 (#4478)",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-03-21T22:45:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "66f6ee1f3fbb464add5b95672ddf51c3553a23cc",
          "body": "Includes transpiled JS/TS, and Typescript declaration files (typings).\n\n[skip ci]",
          "is_bot": false,
          "headline": "Bundled output for commit 60d72060c59b1e60c5cc596ee66e771928dbccb6",
          "author_name": "flarum-bot",
          "author_login": "flarum-bot",
          "committed_at": "2026-03-21T08:21:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e95f17cb324f9aca7553c65a0821bb02dcb383ea",
          "body": "…ensions (#4475)\n\n* chore: add build-typings scripts and TS deps to all bundled extensions\n\nEight extensions (approval, emoji, markdown, mentions, nicknames, sticky,\nsubscriptions, suspend) had declarationDir configured in tsconfig.json but\nwere missing the build-typings/check-typings scripts and ty\n[…]\norum/helpers/getEmojiIconCode.js → .ts\n- forum/fragments/AutocompleteDropdown.js → .tsx\n- forum/addComposerAutocomplete.js → .tsx (with EmojiTextEditor interface)\n\nCoverage goes from 70.07% to 96.22%.",
          "is_bot": false,
          "headline": "[2.x] chore: add build-typings scripts and TS deps to all bundled ext…",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-03-21T08:16:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "aefdc7a490a23dd1b1c28effe0630ff2ac2b9ff5",
          "body": "…ents (#4453)\n\nApplying opacity < 1 directly to .Post-header created a new CSS stacking\ncontext, which caused the user-card dropdown (shown on avatar hover) to be\nconfined to that stacking context and disappear when the user tried to\nnavigate to it.\n\nMoving opacity to the .Post--unapproved wrapper f\n[…]\nissue and produces the same visual result — the whole post is dimmed at 50%.\nThe per-child selectors for .EventPost-icon/.EventPost-info are covered by\nthe parent rule and can be removed.\n\nFixes #4212",
          "is_bot": false,
          "headline": "fix(approval): apply opacity to whole unapproved post, not child elem…",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-03-15T08:03:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f4d2b4f6003ad40ba3aa4f34ade7d9443772c80c",
          "body": "… 3-section sidebar (#4446)\n\n* revert(admin): remove collapsible extension categories, restore 3-section sidebar\n\nThe collapsible category groups introduced in #4392 added too much\nfriction — everything collapsed by default, count badges read like\nnotification counts, and single-item categories (Inf\n[…]\nrestoring\n\"feature\" keeps the data consistent with the rendering logic.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "[2.x] revert(admin): remove collapsible extension categories, restore…",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-03-14T22:59:06Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c9cbe0287d167e232bf4f0398731871f151e030d",
          "body": "Includes transpiled JS/TS, and Typescript declaration files (typings).\n\n[skip ci]",
          "is_bot": false,
          "headline": "Bundled output for commit ac6cc20a85963e1ec90cf6d405d4263d62695286",
          "author_name": "flarum-bot",
          "author_login": "flarum-bot",
          "committed_at": "2026-03-12T00:31:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bd8a283deecd93d53ee8ed7b05244120671c66cd",
          "body": "…re + bundled extensions (#4430)\n\n* feat(core): add haptic feedback utility and integrate across core + bundled extensions\n\nAdds `haptic()` — a mobile haptic feedback utility backed by the `web-haptics`\npackage, supporting Android (Web Vibration API) and iOS (Taptic Engine via hidden\ncheckbox trick)\n[…]\nClaude Sonnet 4.6 <noreply@anthropic.com>\n\n* style: run prettier format\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "[2.x] feat(core): add haptic feedback utility and integrate across co…",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-03-12T00:27:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "242fa50c493c8d9bf72cd45c99ecbade99c028a1",
          "body": "…abandoned package support (#4392)\n\n* feat(admin): collapsible extension categories, health widget, abandoned package support\n\n- AdminNav: replace static category headers with collapsible groups; each group\n  shows a count badge, category icon, and expand/collapse chevron. Categories\n  default to co\n[…]\ning directly to an\nextension URL (e.g. /admin#/extension/flarum-flags).\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "[2.x] feat(admin): collapsible extension categories, health widget & …",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-03-02T06:56:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d6d3c7468f8f2b754849f3fd990d25db96732558",
          "body": null,
          "is_bot": false,
          "headline": "chore: prep for beta.7 (#4377)",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-02-21T13:40:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9947a3ce72810b3f7e9576f9f2df21d65bb5896c",
          "body": "Includes transpiled JS/TS, and Typescript declaration files (typings).\n\n[skip ci]",
          "is_bot": false,
          "headline": "Bundled output for commit 6402e639bb64b06ecdc92ea69e6dacb3655504f7",
          "author_name": "flarum-bot",
          "author_login": "flarum-bot",
          "committed_at": "2026-02-15T21:46:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1cab0296835b0b47dbaf931765deb0c92cdbcfa8",
          "body": "Bumps [webpack](https://github.com/webpack/webpack) from 5.95.0 to 5.104.1.\n- [Release notes](https://github.com/webpack/webpack/releases)\n- [Changelog](https://github.com/webpack/webpack/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/webpack/webpack/compare/v5.95.0...v5.104.1)\n\n---\nupdated-\n[…]\ndency-version: 5.104.1\n  dependency-type: direct:production\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): bump webpack from 5.95.0 to 5.104.1 (#4354)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-02-15T21:42:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9655a561e28b8a2bc2791950dd7dfb01833befd3",
          "body": null,
          "is_bot": false,
          "headline": "chore: prep for beta.6 (#4343)",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-01-24T08:00:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f5ca183cd81a3ef7e8ff2702654f215cebb34a7e",
          "body": null,
          "is_bot": false,
          "headline": "chore: prep for beta.5 (#4313)",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2025-12-20T10:31:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1ad6d5bd3218bfa8d869cfd82c38aa28af738b65",
          "body": null,
          "is_bot": false,
          "headline": "chore: prep beta.4 (#4291)",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2025-11-25T08:50:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e0b052bb14810b861f4d3a3823a67d4f48ba59d0",
          "body": null,
          "is_bot": false,
          "headline": "chore: prepare 2.0.0-beta.3",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2025-04-25T09:19:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ca3b40957eb3a7f15dba66d6635a2825bacc9ce9",
          "body": "Includes transpiled JS/TS, and Typescript declaration files (typings).\n\n[skip ci]",
          "is_bot": false,
          "headline": "Bundled output for commit 649be7cb031a55aa7ea13d2b4f1ae09c5e828667",
          "author_name": "flarum-bot",
          "author_login": "flarum-bot",
          "committed_at": "2025-04-25T08:20:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e26dc11a93bc86a9bf1a2f820e314799e1d7d5bc",
          "body": null,
          "is_bot": false,
          "headline": "chore(a11y): misc a11y improvements (#4211)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2025-04-25T08:17:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9feaef7e86d06620d082daf94367fceb7940f19f",
          "body": null,
          "is_bot": false,
          "headline": "chore: v2.0.0-beta.2",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2025-01-17T08:44:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6e2b7f3da4c107cb9ba96e066a3080f14e61b40b",
          "body": null,
          "is_bot": false,
          "headline": "chore: prepare `2.0.0-beta.1`",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2024-12-07T08:50:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "800508caf5de3516e334b2d538e8bdaf4c55782e",
          "body": "* test: php 8.4\r\n\r\n* fix: php 8.4 deprecations\r\n\r\n* fix: make argument required\r\n\r\n* chore: review changes",
          "is_bot": false,
          "headline": "test: php 8.4 (#4103)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2024-11-08T16:33:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "26b2c3c8c80f1ffff7fabcbfb32e8f07a5bda659",
          "body": "Includes transpiled JS/TS, and Typescript declaration files (typings).\n\n[skip ci]",
          "is_bot": false,
          "headline": "Bundled output for commit a47bd2d45730f004e739d91c290f22330ab93dc4",
          "author_name": "flarum-bot",
          "author_login": "flarum-bot",
          "committed_at": "2024-10-19T17:44:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "58b1cc9ea4260836c2769184716ae6b1a279b3a0",
          "body": "Includes transpiled JS/TS, and Typescript declaration files (typings).\n\n[skip ci]",
          "is_bot": false,
          "headline": "Bundled output for commit 257be2b9db6f5365faa017bd9cc4a0e870efb449",
          "author_name": "flarum-bot",
          "author_login": "flarum-bot",
          "committed_at": "2024-09-28T14:51:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2893f7ee0dcaf4557f5bf2fd23ff80bde56e854c",
          "body": "* feat: private messages",
          "is_bot": false,
          "headline": "feat: messages extension (#4028)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2024-09-28T10:12:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "014620071a5ff90a4c344f807d249a3ea55bf63c",
          "body": "Includes transpiled JS/TS, and Typescript declaration files (typings).\n\n[skip ci]",
          "is_bot": false,
          "headline": "Bundled output for commit 5cea3d3b9bc4c5c6ae751bc4920a37bf032931af",
          "author_name": "flarum-bot",
          "author_login": "flarum-bot",
          "committed_at": "2024-09-28T08:38:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "25866c9d32075514c37016c17a4efdb2879aba5e",
          "body": null,
          "is_bot": false,
          "headline": "feat: admin search UI (#4022)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2024-09-28T08:35:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "01d05c6e31026901f914fee21b052a9ac7ae09d3",
          "body": "* chore: phpunit 10\r\n\r\n* chore: config\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* chore: phpunit 11 (php 8.2 minimum requirement)\r\n\r\n* feat: laravel 11\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* feat: carbon v3\r\n\r\n* fixes",
          "is_bot": false,
          "headline": "chore: update dependencies (#4012)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2024-08-06T15:50:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2612353b5014f018dc8b2f23f6170ce6b1c4f018",
          "body": null,
          "is_bot": false,
          "headline": "fix: 2.0 bugs (#4011)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2024-08-02T11:49:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7d734cc6f58a83659f6f67410616791adfcdd790",
          "body": "* feat: add support for `PgSQL`\r\n* chore: generate dump\r\n* feat: query exception errors db driver hint\r\n* feat: allow defining supported databases\r\n* chore: review comments\r\n* feat: setting for pgsql preferred search config",
          "is_bot": false,
          "headline": "feat: add support for PgSQL (#3985)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2024-06-22T07:03:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "570eb9bbf31a3c2284d7e9cbb870df7e2a338a53",
          "body": "* refactor: json:api refactor iteration 1\r\n* chore: delete dead code\r\n* fix: regressions\r\n* chore: move additions/changes to package\r\n* feat: AccessTokenResource\r\n* feat: allow dependency injection in resources\r\n* feat: `ApiResource` extender\r\n* feat: improve\r\n* feat: refactor tags extension\r\n* feat\n[…]\nt\r\n* feat: eager loading\r\n* test: adapt\r\n* test: phpstan\r\n* test: adapt\r\n* fix: typing\r\n* fix: approving content\r\n* tet: adapt frontend tests\r\n* chore: typings\r\n* chore: review\r\n* fix: breaking change",
          "is_bot": false,
          "headline": "refactor: JSON:API (#3971)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2024-06-21T08:36:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f8d53ed592a5bb03ad8c9e0cefbf857188f338d4",
          "body": null,
          "is_bot": false,
          "headline": "feat: eloquent factories (primarily for tests) (#3982)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2024-05-03T08:20:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6742ee8d6c5e3e3de94ba1e32dee97a21d516ca5",
          "body": null,
          "is_bot": false,
          "headline": "fix(approval): `PostWasApproved` event triggered incorrectly",
          "author_name": "Rafał Całka",
          "author_login": "rafaucau",
          "committed_at": "2023-11-23T17:50:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "23b6afc91d8836e91ab90b8b51bc82684f886225",
          "body": "Includes transpiled JS/TS, and Typescript declaration files (typings).\n\n[skip ci]",
          "is_bot": false,
          "headline": "Bundled output for commit 016503d8c37eab107b36830b6fbcb5468bcb1226",
          "author_name": "flarum-bot",
          "author_login": "flarum-bot",
          "committed_at": "2023-06-29T18:24:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ce9a7bc4924367ba7f32dfc09c6ce9b2df937cfb",
          "body": "Allows running tests without constantly running `composer install` on each extension.",
          "is_bot": false,
          "headline": "chore: improve test suite (#3814)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2023-06-15T12:26:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1ced0f9d990e9adef2c81edb9f184dc24710152b",
          "body": "Includes transpiled JS/TS, and Typescript declaration files (typings).\n\n[skip ci]",
          "is_bot": false,
          "headline": "Bundled output for commit f67ca5782a0b22d194526b6b11a2086443863921",
          "author_name": "flarum-bot",
          "author_login": "flarum-bot",
          "committed_at": "2023-06-07T10:45:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a19ffce641a9361e1b827c5310e18819753a271a",
          "body": "Signed-off-by: Sami Mazouz <sychocouldy@gmail.com>",
          "is_bot": false,
          "headline": "fix(regression): require `flarum/testing:2.0`",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2023-05-31T08:53:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "934ec76282cd12df9845648173d7315ccd38bc48",
          "body": "Signed-off-by: Sami Mazouz <sychocouldy@gmail.com>",
          "is_bot": false,
          "headline": "fix(regression): caught errors",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2023-05-31T08:50:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6e3b39673737cd52c9a4343f7540f66625ea2109",
          "body": "This reverts commit c94c1404843033a407c306895ed0a64333f55bf9.",
          "is_bot": false,
          "headline": "Revert \"fix(regression): caught errors\"",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2023-05-31T08:47:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5f19667948f16db38e534c9128b750778f00b90a",
          "body": "Signed-off-by: Sami Mazouz <sychocouldy@gmail.com>",
          "is_bot": false,
          "headline": "fix(regression): caught errors",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2023-05-31T08:45:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "604129aded5738757c4ad544f1dd9de9023637f2",
          "body": "* chore: set minimum php version to 8.1\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@gmail.com>\r\n\r\n* chore: update codebase to php8.1\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@gmail.com>\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* chore: update workflow php version\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@g\n[…]\nail.com>\r\n\r\n* fix: one last error\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@gmail.com>\r\n\r\n---------\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@gmail.com>\r\nCo-authored-by: StyleCI Bot <bot@styleci.io>",
          "is_bot": false,
          "headline": "chore: update codebase to php8.1 (#3827)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2023-05-30T10:36:12Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c927947b7cd05ea927268ac45b5c821e6dd7d866",
          "body": "Signed-off-by: Sami Mazouz <sychocouldy@gmail.com>",
          "is_bot": false,
          "headline": "chore: v1.8 preparations",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2023-05-20T15:08:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f86ba94b608f957bc49a004e39459b45caf966a1",
          "body": "Bumps [webpack](https://github.com/webpack/webpack) from 5.75.0 to 5.76.0.\r\n- [Release notes](https://github.com/webpack/webpack/releases)\r\n- [Commits](https://github.com/webpack/webpack/compare/v5.75.0...v5.76.0)\r\n\r\n---\r\nupdated-dependencies:\r\n- dependency-name: webpack\r\n  dependency-type: direct:production\r\n...\r\n\r\nSigned-off-by: dependabot[bot] <support@github.com>\r\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): bump webpack from 5.75.0 to 5.76.0 (#3761)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2023-04-19T06:45:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6538996c5ee4bf67a5fe5d41914226b904236ac8",
          "body": "Signed-off-by: Sami Mazouz <sychocouldy@gmail.com>",
          "is_bot": false,
          "headline": "fix: approving a post does not bump user `comment_count` (#3790)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2023-04-16T20:13:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6c1283a69589e47bdf4bcbbb5fbcf0bb8b98ea57",
          "body": "Signed-off-by: Sami Mazouz <sychocouldy@gmail.com>",
          "is_bot": false,
          "headline": "chore(release): preparations",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2023-03-09T18:00:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "767beef696f82acfc21bef40140f3bbb13c322f6",
          "body": "* feat(phpstan): pick up extended model relations typings\r\n* feat(phpstan): pick up extended model date attributes\r\n* feat(core): introduce `castAttribute` extender\r\nStops using `dates` as it's deprecated in laravel 8\r\n* feat(phpstan): pick up extended model attributes through casts\r\n* fix: extender\n[…]\n\r\n* chore: enable phpstan in bundled extensions\r\n* chore: rebasing conflicts\r\n* chore: rebasing conflicts\r\n* chore: typings for latest 1.7 changes\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@gmail.com>",
          "is_bot": false,
          "headline": "chore(phpstan): enable phpstan in bundled extensions (#3667)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2023-01-19T20:49:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1e01f0efc579cec2cfa437dba0ef98dec154cbde",
          "body": "Includes transpiled JS/TS, and Typescript declaration files (typings).\n\n[skip ci]",
          "is_bot": false,
          "headline": "Bundled output for commit 64fa35f2f350f98d213b87da6fcd72d465823b18",
          "author_name": "flarum-bot",
          "author_login": "flarum-bot",
          "committed_at": "2022-11-25T17:25:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "26d8aa0930a7ca0b296e1ceb6e6f07d1d5a9b24f",
          "body": "Includes transpiled JS/TS, and Typescript declaration files (typings).\n\n[skip ci]",
          "is_bot": false,
          "headline": "Bundled output for commit 18bdd48835a6783a3cea8f400932e87d7582fc7d",
          "author_name": "flarum-bot",
          "author_login": "flarum-bot",
          "committed_at": "2022-11-16T10:30:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2d1e61f6cf564cb01df0e0ce496dd369e9784dbc",
          "body": "Includes transpiled JS/TS, and Typescript declaration files (typings).\n\n[skip ci]",
          "is_bot": false,
          "headline": "Bundled output for commit 259db92b9a8da063116e38c4034fe6c1bef42cbf",
          "author_name": "flarum-bot",
          "author_login": "flarum-bot",
          "committed_at": "2022-11-10T23:30:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e8ec7ae114547ccb5bbd4fb49cad26dbd82e646f",
          "body": null,
          "is_bot": false,
          "headline": "chore: dependency on core updated for extensions",
          "author_name": "Daniël Klabbers",
          "author_login": "luceos",
          "committed_at": "2022-11-10T12:48:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b6b7e568c24560583398c8ca1f89699c336d1653",
          "body": "* test(subscriptions): approved reply sends out notifications to users\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@gmail.com>\r\n\r\n* feat: send notifications when a post is approved\r\n\r\nThe code in approval was extracted into a listener because no matter what listeners are always executed before subscribers even if the extension is set to load before.\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@gmail.com>\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@gmail.com>",
          "is_bot": false,
          "headline": "feat: send notifications of a new reply when post is approved (#3656)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2022-11-07T11:52:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4cfae1a0823e0c33c7977d16a2b1741433482c3e",
          "body": null,
          "is_bot": false,
          "headline": "Apply fixes from StyleCI",
          "author_name": "StyleCI Bot",
          "author_login": "StyleCIBot",
          "committed_at": "2022-09-22T08:21:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "656713b750e1de22897854df248f5101188d4437",
          "body": "In certain edge cases posts get approved through moderative action and\nthrows an error when the user has already been deleted.\n\nRef: DISCUSS-11K on sentry",
          "is_bot": false,
          "headline": "fix(approval): posts approved for deleted users error",
          "author_name": "Daniël Klabbers",
          "author_login": "luceos",
          "committed_at": "2022-09-22T08:20:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e0acf8edcc4178013ac08645f53589154987dcc1",
          "body": null,
          "is_bot": false,
          "headline": "chore: v1.5.0 preparations",
          "author_name": "Daniël Klabbers",
          "author_login": "luceos",
          "committed_at": "2022-09-13T08:55:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8e67cdf0808bf6af8fba747db464676a3d649465",
          "body": "Includes transpiled JS/TS.\n\n[skip ci]",
          "is_bot": false,
          "headline": "Bundled output for commit bb641144b6bc5c59798351459fbf8df8cbf6aec6",
          "author_name": "flarum-bot",
          "author_login": "flarum-bot",
          "committed_at": "2022-08-02T11:36:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b11b51b1c26b6828e674abfb31ad5c8b65b63f08",
          "body": "* chore: use subscribers\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* Un-static\r\n\r\nCo-authored-by: StyleCI Bot <bot@styleci.io>",
          "is_bot": false,
          "headline": "chore(approval, likes): use subscribers (#3577)",
          "author_name": "Ian Morland",
          "author_login": "imorland",
          "committed_at": "2022-08-02T10:27:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c89b911432ec47551c441f28968c1054834607c2",
          "body": "* chore: centralize editorconfig\r\n* chore: tweak tsconfigs for local development\r\n* revert src path change\r\n* fix: akismet type checking requires flag ext `@types`\r\n* fix: make tags route optional to avoid typescript typing error",
          "is_bot": false,
          "headline": "chore: monorepo local development improvements (#3523)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2022-07-18T14:19:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b949cf8b1553781a62dde32a0326608ea6db479e",
          "body": null,
          "is_bot": false,
          "headline": "chore: update v1.4 constraints and update issues url",
          "author_name": "Daniël Klabbers",
          "author_login": "luceos",
          "committed_at": "2022-07-12T21:30:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e99e89fa7244e98ee9c0fe45cd46ca65be199094",
          "body": "…513)\n\nSigned-off-by: Sami Mazouz <ilyasmazouz@gmail.com>",
          "is_bot": false,
          "headline": "chore: add `.gitattributes` to extensions to export-ignore files. (#3…",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2022-07-08T19:38:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eef61384adb54e508ca329382152ea853c5ddd72",
          "body": "…pers are added\n\nSigned-off-by: Sami Mazouz <ilyasmazouz@gmail.com>",
          "is_bot": false,
          "headline": "fix(approval): unapproved posts visible to all when no visibility sco…",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2022-07-08T18:16:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c1f34a6fa509672c290e1aedae88027301a4251d",
          "body": "Signed-off-by: Sami Mazouz <ilyasmazouz@gmail.com>",
          "is_bot": false,
          "headline": "test(approval): unapproved content can only be seen by allowed users",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2022-07-08T18:16:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "83ba3403469a0dc0a0aa165aabbfb8bf387df862",
          "body": "* chore: yarn workspaces means we only need a single `yarn.lock`\r\n* fix: add a `cache_dependency_path` workflow input\r\n* fix: re-introduce `env.cache_dependency_path`",
          "is_bot": false,
          "headline": "chore: with yarn workspaces we only need a single `yarn.lock` (#3464)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2022-06-19T18:01:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6f18506101990f9a9f990dbd8c3721ebf29ec426",
          "body": null,
          "is_bot": false,
          "headline": "update constraint to v1.3",
          "author_name": "Daniël Klabbers",
          "author_login": "luceos",
          "committed_at": "2022-05-10T14:28:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5791efdb4c44f61ba373691024b8aadd2fb9e653",
          "body": null,
          "is_bot": false,
          "headline": "feat: deprecate discussion `post_number_index` field.",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2022-03-31T06:46:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d46f08dfbe117a604be3d4e5aa27eb41ed7ba1d8",
          "body": "With all the commits below, we resolve all outstanding typing issues in the repo, and CI jobs run green.\r\n\r\n* fix: Convert DashboardPage and DashboardWidget to TypeScript\r\n\r\n* fix: fix type errors in package manager ext\r\n\r\n* fix: Convert Post component to TypeScript\r\n\r\n* fix: avatar typings should a\n[…]\nlarum-cli audit infra --monorepo --fix\r\n\r\n* feat: make `app.data` typings extensible\r\n\r\n* chore(core): format\r\n\r\n* chore: boost tags TypeScript coverage\r\n\r\n* fix(tags): further increase type coverage.",
          "is_bot": false,
          "headline": "fix: Assorted Typing Fixes (#3348)",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2022-03-23T15:43:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8c34f72b9ea68f111a71b81fa54da6d6c06a2ec0",
          "body": "This is necessary for yarn workspaces to work.",
          "is_bot": false,
          "headline": "chore: add version to core/ext package.json",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2022-03-12T00:12:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "31cd6cc474c9ad43803bbb596b8dcb11e8e4a65b",
          "body": null,
          "is_bot": false,
          "headline": "chore: flarum-cli audit infra --fix",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2022-03-11T23:02:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "250878e921e11d6880e636f33cc3433e2728d160",
          "body": null,
          "is_bot": false,
          "headline": "chore: set up composer path repos",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2022-03-11T23:02:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5477fe156116e8d0404db9c4612a1e8760d31b73",
          "body": "- Remove .github conf folder from Flarum packages\n\n- Remove styleci config from all packages",
          "is_bot": false,
          "headline": "chore: remove centralizable repo config",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2022-03-11T23:01:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b88100d3db35e688f6fdcea083539d18c38d27f2",
          "body": null,
          "is_bot": false,
          "headline": "Release v1.2",
          "author_name": "Daniel Klabbers",
          "author_login": "luceos",
          "committed_at": "2022-01-20T10:55:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f07126f684ab0dbe58a65b47ccef5889d7b7bd9e",
          "body": null,
          "is_bot": false,
          "headline": "Merge branch 'master' of github.com:flarum/approval",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2022-01-20T08:24:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c9b8cdec2f5a704f195b045c7aa712905a906fe7",
          "body": null,
          "is_bot": false,
          "headline": "chore: remove unnecessary tsconfig",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2022-01-20T08:24:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4f9333ad8c08e690b332fad53d2b2fec4c5c19f9",
          "body": "Includes transpiled JS/TS.\n\n[skip ci]",
          "is_bot": false,
          "headline": "Bundled output for commit 05246fb155cd43dba1e71caa5d481c84509c00e4",
          "author_name": "flarum-bot",
          "author_login": "flarum-bot",
          "committed_at": "2022-01-20T08:16:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f6c002b86a9116242b716e14e96b00eac4a8ad2f",
          "body": null,
          "is_bot": false,
          "headline": "chore: flarum-cli audit infra --fix",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2022-01-20T08:14:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b8359596ec0c2949fefe1923514855a05d1cbdc7",
          "body": "Includes transpiled JS/TS.\n\n[skip ci]",
          "is_bot": false,
          "headline": "Bundled output for commit 200d48820996207938b3732cd87336d1b8648c2d",
          "author_name": "flarum-bot",
          "author_login": "flarum-bot",
          "committed_at": "2022-01-11T10:44:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "07b07eedeee626b78a7d644f3e44e0ee5df852ab",
          "body": "* Bump deps\r\n\r\n* Update imports\r\n\r\n* format",
          "is_bot": false,
          "headline": "chore: repo maintenance (#28)",
          "author_name": "Ian Morland",
          "author_login": "imorland",
          "committed_at": "2022-01-11T10:43:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "df8a12a5fdc6d0ec695f53c2b095c3ecb5d5bcc3",
          "body": "Includes transpiled JS/TS.\n\n[skip ci]",
          "is_bot": false,
          "headline": "Bundled output for commit 152a9bed14791797c53cd500db703abe2faed6c1",
          "author_name": "flarum-bot",
          "author_login": "flarum-bot",
          "committed_at": "2021-10-13T11:06:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "55e99dd554b90fb98736263296336c34a960f493",
          "body": null,
          "is_bot": false,
          "headline": "chore: fix JS",
          "author_name": "David Wheatley",
          "author_login": "davwheat",
          "committed_at": "2021-10-13T11:05:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c4e8ead35ba86898f629deed9a21bdda63f23224",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump bundled extension constraint to core 1.1",
          "author_name": "David Wheatley",
          "author_login": "davwheat",
          "committed_at": "2021-10-13T07:05:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "caef2c40b77ee70f7a6fe7a7f9ba8caa362fff5b",
          "body": "Includes transpiled JS/TS.\n\n[skip ci]",
          "is_bot": false,
          "headline": "Bundled output for commit ad168f345c105869045eb0e766d0d0b815c08764",
          "author_name": "flarum-bot",
          "author_login": "flarum-bot",
          "committed_at": "2021-10-12T01:27:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f416d826ec288042c2157b63091d9d9b185b0c90",
          "body": null,
          "is_bot": false,
          "headline": "Release v1.1.0",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-10-12T01:02:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "65bb7b45a7664db2a9505351750e0bf37541eb09",
          "body": null,
          "is_bot": false,
          "headline": "fix branch alias",
          "author_name": "Daniel Klabbers",
          "author_login": "luceos",
          "committed_at": "2021-05-25T20:44:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "db5192d747afe08eb6a617951187a7041c30b71f",
          "body": null,
          "is_bot": false,
          "headline": "changes for stable",
          "author_name": "Daniel Klabbers",
          "author_login": "luceos",
          "committed_at": "2021-05-25T13:13:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "15d10d8b443841f024310c5d35a527f2d8274156",
          "body": null,
          "is_bot": false,
          "headline": "Bump composer reqs for 1.0.0",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-05-16T22:27:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8f53b3b7fae624f2a8619bf307ae6ba1a49bd33e",
          "body": null,
          "is_bot": false,
          "headline": "Update copyright year",
          "author_name": "David Wheatley",
          "author_login": "davwheat",
          "committed_at": "2021-05-14T23:47:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7a05e1137159d928a082d3442db742e2e3be9dd0",
          "body": null,
          "is_bot": false,
          "headline": "Massively simplify TagPolicy",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-05-12T02:16:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9d8ebf82c0489b3a141f3c5dbc67340ee5ab1174",
          "body": "Wrapping all `wheres` in an `orWhere` ensures that there's no conflict.\r\n\r\nSee https://github.com/flarum/core/issues/2798, https://github.com/flarum/docs/pull/200",
          "is_bot": false,
          "headline": "Fix conflicts with other extension visibility scoping (#26)",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-04-20T18:51:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "21bb624b4fd43fd6f05d02dc0ef9b358b3dd1608",
          "body": null,
          "is_bot": false,
          "headline": "forgot one change in changelog",
          "author_name": "Daniel Klabbers",
          "author_login": "luceos",
          "committed_at": "2021-03-15T09:24:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ec2fe024e4f2b5ff67ff81d7a81666b5e6e4003d",
          "body": null,
          "is_bot": false,
          "headline": "Release v0.1.0-beta.16",
          "author_name": "Daniel Klabbers",
          "author_login": "luceos",
          "committed_at": "2021-03-15T09:23:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "063035bba1b3219db0db1efc9d981f3d0502f66d",
          "body": null,
          "is_bot": false,
          "headline": "Update to use new extenders",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-03-13T20:15:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d3bf2d070c80b76e7b1d5cf4ae4de03234ba89df",
          "body": null,
          "is_bot": false,
          "headline": "Change Category (#24)",
          "author_name": "Charlie",
          "author_login": "KyrneDev",
          "committed_at": "2021-03-08T19:22:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "758e5be0eff8115d8f341f65cbced7252871bba0",
          "body": "…nt (#16)",
          "is_bot": false,
          "headline": "ApproveContent then refresh user table DiscussionCount and CommentCou…",
          "author_name": "imzhi",
          "author_login": "imzhi",
          "committed_at": "2021-02-19T13:18:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a6c09f1877744f21c2910677fb7c2e4645ea1402",
          "body": null,
          "is_bot": false,
          "headline": "Move locale files from language pack to extension. (#22)",
          "author_name": "Robert Korulczyk",
          "author_login": "rob006",
          "committed_at": "2021-02-17T21:26:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 33,
      "commits_last_year": 22,
      "latest_release_at": "2026-07-08T15:54:36Z",
      "latest_release_tag": "v2.0.0-rc.5",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 14,
      "days_since_latest_release": 23,
      "mean_days_between_releases": 48
    },
    "community": {
      "has_readme": false,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 62,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": true
    },
    "ecosystem": {
      "packages": [
        {
          "name": "flarum/approval",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "moderation"
          ],
          "ecosystem": "packagist",
          "matches_repo": true,
          "registry_url": "https://packagist.org/packages/flarum/approval",
          "is_deprecated": false,
          "latest_version": "v2.0.0-rc.5",
          "repository_url": "https://github.com/flarum/approval",
          "versions_count": 35,
          "total_downloads": 479208,
          "dependents_count": 37,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": 14012,
          "first_published_at": null,
          "latest_published_at": "2026-07-08T15:08:06Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 23
        }
      ]
    },
    "popularity": {
      "forks": 11,
      "stars": 10,
      "watchers": 7,
      "fork_history": {
        "days": [
          {
            "date": "2015-12-26",
            "count": 1
          },
          {
            "date": "2016-08-26",
            "count": 1
          },
          {
            "date": "2017-02-12",
            "count": 1
          },
          {
            "date": "2017-05-14",
            "count": 1
          },
          {
            "date": "2017-09-13",
            "count": 1
          },
          {
            "date": "2017-10-06",
            "count": 1
          },
          {
            "date": "2018-07-19",
            "count": 1
          },
          {
            "date": "2020-02-27",
            "count": 1
          },
          {
            "date": "2020-04-22",
            "count": 1
          },
          {
            "date": "2021-08-02",
            "count": 1
          },
          {
            "date": "2024-01-23",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 11,
        "total_forks": 11
      },
      "star_history": null,
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "js/tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 7489,
      "source_files_sampled": 30,
      "oversized_source_files": 0,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "composer.json",
        "js/package.json"
      ],
      "advisories": {
        "error": "No resolved dependencies carried a version and a supported ecosystem",
        "scope": "repository_graph",
        "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": 13,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm",
        "packagist"
      ],
      "dependencies": [
        {
          "name": "flarum/core",
          "manifest": "composer.json",
          "ecosystem": "packagist",
          "version_constraint": "^2.0.0-rc.5"
        },
        {
          "name": "flarum/flags",
          "manifest": "composer.json",
          "ecosystem": "packagist",
          "version_constraint": "^2.0"
        }
      ],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "flarum/core",
            "direct": true,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "flarum/flags",
            "direct": true,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "@flarum/prettier-config",
            "direct": false,
            "version": "^1.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "flarum-tsconfig",
            "direct": false,
            "version": "^2.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "flarum-webpack-config",
            "direct": false,
            "version": "^3.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "prettier",
            "direct": false,
            "version": "^2.5.1",
            "ecosystem": "npm"
          },
          {
            "name": "typescript",
            "direct": false,
            "version": "^4.5.4",
            "ecosystem": "npm"
          },
          {
            "name": "typescript-coverage-report",
            "direct": false,
            "version": "^0.6.1",
            "ecosystem": "npm"
          },
          {
            "name": "webpack",
            "direct": false,
            "version": "^5.104.1",
            "ecosystem": "npm"
          },
          {
            "name": "webpack-cli",
            "direct": false,
            "version": "^4.9.1",
            "ecosystem": "npm"
          },
          {
            "name": "flarum/audit",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "flarum/tags",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "flarum/testing",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 13,
        "direct_count": 2,
        "indirect_count": 11
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 0,
        "merged_prs": 24,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 5
      },
      "bus_factor": 3,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "tobyzerner",
          "commits": 59,
          "avatar_url": "https://avatars.githubusercontent.com/u/128862?v=4"
        },
        {
          "type": "User",
          "login": "SychO9",
          "commits": 29,
          "avatar_url": "https://avatars.githubusercontent.com/u/20267363?v=4"
        },
        {
          "type": "User",
          "login": "flarum-bot",
          "commits": 26,
          "avatar_url": "https://avatars.githubusercontent.com/u/39334649?v=4"
        },
        {
          "type": "User",
          "login": "askvortsov1",
          "commits": 25,
          "avatar_url": "https://avatars.githubusercontent.com/u/38059171?v=4"
        },
        {
          "type": "User",
          "login": "franzliedke",
          "commits": 19,
          "avatar_url": "https://avatars.githubusercontent.com/u/249125?v=4"
        },
        {
          "type": "User",
          "login": "imorland",
          "commits": 19,
          "avatar_url": "https://avatars.githubusercontent.com/u/16573496?v=4"
        },
        {
          "type": "User",
          "login": "luceos",
          "commits": 16,
          "avatar_url": "https://avatars.githubusercontent.com/u/504687?v=4"
        },
        {
          "type": "User",
          "login": "davwheat",
          "commits": 3,
          "avatar_url": "https://avatars.githubusercontent.com/u/7406822?v=4"
        },
        {
          "type": "User",
          "login": "AakLak",
          "commits": 2,
          "avatar_url": "https://avatars.githubusercontent.com/u/30278646?v=4"
        },
        {
          "type": "User",
          "login": "milescellar",
          "commits": 2,
          "avatar_url": "https://avatars.githubusercontent.com/u/160068451?v=4"
        }
      ],
      "contributors_sampled": 20,
      "top_contributor_share": 0.281
    },
    "quality_signals": {
      "has_ci": false,
      "has_tests": true,
      "ci_workflows": [],
      "has_docs_dir": false,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": null,
            "reason": "no pull request found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 21 contributing companies or organizations",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": null,
            "reason": "no workflows found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 10,
            "reason": "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": 6,
            "reason": "8 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 6",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": null,
            "reason": "no dependencies found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "no SAST tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 10,
            "reason": "security policy file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": null,
            "reason": "No tokens found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 10,
            "reason": "0 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "68649f8b09643ce0f0157fddf47afe1937e90780",
        "ran_at": "2026-07-31T23:38:03Z",
        "aggregate_score": 5.5,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-31T23:35:21Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": "2022-01-11T10:43:15Z",
      "ci_last_conclusion": null,
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/flarum/approval",
    "host": "github.com",
    "name": "approval",
    "owner": "flarum"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 56,
      "inputs": {
        "security": 55,
        "vitality": 75,
        "community": 46,
        "governance": 77,
        "engineering": 22
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 75,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 64,
            "inputs": {
              "commits_last_year": 22,
              "human_commit_share": 0.98,
              "days_since_last_push": 0,
              "active_weeks_last_year": 14
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "14/52 weeks with commits",
                "points": 9.7,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 14
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "22 commits in the last year",
                "points": 12.2,
                "status": "partial",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 22
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "8 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 6",
                "points": 6,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 92,
            "inputs": {
              "releases_count": 33,
              "latest_release_tag": "v2.0.0-rc.5",
              "releases_from_tags": false,
              "days_since_latest_release": 23,
              "mean_days_between_releases": 48
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "33 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 33
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 23 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 23
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~48 days",
                "points": 19.8,
                "status": "partial",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 48
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "maintained",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": null,
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": 0,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 0 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 46,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 28,
            "inputs": {
              "forks": 11,
              "stars": 10,
              "watchers": 7,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "10 stars",
                "points": 15.5,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 10
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "11 forks",
                "points": 8.3,
                "status": "partial",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 11
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "7 watchers",
                "points": 4.3,
                "status": "partial",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 7
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 52,
            "inputs": {
              "has_readme": false,
              "has_license": true,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 0,
                "status": "missed",
                "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": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 6.3,
                "status": "met",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "moderate",
            "name": "Ecosystem adoption (downloads)",
            "note": null,
            "notes": [],
            "value": 66,
            "inputs": {
              "packages": [
                "flarum/approval"
              ],
              "dependents": 37,
              "ecosystems": "packagist",
              "total_downloads": 479208,
              "monthly_downloads": 14012
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "14,012 downloads/month across packagist",
                "points": 55.3,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 14012,
                      "ecosystems": "packagist"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "37 packages depend on it",
                "points": 10.5,
                "status": "partial",
                "details": [
                  {
                    "code": "registry_dependents",
                    "params": {
                      "count": 37
                    }
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "good",
        "name": "Sustainability & Governance",
        "value": 77,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "good",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 76,
            "inputs": {
              "bus_factor": 3,
              "contributors_sampled": 20,
              "top_contributor_share": 0.281
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "3 contributor(s) cover half of all commits",
                "points": 36,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 28% of commits",
                "points": 16.2,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 28
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "20 contributors",
                "points": 13.5,
                "status": "met",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 20
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 21 contributing companies or organizations",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "moderate",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 60,
            "inputs": {
              "merged_prs": 24,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 5
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "24/29 decided PRs merged",
                "points": 31.7,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 24,
                      "decided": 29
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "good",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 76,
            "inputs": {
              "followers": 798,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "flarum",
              "public_repos": 53,
              "account_age_days": 4691
            },
            "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": "798 followers of flarum",
                "points": 20.9,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 798,
                      "login": "flarum"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "53 public repos, account ~12 yr old",
                "points": 24.6,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 53
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 12
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "flarum/approval"
              ],
              "ecosystems": "packagist",
              "any_deprecated": false,
              "min_days_since_publish": 23
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on packagist",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "packagist"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 23 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 23
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "35 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 35
                    }
                  }
                ],
                "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": "critical",
        "name": "Engineering Quality",
        "value": 22,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "at_risk",
            "name": "Engineering practices",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 30,
            "inputs": {
              "has_ci": false,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "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": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "critical",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 10,
            "inputs": {
              "topics": [],
              "has_wiki": false,
              "homepage": null,
              "has_readme": false,
              "has_docs_dir": false,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 55,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "moderate",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): CI-Tests, Dangerous-Workflow, Packaging, Pinned-Dependencies, Signed-Releases, Token-Permissions. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "ci_tests",
                    "dangerous_workflow",
                    "packaging",
                    "pinned_dependencies",
                    "signed_releases",
                    "token_permissions"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 55,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 12,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 6,
              "scorecard_aggregate": 5.5
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 21 contributing companies or organizations",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no workflows found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "update tool detected",
                "points": 7.5,
                "status": "met",
                "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": "8 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 6",
                "points": 4.5,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "no dependencies found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "no SAST tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "No tokens found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "0 existing vulnerabilities detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 19
            },
            "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": 53,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.796,
              "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": "78 of 98 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 78,
                      "sampled": 98
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Pinned-Dependencies. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_pinned_dependencies"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 52,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "js/tsconfig.json"
              ],
              "agent_commit_share": 0.03,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0.02
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "js/tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "js/tsconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "3 of the last 100 commits agent-authored or agent-credited",
                "points": 6,
                "status": "partial",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 3,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "2 of the last 100 commits are automated dependency updates",
                "points": 8,
                "status": "met",
                "details": [
                  {
                    "code": "dependency_bot_commits",
                    "params": {
                      "count": 2,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "no dependencies found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "good",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 82,
            "inputs": {
              "primary_language": "PHP",
              "largest_source_bytes": 7489,
              "source_files_sampled": 30,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "PHP with type-check config (js/tsconfig.json)",
                "points": 27,
                "status": "partial",
                "details": [
                  {
                    "code": "typecheck_config_language",
                    "params": {
                      "files": "js/tsconfig.json",
                      "language": "PHP"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/30 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 30,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "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",
    "No resolved dependencies carried a version and a supported ecosystem"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-31T23:38:16.116143Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/f/flarum/approval.svg",
  "full_name": "flarum/approval",
  "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 statisticsPackagist.