Звіт у форматі JSON машиночитний
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 1953,
"has_wiki": false,
"homepage": "https://gerrit.wikimedia.org",
"languages": {
"PHP": 471985,
"Shell": 151
},
"pushed_at": "2026-05-06T19:49:58Z",
"created_at": "2012-11-01T19:33:40Z",
"owner_type": "Organization",
"updated_at": "2026-07-21T10:57:57Z",
"description": "Mirror of https://gerrit.wikimedia.org/g/mediawiki/tools/codesniffer. Please see https://www.mediawiki.org/wiki/Developer_access for contributing",
"is_archived": false,
"is_disabled": false,
"license_spdx": "GPL-2.0",
"default_branch": "master",
"license_spdx_raw": "GPL-2.0",
"primary_language": "PHP",
"significant_languages": [
"PHP"
]
},
"owner": {
"blog": "https://www.wikimedia.org",
"name": "Wikimedia",
"type": "Organization",
"login": "wikimedia",
"company": null,
"location": "United States of America",
"followers": 2188,
"avatar_url": "https://avatars.githubusercontent.com/u/56668?v=4",
"created_at": "2009-02-21T20:22:30Z",
"is_verified": null,
"public_repos": 1963,
"account_age_days": 6365
},
"license": {
"state": "standard",
"spdx_id": "GPL-2.0",
"raw_spdx": "GPL-2.0",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v51.0.0",
"kind": "major",
"published_at": "2026-05-03T06:29:24Z"
},
{
"tag": "v50.0.0",
"kind": "major",
"published_at": "2026-02-10T11:49:03Z"
},
{
"tag": "v49.0.0",
"kind": "major",
"published_at": "2026-01-11T00:02:41Z"
},
{
"tag": "v48.0.0",
"kind": "major",
"published_at": "2025-09-04T20:12:57Z"
},
{
"tag": "v47.0.0",
"kind": "major",
"published_at": "2025-05-04T07:30:05Z"
},
{
"tag": "v46.0.0",
"kind": "major",
"published_at": "2025-01-27T21:05:44Z"
},
{
"tag": "v45.0.0",
"kind": "major",
"published_at": "2024-10-29T17:38:15Z"
},
{
"tag": "v44.0.0",
"kind": "major",
"published_at": "2024-08-10T11:11:32Z"
},
{
"tag": "v43.0.0",
"kind": "major",
"published_at": "2024-01-29T16:06:37Z"
},
{
"tag": "v42.0.0",
"kind": "major",
"published_at": "2023-09-21T13:34:41Z"
},
{
"tag": "v41.0.0",
"kind": "major",
"published_at": "2023-02-25T22:10:21Z"
},
{
"tag": "v40.0.1",
"kind": "patch",
"published_at": "2022-11-01T20:02:35Z"
},
{
"tag": "v40.0.0",
"kind": "major",
"published_at": "2022-11-01T19:15:19Z"
},
{
"tag": "v39.0.0",
"kind": "major",
"published_at": "2022-05-04T16:19:01Z"
},
{
"tag": "v38.0.0",
"kind": "major",
"published_at": "2021-10-21T18:15:41Z"
},
{
"tag": "v37.0.0",
"kind": "major",
"published_at": "2021-07-20T17:50:07Z"
},
{
"tag": "v36.0.0",
"kind": "major",
"published_at": "2021-04-29T02:21:21Z"
},
{
"tag": "v35.0.0",
"kind": "major",
"published_at": "2021-01-28T20:56:31Z"
},
{
"tag": "v34.0.0",
"kind": "major",
"published_at": "2020-12-05T07:12:58Z"
},
{
"tag": "v33.0.0",
"kind": "major",
"published_at": "2020-10-30T16:03:08Z"
},
{
"tag": "v32.0.0",
"kind": "major",
"published_at": "2020-10-26T15:57:52Z"
},
{
"tag": "v31.0.0",
"kind": "major",
"published_at": "2020-05-26T19:06:48Z"
},
{
"tag": "v30.0.0",
"kind": "major",
"published_at": "2020-02-19T12:55:25Z"
},
{
"tag": "v29.0.0",
"kind": "major",
"published_at": "2020-01-09T18:09:25Z"
},
{
"tag": "v28.0.0",
"kind": "major",
"published_at": "2019-10-09T13:13:13Z"
},
{
"tag": "v27.0.0",
"kind": "major",
"published_at": "2019-10-03T10:34:50Z"
},
{
"tag": "v26.0.0",
"kind": "major",
"published_at": "2019-05-10T23:43:13Z"
},
{
"tag": "25.0.0",
"kind": "major",
"published_at": "2019-04-05T21:56:35Z"
},
{
"tag": "v24.0.0",
"kind": "major",
"published_at": "2019-02-06T03:17:18Z"
},
{
"tag": "v23.0.0",
"kind": "major",
"published_at": "2018-11-14T01:45:17Z"
},
{
"tag": "v22.0.0",
"kind": "major",
"published_at": "2018-09-02T08:19:25Z"
},
{
"tag": "v21.0.0",
"kind": "major",
"published_at": "2018-07-26T03:51:46Z"
},
{
"tag": "v20.0.0",
"kind": "major",
"published_at": "2018-05-24T18:18:33Z"
},
{
"tag": "19.4.0",
"kind": "minor",
"published_at": "2021-01-12T21:27:05Z"
},
{
"tag": "19.3.0",
"kind": "minor",
"published_at": "2021-01-12T20:41:09Z"
},
{
"tag": "v19.2.0",
"kind": "minor",
"published_at": "2019-02-06T04:15:49Z"
},
{
"tag": "19.1.0",
"kind": "minor",
"published_at": "2018-10-23T00:24:06Z"
},
{
"tag": "v19.0.0",
"kind": "major",
"published_at": "2018-05-24T17:18:06Z"
},
{
"tag": "v18.0.0",
"kind": "major",
"published_at": "2018-04-13T18:30:54Z"
},
{
"tag": "v17.0.0",
"kind": "major",
"published_at": "2018-03-28T17:44:06Z"
},
{
"tag": "v16.0.1",
"kind": "patch",
"published_at": "2018-02-24T07:47:50Z"
},
{
"tag": "v16.0.0",
"kind": "major",
"published_at": "2018-02-15T06:07:17Z"
},
{
"tag": "v15.0.0",
"kind": "major",
"published_at": "2017-12-29T20:25:40Z"
},
{
"tag": "v14.1.0",
"kind": "minor",
"published_at": "2017-10-21T02:22:31Z"
},
{
"tag": "v14.0.0",
"kind": "major",
"published_at": "2017-10-21T02:04:11Z"
},
{
"tag": "v13.0.0",
"kind": "major",
"published_at": "2017-09-24T03:33:15Z"
},
{
"tag": "v0.12.0",
"kind": "minor",
"published_at": "2017-08-30T06:01:51Z"
},
{
"tag": "v0.11.1",
"kind": "patch",
"published_at": "2017-08-13T18:23:02Z"
},
{
"tag": "v0.11.0",
"kind": "minor",
"published_at": "2017-08-11T02:17:24Z"
},
{
"tag": "v0.10.1",
"kind": "patch",
"published_at": "2017-07-23T00:59:17Z"
},
{
"tag": "v0.10.0",
"kind": "minor",
"published_at": "2017-07-01T00:43:26Z"
},
{
"tag": "v0.9.0",
"kind": "minor",
"published_at": "2017-06-20T02:10:42Z"
},
{
"tag": "v0.8.1",
"kind": "patch",
"published_at": "2017-07-05T20:52:44Z"
},
{
"tag": "v0.8.0",
"kind": "minor",
"published_at": "2017-05-04T19:15:03Z"
},
{
"tag": "v0.8.0-alpha.1",
"kind": "prerelease",
"published_at": "2016-09-22T03:45:15Z"
},
{
"tag": "v0.7.2",
"kind": "patch",
"published_at": "2016-05-28T01:08:59Z"
},
{
"tag": "v0.7.1",
"kind": "patch",
"published_at": "2016-05-06T19:53:37Z"
},
{
"tag": "v0.7.0",
"kind": "minor",
"published_at": "2016-05-06T19:34:07Z"
},
{
"tag": "v0.6.0",
"kind": "minor",
"published_at": "2016-02-17T10:22:13Z"
},
{
"tag": "v0.5.1",
"kind": "patch",
"published_at": "2015-12-29T01:03:51Z"
},
{
"tag": "v0.5.0",
"kind": "minor",
"published_at": "2015-10-23T07:51:32Z"
},
{
"tag": "v0.4.0",
"kind": "minor",
"published_at": "2015-09-26T21:34:16Z"
},
{
"tag": "v0.3.0",
"kind": "minor",
"published_at": "2015-06-19T16:36:59Z"
},
{
"tag": "v0.2.0",
"kind": "minor",
"published_at": "2015-06-02T18:42:05Z"
},
{
"tag": "0.1.0",
"kind": "minor",
"published_at": "2015-01-05T21:59:34Z"
}
],
"recent_commits": [
{
"oid": "9fd2bf1d8e772ce9ee253862574235a2b38f4215",
"body": "Depends-On: I5f3bd59cdc1e6f398e8969802ecc4260789f4630\nDepends-On: I3eb0b7cb85d0ba3d37261c8d61ec873f1573be31\nDepends-On: Id92677e30a1f59cc516c933cbcac45ca6aad6aee\nChange-Id: I5b0fe75e6b42cab54227a837f4dd42373b164550",
"is_bot": false,
"headline": "Deprecate $wgLang",
"author_name": "MGChecker",
"author_login": "MGChecker",
"committed_at": "2026-05-06T19:49:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f1d68132f2cca6fd36b7816988a53450909ca88d",
"body": "Change-Id: I4e434cf0b67178c9e6b07f04cd436d47655f93c9",
"is_bot": false,
"headline": "Drop support for PHP 8.2",
"author_name": "Alexander Vorwerk",
"author_login": "ZabeMath",
"committed_at": "2026-05-03T10:23:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9d8a2f4be6d5abe217dfb3b2483263b3c233603f",
"body": "Depends-On: I1134415f9bba7ea01e65012b49c9b5e3c37c092a\nChange-Id: Ida6e9ac70450a83f86ecc49e5782d2a0cb1a37d9",
"is_bot": false,
"headline": "Drop support for composer/spdx-licenses 1.5.*",
"author_name": "Alexander Vorwerk",
"author_login": "ZabeMath",
"committed_at": "2026-05-03T10:23:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d9f3595b7e9c73b1f725b0074ac04670c707211e",
"body": "Change-Id: I72481161760355c75948250d4466b24e316df5f1",
"is_bot": false,
"headline": "Release v51.0.0",
"author_name": "James D. Forrester",
"author_login": "jdforrester",
"committed_at": "2026-05-03T06:29:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c76359921d059406b676bea55120354289693dca",
"body": "Change-Id: Ie16f985f9f9d9783e11aae32cbdb3ed15275ad94",
"is_bot": false,
"headline": "Upgrading phpcsstandards/phpcsextra (1.4.0 => 1.5.0)",
"author_name": "Alexander Vorwerk",
"author_login": "ZabeMath",
"committed_at": "2026-05-03T00:45:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ec8fa24c896e2c4f6a2df919f9f4ac2f7f67cc1e",
"body": "Change-Id: I4f79666a5f88b4fd839aaf333e036455898a9ae8",
"is_bot": false,
"headline": "Allow composer/spdx-licenses 1.6.0",
"author_name": "Alexander Vorwerk",
"author_login": "ZabeMath",
"committed_at": "2026-05-02T12:58:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3f4ae40d82ded6c90d067e10b9d7b93bea27d258",
"body": "Require strict types on function calls to php internal functions or\non function calls within the library.\n\nBug: T422722\nChange-Id: I2120639553e59b6cdb0134b30c64d091b914e888",
"is_bot": false,
"headline": "chore: Declare strict types on all php files",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2026-04-19T21:24:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "afb70141ee55be78be69e862a1f89e78b8cae3ed",
"body": "File::findExtendedClassName is documented to return also false,\nFile::getDeclarationName is documented to return also null.\n\nChange-Id: I6b2de10b7a75b861efe61c5cd0ac5b68b6a4c9c7",
"is_bot": false,
"headline": "chore: Handle possible false/null in PHPUnitTestTrait",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2026-04-19T21:24:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "16d8b3bd4b88833fe36439519bb6a89efedcb13e",
"body": "Deprecated in php8.2\nhttps://wiki.php.net/rfc/remove_utf8_decode_and_utf8_encode\n\nChange-Id: I5aa0657da64b38e10cd47c7aa2a10d6e23e9b056",
"is_bot": false,
"headline": "ForbiddenFunctionsSniff: Add utf8_encode and utf8_decode",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2026-04-14T10:06:13Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8ff6fc7e72c0a6f93580abaca518f31e9b2fb3ba",
"body": "Bug: T410854\nChange-Id: Iae83297046e1e44974cfbf2f13f86ef3e4c59841",
"is_bot": false,
"headline": "Fix NullableTypeSniff for union types",
"author_name": "MGChecker",
"author_login": "MGChecker",
"committed_at": "2026-04-02T17:31:51Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ded2a13a9007982a636bb9731408c57ad778e734",
"body": "It is always enabled and statically linked since PHP 8.0, so there is\nno need to check for it unlike with older versions.\n\n https://wiki.php.net/rfc/always_enable_json\n\nBug: T401078\nChange-Id: I5ae2a3bc22e197f53fd6d868f2ba608a6f9f0565",
"is_bot": false,
"headline": "build: Don't list json as a required extension",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2026-03-29T21:06:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bc675aa4fc75f541498b7545e8f512909462d543",
"body": "Follow-Up: I479542e2ee50685c227ca3a433c7a1d105bf7e6d\nChange-Id: I2f7c8aa23d252152b011e9ceda6a87a8c1536a43",
"is_bot": false,
"headline": "build: Updating mediawiki/mediawiki-phan-config to 0.20.0",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2026-03-07T20:53:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "433ad3f94672ead361dbe5196aa8a703572e61ec",
"body": "Bug: T406326\nChange-Id: Ief727117b8e927204289f803f7cf516b2398a57d",
"is_bot": false,
"headline": "build: Upgrade mediawiki-phan-config for PHP 8.5 support",
"author_name": "James D. Forrester",
"author_login": "jdforrester",
"committed_at": "2026-02-12T17:54:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8f8ba0099b59f26c908f8d3b299ba01fb9a0e1dc",
"body": "This entirely replaces the parameter type regexp, fixing some bugs, but\nin a way that is possibly breaking; and it marks more functions as\ndeprecated. Hence it is not appropriate for a minor/patch release.\n\nChange-Id: Ic5d017422af39864744603241dbc45d7fe99f1f7",
"is_bot": false,
"headline": "Release v50.0.0",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2026-02-10T11:49:03Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "956a332af26cefb3912c2ac70d1eca65e3af3e4a",
"body": "The previous bespoke regex was missing complex union types, for example\narrays containing variadic callables, and nested array shapes. Also,\nsome parts of it were working in unclear ways, like the \"type wrapped in\nbraces\" actually matching array shapes, or the \"plain letters\" actually\nmatching space\n[…]\nSo, import the union type regexps for phan, which handle all these edge\ncases. Then add the few special cases we want on top of that.\n\nBug: T410187\nChange-Id: I450b9ebb1095b434750990714b94debd8e6aa2dd",
"is_bot": false,
"headline": "Use parameter type regex from phan",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2026-02-10T00:38:50Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "60150901985dc0643d0e1274976f9249b98b1e2c",
"body": "Change-Id: I6166f4c1bc345f6d43989e078b751fae37b7297d",
"is_bot": false,
"headline": "build: Upgrade mediawiki/minus-x from 2.0.0 to 2.0.1",
"author_name": "Alexander Vorwerk",
"author_login": "ZabeMath",
"committed_at": "2026-01-29T21:21:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cf13be32f7ca83a963bd19e105f9dc33a1d16b13",
"body": "Bug: T415723\nChange-Id: Id2b372d8da32479a192f89d9e35c5ad5f7b010df",
"is_bot": false,
"headline": "build: Upgrade PHPUnit from 10.5.58 to 10.5.63 to unblock CI",
"author_name": "James D. Forrester",
"author_login": "jdforrester",
"committed_at": "2026-01-27T23:42:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8d1b6553e57976f2daff36e9e4f6d438547ee433",
"body": "Change-Id: I7430909b1e70ef8db31128f4115be6082f979e1d",
"is_bot": false,
"headline": "ForbiddenFunctionsSniff: Add more deprecated php internal functions",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2026-01-18T01:17:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cbed3a74027cb2c9d9622d73d03a6ce408508bc1",
"body": "Change-Id: Ic5c5728e481324b12ed9a1affbf7c161e914a0ff",
"is_bot": false,
"headline": "build: Upgrade mediawiki/minus-x from 1.1.3 to 2.0.0",
"author_name": "Alexander Vorwerk",
"author_login": "ZabeMath",
"committed_at": "2026-01-13T00:42:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "15219ac40cd18f259a7170270165c0a7b47af10a",
"body": "Change-Id: I98fadd962d247f1481d8ec381ff43826e1e2c721",
"is_bot": false,
"headline": "Release v49.0.0",
"author_name": "Alexander Vorwerk",
"author_login": "ZabeMath",
"committed_at": "2026-01-11T00:02:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e1b27533361b43f8a341bc11e2322df8793bcc68",
"body": "Change-Id: Ibb108885fd61ce4eacf6aea2ff5382ec263edee8",
"is_bot": false,
"headline": "Use tabs instead of spaces in phpunit.xml.dist",
"author_name": "Alexander Vorwerk",
"author_login": "ZabeMath",
"committed_at": "2026-01-10T23:45:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "077caad0788c29ed5cf7caaed2ff812e66cb3709",
"body": "Allowed with php8.2\nAlso use const for a static variable and inline the function,\nas const can also be build by other consts\n\nChange-Id: I39296c8bad3caacdc7dc9bf177213c8d62de4e4b",
"is_bot": false,
"headline": "chore: Use const in traits",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2026-01-10T22:03:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "719255ced59bbbf189897b7aad9cd5add72e4856",
"body": "Change-Id: I89d2478e1d2a00c7f4a7f1d20a6c5c73ba6ffd08",
"is_bot": false,
"headline": "Drop support for PHP 8.1",
"author_name": "Alexander Vorwerk",
"author_login": "ZabeMath",
"committed_at": "2026-01-10T20:04:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "77fa933638e539167f813a3d54186bd2dd6cd9ae",
"body": "This repo is a libup canary repo\n\nChange-Id: I4dd9cfc9de73be3ee499dd5a1ee767b37d58d676",
"is_bot": false,
"headline": "build: Updating mediawiki/mediawiki-phan-config to 0.18.0",
"author_name": "Alexander Vorwerk",
"author_login": "ZabeMath",
"committed_at": "2026-01-10T19:50:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0cc39024d16b6243f96cd1d53971cb0ea7cd0a99",
"body": "Why\n- I accidentally downloaded the wrong version because the current version information was a little buried\n\nWhat\n- update README.md to mention latest version as 48.0.0 instead of 40.0.1\n- add links to places where the latest version can be accurately looked up\n\nChange-Id: Ib2da341ccf4d2c0beb73fcaa0b7ec6deef3b50c6",
"is_bot": false,
"headline": "readme: update version information",
"author_name": "Novem Linguae",
"author_login": "NovemLinguae",
"committed_at": "2026-01-05T12:40:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "64f6ca2c828dd2c75a754342e500d24199cf6447",
"body": "Change-Id: I60dfe2478d0ca4e507518e21dc06fb5decde228b",
"is_bot": false,
"headline": "ForbiddenFunctionsSniff: Add some deprecated php internal functions",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-12-29T17:20:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "598040b3764b341fcc28d428286680d126f784e6",
"body": "Some of php predefined variables are removed or deprecated,\nremove them from the internal list to treat them as invalid.\n\nReference:\n- $php_errormsg, deprecated in php7.2, removed in php8.0\n- $HTTP_RAW_POST_DATA, deprecated in php5.6, removed in php7.2\n- $http_response_header, deprecated in php8.5\n\nBug: T413540\nChange-Id: I024f7d3eeb2e1c23d61af6fe132294922cf01514",
"is_bot": false,
"headline": "ValidGlobalNameSniff: Treat deprecated or removed globals as invalid",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-12-28T19:06:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0af2e089ee7e5bcb1249b63dc24d2c524e263fe8",
"body": "Bug: T411741\nChange-Id: I07261e0fec42ea4ff5d7ec06b200defdee291413",
"is_bot": false,
"headline": "AssignmentInReturnSniff: Ignore arrow functions",
"author_name": "SomeRandomDeveloper",
"author_login": "SomeMWDev",
"committed_at": "2025-12-04T01:11:05Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "09ac7af0d9eb1b6521d3aaff7d92d942aa314069",
"body": "I'm not sure if a standard exists for this, but we try to be very\npermissive, to avoid confusing error messages as reported in the task.\n\nBug: T410187\nChange-Id: I5be62b74d238e4cf6986fce667256488b4d0bbff",
"is_bot": false,
"headline": "FunctionCommentSniff: Parse callable parameter syntax",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-11-17T15:12:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fc27dc8e8170eae2dea100b6e1a0c8f064334c73",
"body": "…bid @phan-template and @psalm-template in favour of @template\n\nBug: T410185\nChange-Id: I92e0c12b67245d8d821c530dbbe39ab0bc2b7830",
"is_bot": false,
"headline": "MediaWiki.Commenting.FunctionAnnotations.NonNormalizedAnnotation: For…",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-11-17T15:08:32Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ea472b3c5d07af45d83b8deeaa1da5684d89e348",
"body": "Bug: T409228\nChange-Id: If9c7b0b575f83f192af956e63cfd9940d88c1ced",
"is_bot": false,
"headline": "UnusedUseStatementSniff: add support for more annotations",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-11-15T01:01:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "38ffbf59e4805072f9f504c75a560f41bb2e6614",
"body": "- https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/tag/3.13.3\n- https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/tag/3.13.4\n- https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/tag/3.13.5\n\nBug: T404305\nChange-Id: I5c3091b7ef14714481a2f2270c18fed4a328f0c5",
"is_bot": false,
"headline": "Upgrade squizlabs/php_codesniffer from 3.13.2 to 3.13.5",
"author_name": "James D. Forrester",
"author_login": "jdforrester",
"committed_at": "2025-11-14T20:13:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ca3ee875a18b41dc550e42bd24a498cb4072ee02",
"body": "Bug: T392430\nChange-Id: I38ac36544bdb766e3811bb6dada0a537829a89c8",
"is_bot": false,
"headline": "UnusedUseStatementSniff: Ignore const when searching class names",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-11-14T19:57:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "39e35165660ab432cc42b434efb6f6ebf4d69361",
"body": "- Update PHPUnit config for version 10 with `--migrate-configuration`\n- Enabled options to display all notices, deprecations, etc.\n\nChange-Id: I42726a658d43efc833c52f81abeb4db61f7df224",
"is_bot": false,
"headline": "build: Update phpunit/phpunit to 10.5.58",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-10-30T20:38:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6d46ca2334d5e1c5be10bf28e01f6010cfbff212",
"body": "Bug: T272803\nBug: T335006\nBug: T393853\nBug: T397047\nBug: T397781\nBug: T398060\nBug: T398711\nBug: T401074\nBug: T402593\nBug: T403736\nChange-Id: I71479d9a497edefdc633ff1b53fbd81b2de17d5a",
"is_bot": false,
"headline": "HISTORY: Tag as v48.0.0",
"author_name": "James D. Forrester",
"author_login": "jdforrester",
"committed_at": "2025-09-04T20:12:57Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "efe3188e4b68f530a5ae6310214dcc17c02682a3",
"body": "The new tokens from php8 for union types are not skipped when searching\nfor the context. This also includes readonly token.\n\nThe error message includes the token with its content, that makes the\nerror message read harder, but still possible to see the real error\nwithout this adjustment.\n\nChange-Id: Id2195bddc637b8f0b8848c6d89ca403dfa079dcb",
"is_bot": false,
"headline": "EmptyTagSniff: Improve error message for union-typed properties",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-09-04T17:33:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "00586acb9ca7dd8b40e1b9484e37bbb7aeefe589",
"body": "New tokens from php8 are not skipped when searching visibility token\n\nChange-Id: I1e27afd09dd6560cadefb459c600c0824af8b44d",
"is_bot": false,
"headline": "RedundantVarNameSniff: Detect union-typed properties",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-09-04T17:22:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "30d4a394b118186e57aa7df579c5d5503f704507",
"body": "There is no more need to handle the nullable operator special\n\nBug: T398711\nChange-Id: I036eecd7ff7f0607a59ed7427416436c555554a0",
"is_bot": false,
"headline": "FunctionCommentSniff: Remove PHP71NullableDocOptionalArg error",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-09-04T17:21:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a50ad0c43d58b2af3d1bb6ea251de0d8cd69726a",
"body": "- https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/tag/3.13.1\n- https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/tag/3.13.2\n\nBug: T403736\nChange-Id: Ic9834d48129c8c12ffc2d3ef21596aac48ecc0bd",
"is_bot": false,
"headline": "Upgrade squizlabs/php_codesniffer from 3.13.0 to 3.13.2",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-09-04T17:17:03Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "21c4faa554cef9532a7055938a4788da2190000f",
"body": "Validate namespace names:\n- Not using wrong casing of \"MediaWiki\"\n- Not using \"phpunit\" namespace (mostly autogenerated)\n- Not using underscores (similiar to function and class names)\n- Not using lower camel case\n\nBug: T397047\nChange-Id: I61ff4a26f5d4821ff2e45099edd63a3741b9e2f3",
"is_bot": false,
"headline": "Add new NamespaceNameSniff to check naming conventions",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-09-04T17:12:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9fca6b1d34190771dbbd71a6d197eeefe38ad633",
"body": "New tokens from php8 are not skipped when searching visibility token\n\nChange-Id: Idec1ddb77097ae09c3161b34b2a89a4f7ed978b5",
"is_bot": false,
"headline": "PropertyAnnotationsSniff: Detect union-typed properties",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-09-04T17:11:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6d8e84908c51046b253b48ab7255a611e7a3c36d",
"body": "New tokens from php8 are not skipped when searching visibility token\n\nChange-Id: I656092431ef8fef6e921b31f74059fcfdee4d6ce",
"is_bot": false,
"headline": "PropertyDocumentationSniff: Detect union-typed properties",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-09-04T17:10:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6d1f3d9200b95901eda529705262792ba2b9d41e",
"body": "Bug: T401074\nChange-Id: I384601c9828918fca4e4314a2ef30f0eab1f8289",
"is_bot": false,
"headline": "tests: Add generic pass for constructor property promotion",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-09-04T15:25:01Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6d61dcc42c8eba7c0b3a8441e3078c8cf431b7ce",
"body": "Bug: T402593\nChange-Id: Ib3819bce55613e05e2c0c28130a75d2c6284a2d1",
"is_bot": false,
"headline": "composer.json: Relax constraint for composer/semver",
"author_name": "Reedy",
"author_login": "reedy",
"committed_at": "2025-09-04T14:45:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fc06159295ceafa486456bff4488759bba413892",
"body": "Change-Id: I239d0854cb932c64320084ec84928bd66668fd71",
"is_bot": false,
"headline": "build: Updating mediawiki/mediawiki-phan-config to 0.17.0",
"author_name": "libraryupgrader",
"author_login": null,
"committed_at": "2025-08-08T07:13:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a0d9b417bf37d510b2559e8d66ceb372aaaeaca0",
"body": "Change-Id: Icf4d2da2b3078eb0e1bbdfb7c7aa4081cf70d4e7",
"is_bot": false,
"headline": "PhpunitAnnotationsSniff: Allow @maximumDuration annotation",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-08-01T20:34:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3c56765b30df918ff61ca6f83201d2d76f463b7c",
"body": "Change-Id: I116aeb86c70eace2ae43a2de0e36bd1e07ecd871",
"is_bot": false,
"headline": "build: Use autoload-dev for tests in composer.json",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-07-28T08:29:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b8e6c6906f48f32ba05ddcb3f418acbb143f4666",
"body": "See review comments on I6c065131b56619c17c9d585263b4069265fd98fd\n\nChange-Id: I607125b736b5763cfa76bdbddb0c6148c4da7b8e",
"is_bot": false,
"headline": "ClassAnnotationsSniff: Allow @private",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-07-28T07:47:51Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7a0cf3ff09bd17231d659757b8d4ac6e467a9886",
"body": "Doc related annotations\n- @example\n- @experimental\n\nAllow some class modifier as annotation\n- @abstract\n- @extends\n- @final\n- @implements\n\nAllow following phan annotations on class comments:\n- @inherits\n- @phan-forbid-undeclared-magic-properties\n\nChange-Id: I714e0f7204f1c55117e36100414c3ace6c61ef59",
"is_bot": false,
"headline": "ClassAnnotationsSniff: Add more annotations",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-07-27T09:03:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "789ac9e5023672a9295d763f8445105cd67c1f40",
"body": "Usable with phan 5.3.0\nhttps://github.com/phan/phan/issues/4152\n\nChange-Id: Id572b79775088c982ccafe9956901151a355f330",
"is_bot": false,
"headline": "Annotations: Allow @no-named-arguments on function or class",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-07-17T20:12:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3b90b08cf52a8c121eabfbaffa9e4d450249c25f",
"body": "Analogous to PropertyDocumentationSniff (and parts of\nFunctionCommentSniff). For now, this only checks spacing in the doc\ncomment, but it could later be expanded to check more things.\n\nChange-Id: I599b5971ece2213603fbcb06747f229b21913770",
"is_bot": false,
"headline": "Add new ClassDocumentationSniff",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-07-07T14:39:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "121703f55a818d37658ad56e7642633dc4cbf111",
"body": "In I044ef8847d12ae, we went with the more specific version because I\nwasn't sure if there were any tools outside phan for which the\n`@template` annotations worked differently.\n\nToday it seems clear that all tools that support `@template` support\nroughly the same syntax, so it makes sense to allow the unprefixed\nversion.\n\nBug: T397781\nChange-Id: I22873f2b5bf3398843d29935039ef6099d597838",
"is_bot": false,
"headline": "Allow the `@template` annotation",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-07-07T14:08:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d56e07dca864cc4fe855a97e142303d8e07d5114",
"body": "Similar to the existing FunctionAnnotationsSniff and\nPropertyAnnotationsSniff.\n\nBug: T398060\nChange-Id: I3fbe7f74074149a203be1f1693fe5d95e04d896e",
"is_bot": false,
"headline": "Add ClassAnnotationsSniff to check for disallowed class annotations",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-07-06T23:44:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "66d8d4b159484c63d179d0c8b4d1511194fa95bd",
"body": "This lets us share more code between FunctionAnnotationsSniff and\nPropertyAnnotationsSniff; and in a subsequent patches, a similar sniff\nfor classes.\n\nAlso bring the lists of allowed annotations all in the same place, and\ndeduplicate them by keeping a list of annotations allowed everywhere.\n\nThe lis\n[…]\nd, with the exception of\n`@phan-read-only` and `@phan-write-only` now being allowed on\nproperties, since the former is needed for this very patch.\n\nChange-Id: Ifd8db9b4c94b00bcc388d7d685ccfeb9244bc7d8",
"is_bot": false,
"headline": "Introduce CommentAnnotationsTrait to deduplicate some code for doc tags",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-07-06T22:49:42Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a9ad233938a123cdee08b752ca63ab63d7301f2c",
"body": "Change-Id: Ic715b21ee4adf0452c6f257394f55eb582372401",
"is_bot": false,
"headline": "build: Update mediawiki-phan-config to 0.16.0",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-07-06T22:44:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ecc19356267eb926f8b5edeffa53a1666b475360",
"body": "Forbid empty doc comments, and comments with empty lines at the start or\nend. All issues are autofixable.\n\nChange-Id: I4179400c923cee2b8aeb75667c6ddd22b1b73021",
"is_bot": false,
"headline": "Check doc comment formatting for functions and properties",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-07-06T21:36:57Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "778c7974249008a98dc6a9631fdc3905864c05b2",
"body": "Bug: T398060\nChange-Id: Ic535acc31d23cabf3239710be24385551e665f41",
"is_bot": false,
"headline": "Add sniff to check comments before classes",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-07-06T21:32:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "46f7e4e6f912523824fc98eada9d4da1831057ec",
"body": "PHPUnit ignores empty lines after class and function comments, so we\nshould do the same. Also, if we need to get a class/function, we already\ndetermined that the comment contains a PHPUnit annotation anyway.\n\nAlso allow attributes between the comment and the class or function.\n\nChange-Id: I0b30d845c84bb0e66ff98b424bcf5d336abeefec",
"is_bot": false,
"headline": "Allow empty lines after comment in PHPunitAnnotationsSniff",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-07-06T17:49:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "13c9553a50c9ea18b3925b256e77f4385ce09664",
"body": "Similiar to the existing FunctionAnnotationsSniff validate the\nannotations on phpDoc-blocks for class properties against an allow list.\n\nRemove @phan-var from the FunctionAnnotationsSniff\n\nBug: T398060\nChange-Id: I111ce0eba0f35cafa78fcdfa027bcd458ff2978b",
"is_bot": false,
"headline": "New PropertyAnnotationsSniff to validate property annotations",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-06-28T21:51:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f0a6d435d9c8b94ed5c9870a4a4cb44062358353",
"body": "Check more tokens:\n- readonly is new in php8.1 (written after visibility)\n- final is new in php8.4 (written before visibility)\n\nChange-Id: Ia361f06c72b1c0d3f63d33583adc75c373c3fcab",
"is_bot": false,
"headline": "RedundantVarNameSniff: Check for readonly and final",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-06-28T20:45:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0b446de1832fbdce7f32b0cec04c26ab42ae991b",
"body": "Check more tokens:\n- readonly is new in php8.1 (written after visibility)\n- final is new in php8.4 (written before visibility)\n- anon classes are possible since php7\n\nUse array_key_last, since php8.1 functions are allowed\n\nChange-Id: I5b3964e433cf80e94d3953acde795589f29806c8",
"is_bot": false,
"headline": "PropertyDocumentationSniff: Check for readonly, final and anon classes",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-06-28T19:30:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e25b084c1db7955d9db1b27231d4757c7efc90a1",
"body": "PHP itself produce a warning with php8\n\nChange-Id: Ie8d0219cbb563d93cfa3c0077f2d6b7dcfe5f7ab",
"is_bot": false,
"headline": "Remove FinalPrivateSniff",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-06-18T21:41:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0d983eb9aaee4e72ca72420b9cbe389bf593e63a",
"body": "Remove symfony/polyfill-php80 as no longer needed.\nIt is still required by phan/phan and not uninstalled\n\nChange-Id: Icafffd8c39f8362c7c6dafbc26424125247fe244",
"is_bot": false,
"headline": "build: Require php 8.1",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-06-18T21:41:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9d2242dd3000e5689b79bd1caa344c67f8a88a19",
"body": "When coding without an IDE, I often copy-paste `use` statements\nbetween files, and sometimes I end up with duplicate identical uses.\nI wish that PHPCBF would fix them for me.\n\nIf any conflicting `use` statements are not identical, report\na non-fixable issue.\n\nChange-Id: I2113c4dcb43965146db2ff8fb54206d147664b9e",
"is_bot": false,
"headline": "UnusedUseStatementSniff: Also report duplicate/conflicting uses",
"author_name": "Bartosz Dziewoński",
"author_login": "MatmaRex",
"committed_at": "2025-06-16T21:04:13Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d3e2d4697f161b6e30f3409ef414ac55a451fb5f",
"body": "Due to a change in phpcsstandards/phpcsutils, this repo needs newer\nphpcsstandards/phpcsextra to pass tests.\n\nThe indirect dependency phpcsstandards/phpcsutils is updated from 1.0.12\nto 1.1.0 and sniff error codes changed as sniffs now detect errors\noutside the closure scope.\nThis is fixed in the di\n[…]\ns update to 1.1.0\n\nhttps://github.com/PHPCSStandards/PHPCSUtils/releases/tag/1.1.0\nhttps://github.com/PHPCSStandards/PHPCSExtra/releases/tag/1.4.0\n\nChange-Id: I82c21c8e28bb621830f44e38c8fa08d4eb3460c6",
"is_bot": false,
"headline": "Upgrade phpcsstandards/phpcsextra from 1.3.0 to 1.4.0",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-06-16T18:16:51Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "caba63154ede69ad1a65852d54acdd0929898ea1",
"body": "Note that we're dropping the use of upstream's newly-deprecated sniff,\nSquiz.CSS.SemicolonSpacing\n\nBug: T393853\nChange-Id: Iad48fa8b3ae348d13890ba91594fcaff7fa9f25b",
"is_bot": false,
"headline": "Upgrade squizlabs/php_codesniffer from 3.12.2 to 3.13.0",
"author_name": "James D. Forrester",
"author_login": "jdforrester",
"committed_at": "2025-06-02T17:41:56Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "24b9829e363cb4d7c1e0f80a31fd407018d84096",
"body": "No need to check the functions of anon classes used in test files\n\nChange-Id: I4e6961ac126972597949dc91285f519ef1856bc4",
"is_bot": false,
"headline": "PHPUnitTypeHintsSniff: Skip anon classes",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-06-02T17:11:21Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "288186ec0d08c15184d6dbc4c2b4abb849b5e523",
"body": "For parity with @phan-suppress-next-line; I don't think these were omitted\non purpose.\n\nNote, @phan-suppress-current-line should not be needed here.\n\nChange-Id: Ie998000268277cd6a0e38e08903344f62f28068b",
"is_bot": false,
"headline": "FunctionAnnotationsSniff: allow more phan suppressions",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-05-30T20:57:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8e84dd7fcb6c6c0f1e757af41b547f4d03523358",
"body": "They should be equivalent.\n\nBug: T335006\nChange-Id: I6f13dfcb80e0b051114d5eeff977daebc88d2016",
"is_bot": false,
"headline": "Replace NestedFunctionsSniff with upstream InnerFunctionsSniff",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-05-27T15:41:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a42d6663ea937d7f1a14e88d9984d6eee820144f",
"body": "Only function starting with get* or is* are required to document the\nreturn value with @return or with return type. Require it for all\nparameterless functions.\n\nNeeds check for live coding in FunctionComment to pass example in\nvariadic_argument_incomplete.php without require documentation.\n\nBug: T272803\nChange-Id: I1efd60ddb98fd1091d894c5ff121097e86253246",
"is_bot": false,
"headline": "Require documentation for parameterless function with return value",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-05-15T16:23:21Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ed516d39b93c7012a905156fb2d60071eb4e8b9d",
"body": "Forbid new annotations from PHPUnit 10\nhttps://github.com/sebastianbergmann/phpunit/commit/263079aaafb0251c0e72a2a60402ac8a5cb8b244\nThere are similiar to @backupGlobals or @backupStaticAttributes\n\nChange-Id: Ibd5aed0623e50d87899b9a5e425dcc7988b31c2e",
"is_bot": false,
"headline": "PhpunitAnnotationsSniff: Forbid new @exclude*FromBackup annotations",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-05-05T19:17:56Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "12eb62747f590d58b8e6d0463baa31c96ceb23ef",
"body": "See changelog: https://github.com/PHPCSStandards/PHPCSExtra/releases/tag/1.3.0\n\nChange-Id: Ia8cc2651b4bf061a5f7a2dd571858ab731a761af",
"is_bot": false,
"headline": "build: Upgrade phpcsstandards/phpcsextra to 1.3.0",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-05-05T18:04:30Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b48ff19466020a5577869f5e7a285f3fd2603f69",
"body": "Deprecated in upstream version 3.12.1, see\nhttps://github.com/PHPCSStandards/PHP_CodeSniffer/issues/921. Call-time\npass-by-reference is no longer a thing since PHP 5.4.\n\nChange-Id: I3b5523160bf2b70f4b0dfbb71004dfbf5c801b35",
"is_bot": false,
"headline": "Drop Generic.Functions.CallTimePassByReference",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-05-05T17:18:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3780a2706ecf565ecd2bd2aacdc3c4f6d7b54553",
"body": "Change-Id: Id74a1c2c6444df5a37446dca73c069145cdedac6",
"is_bot": false,
"headline": "PHPUnit sniffs: Avoid error on live coding about missing scope opener",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-05-04T15:09:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "056bb337d5229699356884563431b9cc6521ad14",
"body": "Change-Id: Id86cd3501d02505a438ba49c1be968bdaac0a6ea",
"is_bot": false,
"headline": "HISTORY: Tag as v47.0.0",
"author_name": "James D. Forrester",
"author_login": "jdforrester",
"committed_at": "2025-05-04T07:30:05Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cb08456a9728373232fd242faee4292dc0d14f53",
"body": "Upstream changes now mean that our tests now trigger one extra\nSquiz.WhiteSpace.ScopeKeywordSpacing.Incorrect, but one fewer\nSquiz.WhiteSpace.FunctionSpacing.Before, and the fixer removes\nthe empty line before the start of a function block now.\n\nChange-Id: I066fc8a88d5d58405939715eed38af6df4a1d923",
"is_bot": false,
"headline": "Upgrade squizlabs/php_codesniffer from 3.11.3 to 3.12.2",
"author_name": "James D. Forrester",
"author_login": "jdforrester",
"committed_at": "2025-05-04T07:28:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7ff49a386618d6fd415a4c79ea1cf6d80a2234d8",
"body": "Ensure a data provider function starts with provide or\nends with Provider. This allows to apply further checks on data provider\nfunctions later, like a check for static functions (T333745)\n\nDocumented at\nhttps://www.mediawiki.org/w/index.php?title=Manual:PHP_unit_testing/Writing_unit_tests&oldid=6864877#Data_providers\n\nAlso check for punctation like \"()\" at end and remove with autofix\n\nBug: T337098\nChange-Id: Ie83678177d227ff4684c77f54b6d3e42e2ff468e",
"is_bot": false,
"headline": "PhpunitAnnotationsSniff: Enforce naming convention for @dataProvider",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-05-01T04:31:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e1d17a7ec10979b45da1078cfae135431d7ef436",
"body": "When checking for unnecessary whitespace within parentheses, look for\nthe next non-whitespace token before the closer parenthesis, rather than\ntrying to count the tokens. This allows us to catch more cases of\nunnecessary whitespace, as demonstrated by the new tests.\n\nFor arrays (short or long), pres\n[…]\nnthesis, so it's easier to see what is being done.\n\nAdd a few test cases, and disable the rule for long arrays as it's not\nrelevant to this sniff.\n\nChange-Id: Id8a9bb037a485574a8423540d049e118ccb7598c",
"is_bot": false,
"headline": "SpaceyParenthesisSniff: detect unnecessary whitespace in more cases",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-04-01T19:25:31Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "7ae053eb0dac8e243db3bfa4e1a0298f01f2690a",
"body": "Use `findPrevious` to jump to the last non-whitespace token, instead of\nassuming that all whitespace will be in a single token. This allows us\nto catch extra newlines.\n\nChange-Id: Ia17553957913c522544568d56c24c2cf7e26596f",
"is_bot": false,
"headline": "SpaceyParenthesisSniff: account for multiple spaces before parens",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-04-01T19:25:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "756d2e8009c582c6ea71eb8d33dcc7ff595bfc30",
"body": "The sniff does nothing to distinguish between function calls and\nfunction declarations. So, generalize the error message to avoid any\npotential confusion.\n\nI think the assumption of \"array or function\" should always be true as\nlong as the code is valid, but I didn't prove it.\n\nChange-Id: I6031f5f0c24482d6d87399a1f20e39a379dbd61f",
"is_bot": false,
"headline": "SpaceyParenthesisSniff: avoid wrong guesses of function calls",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-04-01T19:25:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9d9868fc82f78586a777ffb127907382338cb04d",
"body": "- Drop the wfFailedExamples / wfPassedExamples boilerplate. We need to\n define functions for some test cases. The tautological doc comment and\n pointless `@return void` are also just a waste of space.\n- Move tests from generic test files to the sniff-specific file. This\n part is a follow-up to I04a2e34ec55a568.\n- Add names to the various test cases.\n\nThe limitations seen in the tests will be fixed in Ia17553957913c522.\n\nChange-Id: I6b8521f8b667fd19fd4f724648250f205d85ce78",
"is_bot": false,
"headline": "Consolidate tests for space before parenthesis",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-04-01T19:24:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "315bb4a7f99c117f4d288d1b41f1b81789f3379b",
"body": "Same condition and comments are used on UnusedUseStatementSniff and\nUnsortedUseStatementsSniff classes.\nMove the closure check in the loop to run it per bracketed namespace,\nChange the empty() check with a level check to handle global and\nnamespace scope.\n\nChange-Id: I0e6e0b831ae32a377b8bf99dfb71d48b7735cd65",
"is_bot": false,
"headline": "Allow EmptyLinesBetweenUseSniff to work with bracketed namespaces",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-04-01T16:06:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "747840d7591fceabbc5dfaa4d01fe20bd7dec189",
"body": "For typed properties the comment before should be ignored when the\ncomment style is not a doc-block /** */.\nFor fully typed functions (arguments and return type) the comment before\nshould be ignored when the comment style is not a doc-block /** */.\n\nMove the check for T_COMMENT into the existing if block to avoid the\nnot-condition and make reuse of the code for \"fully typed\" easier.\n\nBug: T375033\nChange-Id: I04f50dc57c7f3a179c44e5851570b1691895d89d",
"is_bot": false,
"headline": "Relax WrongStyle warning for property and function documentations",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-03-22T19:50:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "37f8a3549a26e1d1adc110005a446e13daabf978",
"body": "--diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]\n Select only files that are Added (A), Copied (C), Deleted (D),\nModified (M), Renamed (R), ...\n\nWhen Gerrit detects a file rename,\nthe Add + Delete flags does not select the file\n\nBug: T388319\nChange-Id: I6f1f0e62a3ff8a09225ee80d2fa102078d30a174",
"is_bot": false,
"headline": "utils: Include renamed files when using bootstrap-ci.php",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-03-18T17:29:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8b3d8d3aeb8befc583c94b1975bd40116325ee4b",
"body": "Done in 9423de5e37,\nbut lost on some rebase afterwards (53f4c763ae / aa5f2b5248 ).\n\nRequire the newline via tests by removing the prepareOutput() part\nfor the expected file\n\nFollow-Up: I048dc72b1caa1acb5f0a278859314d57c6112d03\nChange-Id: Ibd3147ee152c3b676c8aa9672b4b499c6395b458",
"is_bot": false,
"headline": "Readd newline at end of all .expect files",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2025-03-17T21:20:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ada22f4aba53edc2002390c372c50109f4416a0f",
"body": "Currently, our ruleset is very permissive with closure declarations, and\ndoes not flag code that would normally be flagged for normal\n(non-closure) declarations. Turns out the\nOpeningFunctionBraceKernighanRitchieSniff sniff has a configurable\n`checkClosures` property, false by default and that we never enabled.\n\nThe added tests documents the unwanted behaviour. A subsequent patch\nwill enable the closure checks, to show the differences.\n\nChange-Id: Ic9a9f82c5ac4708982e51b48232cc56606821b92",
"is_bot": false,
"headline": "Add tests for closure declarations",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-03-17T21:10:57Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e3a6622777ed1cdf294b6bcea8fdb650cc587c89",
"body": "The sniff in question never checked that it was actually dealing with\nnamespace `use`. This led to an edge case under the following\nconditions:\n- The first `use` statement in the file belongs to a closure.\n- There is at least another `use` after that.\n- The second `use ` statement is the first non-e\n[…]\n for example, see PS 4 of Ic9a9f82c5ac47.\n\nOTOH, checking for closure `use` is cheap and only needs to be done once\nper per file, so just do that.\n\nChange-Id: Id99b1f35234e9b85481c078dc8cb83203a800b8c",
"is_bot": false,
"headline": "EmptyLinesBetweenUseSniff: fix edge case with closures",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-03-17T21:08:04Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "3806162bcd1a7427fcf7da69cba4cbb38c899a3d",
"body": "I was recently confused as to why phpcs was analyzing fewer files in CI than it was locally. Providing some basic output might help readers of CI logs to understand what phpcs is doing.\n\nChange-Id: I1b25b059ba134e6a33e8e5e9d839b9cb3524c027",
"is_bot": false,
"headline": "Add basic output to bootstrap-ci.php",
"author_name": "Ollie",
"author_login": "outdooracorn",
"committed_at": "2025-03-13T23:34:13Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "53f4c763ae0a493bdae4381438e7683d539119b0",
"body": "This is an addition of tests for style inconsistencies that I have\npersonally seen recently. Some of these are covered by existing\nsniffs, and so the test documents that. Others aren't, in particular:\n- We do not enforce that function call parentheses are adjacent to the\n function name (ref CC/PHP:\n[…]\nof each parameter).\n\nSome of these test cases might be moved to more specific test files if\nand when we enable new sniffs that catch those issues.\n\nChange-Id: I04a2e34ec55a56800e3dffa67d3d9e038872a330",
"is_bot": false,
"headline": "Add tests for miscellaneous style inconsistencies seen in the wild",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-03-03T23:27:46Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "6bd8a9ac4c10bf393dcd9ef32e3402399128a9e5",
"body": "Bug: T328529\nBug: T371048\nBug: T378552\nBug: T379674\nChange-Id: I11f928e3de0163d29e5f1c493e272a6e0d714502",
"is_bot": false,
"headline": "HISTORY: Tag as v46.0.0",
"author_name": "Jakob Warkotsch",
"author_login": "jakobw",
"committed_at": "2025-01-27T21:05:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8983532e577ea45109a62e79e22cf26200629393",
"body": "Bug: T379674\nChange-Id: I4af17202b16ecc664068d99a053982923e641e26",
"is_bot": false,
"headline": "Raise PHP CodeSniffer from 3.11.1 to 3.11.3",
"author_name": "Reedy",
"author_login": "reedy",
"committed_at": "2025-01-27T15:03:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "aa5f2b5248612102aa8647b6ba4e722f26800106",
"body": "Partial revert of I1e85a43e3f5626ca017893f25553d6a9fbcaaaf0, which\ndisabled the ScopeIndent sniff on this test file due to upstream issue\nhttps://github.com/squizlabs/PHP_CodeSniffer/issues/3808.\n\nThis has now been resolved in 3.11, so the exclusion can be removed.\n\nChange-Id: I22d18849d0207528bf14ca6709a74523f20a6ff3",
"is_bot": false,
"headline": "Re-enable ScopeIndent sniff on test that was previously failing",
"author_name": "Daimona Eaytoy",
"author_login": "Daimona",
"committed_at": "2025-01-12T23:44:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3a616961bcacabc56ad39ed0ab354e6c05fffcb6",
"body": "Update AssignmentInReturnSniff for the BC break in\nhttps://github.com/PHPCSStandards/PHP_CodeSniffer/pull/647.\n\nBug: T379674\nChange-Id: I01009b858466b7c678c799d8c99207f3395b7a5d",
"is_bot": false,
"headline": "Raise PHP CodeSniffer from 3.10.3 to 3.11.1",
"author_name": "James D. Forrester",
"author_login": "jdforrester",
"committed_at": "2025-01-12T23:39:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9479c6bfde10439bb64929ec14a5f5a0666da50b",
"body": "Bug: T328529\nChange-Id: Ia8f1d8de3183e3e55af5ff88d8ce451e2fb2a9fc",
"is_bot": false,
"headline": "StaticClosureSniff: Work on fn() too",
"author_name": "Reedy",
"author_login": "reedy",
"committed_at": "2025-01-10T12:11:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7bf21d735904dc44010cc21919187a8c0ae0b0a6",
"body": "Change-Id: Iedbf7ba6574ef32c3fcf772bb7d219e093a43901",
"is_bot": false,
"headline": "build: Updating mediawiki/mediawiki-phan-config to 0.15.1",
"author_name": "libraryupgrader",
"author_login": null,
"committed_at": "2025-01-10T06:18:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "82f8c837886262e0b6e0ef86a989e3219ada2c3d",
"body": "New in PHPUnit 9.1\nhttps://github.com/sebastianbergmann/phpunit/issues/4148\n\nChange-Id: Ie147e7446e8edf1febf56cab7f69e0c33584395d",
"is_bot": false,
"headline": "Allow use of @preCondition and @postCondition PHPUnit annotations",
"author_name": "Umherirrender",
"author_login": "umherirrender",
"committed_at": "2024-12-13T23:32:18Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6939f62e11fc840b02afef39a05a6b7cfbf6fa17",
"body": "Change-Id: Ic48bdb85ecf7acc885f7311214424bbf7492cb7b",
"is_bot": false,
"headline": "build: Updating mediawiki/mediawiki-phan-config to 0.15.0",
"author_name": "libraryupgrader",
"author_login": null,
"committed_at": "2024-12-10T04:50:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "46219203f89ed91711f661db01e5d901c304f1f2",
"body": "The mixed type (PHP 8+) already includes 'null'. So trying to fix that\nto '?mixed' fails with a type error.\n\nBug: T378552\nChange-Id: I8e3034888942ed398d6459f45bc3404d358fc289",
"is_bot": false,
"headline": "NullableTypeSniff: 'mixed' is already nullable",
"author_name": "Taavi Väänänen",
"author_login": "supertassu",
"committed_at": "2024-12-09T19:24:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fd6ecb5ffbe353507ca05387176db02f0f41f6fe",
"body": "This feature improves code consistency and readability by ensuring that arrays with PHP symbols (e.g., constants, variables) follow a consistent alphabetical order.\n\nBug: T371048\nChange-Id: Ia125bdc9d82853bcebbc6fdaa83057824dc1059a",
"is_bot": false,
"headline": "Support sorting PHP symbols in arrays",
"author_name": "Muhammad Yasser Jazirahly",
"author_login": "MuhammadJaziraly",
"committed_at": "2024-12-02T09:16:21Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d54068835d534ad246588e20dc88850b98768610",
"body": "Change-Id: Ib20093e38abb3e7cc2befc4dacc0fb69e4c7360a",
"is_bot": false,
"headline": "build: Updating phpunit/phpunit to 9.6.21",
"author_name": "libraryupgrader",
"author_login": null,
"committed_at": "2024-11-28T23:17:21Z",
"body_truncated": false,
"is_coding_agent": false
}
],
"releases_count": 65,
"commits_last_year": 44,
"latest_release_at": "2026-05-03T06:29:24Z",
"latest_release_tag": "v51.0.0",
"releases_from_tags": true,
"days_since_last_push": 82,
"active_weeks_last_year": 18,
"days_since_latest_release": 86,
"mean_days_between_releases": 106.1
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": false,
"health_percentage": 50,
"has_issue_template": false,
"has_code_of_conduct": true,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "mediawiki/mediawiki-codesniffer",
"exists": true,
"license": "GPL-2.0-or-later",
"keywords": [
"codesniffer",
"mediawiki"
],
"ecosystem": "packagist",
"matches_repo": true,
"registry_url": "https://packagist.org/packages/mediawiki/mediawiki-codesniffer",
"is_deprecated": false,
"latest_version": "v51.0.0",
"repository_url": "https://github.com/wikimedia/mediawiki-tools-codesniffer",
"versions_count": 65,
"total_downloads": 3241095,
"dependents_count": 352,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": 75597,
"first_published_at": null,
"latest_published_at": "2026-05-03T06:29:24Z",
"latest_version_yanked": null,
"days_since_latest_publish": 86
}
]
},
"popularity": {
"forks": 12,
"stars": 33,
"watchers": 11,
"fork_history": {
"days": [
{
"date": "2015-06-03",
"count": 1
},
{
"date": "2015-11-29",
"count": 1
},
{
"date": "2016-04-01",
"count": 1
},
{
"date": "2016-04-20",
"count": 1
},
{
"date": "2017-04-07",
"count": 1
},
{
"date": "2017-06-14",
"count": 1
},
{
"date": "2020-01-01",
"count": 1
},
{
"date": "2020-01-19",
"count": 1
},
{
"date": "2022-04-25",
"count": 1
},
{
"date": "2024-11-27",
"count": 1
},
{
"date": "2026-07-27",
"count": 1
}
],
"complete": true,
"collected": 11,
"total_forks": 12
},
"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": [],
"toolchain_manifests": [],
"largest_source_bytes": 26888,
"source_files_sampled": 189,
"oversized_source_files": 0,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"dependencies": {
"manifests": [
"composer.json"
],
"advisories": {
"error": null,
"scope": "repository_graph",
"source": "osv",
"findings": [],
"collected": true,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 7,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 5,
"direct_affected_count": 0
},
"ecosystems": [
"packagist"
],
"dependencies": [
{
"name": "squizlabs/php_codesniffer",
"manifest": "composer.json",
"ecosystem": "packagist",
"version_constraint": "3.13.5"
}
],
"all_dependencies": {
"error": null,
"source": "github-sbom",
"packages": [
{
"name": "squizlabs/php_codesniffer",
"direct": true,
"version": "3.13.5",
"ecosystem": "packagist"
},
{
"name": "composer/semver",
"direct": false,
"version": null,
"ecosystem": "packagist"
},
{
"name": "composer/spdx-licenses",
"direct": false,
"version": null,
"ecosystem": "packagist"
},
{
"name": "ext-dom",
"direct": false,
"version": null,
"ecosystem": "packagist"
},
{
"name": "ext-mbstring",
"direct": false,
"version": null,
"ecosystem": "packagist"
},
{
"name": "mediawiki/mediawiki-phan-config",
"direct": false,
"version": "0.20.0",
"ecosystem": "packagist"
},
{
"name": "mediawiki/minus-x",
"direct": false,
"version": "2.0.1",
"ecosystem": "packagist"
},
{
"name": "php",
"direct": false,
"version": null,
"ecosystem": "packagist"
},
{
"name": "php-parallel-lint/php-console-highlighter",
"direct": false,
"version": "1.0.0",
"ecosystem": "packagist"
},
{
"name": "php-parallel-lint/php-parallel-lint",
"direct": false,
"version": "1.4.0",
"ecosystem": "packagist"
},
{
"name": "phpcsstandards/phpcsextra",
"direct": false,
"version": "1.5.0",
"ecosystem": "packagist"
},
{
"name": "phpunit/phpunit",
"direct": false,
"version": "10.5.63",
"ecosystem": "packagist"
}
],
"collected": true,
"truncated": false,
"total_count": 12,
"direct_count": 1,
"indirect_count": 11
}
},
"maintainership": {
"issues": {
"open_prs": 0,
"merged_prs": 0,
"open_issues": 0,
"closed_ratio": null,
"closed_issues": 0,
"closed_unmerged_prs": 3
},
"bus_factor": 3,
"bot_contributors": 0,
"top_contributors": [
{
"type": "User",
"login": "umherirrender",
"commits": 278,
"avatar_url": "https://avatars.githubusercontent.com/u/1174884?v=4"
},
{
"type": "User",
"login": "legoktm",
"commits": 139,
"avatar_url": "https://avatars.githubusercontent.com/u/81392?v=4"
},
{
"type": "User",
"login": "thiemowmde",
"commits": 118,
"avatar_url": "https://avatars.githubusercontent.com/u/6576639?v=4"
},
{
"type": "User",
"login": "DannyS712",
"commits": 65,
"avatar_url": "https://avatars.githubusercontent.com/u/46829944?v=4"
},
{
"type": "User",
"login": "Daimona",
"commits": 64,
"avatar_url": "https://avatars.githubusercontent.com/u/38216014?v=4"
},
{
"type": "User",
"login": "jdforrester",
"commits": 46,
"avatar_url": "https://avatars.githubusercontent.com/u/881572?v=4"
},
{
"type": "User",
"login": "reedy",
"commits": 31,
"avatar_url": "https://avatars.githubusercontent.com/u/67615?v=4"
},
{
"type": "User",
"login": "hashar",
"commits": 29,
"avatar_url": "https://avatars.githubusercontent.com/u/281689?v=4"
},
{
"type": "User",
"login": "ZabeMath",
"commits": 19,
"avatar_url": "https://avatars.githubusercontent.com/u/35405030?v=4"
},
{
"type": "User",
"login": "paladox",
"commits": 16,
"avatar_url": "https://avatars.githubusercontent.com/u/5727000?v=4"
}
],
"contributors_sampled": 58,
"top_contributor_share": 0.292
},
"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 43 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": 0,
"reason": "no update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 10,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 5,
"reason": "6 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 5",
"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": 0,
"reason": "security policy file not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": null,
"reason": "no releases found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 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": "9fd2bf1d8e772ce9ee253862574235a2b38f4215",
"ran_at": "2026-07-28T15:02:39Z",
"aggregate_score": 3.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": null,
"oldest_open_prs": [],
"last_merged_pr_at": null,
"ci_last_conclusion": null,
"oldest_open_issues": []
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/wikimedia/mediawiki-tools-codesniffer",
"host": "github.com",
"name": "mediawiki-tools-codesniffer",
"owner": "wikimedia"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 55,
"inputs": {
"security": 48,
"vitality": 62,
"community": 59,
"governance": 62,
"engineering": 40
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "moderate",
"name": "Vitality",
"value": 62,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "moderate",
"name": "Development activity",
"note": null,
"notes": [],
"value": 50,
"inputs": {
"commits_last_year": 44,
"human_commit_share": 1,
"days_since_last_push": 82,
"active_weeks_last_year": 18
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 82 days ago",
"points": 18,
"status": "partial",
"details": [
{
"code": "push_recency",
"params": {
"days": 82
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "18/52 weeks with commits",
"points": 12.5,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 18
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "44 commits in the last year",
"points": 14.8,
"status": "partial",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 44
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "6 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 5",
"points": 5,
"status": "partial",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "good",
"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": 80,
"inputs": {
"releases_count": 65,
"latest_release_tag": "v51.0.0",
"releases_from_tags": true,
"days_since_latest_release": 86,
"mean_days_between_releases": 106.1
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "65 version tags (no GitHub releases)",
"points": 16.2,
"status": "partial",
"details": [
{
"code": "version_tags_no_releases",
"params": {
"count": 65
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 86 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 86
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~106.1 days",
"points": 19.8,
"status": "partial",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 106.1
}
}
],
"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": 82,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "last human commit 82 days ago",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_maintained",
"params": {
"days": 82
}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "moderate",
"name": "Community & Adoption",
"value": 59,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "at_risk",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 39,
"inputs": {
"forks": 12,
"stars": 33,
"watchers": 11,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "33 stars",
"points": 24.4,
"status": "partial",
"details": [
{
"code": "stars",
"params": {
"count": 33
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "12 forks",
"points": 8.7,
"status": "partial",
"details": [
{
"code": "forks",
"params": {
"count": 12
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "11 watchers",
"points": 5.6,
"status": "partial",
"details": [
{
"code": "watchers",
"params": {
"count": 11
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "moderate",
"name": "Community health",
"note": null,
"notes": [],
"value": 65,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": false,
"has_issue_template": false,
"has_code_of_conduct": true,
"has_pull_request_template": false
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (GPL-2.0)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "GPL-2.0"
}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 13.5,
"status": "met",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.3
}
]
},
{
"key": "ecosystem_adoption",
"band": "good",
"name": "Ecosystem adoption (downloads)",
"note": null,
"notes": [],
"value": 82,
"inputs": {
"packages": [
"mediawiki/mediawiki-codesniffer"
],
"dependents": 352,
"ecosystems": "packagist",
"total_downloads": 3241095,
"monthly_downloads": 75597
},
"components": [
{
"key": "monthly_downloads",
"name": "Monthly downloads",
"detail": "75,597 downloads/month across packagist",
"points": 65,
"status": "partial",
"details": [
{
"code": "downloads_monthly",
"params": {
"count": 75597,
"ecosystems": "packagist"
}
}
],
"max_points": 80
},
{
"key": "registry_dependents",
"name": "Registry dependents",
"detail": "352 packages depend on it",
"points": 17,
"status": "partial",
"details": [
{
"code": "registry_dependents",
"params": {
"count": 352
}
}
],
"max_points": 20
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 62,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "good",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 75,
"inputs": {
"bus_factor": 3,
"contributors_sampled": 58,
"top_contributor_share": 0.292
},
"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 29% of commits",
"points": 15.9,
"status": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 29
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "58 contributors",
"points": 13.5,
"status": "met",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 58
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 43 contributing companies or organizations",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "critical",
"name": "Issue & PR responsiveness",
"note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"issue_resolution"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 1,
"inputs": {
"merged_prs": 0,
"open_issues": 0,
"closed_issues": 0,
"issue_closed_ratio": null,
"closed_unmerged_prs": 3
},
"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": "0/3 decided PRs merged",
"points": 0,
"status": "missed",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 0,
"decided": 3
}
}
],
"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": 79,
"inputs": {
"followers": 2188,
"owner_type": "Organization",
"is_verified": null,
"owner_login": "wikimedia",
"public_repos": 1963,
"account_age_days": 6365
},
"components": [
{
"key": "ownership_backing",
"name": "Ownership backing",
"detail": "organization-owned",
"points": 30,
"status": "met",
"details": [
{
"code": "owner_organization",
"params": {}
}
],
"max_points": 30
},
{
"key": "verified_domain",
"name": "Verified domain",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "owner_reach",
"name": "Owner reach",
"detail": "2,188 followers of wikimedia",
"points": 24,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 2188,
"login": "wikimedia"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "1963 public repos, account ~17 yr old",
"points": 25,
"status": "met",
"details": [
{
"code": "public_repos",
"params": {
"count": 1963
}
},
{
"code": "account_age_years",
"params": {
"years": 17
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"mediawiki/mediawiki-codesniffer"
],
"ecosystems": "packagist",
"any_deprecated": false,
"min_days_since_publish": 86
},
"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 86 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 86
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "65 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 65
}
}
],
"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": "at_risk",
"name": "Engineering Quality",
"value": 40,
"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": "moderate",
"name": "Documentation",
"note": null,
"notes": [],
"value": 55,
"inputs": {
"topics": [],
"has_wiki": false,
"homepage": "https://gerrit.wikimedia.org",
"has_readme": true,
"has_docs_dir": false,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": "https://gerrit.wikimedia.org",
"points": 15,
"status": "met",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": 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": "at_risk",
"name": "Security",
"value": 48,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "at_risk",
"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": 35,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 12,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 6,
"scorecard_aggregate": 3.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 43 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": "no update tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "6 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 5",
"points": 3.8,
"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 not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "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": "dependency_advisories",
"band": "excellent",
"name": "Dependency advisories",
"note": "Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories, No advisories left outstanding. Remaining weights renormalized. Matched 7 resolved dependencies against OSV; 5 could not be assessed (no resolved version, an unsupported ecosystem, or beyond the reported package list). This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"indirect_dependencies_free_of_known_advisories",
"no_advisories_left_outstanding"
]
}
},
{
"code": "weights_renormalized",
"params": {}
},
{
"code": "advisories_scope_repository",
"params": {
"assessed": 7
}
},
{
"code": "advisories_unassessed",
"params": {
"count": 5
}
},
{
"code": "advisories_repo_graph_caveat",
"params": {}
},
{
"code": "advisories_reachability",
"params": {}
}
],
"value": 100,
"inputs": {
"source": "osv",
"advisories": 0,
"affected_packages": 0,
"assessed_packages": 7,
"unassessed_packages": 5,
"affected_by_severity": "none",
"direct_affected_packages": 0
},
"components": [
{
"key": "direct_dependencies_free_of_known_advisories",
"name": "Direct dependencies free of known advisories",
"detail": "no direct dependency carries a known advisory",
"points": 35,
"status": "met",
"details": [
{
"code": "no_direct_advisories",
"params": {}
}
],
"max_points": 35
},
{
"key": "indirect_dependencies_free_of_known_advisories",
"name": "Indirect dependencies free of known advisories",
"detail": "transitive set not separable from development and test dependencies in this scope",
"points": 0,
"status": "excluded",
"details": [
{
"code": "advisories_scope_not_separable",
"params": {}
}
],
"max_points": 25
},
{
"key": "no_advisories_left_outstanding",
"name": "No advisories left outstanding",
"detail": "no advisory carries a publication date",
"points": 0,
"status": "excluded",
"details": [
{
"code": "advisories_no_publication_date",
"params": {}
}
],
"max_points": 40
}
]
},
{
"key": "malicious_dependencies",
"band": "excellent",
"name": "Malicious dependencies",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"source": "osv",
"meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
"packages": [],
"red_flag": false,
"assessed_packages": 7,
"malicious_packages": 0,
"direct_malicious_packages": 0,
"withdrawn_malicious_packages": 0,
"installable_malicious_packages": 0
},
"components": [
{
"key": "no_dependency_reported_as_a_malicious_package",
"name": "No dependency reported as a malicious package",
"detail": "no dependency is reported as a malicious package",
"points": 100,
"status": "met",
"details": [
{
"code": "no_malicious_dependencies",
"params": {}
}
],
"max_points": 100
}
]
},
{
"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": 17
},
"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": "at_risk",
"name": "AI Readiness",
"value": 35,
"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.8,
"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": "80 of 100 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 80,
"sampled": 100
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "critical",
"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": 24,
"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": [],
"agent_commit_share": 0,
"toolchain_manifests": [],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "no agent-authored commits among the last 100",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_authored_commits",
"params": {
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "no automated dependency updates observed",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_dependency_automation",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "no dependencies found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "moderate",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 55,
"inputs": {
"primary_language": "PHP",
"largest_source_bytes": 26888,
"source_files_sampled": 189,
"oversized_source_files": 0
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "PHP without a type-check config",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_typecheck_config_language",
"params": {
"language": "PHP"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "0/189 source files over 60KB",
"points": 55,
"status": "met",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 189,
"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"
],
"report_type": "repository",
"generated_at": "2026-07-28T15:02:56.681419Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/w/wikimedia/mediawiki-tools-codesniffer.svg",
"full_name": "wikimedia/mediawiki-tools-codesniffer",
"license_state": "standard",
"license_spdx": "GPL-2.0"
}