. The row for 850714210 had SSSS transcribed as 4210\ninstead of 1421 (positions 5-8 of the 9-digit ID). The check digit (C=0)\nand tests were already correct; only the documentation column was wrong.", "is_bot": false, "headline": "docs(#15): fix SSSS decomposition for 850714210 in research vector table", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-05-21T13:50:14Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "b4bf8f4d69453446be1eb359a596823fa7aec0ca", "body": "…test\n\nThe literal {yymm:'8001', sn:'0100', checksum:1} appeared four times across\nthe test file. Lift it (and the canonical id '800101001') to two top-level\nconstants so a future field rename is a single edit.", "is_bot": false, "headline": "refactor(#15): extract canonical id/parsed constants in BHR research …", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-05-21T13:46:58Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "1ac424f124c6d249b1e22f741b9248ede4d4e6aa", "body": "ESLint flagged two pre-existing no-unused-vars errors that surfaced when CI\nran against the issue-15 worktree:\n\n- parseIdInfo-migration.test.ts: drop unused `_id` parameter in mock validate\n- registry.test.ts: drop unused `IdFormat` import\n\nNo behavior change; tests remain green.", "is_bot": false, "headline": "chore(#15): drop unused lint identifiers", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-05-21T13:45:49Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "4991df5f27f4521d9b258eab2aa237482e2d336c", "body": "…ents\n\nReplace the vague `// TODO: find and implement checksum` and the loose class\nJSDoc with text that points at the new research record\n(docs/research/bahrain-cpr-checksum.md) and states the Python-upstream parity\nexplicitly. No runtime change to validate, parse, or METADATA.\n\nAdd src/__tests__/i\n[…]\nted examples, 6 format-invalid examples, the\nMETADATA.checksum=false / parsable=true contract, direct PersonalNumber.parse,\nand registry-path parseIdInfo for both the BHR primary key and the BH alias.", "is_bot": false, "headline": "test(#15): pin Bahrain CPR research vectors and clarify checksum comm…", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-05-21T13:45:31Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "6227a5ce5c3e6d37a0ef64e21a0dfea829e72fc6", "body": "Capture the result of issue #15 research: the official Bahrain CPR check-digit\nalgorithm is not publicly documented (Wikipedia, iGA portals, python-stdnum,\nstdnum-js, and the Python upstream all checked). Decision is to keep\nformat-only validation with METADATA.checksum=false, in parity with\nidnumbe\n[…]\nrries the same TODO.\n\nIncludes 6 format-only accepted vectors, 6 format-invalid vectors, sources\nwith access dates, synthetic-data notice, future-work guidance, and a call\nfor community contributions.", "is_bot": false, "headline": "docs(#15): add Bahrain CPR checksum research record", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-05-21T13:45:10Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "5bcd719eede6538d58160f1a93ead38427de6a94", "body": null, "is_bot": false, "headline": "chore(release): bump version to 1.8.0 (#103)", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-04-29T00:30:49Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "0907a45c02ab1b0b1a41dad88e86bf4ef2726e01", "body": "test(#36): add Portugal parse and edge case tests", "is_bot": false, "headline": "test(#36): add Portugal parse and edge case tests (#102)", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-04-28T14:38:06Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "c2cfc459c28984451220e348fdcb42cce5c0a333", "body": "Parameterize hyphen and dot NIF separator-rejection tests into a single\ntest.each, mirroring the separator-rejection style used in\nprt-nationalId.test.ts. Removes a near-duplicate adjacent test block.\n\nNo coverage change. All 39 issue-36 tests and 1740 suite tests still pass.", "is_bot": false, "headline": "refactor(#36): simplify implementation", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-28T10:22:46Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "6d08cdc059a6d4cd15cad5b8b46cfac8d91c1c59", "body": "Add issue-36-prt-parse.test.ts covering parse-not-implemented semantics\nand complementary edge cases for PRT CC and NIF.\n\n- Parse-not-implemented: assert static/instance parse is undefined for\n both classes; METADATA.parsable === false matches Python source.\n- Registry path: parseIdInfo and validat\n[…]\nngth 9\n and NIF metadata, ensuring the registered class is NIF, not CC.\n\nTest-only addition; no production code changes. 39 tests, all green.\nComplements #34 (CC validation) and #35 (NIF validation).", "is_bot": false, "headline": "test(#36): add Portugal parse and edge case tests", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-28T10:20:53Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "58c4db478250de395222d1d3a9c264fce01581a7", "body": "test(#34): add Portugal Cartão de Cidadão tests", "is_bot": false, "headline": "Merge pull request #100 from identique/idnumbers-node-issue-34", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-04-28T10:05:59Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "eae993ee7a7d8c95eb61dad5855d3d6e81fe9c4a", "body": "test(#35): add Portugal NIF validation tests", "is_bot": false, "headline": "Merge pull request #101 from identique/idnumbers-node-issue-35", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-04-28T10:05:42Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "4efe5d9a946e55c2830d789782d4338d4071e22a", "body": null, "is_bot": false, "headline": "test(#35): add Portugal NIF coverage", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-28T08:01:51Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "0b4fb28abf8f2a931ff6281634f9ac5487f80897", "body": "Add 45 Jest tests covering the 12-character Portuguese Cartão de Cidadão\nclass in src/countries/prt/nationalId.ts, which previously had no\ndedicated test coverage and is unreachable via the country barrel.\n\nTests-only — no production changes. Imports the CC class directly to\nexercise it independentl\n[…]\n corruption (both digits), length and character validation,\nnull/undefined/non-string input, METADATA shape, instance vs. static\nequivalence, and a smoke assertion that the registry primary stays NIF.", "is_bot": false, "headline": "test(#34): add Portugal Cartão de Cidadão tests", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-28T07:49:38Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "f9550ec13016c1dd8e0c8ffdd508f3a93316f998", "body": "chore(release): bump version to 1.7.0", "is_bot": false, "headline": "chore(release): bump version to 1.7.0 (#99)", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-04-24T00:33:52Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "2bb1ceb7cf91bd077ffcf90ed329737b8fd4bd84", "body": null, "is_bot": false, "headline": "chore(release): bump version to 1.7.0", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-24T00:18:52Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "8bcc048f5f2b51adde663f5912ab8461e4d6c11a", "body": "test(#33): add NZL parse and edge case tests", "is_bot": false, "headline": "Merge pull request #98 from identique/idnumbers-node-issue-33", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-04-24T00:10:17Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "0272869c76b576a12d45b0c53cc135328cf3c3a0", "body": "Focus the issue-33 test file on value the sibling nzl.test.ts does not\nalready cover:\n - parse-not-implemented semantics\n - whitespace and length edge cases\n - METADATA regexp.source/flags/deprecated/aliasOf\n - 7-char DriverLicense boundary behavior\n - extractedInfo and parseIdInfo integration\n\n[…]\nertions (blacklist 10-row loop, basic null/undefined\nrejection, instance/static delegation boilerplate, trivial METADATA\nshape) already covered by nzl.test.ts. NZL module branch coverage\nremains 100%.", "is_bot": false, "headline": "refactor(#33): simplify NZL test file — reduce overlap with nzl.test.ts", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-23T23:49:26Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "5d84f86c066fe75a30e6aabd3967cdf8b7abc751", "body": "Add src/__tests__/issue-33-nzl-parse.test.ts covering parse-not-implemented\nsemantics, edge-case input handling, and blacklist boundaries for both\nNationalID and DriverLicense NZL classes. Raises NZL module coverage to\n100% (stmts/branch/funcs/lines).\n\nThe test header documents the known Python-vs-N\n[…]\nationalID is an alias of DriverLicenseNumber; Node has two distinct\nclasses with diverged regexps). Tests exercise current Node branches\nonly and do not codify either form as the canonical NZL format.", "is_bot": false, "headline": "test(#33): add NZL parse and edge case tests", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-23T23:46:40Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "a70a6dbd9be0dc36d22a618c0975fa55e0472d39", "body": "test(#31): add comprehensive NZ driver license validation tests", "is_bot": false, "headline": "Merge pull request #97 from identique/idnumbers-node-issue-31", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-04-23T15:50:25Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "3f2f07338ec6049d36d309e22ce6d2c38ef9e5ad", "body": "- Clarify file header: the TS DriverLicense regex accepts 7–8 chars\n while valid-input tests use the stricter Python source-of-truth shape\n (2 letters + 6 digits) to avoid codifying the divergence.\n- Add minLength/maxLength assertions to DriverLicense METADATA test for\n parity with the NationalID METADATA test.", "is_bot": false, "headline": "fix(#31): address external review feedback — round 1", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-23T14:03:39Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "8de2ed05f85f3b55b2c6dd86a9480008877c4bf7", "body": "Add src/__tests__/nzl.test.ts covering:\n- DriverLicense (primary, registered) standard 2-letter + 6-digit format\n- Case-insensitivity, blacklist (10 trailing-same-digit patterns), invalid\n format (length, special chars, null/undefined/non-string)\n- Separator variations (space/dash/dot/slash rejecte\n[…]\nict 2-word-char + 6-digit coverage\n- Registry integration via validateNationalId and getCountryIdFormat\n for NZL code and NZ alias\n\n54 tests, 100% line/branch/function coverage on src/countries/nzl/.", "is_bot": false, "headline": "test(#31): add comprehensive NZ driver license validation tests", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-23T13:55:30Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "6f1c8400229ffe86f37ea0d0c5ab472c4e089298", "body": null, "is_bot": false, "headline": "chore(release): bump version to 1.6.0", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-07T03:44:36Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "526b8176684b4fb649d7d2e25cd1eff92ea282bd", "body": "test(nor): add fødselsnummer, D-nummer, checksum/parse tests + D-nummer support", "is_bot": false, "headline": "Merge pull request #96 from identique/idnumbers-node-issue-28", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-04-07T03:32:20Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "51a8ea0ccc433e8c2d16f92d510cac91ec3acbcc", "body": "- Remove dead try/catch in parse(): JS Date never throws on overflow; date\n validity is already enforced by getFullYear/getMonth/getDate comparisons\n- Add typeof string guard at top of parse() to mirror validate() and prevent\n parse() from accidentally accepting non-string inputs whose toString()\n\n[…]\n40 between fødselsnummer max (31) and D-nummer min (41)\n- Add 1900s D-nummer test vector 45055590110 covering interaction between\n D-nummer day adjustment and individual 900-999/yy>=40 century branch", "is_bot": false, "headline": "fix(#28,#29): address external review feedback — round 3", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-07T03:02:47Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "0848abb8efb99eb92d09fdc4e956c48b8b93eaad", "body": "- Make idType field optional on NationalIdParseResult to avoid breaking change\n for downstream consumers constructing the type literally; parse() always\n populates it\n- Document Python parity deviation in source comment and CHANGELOG: D-nummer\n support is a TypeScript-side extension required by i\n[…]\n other behaviors remain identical to Python source\n- Fix DD=72 test: clarify isDNummer=false (72>71), use checksum-valid vector\n 72019000290 to isolate date-overflow rejection from checksum rejection", "is_bot": false, "headline": "fix(#28,#29): address external review feedback — round 2", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-07T02:44:09Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "cdb2f73dec97b89a860c1eee3350dc8bc6cabcbe", "body": "- Fix DD=40 test: clarify isDNummer=false (40\u003c41), use checksum-valid vector\n 40019000119 to isolate date-overflow rejection path from checksum rejection\n- Remove duplicate standalone leap-year test (already covered in test.each table)", "is_bot": false, "headline": "fix(#28,#29): address external review feedback — round 1", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-05T09:45:27Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "c59983ad01e3c64460e23bf6d3fe7613092c23a7", "body": "… coverage", "is_bot": false, "headline": "docs(#28,#29,#30): update CHANGELOG for NOR D-nummer support and test…", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-05T02:52:55Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "7f8d61f5c2fb58e532227cb63d2a174964ea11d4", "body": "- Fix misleading test.each label for 29029600013: individual 000 (not 001), gender FEMALE (not male)\n- Add 1800s century test vector (10107055008): individual 550, yy=70>=54 → century 18", "is_bot": false, "headline": "fix(#28): address review feedback — round 1", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-05T02:49:33Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "edf82aed89bda822f79065c2463146693706c298", "body": "- Remove redundant `as const` from idType literal assignment\n- Extract mmNum to avoid double parseInt(mm, 10) in date construction/validation\n- Shorten D-nummer detection comment to non-obvious why only\n- Import NationalIdParseResult in test for clean type assertion", "is_bot": false, "headline": "refactor(#28): simplify implementation", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-05T02:42:19Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "b7bd4348aee7de89fd612ee0dc4842a7f5e3a39a", "body": "…upport\n\n- Extend NationalIdParseResult with idType discriminator ('fodselsnummer' | 'd-nummer')\n- Update parse() to detect D-nummer (DD 41-71): subtract 40 from day field, set idType\n- Add comprehensive test file covering all three milestone v1.6.0 issues:\n - 14 fødselsnummer validation tests (val\n[…]\n first+second check digits, malformed input)\n - 11 parse() function tests (birth date, gender, idType, checksum field, errors)\n - 5 integration tests (validateNationalId, parseIdInfo via public API)", "is_bot": false, "headline": "test(#28,#29,#30): add Norway NationalID test coverage and D-nummer s…", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-05T02:40:26Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "b7af32f38f57206754d6ae9c930292e28f4cc4db", "body": null, "is_bot": false, "headline": "chore(release): bump version to 1.5.0", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-03T17:34:58Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "cbba9779e09b87a90b364ec3a693aea030430f4a", "body": "test(#24): add Slovakia edge case and error tests", "is_bot": false, "headline": "Merge pull request #95 from identique/idnumbers-node-issue-24", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-04-03T17:32:19Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "b2aee5e02e1006e741fa3ebde275b6530818f56c", "body": "- Strengthen minimum boundary test with explicit getFullYear() assertion\n to make the yy \u003c 50 → 2000s rule clear\n- Clarify checksum comments for Feb 30/31 tests to show parseInt\n stripping leading zeros", "is_bot": false, "headline": "fix(#24): address external review feedback — round 1", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-03T17:28:46Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "f0d0e43c3cf6b1c58c4890253042e49ce1d6f8ba", "body": "Add comprehensive edge case tests for SVK Birth Number validator:\n- Invalid dates: Feb 30/31, Apr 31, Jun 31\n- Invalid month codes: female month 63 (maps to 13)\n- Invalid formats: leading/trailing whitespace, mixed alphanumeric,\n invalid slash position\n- Boundary conditions: min/max valid ID dates\n\nBranch coverage: 100%, 56 total tests.", "is_bot": false, "headline": "test(#24): add Slovakia edge case and error tests", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-03T17:11:33Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "8d8669ffc522d1ca34aafd0a605fc07b775aa570", "body": "test(#23): add Slovakia parse() function tests", "is_bot": false, "headline": "Merge pull request #94 from identique/idnumbers-node-issue-23", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-04-03T16:58:44Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "f10724c892aaa0f13effcf0708c9a55a26208d32", "body": null, "is_bot": false, "headline": "test(#23): add Feb 29 non-leap year edge case", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-03T16:53:00Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "a48ebdf1504a490836cd4e305601691a46d95dcb", "body": "Remove redundant Python Parity block (assertions already covered),\ndrop duplicate gender test, fix section naming, remove obvious comments.", "is_bot": false, "headline": "refactor(#23): simplify SVK parse tests", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-03T16:25:13Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "a30c37070f5917cd05883ee5773a1f186b635187", "body": "Cover birth date extraction (century handling, failsafe months),\ngender extraction, sequence number, slash format, and error handling.\n37 tests with full branch coverage of NationalID.parse().", "is_bot": false, "headline": "test(#23): add comprehensive Slovakia parse() function tests", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-04-03T16:22:50Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "30182e9f0c074916b118f1cbff7caf390808fc88", "body": "Add comprehensive test file src/__tests__/svk.test.ts (45 tests) for Slovakia Birth Number (Rodné číslo) validate() function covering male/female IDs, slash/no-slash formats, century boundary, date validation, checksum (mod 11), failsafe month codes (2004 law), invalid inputs, registry integration, and direct module access. Coverage: 97.5% lines, 100% branches, 100% functions.", "is_bot": false, "headline": "test(#22): add Slovakia validate() function tests (#93)", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-04-03T15:58:30Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "2888c05aecaef28fe827bde707e3ca43220fd95c", "body": "fix(#91): add npm provenance for verified publish badge", "is_bot": false, "headline": "Merge pull request #92 from identique/idnumbers-node-issue-91", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-03-29T15:44:27Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "d4fa765c7e7df09d415e6954c50dacc092b459a1", "body": null, "is_bot": false, "headline": "fix(#91): add npm provenance for verified publish badge", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-03-29T15:43:57Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "429e136edbdc29d52e213d88c7172b59d96325d7", "body": null, "is_bot": false, "headline": "chore(release): bump version to 1.4.0", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-03-29T15:07:43Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "c7427244d68bb8749b4cb8310bc44e1e98596726", "body": "feat(#86): port 11 missing ID types from Python version", "is_bot": false, "headline": "Merge pull request #90 from identique/idnumbers-node-issue-86", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-03-29T13:27:17Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "9ff0899ec4a99b2841ee50ad40418928eea87d7c", "body": null, "is_bot": false, "headline": "fix(#86): restrict AUT UID regex to U prefix, add BGR 13-digit tests", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-03-17T03:03:31Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "5119c6785aca1f5fc9176933fe75c9e659cb35b5", "body": null, "is_bot": false, "headline": "refactor(#86): simplify implementation", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-03-17T02:50:09Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "a8127c0bbf25a6a94b32948dd179e4c664dcabba", "body": "Add TaxFileNumber and DriverLicenseNumber for AUS, EntityTaxIDNumber\nfor AUT, EntityVAT for BEL, UnifiedIdCode (EIK/BULSTAT) for BGR,\nBusinessID (UID) for CHE, OldIdentityCard for GRC, BusinessIDNumber (BIN)\nfor KAZ, OldResidentRegistration for KOR, OldPersonalCode for LVA, and\nFiscalInformationNumber (RIF) for VEN.\n\nAll types exported from country modules. No COUNTRY_REGISTRY entries\nadded (preserves 80-key count). Tests derived from Python test vectors.", "is_bot": false, "headline": "feat(#86): port 11 missing ID types from Python version", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-03-17T02:42:26Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "e127c124a9f82210edf7da30c9ebba032e454042", "body": "refactor(#85): remove hardcoded test ID bypasses across 12 countries", "is_bot": false, "headline": "Merge pull request #89 from identique/idnumbers-node-issue-85", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-03-17T02:20:52Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "3751cbf3fe49dd165b2cbeada6a329e71eb799e1", "body": "Remove hardcoded ID string bypasses that masked algorithm bugs in ARE,\nAUS, CHE, CZE, EST, ITA, LVA, NGA, NZL, PHL, PRT, and SVK.\n\nSource changes:\n- ARE: remove testValidIds/testInvalidIds arrays, rely on Luhn\n- AUS: remove '5123456701' bypass, rely on weighted checksum\n- CHE: remove specific ID che\n[…]\nXX' prefix case, fix regex to digits-only year\n\nTest changes:\n- Replace all affected test IDs with algorithmically valid data\n- Add previously-invalid IDs as valid where Python accepts them (NGA, PHL)", "is_bot": false, "headline": "refactor(#85): remove hardcoded test ID bypasses across 12 countries", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-03-15T09:20:23Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "becf0bef7e11579326e39c47222fbf936feab494", "body": "fix(#84): fix over-validation rejecting valid IDs in DNK, CAN, ALB", "is_bot": false, "headline": "Merge pull request #88 from identique/idnumbers-node-issue-84", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-03-15T08:56:54Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "f7bccc8be0b4d33b3cfd273972f48e6b60bbc0af", "body": "Add 050308094A (year 1805, previously clamped to 1905) and\nI90308094A (Python test vector). Assert parsed birthDate year\nto prove year-clamping removal works correctly.", "is_bot": false, "headline": "test(#84): add ALB year-clamping regression test vectors", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-03-15T08:53:58Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "24a41dec171e0f66873a61d5154b7fd3658b3486", "body": "- DNK: move 0101701235 to valid (proves checksum removal), add\n 061085-1178, use 3201701234 as invalid (bad date)\n- CAN: add 0-prefix and 8-prefix valid SINs (046454286, 812345676),\n add Python test vector 130692544, update migration invalidId\n- ALB: update example comment for CAN first-digit change", "is_bot": false, "headline": "test(#84): update test data for DNK, CAN, ALB fixes", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-03-15T08:47:00Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "2314b2f360c34fe515e866176b647ee529efdfb7", "body": "Remove year-range clamping (not present in Python source).\nChange gender/month threshold from \u003c= 12 to \u003c 50 to match Python.\nSet hasChecksum: false to match Python metadata.", "is_bot": false, "headline": "fix(#84): remove year clamping and fix gender threshold in ALB", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-03-15T08:46:43Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "7d4ba6e596bd9721beaa0624e8c6e86fe90e7b4f", "body": "Python source has no restriction on SINs starting with 0 or 8.\nValidation should rely solely on Luhn checksum.", "is_bot": false, "headline": "fix(#84): remove first-digit restriction from CAN SIN", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-03-15T08:46:29Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "82c1e6934a38781d695c49427c373129728b196a", "body": "CPR numbers issued after October 2007 do not use check digits.\nPython source marks checksum: False. Remove the validateChecksum()\nfunction and hardcoded bypasses, set hasChecksum: false in metadata.", "is_bot": false, "headline": "fix(#84): remove checksum validation from DNK CPR", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-03-15T08:46:11Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "a2b618d8ccaf5940d7e9b6a90f5f3c047322be16", "body": "fix(#83): correct validation logic in BGR, TUR, SGP, JPN, LKA", "is_bot": false, "headline": "Merge pull request #87 from identique/idnumbers-node-issue-83", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-03-15T08:32:12Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "472eb10781cd8dea252a203edabf15283e2760f6", "body": "Add M1234567N (valid) and M1234567X (invalid) to confirm the\nM-series check letter lookup table is correct.", "is_bot": false, "headline": "test(#83): add SGP M-prefix test vectors", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-03-15T08:21:52Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "f3a149bbbee3143c1ee1fd6dd4b1248ecdcf78ae", "body": "Replace incorrect test data with Python-verified IDs:\n- BGR: use 7501020018/7542011030 with correct parse expectations\n- TUR: add 15973515680 valid case\n- SGP: add Python test IDs (S8076606H, G4549883U, etc.)\n- LKA: use proper checksum-validated IDs from Python test suite", "is_bot": false, "headline": "test(#83): update test data for BGR, TUR, SGP, LKA fixes", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-03-15T08:21:52Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "173cc5b76ec5c2f09afffc1247763907dcf337fb", "body": "Replace hardcoded blacklists and permissive validation with proper\nweighted modulus 11 checksum. Support both old format (9d+V/X) and\nnew format (12d) with old-to-new conversion matching Python source.", "is_bot": false, "headline": "fix(#83): rewrite LKA validation with proper checksum algorithm", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-03-15T08:21:52Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "c98b7ab979f5fa389cd6dc6a0e76cfdf21d327a7", "body": "The checksum weights must be applied in forward order matching the\nPython source. The previous reverse-order application produced\nincorrect checksums for most ID numbers.", "is_bot": false, "headline": "fix(#83): apply JPN My Number weights in forward order", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-03-15T08:21:52Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "245e98d85f3b0b034836402973c599479b75a6ad", "body": "Replace shared ST/FG maps with offset approach with per-prefix\nlookup tables matching the Python source. The previous shared\nmaps produced incorrect check letters for T, G, and M prefixes.", "is_bot": false, "headline": "fix(#83): replace SGP check letter maps with per-prefix tables", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-03-15T08:21:52Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "a160029e8344f9bbd119c40399925be469dbbaff", "body": "JavaScript's % operator can return negative values unlike Python's.\nUse double-modulus pattern to ensure non-negative result for the\n10th digit calculation in both validate() and checksum().", "is_bot": false, "headline": "fix(#83): handle negative modulus in TUR validation", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-03-15T08:21:52Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "d83937157efa0707b6b94c23333e9268fec069d1", "body": "Change 1800s century offset from incorrect 1900 to correct 1800\nwhen month part exceeds 20. Remove hardcoded test bypass for\n'7523169263' that was masking the date parsing bug.", "is_bot": false, "headline": "fix(#83): correct BGR century calculation for monthPart > 20", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-03-15T08:21:52Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "da4015c7774d719ca93a0c701f40ffceed658822", "body": null, "is_bot": false, "headline": "chore(release): bump version to 1.3.0", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-02-17T13:48:09Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "f96ce520a72730542f9d48f247af5ff578e2c2c2", "body": null, "is_bot": false, "headline": "chore(release): update CHANGELOG for v1.3.0", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-02-17T13:47:59Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "962f5740b10210220c05435f75e7f5232ff4fa5c", "body": "refactor(#53): migrate getCountryIdFormat to registry lookup", "is_bot": false, "headline": "Merge pull request #81 from identique/idnumbers-node-issue-53", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-02-17T13:35:12Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "2be8fe018c75661f34acee1215ea81958800e7be", "body": null, "is_bot": false, "headline": "style(#53): fix Prettier formatting in migration test", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-02-17T11:17:40Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "4c628a95e7198a449678f080456e248973670d75", "body": "- Replace Cyrillic 'С' with ASCII 'C' in LKA format string\n- Return enriched copy instead of mutating registry object", "is_bot": false, "headline": "fix(#53): address Copilot review feedback", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-02-17T11:08:11Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "8b6de6b54595e20885929fb41fd6ef2f5e53cd13", "body": "Add 142 tests covering all 80 countries (complete IdFormat fields),\n18 format string assertions, 25 alias resolutions, case insensitivity,\nedge cases, and former stub entries returning null.", "is_bot": false, "headline": "test(#53): add getCountryIdFormat parity tests", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-02-17T08:55:25Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "0c9e4fc1721012d50ac3fbbd4a636a73c068846e", "body": "Replace the ~340-line switch statement with a registry-based lookup\nenriched by SUPPORTED_COUNTRIES data and preserved format strings.\nAll 80 registered countries now return complete IdFormat info.\nRemove 19 unused country imports. Tighten return type to IdFormat | null.", "is_bot": false, "headline": "refactor(#53): replace getCountryIdFormat switch with registry lookup", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-02-17T08:54:14Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "8e95155008442612ec15a23e726d17fdec91fde3", "body": "refactor(#51): migrate validateNationalId to registry lookup", "is_bot": false, "headline": "Merge pull request #80 from identique/idnumbers-node-issue-51", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-02-17T08:47:39Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "274f07b93f7cef1b6d2e2e7a815da3624c3d2d91", "body": "refactor(#52): migrate parseIdInfo to registry lookup", "is_bot": false, "headline": "Merge pull request #79 from identique/idnumbers-node-issue-52", "author_name": "Angus", "author_login": "AngusHsu", "committed_at": "2026-02-17T08:47:20Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "5eb81acd1e72ec237f1f3f1d952016c31faa0b9d", "body": "…parse()\n\nDNK's validate() only checked format and checksum but not date validity,\nwhile parse() did validate dates. This caused a regression where IDs with\nimpossible dates (e.g. month 13) would pass validate() but fail parse(),\nreturning isValid:true with null extractedInfo.", "is_bot": false, "headline": "fix(#51): add date validation to DNK validate() for consistency with …", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-02-16T18:31:05Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "2df0a7750d5d4c866bf9242ff3de30340cdb9385", "body": "Add 389 parity tests covering all 80 countries, composite validators\n(BGD, SMR, NZL), alias resolution, and error handling. Add 7 unit tests\nfor the new resolveKey() method on ValidatorRegistry.", "is_bot": false, "headline": "test(#51): add validateNationalId parity tests and resolveKey unit tests", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-02-16T18:19:01Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "2a12dd90b3a51ae1b781af31c507409a61cc2892", "body": "Replace the ~800-line switch statement with a unified registry-based\npattern: resolve key, validate, conditionally parse, return result.\nRemove ~60 unused class imports that were only needed by the switch.", "is_bot": false, "headline": "refactor(#51): replace validateNationalId switch with registry lookup", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-02-16T17:33:24Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "d3f3644de64d3bba6e52c68b35f02f82b04bef6c", "body": "- BGD: create composite validator supporting both old (13-digit) and new\n (17-digit) national ID formats with OR logic\n- SMR: create composite validator supporting both SSI and COE formats\n- NZL: change registration from NationalID to DriverLicense to match\n the existing validateNationalId switch behavior", "is_bot": false, "headline": "fix(#51): correct BGD, SMR, NZL validator registrations", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-02-16T17:30:55Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "7490c0148d690a07643cde353e03b8b20e602abf", "body": "Add resolveKey() method that returns the primary key (alpha-3) for any\nkey or alias. Refactor get(), has(), and getFormat() to use resolveKey()\ninternally, eliminating duplicated alias resolution logic.", "is_bot": false, "headline": "feat(#51): add resolveKey() to ValidatorRegistry", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-02-16T17:28:39Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "70d2511df9fb30ad93c5ae39879a3658c33fe212", "body": "…mport\n\n- Replace `any` types in adapters.ts with explicit CountryModule, AnyMetadata,\n and FunctionBasedMetadata interfaces\n- Replace `any` in RegistryEntry with CountryModule type\n- Remove side-effect import from registry/index.ts to keep it side-effect free\n for type-only consumers\n- Re-export new adapter types from barrel\n\nAddresses Copilot review feedback on PR #79.", "is_bot": false, "headline": "refactor(#52): improve type safety and remove redundant side-effect i…", "author_name": "Angus Hsu", "author_login": "AngusHsu", "committed_at": "2026-02-16T17:26:00Z", "body_truncated": false, "is_coding_agent": false } ], "releases_count": 12, "commits_last_year": 137, "latest_release_at": "2026-07-17T11:33:00Z", "latest_release_tag": "v1.9.0", "releases_from_tags": false, "days_since_last_push": 4, "active_weeks_last_year": 16, "days_since_latest_release": 5, "mean_days_between_releases": 25.4 }, "community": { "has_readme": true, "has_license": true, "has_description": true, "has_contributing": false, "health_percentage": 50, "has_issue_template": false, "has_code_of_conduct": false, "has_pull_request_template": false }, "ecosystem": { "packages": [ { "name": "idnumbers", "exists": true, "license": "MIT", "keywords": [ "id", "identification", "validation", "national-id", "ssn", "medicare", "nino", "sin", "tax-id", "typescript", "verification", "usa", "australia", "south-africa", "united-kingdom", "canada", "germany", "france", "netherlands", "albania", "austria", "belgium", "italy", "spain", "denmark", "poland", "czech-republic", "finland", "social-security", "national-insurance", "social-insurance", "fiscal-code", "dni", "cpr", "bsn", "atin", "pesel", "hetu", "birth-number" ], "ecosystem": "npm", "matches_repo": true, "registry_url": "https://www.npmjs.com/package/idnumbers", "is_deprecated": false, "latest_version": "1.9.0", "repository_url": "https://github.com/identique/idnumbers-npm", "versions_count": 12, "total_downloads": null, "dependents_count": null, "deprecation_note": null, "maintainers_count": 1, "monthly_downloads": 12676, "first_published_at": "2025-11-02T02:59:48.610000Z", "latest_published_at": "2026-07-17T11:39:35.934000Z", "latest_version_yanked": null, "days_since_latest_publish": 4 } ] }, "popularity": { "forks": 2, "stars": 0, "watchers": 0, "fork_history": { "days": [ { "date": "2026-01-21", "count": 1 }, { "date": "2026-06-29", "count": 1 } ], "complete": true, "collected": 2, "total_forks": 2 }, "star_history": { "days": [], "complete": true, "collected": 0, "total_stars": 0 }, "open_issues_and_prs": 59 }, "ai_readiness": { "has_nix": false, "example_dirs": [ "examples" ], "has_llms_txt": false, "has_dockerfile": false, "has_mcp_signal": false, "bootstrap_files": [], "api_schema_files": [], "has_devcontainer": false, "typecheck_configs": [ "tsconfig.json" ], "toolchain_manifests": [], "largest_source_bytes": 23937, "source_files_sampled": 197, "oversized_source_files": 0, "agent_instruction_files": [], "agent_instruction_max_bytes": null }, "dependencies": { "manifests": [ "package.json" ], "advisories": { "error": null, "scope": null, "source": null, "findings": [], "collected": false, "malicious": [], "truncated": false, "by_severity": {}, "advisory_count": 0, "affected_count": 0, "assessed_count": 0, "malicious_count": 0, "assessed_package": null, "unassessed_count": 0, "direct_affected_count": 0 }, "ecosystems": [ "npm" ], "dependencies": [], "all_dependencies": { "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository", "source": null, "packages": [], "collected": false, "truncated": false, "total_count": null, "direct_count": null, "indirect_count": null } }, "maintainership": { "issues": { "open_prs": 8, "merged_prs": 44, "open_issues": 51, "closed_ratio": 0.532, "closed_issues": 58, "closed_unmerged_prs": 1 }, "bus_factor": 1, "bot_contributors": 0, "top_contributors": [ { "type": "User", "login": "AngusHsu", "commits": 137, "avatar_url": "https://avatars.githubusercontent.com/u/26132913?v=4" } ], "contributors_sampled": 1, "top_contributor_share": 1 }, "quality_signals": { "has_ci": true, "has_tests": true, "ci_workflows": [ "ci.yml", "npm-publish.yml", "test-npm-publish.yml" ], "has_docs_dir": true, "linter_configs": [ ".eslintrc.js" ], "has_editorconfig": false, "has_linter_config": true, "has_precommit_config": false }, "security_signals": { "lockfiles": [ "package-lock.json" ], "scorecard": { "checks": [ { "name": "Binary-Artifacts", "score": 10, "reason": "no binaries found in the repo", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts" }, { "name": "Branch-Protection", "score": 8, "reason": "branch protection is not maximal on development and all release branches", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection" }, { "name": "CI-Tests", "score": 10, "reason": "13 out of 13 merged PRs checked by a CI test -- score normalized to 10", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests" }, { "name": "CII-Best-Practices", "score": 0, "reason": "no effort to earn an OpenSSF best practices badge detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices" }, { "name": "Code-Review", "score": 0, "reason": "Found 1/14 approved changesets -- score normalized to 0", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review" }, { "name": "Contributors", "score": 0, "reason": "project has 0 contributing companies or organizations -- score normalized to 0", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors" }, { "name": "Dangerous-Workflow", "score": 10, "reason": "no dangerous workflow patterns detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow" }, { "name": "Dependency-Update-Tool", "score": 0, "reason": "no update tool detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool" }, { "name": "Fuzzing", "score": 0, "reason": "project is not fuzzed", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing" }, { "name": "License", "score": 10, "reason": "license file detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license" }, { "name": "Maintained", "score": 10, "reason": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained" }, { "name": "Packaging", "score": 10, "reason": "packaging workflow detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging" }, { "name": "Pinned-Dependencies", "score": 3, "reason": "dependency not pinned by hash detected -- score normalized to 3", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies" }, { "name": "SAST", "score": 0, "reason": "SAST tool is not run on all commits -- score normalized to 0", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast" }, { "name": "Security-Policy", "score": 0, "reason": "security policy file not detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy" }, { "name": "Signed-Releases", "score": null, "reason": "no releases found", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases" }, { "name": "Token-Permissions", "score": 0, "reason": "detected GitHub workflow tokens with excessive permissions", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions" }, { "name": "Vulnerabilities", "score": 0, "reason": "24 existing vulnerabilities detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities" } ], "commit": "b2ec45bf46eb8155da8c9769526c64895726afa7", "ran_at": "2026-07-22T11:39:34Z", "aggregate_score": 4.4, "scorecard_version": "v5.5.0" }, "has_codeql_workflow": false, "has_security_policy": false, "has_dependabot_config": false }, "contribution_flow": { "collected": true, "ci_last_run_at": "2026-07-17T11:39:39Z", "oldest_open_prs": [ { "number": 114, "created_at": "2026-06-29T12:47:56Z", "last_comment_at": "2026-07-19T17:48:11Z", "last_comment_author": "ramezhanna" }, { "number": 154, "created_at": "2026-07-17T04:21:21Z", "last_comment_at": null, "last_comment_author": null }, { "number": 156, "created_at": "2026-07-17T11:54:57Z", "last_comment_at": null, "last_comment_author": null }, { "number": 157, "created_at": "2026-07-17T11:55:00Z", "last_comment_at": null, "last_comment_author": null }, { "number": 158, "created_at": "2026-07-17T11:55:02Z", "last_comment_at": null, "last_comment_author": null }, { "number": 159, "created_at": "2026-07-17T11:55:05Z", "last_comment_at": null, "last_comment_author": null }, { "number": 161, "created_at": "2026-07-18T05:45:37Z", "last_comment_at": null, "last_comment_author": null }, { "number": 162, "created_at": "2026-07-18T05:45:43Z", "last_comment_at": null, "last_comment_author": null } ], "last_merged_pr_at": "2026-07-17T11:32:33Z", "ci_last_conclusion": "SUCCESS", "oldest_open_issues": [ { "number": 39, "created_at": "2025-11-26T08:34:28Z", "last_comment_at": "2025-11-29T21:27:19Z", "last_comment_author": "VidhyaDivakar" }, { "number": 40, "created_at": "2025-11-26T08:34:32Z", "last_comment_at": null, "last_comment_author": null }, { "number": 41, "created_at": "2025-11-26T08:35:03Z", "last_comment_at": null, "last_comment_author": null }, { "number": 54, "created_at": "2025-11-26T08:47:37Z", "last_comment_at": "2026-07-02T12:35:49Z", "last_comment_author": "ramezhanna" }, { "number": 55, "created_at": "2025-11-26T08:47:41Z", "last_comment_at": null, "last_comment_author": null }, { "number": 56, "created_at": "2025-11-26T08:47:46Z", "last_comment_at": null, "last_comment_author": null }, { "number": 57, "created_at": "2025-11-26T08:47:55Z", "last_comment_at": null, "last_comment_author": null }, { "number": 58, "created_at": "2025-11-26T08:48:02Z", "last_comment_at": null, "last_comment_author": null }, { "number": 59, "created_at": "2025-11-26T08:48:10Z", "last_comment_at": "2026-07-17T07:28:39Z", "last_comment_author": "AngusHsu" }, { "number": 60, "created_at": "2025-11-26T08:48:14Z", "last_comment_at": "2026-07-17T07:28:40Z", "last_comment_author": "AngusHsu" }, { "number": 61, "created_at": "2025-11-26T08:48:20Z", "last_comment_at": "2026-07-17T07:28:42Z", "last_comment_author": "AngusHsu" }, { "number": 115, "created_at": "2026-07-06T11:17:29Z", "last_comment_at": null, "last_comment_author": null }, { "number": 116, "created_at": "2026-07-06T11:17:30Z", "last_comment_at": null, "last_comment_author": null }, { "number": 117, "created_at": "2026-07-06T11:17:32Z", "last_comment_at": null, "last_comment_author": null }, { "number": 118, "created_at": "2026-07-06T11:17:34Z", "last_comment_at": null, "last_comment_author": null }, { "number": 119, "created_at": "2026-07-06T11:17:36Z", "last_comment_at": null, "last_comment_author": null }, { "number": 120, "created_at": "2026-07-06T11:17:37Z", "last_comment_at": null, "last_comment_author": null }, { "number": 121, "created_at": "2026-07-06T11:17:39Z", "last_comment_at": null, "last_comment_author": null }, { "number": 122, "created_at": "2026-07-06T11:17:42Z", "last_comment_at": null, "last_comment_author": null }, { "number": 123, "created_at": "2026-07-06T11:17:44Z", "last_comment_at": null, "last_comment_author": null } ] } }, "config": { "disabled_metrics": [], "disabled_categories": [], "disabled_components": {} }, "source": { "url": "https://github.com/identique/idnumbers-npm", "host": "github.com", "name": "idnumbers-npm", "owner": "identique" }, "metrics": { "overall": { "key": "overall", "band": "moderate", "name": "Overall health", "note": null, "notes": [], "value": 61, "inputs": { "security": 44, "vitality": 85, "community": 35, "governance": 50, "engineering": 84 }, "components": [] }, "categories": [ { "key": "vitality", "band": "excellent", "name": "Vitality", "value": 85, "weight": 0.22, "metrics": [ { "key": "development_activity", "band": "good", "name": "Development activity", "note": null, "notes": [], "value": 75, "inputs": { "commits_last_year": 137, "human_commit_share": 1, "days_since_last_push": 4, "active_weeks_last_year": 16 }, "components": [ { "key": "push_recency", "name": "Push recency", "detail": "last push 4 days ago", "points": 36, "status": "met", "details": [ { "code": "push_recency", "params": { "days": 4 } } ], "max_points": 36 }, { "key": "commit_cadence", "name": "Commit cadence", "detail": "16/52 weeks with commits", "points": 11.1, "status": "partial", "details": [ { "code": "commit_cadence_weeks", "params": { "weeks": 16 } } ], "max_points": 36 }, { "key": "commit_volume", "name": "Commit volume", "detail": "137 commits in the last year", "points": 18, "status": "met", "details": [ { "code": "commits_last_year", "params": { "count": 137 } } ], "max_points": 18 }, { "key": "openssf_scorecard_maintained", "name": "OpenSSF Scorecard: Maintained", "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10", "points": 10, "status": "met", "details": [], "max_points": 10 } ] }, { "key": "release_discipline", "band": "excellent", "name": "Release discipline", "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.", "notes": [ { "code": "excluded_no_data", "params": { "components": [ "openssf_scorecard_signed_releases" ] } }, { "code": "weights_renormalized", "params": {} } ], "value": 100, "inputs": { "releases_count": 12, "latest_release_tag": "v1.9.0", "releases_from_tags": false, "days_since_latest_release": 5, "mean_days_between_releases": 25.4 }, "components": [ { "key": "ships_releases", "name": "Ships releases", "detail": "12 releases published", "points": 27, "status": "met", "details": [ { "code": "releases_published", "params": { "count": 12 } } ], "max_points": 27 }, { "key": "release_recency", "name": "Release recency", "detail": "latest release 5 days ago", "points": 36, "status": "met", "details": [ { "code": "release_recency", "params": { "days": 5 } } ], "max_points": 36 }, { "key": "release_cadence", "name": "Release cadence", "detail": "a release every ~25.4 days", "points": 27, "status": "met", "details": [ { "code": "release_cadence", "params": { "gap": 25.4 } } ], "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": 5, "days_since_last_human_commit_is_floor": false }, "components": [ { "key": "project_is_still_maintained", "name": "Project is still maintained", "detail": "last human commit 5 days ago", "points": 100, "status": "met", "details": [ { "code": "abandonment_maintained", "params": { "days": 5 } } ], "max_points": 100 } ] } ], "description": "Is the project alive — is code being written and are releases shipping?" }, { "key": "community", "band": "at_risk", "name": "Community & Adoption", "value": 35, "weight": 0.18, "metrics": [ { "key": "popularity", "band": "critical", "name": "Popularity & adoption", "note": null, "notes": [], "value": 1, "inputs": { "forks": 2, "stars": 0, "watchers": 0, "growth_state": "unverified", "growth_factor_pct": 100, "growth_unverified_reason": "no_history" }, "components": [ { "key": "stars", "name": "Stars", "detail": "0 stars", "points": 0, "status": "missed", "details": [ { "code": "stars", "params": { "count": 0 } } ], "max_points": 60 }, { "key": "forks", "name": "Forks", "detail": "2 forks", "points": 0, "status": "missed", "details": [ { "code": "forks", "params": { "count": 2 } } ], "max_points": 25 }, { "key": "watchers", "name": "Watchers", "detail": "0 watchers", "points": 0, "status": "missed", "details": [ { "code": "watchers", "params": { "count": 0 } } ], "max_points": 15 } ] }, { "key": "community_health", "band": "moderate", "name": "Community health", "note": null, "notes": [], "value": 50, "inputs": { "has_readme": true, "has_license": true, "has_contributing": false, "has_issue_template": false, "has_code_of_conduct": false, "has_pull_request_template": false }, "components": [ { "key": "readme", "name": "README", "detail": null, "points": 22.5, "status": "met", "details": [], "max_points": 22.5 }, { "key": "license", "name": "License", "detail": "recognized license (MIT)", "points": 22.5, "status": "met", "details": [ { "code": "license_standard", "params": {} }, { "code": "license_spdx", "params": { "spdx": "MIT" } } ], "max_points": 22.5 }, { "key": "contributing_guide", "name": "CONTRIBUTING guide", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 18 }, { "key": "code_of_conduct", "name": "Code of conduct", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 13.5 }, { "key": "issue_template", "name": "Issue template", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 7.2 }, { "key": "pr_template", "name": "PR template", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 6.3 } ] }, { "key": "ecosystem_adoption", "band": "moderate", "name": "Ecosystem adoption (downloads)", "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.", "notes": [ { "code": "excluded_no_data", "params": { "components": [ "registry_dependents" ] } }, { "code": "weights_renormalized", "params": {} } ], "value": 68, "inputs": { "packages": [ "idnumbers" ], "dependents": null, "ecosystems": "npm", "total_downloads": null, "monthly_downloads": 12676 }, "components": [ { "key": "monthly_downloads", "name": "Monthly downloads", "detail": "12,676 downloads/month across npm", "points": 54.7, "status": "partial", "details": [ { "code": "downloads_monthly", "params": { "count": 12676, "ecosystems": "npm" } } ], "max_points": 80 }, { "key": "registry_dependents", "name": "Registry dependents", "detail": "not reported by this ecosystem", "points": 0, "status": "excluded", "details": [ { "code": "not_reported_by_this_ecosystem", "params": {} } ], "max_points": 20 } ] } ], "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?" }, { "key": "governance", "band": "moderate", "name": "Sustainability & Governance", "value": 50, "weight": 0.24, "metrics": [ { "key": "maintainer_resilience", "band": "critical", "name": "Maintainer resilience (bus factor)", "note": null, "notes": [], "value": 10, "inputs": { "bus_factor": 1, "contributors_sampled": 1, "top_contributor_share": 1 }, "components": [ { "key": "bus_factor", "name": "Bus factor", "detail": "1 contributor(s) cover half of all commits", "points": 9, "status": "partial", "details": [ { "code": "bus_factor", "params": { "count": 1 } } ], "max_points": 54 }, { "key": "commit_distribution", "name": "Commit distribution", "detail": "top contributor authored 100% of commits", "points": 0, "status": "missed", "details": [ { "code": "top_contributor_share", "params": { "share": 100 } } ], "max_points": 22.5 }, { "key": "contributor_breadth", "name": "Contributor breadth", "detail": "1 contributors", "points": 1.4, "status": "partial", "details": [ { "code": "contributors_sampled", "params": { "count": 1 } } ], "max_points": 13.5 }, { "key": "openssf_scorecard_contributors", "name": "OpenSSF Scorecard: Contributors", "detail": "project has 0 contributing companies or organizations -- score normalized to 0", "points": 0, "status": "missed", "details": [], "max_points": 10 } ] }, { "key": "responsiveness", "band": "moderate", "name": "Issue & PR responsiveness", "note": null, "notes": [], "value": 62, "inputs": { "merged_prs": 44, "open_issues": 51, "closed_issues": 58, "issue_closed_ratio": 0.532, "closed_unmerged_prs": 1 }, "components": [ { "key": "issue_resolution", "name": "Issue resolution", "detail": "53% of issues closed", "points": 24.9, "status": "partial", "details": [ { "code": "issues_closed_share", "params": { "share": 53 } } ], "max_points": 46.75 }, { "key": "pr_acceptance", "name": "PR acceptance", "detail": "44/45 decided PRs merged", "points": 37.4, "status": "partial", "details": [ { "code": "decided_prs_merged", "params": { "merged": 44, "decided": 45 } } ], "max_points": 38.25 }, { "key": "openssf_scorecard_code_review", "name": "OpenSSF Scorecard: Code-Review", "detail": "Found 1/14 approved changesets -- score normalized to 0", "points": 0, "status": "missed", "details": [], "max_points": 15 } ] }, { "key": "stewardship", "band": "at_risk", "name": "Ownership & stewardship", "note": null, "notes": [], "value": 44, "inputs": { "followers": 1, "owner_type": "Organization", "is_verified": null, "owner_login": "identique", "public_repos": 3, "account_age_days": 1269 }, "components": [ { "key": "ownership_backing", "name": "Ownership backing", "detail": "organization-owned", "points": 30, "status": "met", "details": [ { "code": "owner_organization", "params": {} } ], "max_points": 30 }, { "key": "verified_domain", "name": "Verified domain", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 20 }, { "key": "owner_reach", "name": "Owner reach", "detail": "1 followers of identique", "points": 2.2, "status": "partial", "details": [ { "code": "owner_followers", "params": { "count": 1, "login": "identique" } } ], "max_points": 25 }, { "key": "track_record", "name": "Track record", "detail": "3 public repos, account ~3 yr old", "points": 11.3, "status": "partial", "details": [ { "code": "public_repos", "params": { "count": 3 } }, { "code": "account_age_years", "params": { "years": 3 } } ], "max_points": 25 } ] }, { "key": "package_maintenance", "band": "excellent", "name": "Package maintenance", "note": null, "notes": [], "value": 100, "inputs": { "packages": [ "idnumbers" ], "ecosystems": "npm", "any_deprecated": false, "min_days_since_publish": 4 }, "components": [ { "key": "published_resolvable", "name": "Published & resolvable", "detail": "1 package(s) on npm", "points": 25, "status": "met", "details": [ { "code": "packages_published", "params": { "count": 1, "ecosystems": "npm" } } ], "max_points": 25 }, { "key": "publish_recency", "name": "Publish recency", "detail": "latest publish 4 days ago", "points": 35, "status": "met", "details": [ { "code": "publish_recency", "params": { "days": 4 } } ], "max_points": 35 }, { "key": "version_history", "name": "Version history", "detail": "12 published versions", "points": 20, "status": "met", "details": [ { "code": "published_versions", "params": { "count": 12 } } ], "max_points": 20 }, { "key": "not_deprecated", "name": "Not deprecated", "detail": "active, not deprecated or yanked", "points": 20, "status": "met", "details": [ { "code": "package_not_deprecated", "params": {} } ], "max_points": 20 } ] } ], "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?" }, { "key": "engineering", "band": "good", "name": "Engineering Quality", "value": 84, "weight": 0.2, "metrics": [ { "key": "engineering_practices", "band": "good", "name": "Engineering practices", "note": null, "notes": [], "value": 84, "inputs": { "has_ci": true, "has_tests": true, "has_editorconfig": false, "has_linter_config": true, "has_precommit_config": false }, "components": [ { "key": "ci_workflows", "name": "CI workflows", "detail": "3 workflow(s)", "points": 24, "status": "met", "details": [ { "code": "ci_workflows", "params": { "count": 3 } } ], "max_points": 24 }, { "key": "tests_present", "name": "Tests present", "detail": null, "points": 24, "status": "met", "details": [], "max_points": 24 }, { "key": "linter_config", "name": "Linter config", "detail": ".eslintrc.js", "points": 16, "status": "met", "details": [ { "code": "file_list", "params": { "files": ".eslintrc.js" } } ], "max_points": 16 }, { "key": "pre_commit_hooks", "name": "Pre-commit hooks", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 9.6 }, { "key": "editorconfig", "name": ".editorconfig", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 6.4 }, { "key": "openssf_scorecard_ci_tests", "name": "OpenSSF Scorecard: CI-Tests", "detail": "13 out of 13 merged PRs checked by a CI test -- score normalized to 10", "points": 20, "status": "met", "details": [], "max_points": 20 } ] }, { "key": "documentation", "band": "excellent", "name": "Documentation", "note": null, "notes": [], "value": 85, "inputs": { "topics": [ "identification-number", "idnumbers", "national-id", "national-id-validator", "national-identification-number", "national-identity", "nodejs", "npm", "parser-library", "typescript", "validation-library" ], "has_wiki": true, "homepage": null, "has_readme": true, "has_docs_dir": true, "has_description": true }, "components": [ { "key": "readme", "name": "README", "detail": null, "points": 30, "status": "met", "details": [], "max_points": 30 }, { "key": "documentation_directory", "name": "Documentation directory", "detail": null, "points": 25, "status": "met", "details": [], "max_points": 25 }, { "key": "documentation_homepage_site", "name": "Documentation / homepage site", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 15 }, { "key": "repository_description", "name": "Repository description", "detail": null, "points": 10, "status": "met", "details": [], "max_points": 10 }, { "key": "topics", "name": "Topics", "detail": "11 topics", "points": 10, "status": "met", "details": [ { "code": "topics_count", "params": { "count": 11 } } ], "max_points": 10 }, { "key": "wiki", "name": "Wiki", "detail": null, "points": 10, "status": "met", "details": [], "max_points": 10 } ] } ], "description": "Are baseline engineering and documentation practices in place?" }, { "key": "security", "band": "at_risk", "name": "Security", "value": 44, "weight": 0.16, "metrics": [ { "key": "security_posture", "band": "at_risk", "name": "Security posture", "note": "Excluded from scoring (no data or not applicable): Signed-Releases. Remaining weights renormalized.", "notes": [ { "code": "excluded_no_data", "params": { "components": [ "signed_releases" ] } }, { "code": "weights_renormalized", "params": {} } ], "value": 44, "inputs": { "source": "openssf_scorecard", "checks_evaluated": 17, "scorecard_version": "v5.5.0", "checks_inconclusive": 1, "scorecard_aggregate": 4.4 }, "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 is not maximal on development and all release branches", "points": 6, "status": "partial", "details": [], "max_points": 7.5 }, { "key": "ci_tests", "name": "CI-Tests", "detail": "13 out of 13 merged PRs checked by a CI test -- score normalized to 10", "points": 2.5, "status": "met", "details": [], "max_points": 2.5 }, { "key": "cii_best_practices", "name": "CII-Best-Practices", "detail": "no effort to earn an OpenSSF best practices badge detected", "points": 0, "status": "missed", "details": [], "max_points": 2.5 }, { "key": "code_review", "name": "Code-Review", "detail": "Found 1/14 approved changesets -- score normalized to 0", "points": 0, "status": "missed", "details": [], "max_points": 7.5 }, { "key": "contributors", "name": "Contributors", "detail": "project has 0 contributing companies or organizations -- score normalized to 0", "points": 0, "status": "missed", "details": [], "max_points": 2.5 }, { "key": "dangerous_workflow", "name": "Dangerous-Workflow", "detail": "no dangerous workflow patterns detected", "points": 10, "status": "met", "details": [], "max_points": 10 }, { "key": "dependency_update_tool", "name": "Dependency-Update-Tool", "detail": "no update tool detected", "points": 0, "status": "missed", "details": [], "max_points": 7.5 }, { "key": "fuzzing", "name": "Fuzzing", "detail": "project is not fuzzed", "points": 0, "status": "missed", "details": [], "max_points": 5 }, { "key": "license", "name": "License", "detail": "license file detected", "points": 2.5, "status": "met", "details": [], "max_points": 2.5 }, { "key": "maintained", "name": "Maintained", "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10", "points": 7.5, "status": "met", "details": [], "max_points": 7.5 }, { "key": "packaging", "name": "Packaging", "detail": "packaging workflow detected", "points": 5, "status": "met", "details": [], "max_points": 5 }, { "key": "pinned_dependencies", "name": "Pinned-Dependencies", "detail": "dependency not pinned by hash detected -- score normalized to 3", "points": 1.5, "status": "partial", "details": [], "max_points": 5 }, { "key": "sast", "name": "SAST", "detail": "SAST tool is not run on all commits -- score normalized to 0", "points": 0, "status": "missed", "details": [], "max_points": 5 }, { "key": "security_policy", "name": "Security-Policy", "detail": "security policy file not detected", "points": 0, "status": "missed", "details": [], "max_points": 5 }, { "key": "signed_releases", "name": "Signed-Releases", "detail": "no releases found", "points": 0, "status": "excluded", "details": [ { "code": "no_data", "params": {} } ], "max_points": 7.5 }, { "key": "token_permissions", "name": "Token-Permissions", "detail": "detected GitHub workflow tokens with excessive permissions", "points": 0, "status": "missed", "details": [], "max_points": 7.5 }, { "key": "vulnerabilities", "name": "Vulnerabilities", "detail": "24 existing vulnerabilities detected", "points": 0, "status": "missed", "details": [], "max_points": 7.5 } ] }, { "key": "high_risk_jurisdiction_exposure", "band": "excellent", "name": "High-Risk Jurisdiction Exposure", "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.", "notes": [ { "code": "jurisdiction_evidence_limits", "params": {} } ], "value": 100, "inputs": { "meaning": "self-published location evidence; not nationality or citizenship", "red_flag": false, "exposures": [], "policy_countries": [ "Russia", "Iran", "North Korea" ], "review_only_matches": 0, "assessed_self_published_locations": 1 }, "components": [ { "key": "policy_exposure_multiplier", "name": "Policy exposure multiplier", "detail": "no confirmed policy-scope location match", "points": 100, "status": "met", "details": [ { "code": "jurisdiction_no_match", "params": {} } ], "max_points": 100 } ] } ], "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?" }, { "key": "ai_readiness", "band": "moderate", "name": "AI Readiness", "value": 56, "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.99, "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": "99 of 100 human commits state their intent (structured subject or explanatory body)", "points": 40, "status": "met", "details": [ { "code": "legible_history", "params": { "legible": 99, "sampled": 100 } } ], "max_points": 40 } ] }, { "key": "ai_verify_loop", "band": "moderate", "name": "Verify loop (build / test / typecheck)", "note": null, "notes": [], "value": 57, "inputs": { "has_nix": false, "has_tests": true, "lockfiles": [ "package-lock.json" ], "has_dockerfile": false, "typed_language": true, "bootstrap_files": [], "has_devcontainer": false, "has_linter_config": true, "typecheck_configs": [ "tsconfig.json" ], "agent_commit_share": 0, "toolchain_manifests": [], "dependency_bot_commit_share": 0 }, "components": [ { "key": "one_command_bootstrap", "name": "One-command bootstrap", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 18 }, { "key": "automated_tests", "name": "Automated tests", "detail": null, "points": 22, "status": "met", "details": [], "max_points": 22 }, { "key": "lint_format_config", "name": "Lint / format config", "detail": ".eslintrc.js", "points": 11, "status": "met", "details": [ { "code": "file_list", "params": { "files": ".eslintrc.js" } } ], "max_points": 11 }, { "key": "static_type_checking", "name": "Static type checking", "detail": "tsconfig.json", "points": 11, "status": "met", "details": [ { "code": "file_list", "params": { "files": "tsconfig.json" } } ], "max_points": 11 }, { "key": "reproducible_environment", "name": "Reproducible environment", "detail": "lockfile", "points": 10, "status": "met", "details": [ { "code": "file_list", "params": { "files": "lockfile" } } ], "max_points": 10 }, { "key": "demonstrated_agent_practice", "name": "Demonstrated agent practice", "detail": "no agent-authored commits among the last 100", "points": 0, "status": "missed", "details": [ { "code": "no_agent_authored_commits", "params": { "sampled": 100 } } ], "max_points": 10 }, { "key": "automated_maintenance", "name": "Automated maintenance", "detail": "no automated dependency updates observed", "points": 0, "status": "missed", "details": [ { "code": "no_dependency_automation", "params": {} } ], "max_points": 8 }, { "key": "openssf_scorecard_pinned_dependencies", "name": "OpenSSF Scorecard: Pinned-Dependencies", "detail": "dependency not pinned by hash detected -- score normalized to 3", "points": 3, "status": "partial", "details": [], "max_points": 10 } ] }, { "key": "ai_code_legibility", "band": "excellent", "name": "Code legibility for models", "note": null, "notes": [], "value": 100, "inputs": { "primary_language": "TypeScript", "largest_source_bytes": 23937, "source_files_sampled": 197, "oversized_source_files": 0 }, "components": [ { "key": "type_checkable_code", "name": "Type-checkable code", "detail": "TypeScript (statically typed)", "points": 45, "status": "met", "details": [ { "code": "statically_typed_language", "params": { "language": "TypeScript" } } ], "max_points": 45 }, { "key": "manageable_file_sizes", "name": "Manageable file sizes", "detail": "0/197 source files over 60KB", "points": 55, "status": "met", "details": [ { "code": "oversized_source_files", "params": { "kb": 60, "sampled": 197, "oversized": 0 } } ], "max_points": 55 } ] }, { "key": "ai_interfaces", "band": "at_risk", "name": "Machine-readable interfaces", "note": null, "notes": [], "value": 40, "inputs": { "example_dirs": [ "examples" ], "has_mcp_signal": false, "api_schema_files": [] }, "components": [ { "key": "api_schema_openapi_graphql_proto", "name": "API schema (OpenAPI/GraphQL/proto)", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 40 }, { "key": "mcp_server", "name": "MCP server", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 20 }, { "key": "runnable_examples", "name": "Runnable examples", "detail": "examples", "points": 40, "status": "met", "details": [ { "code": "file_list", "params": { "files": "examples" } } ], "max_points": 40 } ] } ], "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score." } ], "metrics_version": "1.13.0" }, "warnings": [ "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository", "deps.dev does not index npm:idnumbers@1.9.0; advisories assessed against the repository dependency graph instead" ], "report_type": "repository", "generated_at": "2026-07-22T11:39:49.702934Z", "schema_version": "0.26.0", "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/i/identique/idnumbers-npm.svg", "full_name": "identique/idnumbers-npm", "license_state": "standard", "license_spdx": "MIT" }, "repoMeta": null, "notFound": false, "related": [ { "id": 143, "full_name": "strapi/strapi", "url": "https://github.com/strapi/strapi", "description": "🚀 Strapi is the leading open-source headless CMS. It’s 100% JavaScript/TypeScript, fully customizable, and developer-first.", "ecosystem": "npm", "ecosystems": [ "npm" ], "primary_language": "TypeScript", "languages": [ "TypeScript", "JavaScript" ], "topics": [ "strapi", "nodejs", "api", "dashboard", "javascript", "graphql", "rest", "cms", "headless-cms", "jamstack", "customizable", "hacktoberfest", "mysql", "content-management", "cms-framework", "content-management-system", "typescript", "no-code", "posgresql" ], "license_spdx": null, "license_state": "custom", "stars": 72664, "forks": 9793, "watchers": 649, "monthly_downloads": null, "latest_score": 90, "latest_band": "excellent", "latest_scanned_at": "2026-07-15T20:41:36.268873Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "unverified", "red_flags": [], "badge_url": "" }, { "id": 16084, "full_name": "valkey-io/valkey-glide", "url": "https://github.com/valkey-io/valkey-glide", "description": "An open source Valkey client library that supports Valkey, and Redis open source 6.2, 7.0 and 7.2. Valkey GLIDE is designed for reliability, optimized performance, and high-availability, for Valkey and Redis OSS based applications. GLIDE is a multi language client library, written in Rust with programming language bindings, such as Java and Python", "ecosystem": "npm", "ecosystems": [ "npm", "go", "crates", "maven", "pypi" ], "primary_language": "Java", "languages": [ "Java", "Python", "Rust", "Go", "TypeScript" ], "topics": [ "cache", "fault-tolerance", "golang", "java", "javascript", "kotlin", "nodejs", "open-source", "performance", "python", "reliability", "rust", "typescript", "valkey", "valkey-client", "database", "key-value", "csharp", "pubsub", "scala", "redis", "client", "driver", "napi", "cross-platform", "cluster", "standalone", "high-availability", "fault-tolerant", "distributed", "scalable", "resilient", "valkey-glide" ], "license_spdx": "Apache-2.0", "license_state": "standard", "stars": 765, "forks": 167, "watchers": 13, "monthly_downloads": 1360064, "latest_score": 88, "latest_band": "excellent", "latest_scanned_at": "2026-07-17T13:50:04.256599Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "unverified", "red_flags": [], "badge_url": "" }, { "id": 119, "full_name": "immich-app/immich", "url": "https://github.com/immich-app/immich", "description": "High performance self-hosted photo and video management solution.", "ecosystem": "npm", "ecosystems": [ "npm", "pypi" ], "primary_language": "TypeScript", "languages": [], "topics": [ "backup-tool", "flutter", "google-photos", "google-photos-alternative", "javascript", "mobile-app", "nestjs", "nodejs", "photo-gallery", "photos", "photos-management", "self-hosted", "svelte", "sveltekit", "typescript", "videos" ], "license_spdx": "AGPL-3.0", "license_state": "standard", "stars": 107459, "forks": 6188, "watchers": 336, "monthly_downloads": 0, "latest_score": 88, "latest_band": "excellent", "latest_scanned_at": "2026-07-13T01:53:16.311041Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "unverified", "red_flags": [], "badge_url": "" }, { "id": 19113, "full_name": "alextran1502/immich", "url": "https://github.com/alextran1502/immich", "description": "High performance self-hosted photo and video management solution.", "ecosystem": "npm", "ecosystems": [ "npm", "pypi" ], "primary_language": "TypeScript", "languages": [ "TypeScript", "Dart", "Svelte" ], "topics": [ "backup-tool", "mobile-app", "photo-gallery", "photos", "self-hosted", "videos", "flutter", "nestjs", "nodejs", "google-photos-alternative", "svelte", "sveltekit", "google-photos", "photos-management", "typescript", "javascript" ], "license_spdx": "AGPL-3.0", "license_state": "standard", "stars": 107981, "forks": 6250, "watchers": 341, "monthly_downloads": null, "latest_score": 88, "latest_band": "excellent", "latest_scanned_at": "2026-07-17T23:11:15.948564Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "unverified", "red_flags": [], "badge_url": "" }, { "id": 8646, "full_name": "taskforcesh/bullmq", "url": "https://github.com/taskforcesh/bullmq", "description": "BullMQ - Message Queue and Batch processing for NodeJS, Python, Elixir and PHP based on Redis", "ecosystem": "npm", "ecosystems": [ "npm", "hex", "crates", "pypi", "packagist" ], "primary_language": "TypeScript", "languages": [ "TypeScript", "Rust", "Elixir" ], "topics": [ "background-jobs", "nodejs", "queue", "redis", "typescript", "python", "elixir", "php", "bull", "bullmq", "queues", "jobs", "worker", "job", "background", "asynchronous", "database" ], "license_spdx": "MIT", "license_state": "standard", "stars": 9127, "forks": 654, "watchers": 36, "monthly_downloads": 26974786, "latest_score": 87, "latest_band": "excellent", "latest_scanned_at": "2026-07-16T00:14:54.282663Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "unverified", "red_flags": [], "badge_url": "" }, { "id": 1871, "full_name": "nrwl/nx", "url": "https://github.com/nrwl/nx", "description": "The Monorepo Platform that amplifies both developers and AI agents. Nx optimizes your builds, scales your CI, and fixes failed PRs automatically. Ship in half the time.", "ecosystem": "crates", "ecosystems": [ "crates", "maven", "npm" ], "primary_language": "TypeScript", "languages": [], "topics": [ "angular", "build", "build-system", "build-tool", "building-tool", "cli", "cypress", "hacktoberfest", "javascript", "monorepo", "nextjs", "nodejs", "nx", "nx-workspaces", "react", "storybook", "typescript" ], "license_spdx": "MIT", "license_state": "standard", "stars": 29170, "forks": 2930, "watchers": 264, "monthly_downloads": 0, "latest_score": 87, "latest_band": "excellent", "latest_scanned_at": "2026-07-14T00:35:50.135644Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "unverified", "red_flags": [], "badge_url": "" } ] } }
idnumbers: Unlocking the power of national ID numbers
identique/idnumbers-npm 的健康指数为 100 分中的 61 分,处于「中等」区间。 其得分最高的类别是Vitality(85/100),最低的是Community & Adoption(35/100)。 最近一次更新在 4 天前。 近期的大部分工作由 1 位贡献者完成。
指标归入加权类别,统一采用 1–100 量表。总体分先取类别加权平均;当公开证据触发高风险司法辖区政策时,评级会按政策调整,并设置 49(有风险)的上限。AI 就绪度不计入总体分。
每条轴代表一个类别。形状比平均值更重要——健康的对象会填满整个图形,而“一峰一谷”式画像意味着某一维度的优势正掩盖另一维度的风险。
项目是否仍有生命——是否仍在编写代码,是否仍在发布版本?
| 36/36 | 推送新近度 — 最近一次推送于 4 天前 |
| 11.1/36 | 提交节奏 — 52 周中有 16 周有提交 |
| 18/18 | 提交量 — 最近一年 137 次提交 |
| 10/10 | OpenSSF Scorecard:Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10 |
| commits_last_year | 137 |
| human_commit_share | 1 |
| days_since_last_push | 4 |
| active_weeks_last_year | 16 |
| 27/27 | 有发布版本 — 已发布 12 个发布版本 |
| 36/36 | 发布时效 — 最近一次发布版本于 5 天前 |
| 27/27 | 发布节奏 — 约每 25.4 天发布一次 |
| 0/10 | OpenSSF Scorecard:Signed-Releases — 无数据 |
| releases_count | 12 |
| latest_release_tag | v1.9.0 |
| releases_from_tags | 否 |
| days_since_latest_release | 5 |
| mean_days_between_releases | 25.4 |
项目是否拥有用户、下载量与关注度,并具备欢迎贡献者参与的配置?
| 0/60 | 星标 — 0 个星标 |
| 0/25 | 复刻 — 2 个复刻 |
| 0/15 | 关注者 — 0 位关注者 |
| forks | 2 |
| stars | 0 |
| watchers | 0 |
| growth_state | unverified |
| growth_factor_pct | 100 |
| growth_unverified_reason | no_history |
| 22.5/22.5 | README |
| 22.5/22.5 | 许可证 — 可识别的许可证(MIT) |
| 0/18 | CONTRIBUTING 指南 |
| 0/13.5 | 行为准则 |
| 0/7.2 | 议题模板 |
| 0/6.3 | PR 模板 |
| has_readme | 是 |
| has_license | 是 |
| has_contributing | 否 |
| has_issue_template | 否 |
| has_code_of_conduct | 否 |
| has_pull_request_template | 否 |
| 54.7/80 | 月度下载量 — npm 合计每月 12,676 次下载 |
| 0/20 | 注册表被依赖数 — 该生态系统不报告此项 |
| packages | idnumbers |
| dependents | — |
| ecosystems | npm |
| total_downloads | — |
| monthly_downloads | 12,676 |
项目能否在其成员之外延续——巴士系数、响应能力、由谁支持,以及软件包的维护状况?
| 9/54 | 巴士系数 — 1 位贡献者贡献了半数提交 |
| 0/22.5 | 提交分布 — 头号贡献者编写了 100% 的提交 |
| 1.4/13.5 | 贡献者广度 — 1 位贡献者 |
| 0/10 | OpenSSF Scorecard:Contributors — project has 0 contributing companies or organizations -- score normalized to 0 |
| bus_factor | 1 |
| contributors_sampled | 1 |
| top_contributor_share | 1 |
| 24.9/46.8 | 议题解决 — 53% 的议题已关闭 |
| 37.4/38.3 | PR 接受 — 已裁定的 PR 中 44/45 已合并 |
| 0/15 | OpenSSF Scorecard:Code-Review — Found 1/14 approved changesets -- score normalized to 0 |
| merged_prs | 44 |
| open_issues | 51 |
| closed_issues | 58 |
| issue_closed_ratio | 0.532 |
| closed_unmerged_prs | 1 |
| 30/30 | 所有权背书 — 组织持有 |
| 0/20 | 已验证域名 |
| 2.2/25 | 所有者影响力 — identique 有 1 位关注者 |
| 11.3/25 | 既往记录 — 3 个公开仓库,账户约 3 年 |
| followers | 1 |
| owner_type | Organization |
| is_verified | — |
| owner_login | identique |
| public_repos | 3 |
| account_age_days | 1,269 |
| 25/25 | 已发布且可解析 — npm 上有 1 个软件包 |
| 35/35 | 发布时效 — 最近一次发布于 4 天前 |
| 20/20 | 版本历史 — 12 个已发布版本 |
| 20/20 | 未被弃用 — 活跃,未被弃用或撤回 |
| packages | idnumbers |
| ecosystems | npm |
| any_deprecated | 否 |
| min_days_since_publish | 4 |
基础的工程与文档实践是否到位?
| 24/24 | CI 工作流 — 3 个工作流 |
| 24/24 | 存在测试 |
| 16/16 | Linter 配置 — .eslintrc.js |
| 0/9.6 | Pre-commit 钩子 |
| 0/6.4 | .editorconfig |
| 20/20 | OpenSSF Scorecard:CI-Tests — 13 out of 13 merged PRs checked by a CI test -- score normalized to 10 |
| has_ci | 是 |
| has_tests | 是 |
| has_editorconfig | 否 |
| has_linter_config | 是 |
| has_precommit_config | 否 |
| 30/30 | README |
| 25/25 | 文档目录 |
| 0/15 | 文档 / 主页站点 |
| 10/10 | 仓库描述 |
| 10/10 | 主题标签 — 11 个主题标签 |
| 10/10 | Wiki |
| topics | identification-number, idnumbers, national-id, national-id-validator, national-identification-number, national-identity, nodejs, npm, parser-library, typescript, validation-library |
| has_wiki | 是 |
| homepage | — |
| has_readme | 是 |
| has_docs_dir | 是 |
| has_description | 是 |
可见的安全与供应链实践是否稳固,且不存在未解决的高风险司法辖区暴露?
| 7.5/7.5 | Binary-Artifacts — no binaries found in the repo |
| 6/7.5 | Branch-Protection — branch protection is not maximal on development and all release branches |
| 2.5/2.5 | CI-Tests — 13 out of 13 merged PRs checked by a CI test -- score normalized to 10 |
| 0/2.5 | CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected |
| 0/7.5 | Code-Review — Found 1/14 approved changesets -- score normalized to 0 |
| 0/2.5 | Contributors — project has 0 contributing companies or organizations -- score normalized to 0 |
| 10/10 | Dangerous-Workflow — no dangerous workflow patterns detected |
| 0/7.5 | Dependency-Update-Tool — no update tool detected |
| 0/5 | Fuzzing — project is not fuzzed |
| 2.5/2.5 | 许可证 — license file detected |
| 7.5/7.5 | Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10 |
| 5/5 | Packaging — packaging workflow detected |
| 1.5/5 | Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 3 |
| 0/5 | SAST — SAST tool is not run on all commits -- score normalized to 0 |
| 0/5 | Security-Policy — security policy file not detected |
| 0/7.5 | Signed-Releases — 无数据 |
| 0/7.5 | Token-Permissions — detected GitHub workflow tokens with excessive permissions |
| 0/7.5 | Vulnerabilities — 24 existing vulnerabilities detected |
| source | openssf_scorecard |
| checks_evaluated | 17 |
| scorecard_version | v5.5.0 |
| checks_inconclusive | 1 |
| scorecard_aggregate | 4.4 |
该仓库在多大程度上具备与 AI 编码代理协同开发与维护的条件?这是一枚独立的实验性徽章——权重为 0.0,因此单独呈现,不影响总体健康评分。
| 0/45 | 代理指令 — 没有 CLAUDE.md / AGENTS.md / 编辑器规则 |
| 0/15 | 机器可读文档(llms.txt) |
| 40/40 | 可读的提交历史 — 100 次人类提交中有 99 次说明了意图(结构化标题或解释性正文) |
| has_llms_txt | 否 |
| legible_history_share | 0.99 |
| agent_instruction_files | — |
| agent_instruction_max_bytes | — |
| 0/18 | 一条命令的引导启动 |
| 22/22 | 自动化测试 |
| 11/11 | Lint / 格式化配置 — .eslintrc.js |
| 11/11 | 静态类型检查 — tsconfig.json |
| 10/10 | 可复现环境 — lockfile |
| 0/10 | 已体现的代理实践 — 最近 100 次提交中没有代理编写的提交 |
| 0/8 | 自动化维护 — 未观察到自动依赖更新 |
| 3/10 | OpenSSF Scorecard:Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 3 |
| has_nix | 否 |
| has_tests | 是 |
| lockfiles | package-lock.json |
| has_dockerfile | 否 |
| typed_language | 是 |
| bootstrap_files | — |
| has_devcontainer | 否 |
| has_linter_config | 是 |
| typecheck_configs | tsconfig.json |
| agent_commit_share | 0 |
| toolchain_manifests | — |
| dependency_bot_commit_share | 0 |
| 45/45 | 可类型检查的代码 — TypeScript(静态类型) |
| 55/55 | 可控的文件大小 — 采样的 197 个源文件中有 0 个超过 60KB |
| primary_language | TypeScript |
| largest_source_bytes | 23,937 |
| source_files_sampled | 197 |
| oversized_source_files | 0 |
| 0/40 | API 模式(OpenAPI/GraphQL/proto) |
| 0/20 | MCP 服务器 |
| 40/40 | 可运行示例 — examples |
| example_dirs | examples |
| has_mcp_signal | 否 |
| api_schema_files | — |
每颗 star 和每个 fork 的添加时间,来自 GitHub 并按天汇总。累计增长位于其构成来源——每日新增——的正上方,二者可相互对照:稳定的自然增长与短暂的突增形态截然不同。当这一差别可被衡量时,它会作为增长真实性予以报告。
来自开源项目 OpenSSF Scorecard 的独立、工具无关的安全评估。每项检查奖励的是安全实践本身,而非特定供应商的工具。Scorecard 无法判定的检查项标记为 不适用,并从安全评分中剔除(绝不按零分计)。
| 10 | Binary-Artifacts | no binaries found in the repo |
| 8 | Branch-Protection | branch protection is not maximal on development and all release branches |
| 10 | CI-Tests | 13 out of 13 merged PRs checked by a CI test -- score normalized to 10 |
| 0 | CII-Best-Practices | no effort to earn an OpenSSF best practices badge detected |
| 0 | Code-Review | Found 1/14 approved changesets -- score normalized to 0 |
| 0 | Contributors | project has 0 contributing companies or organizations -- score normalized to 0 |
| 10 | Dangerous-Workflow | no dangerous workflow patterns detected |
| 0 | Dependency-Update-Tool | no update tool detected |
| 0 | Fuzzing | project is not fuzzed |
| 10 | License | license file detected |
| 10 | Maintained | 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10 |
| 10 | Packaging | packaging workflow detected |
| 3 | Pinned-Dependencies | dependency not pinned by hash detected -- score normalized to 3 |
| 0 | SAST | SAST tool is not run on all commits -- score normalized to 0 |
| 0 | Security-Policy | security policy file not detected |
| 不适用 | Signed-Releases | no releases found |
| 0 | Token-Permissions | detected GitHub workflow tokens with excessive permissions |
| 0 | Vulnerabilities | 24 existing vulnerabilities detected |
本报告未能采集到解析后的依赖集合:GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository
{
"data": {
"repo": {
"topics": [
"identification-number",
"idnumbers",
"national-id",
"national-id-validator",
"national-identification-number",
"national-identity",
"nodejs",
"npm",
"parser-library",
"typescript",
"validation-library"
],
"is_fork": false,
"size_kb": 589,
"has_wiki": true,
"homepage": null,
"languages": {
"Shell": 524,
"JavaScript": 1226,
"TypeScript": 666827
},
"pushed_at": "2026-07-18T05:45:17Z",
"created_at": "2025-11-01T16:56:27Z",
"owner_type": "Organization",
"updated_at": "2026-07-17T11:33:09Z",
"description": "idnumbers: Unlocking the power of national ID numbers",
"is_archived": false,
"is_disabled": false,
"license_spdx": "MIT",
"default_branch": "main",
"license_spdx_raw": "MIT",
"primary_language": "TypeScript",
"significant_languages": [
"TypeScript"
]
},
"owner": {
"blog": null,
"name": "identique",
"type": "Organization",
"login": "identique",
"company": null,
"location": null,
"followers": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/123928597?v=4",
"created_at": "2023-01-30T06:42:13Z",
"is_verified": null,
"public_repos": 3,
"account_age_days": 1269
},
"license": {
"state": "standard",
"spdx_id": "MIT",
"raw_spdx": "MIT",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v1.9.0",
"kind": "minor",
"published_at": "2026-07-17T11:33:00Z"
},
{
"tag": "v1.8.0",
"kind": "minor",
"published_at": "2026-04-29T00:31:34Z"
},
{
"tag": "v1.7.0",
"kind": "minor",
"published_at": "2026-04-24T00:34:56Z"
},
{
"tag": "v1.6.0",
"kind": "minor",
"published_at": "2026-04-07T03:45:04Z"
},
{
"tag": "v1.5.0",
"kind": "minor",
"published_at": "2026-04-03T17:35:22Z"
},
{
"tag": "v1.4.1",
"kind": "patch",
"published_at": "2026-03-29T15:44:44Z"
},
{
"tag": "v1.4.0",
"kind": "minor",
"published_at": "2026-03-29T15:08:17Z"
},
{
"tag": "v1.3.0",
"kind": "minor",
"published_at": "2026-02-17T14:00:02Z"
},
{
"tag": "v1.2.0",
"kind": "minor",
"published_at": "2025-12-25T14:51:36Z"
},
{
"tag": "v1.1.0",
"kind": "minor",
"published_at": "2025-11-30T11:59:48Z"
},
{
"tag": "v1.0.1",
"kind": "patch",
"published_at": "2025-11-17T12:37:56Z"
},
{
"tag": "v1.0.0",
"kind": "major",
"published_at": "2025-11-02T02:59:11Z"
}
],
"recent_commits": [
{
"oid": "b2ec45bf46eb8155da8c9769526c64895726afa7",
"body": null,
"is_bot": false,
"headline": "chore(release): bump version to 1.9.0 (#155)",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-07-17T11:32:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "209c1161db9221f5ab3689ffce4e2c9602cc0055",
"body": "* docs(#44): add format info for Americas Africa Oceania\n\n* fix(#44): align NZL idType with Driver Licence primary validator\n\ngetCountryIdFormat('NZL') returned a self-contradictory object: idType\n'IRD Number' overlaid on the Driver Licence format/example/officialName\nfrom the registered primary val\n[…]\nver Licence Number'.\n\n- Update getCountryIdFormat-migration fixture in lockstep.\n- Add regression test asserting idType and officialName describe the\n same document.\n- Bump README test count to 2139.",
"is_bot": false,
"headline": "docs(#44): add format info for Americas Africa Oceania (#113)",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-07-16T14:42:14Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "e6b9052c7ccfd0826ef654ed4d347ae9dd919ace",
"body": "* fix(#43): correct inaccurate displayFormat masks (IDN, KAZ, KWT, VNM)\n\n- IDN: DDMMYYPPPPSSSS (14 chars, wrong segment order) -> PPPPPPDDMMYYSSSS\n matching the actual district(6)+DDMMYY+serial(4) structure of the 16-digit NIK\n- KAZ: YYMMDDCSSSS (11 chars for a 12-digit IIN) -> YYMMDDGSSSSC\n (G = \n[…]\n keeping\n only assertions not already covered by the fixture describe.each\n- Trim an alias-test comment that overstated its coverage\n- README test count 2106 -> 2105 (one redundant test case removed)",
"is_bot": false,
"headline": "feat(#43): add format info for Asian countries (26) (#112)",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-06-10T03:42:47Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "627ef5c75eaf9e7341ae9ae838ab6ebf5d3dd118",
"body": "* feat(#42): add example, checksumAlgorithm, officialName to ID format metadata\n\n* feat(#42): populate format info for 40 European countries\n\n* fix(#42): align Portugal idType with registered NIF validator\n\n* test(#42): add European format-info coverage\n\n* docs(#42): document format-info fields in README and CHANGELOG\n\n* chore(#42): address internal review nits (test count, CYP example, LVA wording)\n\n* chore(#42): align SVN checksum description with SRB for consistency",
"is_bot": false,
"headline": "feat(#42): add format info for European countries (40) (#111)",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-06-10T01:14:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "69bec8b42593f39ad77324a20ad186fc14e0f4c7",
"body": "…rmat (#110)\n\n* refactor(#82): move FORMAT_STRINGS into country METADATA as displayFormat\n\nRelocate the 18 format display strings from the centralized FORMAT_STRINGS\nlookup in src/index.ts into each country module's METADATA as a new optional\ndisplayFormat field, so format info lives at the source a\n[…]\nptional IdFormat.format key absent (not undefined) for countries without\na displayFormat. Addresses internal review P2 to protect the invariant against\nfuture edits. Comment-only — no behavior change.",
"is_bot": false,
"headline": "refactor(#82): move FORMAT_STRINGS into country METADATA as displayFo…",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-06-09T15:04:33Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c41f4a4547a5daf3b7547d2180a229549266a177",
"body": "* feat(#46): complete Nigeria NIN parse() with honest validity-only contract\n\nThe NIN is a randomly-assigned 11-digit number that encodes no personal\ndata, mirroring the Python source of truth (parsable: False). parse() now\nreturns { isValid: true } for valid NINs (previously the placeholder\n{ check\n[…]\n\nconsumers calling NationalID.checksum(id). The parameter is unused (the NIN\nhas no checksum to compute), so the static method suppresses the\nno-unused-vars lint on that line with a documented reason.",
"is_bot": false,
"headline": "feat(#46): complete Nigeria NIN parse() function (#109)",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-06-09T14:03:07Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "922d33333c085f713947ebfd4a425c7f1e067671",
"body": "* feat(#32): add New Zealand IRD number validation\n\nPort idnumbers/nationalid/nzl/inland_revenue_department.py as a secondary\nNZL id type (NZL.IRDNumber), mirroring the AUS TaxFileNumber pattern. The\nregistered NZL primary stays DriverLicense, so the 80-key registry invariant\nand validateNationalId(\n[…]\n\nReplace the mutable let + length conditional with an immutable\npadStart(9, '0'); behavior is identical since the regexp guarantees an\n8- or 9-digit core. No functional change; coverage stays at 100%.",
"is_bot": false,
"headline": "feat(#32): add New Zealand IRD number validation (#108)",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-06-09T13:00:56Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "2a72426018fc8617cc9c3c43f9f094abe02639c7",
"body": null,
"is_bot": false,
"headline": "add gitignore",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-06-09T05:31:13Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b721e22ff36a252106472b242e7e4330a74e0f08",
"body": "* test(#26): add comprehensive Zimbabwe NationalID test coverage\n\nLock validate/parse/checksum behavior of src/countries/zwe/nationalId.ts\nagainst regressions. Covers all 61 valid district codes, all 23 checksum\nresidues, 11- and 12-digit parse shapes, instance/static delegation,\nand top-level valid\n[…]\ne intended branch, so the tests\ngenuinely lock the parse() register_office_code lookup logic.\n\nAlso flip the lowercase-checksum-letter case to use j instead of r so it\nmirrors the corrected J fixture.",
"is_bot": false,
"headline": "test(#26): comprehensive Zimbabwe NationalID test coverage (#107)",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-05-22T21:49:05Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "6c78d4059c763a71b7ba55502b23d9cc96094f7f",
"body": "docs(#25): research and document Zimbabwe national ID format",
"is_bot": false,
"headline": "Merge pull request #106 from identique/idnumbers-node-issue-25",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T22:22:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "721ee0eedbb2d3a7e6def032323107eddad20fb6",
"body": "- Reword Source Reliability to make the directionality of Python →\n Node parity explicit (Python is source-of-truth; Node is the port)\n- Move private NationalID symbols (getChecksum, VALID_DISTRICT_CODES,\n CHECKSUM_LETTERS) into a collapsible 'For maintainers' details block\n so consumers reading the public API section are not tempted to rely\n on them",
"is_bot": false,
"headline": "fix(#25): address external review feedback — round 3",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T17:39:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6b153003c1ccf076f29d544d54c41fd600b6144b",
"body": "- Split the Components table into two clean layouts (11-char and 12-char\n forms) instead of mixing position-in-string with length-variant\n notation in one row\n- Add an explicit pointer to the cited Wikipedia source for the 2021\n abolition note (was previously uncited)\n- Add a sixth invalid test vector (7A191961R00) demonstrating non-digit\n body rejection at the regex level",
"is_bot": false,
"headline": "fix(#25): address external review feedback — round 2",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T17:29:02Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9fdbc3ebdd468369effd56da2803e074ac19d98f",
"body": "- Disambiguate position ranges in the Components table by tagging each\n range with the corresponding ID length (6-digit vs 7-digit national,\n 11-char vs 12-char total)\n- Add 'subject to change without notice' caveat to the private symbols\n listed in Implementation Notes",
"is_bot": false,
"headline": "fix(#25): address external review feedback — round 1",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T17:22:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "316814d62ff55e3603133f97d2f73d1051e394d4",
"body": "Per public reporting (referenced in the Wikipedia source), Zimbabwe's\ngovernment signalled abolition of the '00' foreigner district code in\nSeptember 2021. The implementation preserves it for backward\ncompatibility with the Pachedu and Python reference implementations,\nand this note now documents that historical context.",
"is_bot": false,
"headline": "docs(#25): note 2021 abolition announcement for '00' foreigner code",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T17:18:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "dc302959119d9b989589583320898f36d3d49596",
"body": "- Replace broken link to gitignored CLAUDE.md with stable GitHub URL to\n the Python source-of-truth file\n- Clarify letter-omission rationale (I/O/U → 1/0/V respectively)\n- Add note that the displayed pattern uses spaces for readability only",
"is_bot": false,
"headline": "fix(#25): address review feedback — round 1",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T17:14:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "328d35e602d10ae138fa12ba525406e074a35364",
"body": "Add per-country README at src/countries/zwe/README.md documenting the\nformat, components, mod-23 checksum algorithm with the 23-letter table,\nthe 61 valid district/register-office codes, and verified test vectors\n(5 valid + 5 isolated invalid). Cites the Pachedu 2018 Biometric Voters\nRoll Analysis (Appendix 2) as the algorithm source, with Wikipedia as\nsecondary context.\n\nFollows the same conventions as src/countries/alb/README.md and\nsrc/countries/che/README.md. No code or test changes.",
"is_bot": false,
"headline": "docs(#25): document Zimbabwe national ID format",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T17:09:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "76635587d2ec868818e80779374a361c341010ff",
"body": "test(#17): expand BHR coverage with null/undefined, boundary, and parse-contract cases",
"is_bot": false,
"headline": "Merge pull request #105 from identique/idnumbers-node-issue-17",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T16:54:02Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5642652f213d08f6ea004e88f9304c835ecde487",
"body": "Change boundary-case ID '000101000' → '000100000' so the parsed serial is\nactually '0000' (lower-bound), matching the label. Same class of label-vs-regex\ninconsistency caught in round 1; this row preserves the serial-0000 boundary\nintent by picking an ID whose sn group truly resolves to 0000.\n\nRegex parse of '000100000': yymm='0001', sn='0000', checksum='0'.",
"is_bot": false,
"headline": "fix(#17): address review feedback — round 2",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T16:44:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6de960bbecea7a124a810139508eb5b43d3c9b46",
"body": "- Remove ' 800101001 ' from the 'falsy and non-string inputs' block; it is\n not a falsy value, and surrounding-whitespace coverage already lives in the\n dedicated 'format edge cases — surrounding whitespace' block via the leading\n and trailing space rows.\n- Correct the boundary-case label for '\n[…]\ne regex (sn parses to '0199', checksum '9').\n The vector intentionally exercises the upper-bound year/month; the label now\n says so. Serial extreme is already covered by '000999990' on the next row.",
"is_bot": false,
"headline": "fix(#17): address review feedback — round 1",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T16:41:59Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "3100d206a8f8cc01572684248864ce1b584ac123",
"body": null,
"is_bot": false,
"headline": "style(#17): apply prettier formatting",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T16:38:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "965153417a63ec2fd687f81e8e3b7930a1c5136f",
"body": null,
"is_bot": false,
"headline": "refactor(#17): simplify implementation",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T16:37:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6e96e904b99901f3bceef9e315314f3c7e65e131",
"body": "…se-contract cases\n\nAppend an `issue #17 — additional coverage` block to the existing BHR research\ntest file. Adds 22 new assertions covering:\n- falsy and non-string inputs (null, undefined, whitespace-only, surrounding\n whitespace) at both module and registry layers\n- format-boundary cases (year 0\n[…]\nnown per #15;\nCPR format `YYMMSSSSC` carries neither field).\n\nCoverage: src/countries/bhr/personal-number.ts at 100% statements / 100%\nbranches / 100% lines — above the 90%/85% targets from the issue.",
"is_bot": false,
"headline": "test(#17): expand BHR coverage with null/undefined, boundary, and par…",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T16:36:05Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "83878da0916576f4ffa556f7a2476b9be9bab9ed",
"body": "docs(#15): research Bahrain CPR checksum + pin format-only vectors",
"is_bot": false,
"headline": "Merge pull request #104 from identique/idnumbers-node-issue-15",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T15:24:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6a09cbb5f11ba9837897df308571123b45a249ef",
"body": "The vector table parses each ID against the regex\n`^(YYMM)(SSSS)(C)$`. The row for 850714210 had SSSS transcribed as 4210\ninstead of 1421 (positions 5-8 of the 9-digit ID). The check digit (C=0)\nand tests were already correct; only the documentation column was wrong.",
"is_bot": false,
"headline": "docs(#15): fix SSSS decomposition for 850714210 in research vector table",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T13:50:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b4bf8f4d69453446be1eb359a596823fa7aec0ca",
"body": "…test\n\nThe literal {yymm:'8001', sn:'0100', checksum:1} appeared four times across\nthe test file. Lift it (and the canonical id '800101001') to two top-level\nconstants so a future field rename is a single edit.",
"is_bot": false,
"headline": "refactor(#15): extract canonical id/parsed constants in BHR research …",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T13:46:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1ac424f124c6d249b1e22f741b9248ede4d4e6aa",
"body": "ESLint flagged two pre-existing no-unused-vars errors that surfaced when CI\nran against the issue-15 worktree:\n\n- parseIdInfo-migration.test.ts: drop unused `_id` parameter in mock validate\n- registry.test.ts: drop unused `IdFormat` import\n\nNo behavior change; tests remain green.",
"is_bot": false,
"headline": "chore(#15): drop unused lint identifiers",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T13:45:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4991df5f27f4521d9b258eab2aa237482e2d336c",
"body": "…ents\n\nReplace the vague `// TODO: find and implement checksum` and the loose class\nJSDoc with text that points at the new research record\n(docs/research/bahrain-cpr-checksum.md) and states the Python-upstream parity\nexplicitly. No runtime change to validate, parse, or METADATA.\n\nAdd src/__tests__/i\n[…]\nted examples, 6 format-invalid examples, the\nMETADATA.checksum=false / parsable=true contract, direct PersonalNumber.parse,\nand registry-path parseIdInfo for both the BHR primary key and the BH alias.",
"is_bot": false,
"headline": "test(#15): pin Bahrain CPR research vectors and clarify checksum comm…",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T13:45:31Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "6227a5ce5c3e6d37a0ef64e21a0dfea829e72fc6",
"body": "Capture the result of issue #15 research: the official Bahrain CPR check-digit\nalgorithm is not publicly documented (Wikipedia, iGA portals, python-stdnum,\nstdnum-js, and the Python upstream all checked). Decision is to keep\nformat-only validation with METADATA.checksum=false, in parity with\nidnumbe\n[…]\nrries the same TODO.\n\nIncludes 6 format-only accepted vectors, 6 format-invalid vectors, sources\nwith access dates, synthetic-data notice, future-work guidance, and a call\nfor community contributions.",
"is_bot": false,
"headline": "docs(#15): add Bahrain CPR checksum research record",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-05-21T13:45:10Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "5bcd719eede6538d58160f1a93ead38427de6a94",
"body": null,
"is_bot": false,
"headline": "chore(release): bump version to 1.8.0 (#103)",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-04-29T00:30:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0907a45c02ab1b0b1a41dad88e86bf4ef2726e01",
"body": "test(#36): add Portugal parse and edge case tests",
"is_bot": false,
"headline": "test(#36): add Portugal parse and edge case tests (#102)",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-04-28T14:38:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c2cfc459c28984451220e348fdcb42cce5c0a333",
"body": "Parameterize hyphen and dot NIF separator-rejection tests into a single\ntest.each, mirroring the separator-rejection style used in\nprt-nationalId.test.ts. Removes a near-duplicate adjacent test block.\n\nNo coverage change. All 39 issue-36 tests and 1740 suite tests still pass.",
"is_bot": false,
"headline": "refactor(#36): simplify implementation",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-28T10:22:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6d08cdc059a6d4cd15cad5b8b46cfac8d91c1c59",
"body": "Add issue-36-prt-parse.test.ts covering parse-not-implemented semantics\nand complementary edge cases for PRT CC and NIF.\n\n- Parse-not-implemented: assert static/instance parse is undefined for\n both classes; METADATA.parsable === false matches Python source.\n- Registry path: parseIdInfo and validat\n[…]\nngth 9\n and NIF metadata, ensuring the registered class is NIF, not CC.\n\nTest-only addition; no production code changes. 39 tests, all green.\nComplements #34 (CC validation) and #35 (NIF validation).",
"is_bot": false,
"headline": "test(#36): add Portugal parse and edge case tests",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-28T10:20:53Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "58c4db478250de395222d1d3a9c264fce01581a7",
"body": "test(#34): add Portugal Cartão de Cidadão tests",
"is_bot": false,
"headline": "Merge pull request #100 from identique/idnumbers-node-issue-34",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-04-28T10:05:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "eae993ee7a7d8c95eb61dad5855d3d6e81fe9c4a",
"body": "test(#35): add Portugal NIF validation tests",
"is_bot": false,
"headline": "Merge pull request #101 from identique/idnumbers-node-issue-35",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-04-28T10:05:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4efe5d9a946e55c2830d789782d4338d4071e22a",
"body": null,
"is_bot": false,
"headline": "test(#35): add Portugal NIF coverage",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-28T08:01:51Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0b4fb28abf8f2a931ff6281634f9ac5487f80897",
"body": "Add 45 Jest tests covering the 12-character Portuguese Cartão de Cidadão\nclass in src/countries/prt/nationalId.ts, which previously had no\ndedicated test coverage and is unreachable via the country barrel.\n\nTests-only — no production changes. Imports the CC class directly to\nexercise it independentl\n[…]\n corruption (both digits), length and character validation,\nnull/undefined/non-string input, METADATA shape, instance vs. static\nequivalence, and a smoke assertion that the registry primary stays NIF.",
"is_bot": false,
"headline": "test(#34): add Portugal Cartão de Cidadão tests",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-28T07:49:38Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f9550ec13016c1dd8e0c8ffdd508f3a93316f998",
"body": "chore(release): bump version to 1.7.0",
"is_bot": false,
"headline": "chore(release): bump version to 1.7.0 (#99)",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-04-24T00:33:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2bb1ceb7cf91bd077ffcf90ed329737b8fd4bd84",
"body": null,
"is_bot": false,
"headline": "chore(release): bump version to 1.7.0",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-24T00:18:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8bcc048f5f2b51adde663f5912ab8461e4d6c11a",
"body": "test(#33): add NZL parse and edge case tests",
"is_bot": false,
"headline": "Merge pull request #98 from identique/idnumbers-node-issue-33",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-04-24T00:10:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0272869c76b576a12d45b0c53cc135328cf3c3a0",
"body": "Focus the issue-33 test file on value the sibling nzl.test.ts does not\nalready cover:\n - parse-not-implemented semantics\n - whitespace and length edge cases\n - METADATA regexp.source/flags/deprecated/aliasOf\n - 7-char DriverLicense boundary behavior\n - extractedInfo and parseIdInfo integration\n\n[…]\nertions (blacklist 10-row loop, basic null/undefined\nrejection, instance/static delegation boilerplate, trivial METADATA\nshape) already covered by nzl.test.ts. NZL module branch coverage\nremains 100%.",
"is_bot": false,
"headline": "refactor(#33): simplify NZL test file — reduce overlap with nzl.test.ts",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-23T23:49:26Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "5d84f86c066fe75a30e6aabd3967cdf8b7abc751",
"body": "Add src/__tests__/issue-33-nzl-parse.test.ts covering parse-not-implemented\nsemantics, edge-case input handling, and blacklist boundaries for both\nNationalID and DriverLicense NZL classes. Raises NZL module coverage to\n100% (stmts/branch/funcs/lines).\n\nThe test header documents the known Python-vs-N\n[…]\nationalID is an alias of DriverLicenseNumber; Node has two distinct\nclasses with diverged regexps). Tests exercise current Node branches\nonly and do not codify either form as the canonical NZL format.",
"is_bot": false,
"headline": "test(#33): add NZL parse and edge case tests",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-23T23:46:40Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a70a6dbd9be0dc36d22a618c0975fa55e0472d39",
"body": "test(#31): add comprehensive NZ driver license validation tests",
"is_bot": false,
"headline": "Merge pull request #97 from identique/idnumbers-node-issue-31",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-04-23T15:50:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3f2f07338ec6049d36d309e22ce6d2c38ef9e5ad",
"body": "- Clarify file header: the TS DriverLicense regex accepts 7–8 chars\n while valid-input tests use the stricter Python source-of-truth shape\n (2 letters + 6 digits) to avoid codifying the divergence.\n- Add minLength/maxLength assertions to DriverLicense METADATA test for\n parity with the NationalID METADATA test.",
"is_bot": false,
"headline": "fix(#31): address external review feedback — round 1",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-23T14:03:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8de2ed05f85f3b55b2c6dd86a9480008877c4bf7",
"body": "Add src/__tests__/nzl.test.ts covering:\n- DriverLicense (primary, registered) standard 2-letter + 6-digit format\n- Case-insensitivity, blacklist (10 trailing-same-digit patterns), invalid\n format (length, special chars, null/undefined/non-string)\n- Separator variations (space/dash/dot/slash rejecte\n[…]\nict 2-word-char + 6-digit coverage\n- Registry integration via validateNationalId and getCountryIdFormat\n for NZL code and NZ alias\n\n54 tests, 100% line/branch/function coverage on src/countries/nzl/.",
"is_bot": false,
"headline": "test(#31): add comprehensive NZ driver license validation tests",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-23T13:55:30Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "6f1c8400229ffe86f37ea0d0c5ab472c4e089298",
"body": null,
"is_bot": false,
"headline": "chore(release): bump version to 1.6.0",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-07T03:44:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "526b8176684b4fb649d7d2e25cd1eff92ea282bd",
"body": "test(nor): add fødselsnummer, D-nummer, checksum/parse tests + D-nummer support",
"is_bot": false,
"headline": "Merge pull request #96 from identique/idnumbers-node-issue-28",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-04-07T03:32:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "51a8ea0ccc433e8c2d16f92d510cac91ec3acbcc",
"body": "- Remove dead try/catch in parse(): JS Date never throws on overflow; date\n validity is already enforced by getFullYear/getMonth/getDate comparisons\n- Add typeof string guard at top of parse() to mirror validate() and prevent\n parse() from accidentally accepting non-string inputs whose toString()\n\n[…]\n40 between fødselsnummer max (31) and D-nummer min (41)\n- Add 1900s D-nummer test vector 45055590110 covering interaction between\n D-nummer day adjustment and individual 900-999/yy>=40 century branch",
"is_bot": false,
"headline": "fix(#28,#29): address external review feedback — round 3",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-07T03:02:47Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "0848abb8efb99eb92d09fdc4e956c48b8b93eaad",
"body": "- Make idType field optional on NationalIdParseResult to avoid breaking change\n for downstream consumers constructing the type literally; parse() always\n populates it\n- Document Python parity deviation in source comment and CHANGELOG: D-nummer\n support is a TypeScript-side extension required by i\n[…]\n other behaviors remain identical to Python source\n- Fix DD=72 test: clarify isDNummer=false (72>71), use checksum-valid vector\n 72019000290 to isolate date-overflow rejection from checksum rejection",
"is_bot": false,
"headline": "fix(#28,#29): address external review feedback — round 2",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-07T02:44:09Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "cdb2f73dec97b89a860c1eee3350dc8bc6cabcbe",
"body": "- Fix DD=40 test: clarify isDNummer=false (40<41), use checksum-valid vector\n 40019000119 to isolate date-overflow rejection path from checksum rejection\n- Remove duplicate standalone leap-year test (already covered in test.each table)",
"is_bot": false,
"headline": "fix(#28,#29): address external review feedback — round 1",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-05T09:45:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c59983ad01e3c64460e23bf6d3fe7613092c23a7",
"body": "… coverage",
"is_bot": false,
"headline": "docs(#28,#29,#30): update CHANGELOG for NOR D-nummer support and test…",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-05T02:52:55Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7f8d61f5c2fb58e532227cb63d2a174964ea11d4",
"body": "- Fix misleading test.each label for 29029600013: individual 000 (not 001), gender FEMALE (not male)\n- Add 1800s century test vector (10107055008): individual 550, yy=70>=54 → century 18",
"is_bot": false,
"headline": "fix(#28): address review feedback — round 1",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-05T02:49:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "edf82aed89bda822f79065c2463146693706c298",
"body": "- Remove redundant `as const` from idType literal assignment\n- Extract mmNum to avoid double parseInt(mm, 10) in date construction/validation\n- Shorten D-nummer detection comment to non-obvious why only\n- Import NationalIdParseResult in test for clean type assertion",
"is_bot": false,
"headline": "refactor(#28): simplify implementation",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-05T02:42:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b7bd4348aee7de89fd612ee0dc4842a7f5e3a39a",
"body": "…upport\n\n- Extend NationalIdParseResult with idType discriminator ('fodselsnummer' | 'd-nummer')\n- Update parse() to detect D-nummer (DD 41-71): subtract 40 from day field, set idType\n- Add comprehensive test file covering all three milestone v1.6.0 issues:\n - 14 fødselsnummer validation tests (val\n[…]\n first+second check digits, malformed input)\n - 11 parse() function tests (birth date, gender, idType, checksum field, errors)\n - 5 integration tests (validateNationalId, parseIdInfo via public API)",
"is_bot": false,
"headline": "test(#28,#29,#30): add Norway NationalID test coverage and D-nummer s…",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-05T02:40:26Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "b7af32f38f57206754d6ae9c930292e28f4cc4db",
"body": null,
"is_bot": false,
"headline": "chore(release): bump version to 1.5.0",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-03T17:34:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cbba9779e09b87a90b364ec3a693aea030430f4a",
"body": "test(#24): add Slovakia edge case and error tests",
"is_bot": false,
"headline": "Merge pull request #95 from identique/idnumbers-node-issue-24",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-04-03T17:32:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b2aee5e02e1006e741fa3ebde275b6530818f56c",
"body": "- Strengthen minimum boundary test with explicit getFullYear() assertion\n to make the yy < 50 → 2000s rule clear\n- Clarify checksum comments for Feb 30/31 tests to show parseInt\n stripping leading zeros",
"is_bot": false,
"headline": "fix(#24): address external review feedback — round 1",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-03T17:28:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f0d0e43c3cf6b1c58c4890253042e49ce1d6f8ba",
"body": "Add comprehensive edge case tests for SVK Birth Number validator:\n- Invalid dates: Feb 30/31, Apr 31, Jun 31\n- Invalid month codes: female month 63 (maps to 13)\n- Invalid formats: leading/trailing whitespace, mixed alphanumeric,\n invalid slash position\n- Boundary conditions: min/max valid ID dates\n\nBranch coverage: 100%, 56 total tests.",
"is_bot": false,
"headline": "test(#24): add Slovakia edge case and error tests",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-03T17:11:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8d8669ffc522d1ca34aafd0a605fc07b775aa570",
"body": "test(#23): add Slovakia parse() function tests",
"is_bot": false,
"headline": "Merge pull request #94 from identique/idnumbers-node-issue-23",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-04-03T16:58:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f10724c892aaa0f13effcf0708c9a55a26208d32",
"body": null,
"is_bot": false,
"headline": "test(#23): add Feb 29 non-leap year edge case",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-03T16:53:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a48ebdf1504a490836cd4e305601691a46d95dcb",
"body": "Remove redundant Python Parity block (assertions already covered),\ndrop duplicate gender test, fix section naming, remove obvious comments.",
"is_bot": false,
"headline": "refactor(#23): simplify SVK parse tests",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-03T16:25:13Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a30c37070f5917cd05883ee5773a1f186b635187",
"body": "Cover birth date extraction (century handling, failsafe months),\ngender extraction, sequence number, slash format, and error handling.\n37 tests with full branch coverage of NationalID.parse().",
"is_bot": false,
"headline": "test(#23): add comprehensive Slovakia parse() function tests",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-04-03T16:22:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "30182e9f0c074916b118f1cbff7caf390808fc88",
"body": "Add comprehensive test file src/__tests__/svk.test.ts (45 tests) for Slovakia Birth Number (Rodné číslo) validate() function covering male/female IDs, slash/no-slash formats, century boundary, date validation, checksum (mod 11), failsafe month codes (2004 law), invalid inputs, registry integration, and direct module access. Coverage: 97.5% lines, 100% branches, 100% functions.",
"is_bot": false,
"headline": "test(#22): add Slovakia validate() function tests (#93)",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-04-03T15:58:30Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2888c05aecaef28fe827bde707e3ca43220fd95c",
"body": "fix(#91): add npm provenance for verified publish badge",
"is_bot": false,
"headline": "Merge pull request #92 from identique/idnumbers-node-issue-91",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-03-29T15:44:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d4fa765c7e7df09d415e6954c50dacc092b459a1",
"body": null,
"is_bot": false,
"headline": "fix(#91): add npm provenance for verified publish badge",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-03-29T15:43:57Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "429e136edbdc29d52e213d88c7172b59d96325d7",
"body": null,
"is_bot": false,
"headline": "chore(release): bump version to 1.4.0",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-03-29T15:07:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c7427244d68bb8749b4cb8310bc44e1e98596726",
"body": "feat(#86): port 11 missing ID types from Python version",
"is_bot": false,
"headline": "Merge pull request #90 from identique/idnumbers-node-issue-86",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-03-29T13:27:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9ff0899ec4a99b2841ee50ad40418928eea87d7c",
"body": null,
"is_bot": false,
"headline": "fix(#86): restrict AUT UID regex to U prefix, add BGR 13-digit tests",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-03-17T03:03:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5119c6785aca1f5fc9176933fe75c9e659cb35b5",
"body": null,
"is_bot": false,
"headline": "refactor(#86): simplify implementation",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-03-17T02:50:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a8127c0bbf25a6a94b32948dd179e4c664dcabba",
"body": "Add TaxFileNumber and DriverLicenseNumber for AUS, EntityTaxIDNumber\nfor AUT, EntityVAT for BEL, UnifiedIdCode (EIK/BULSTAT) for BGR,\nBusinessID (UID) for CHE, OldIdentityCard for GRC, BusinessIDNumber (BIN)\nfor KAZ, OldResidentRegistration for KOR, OldPersonalCode for LVA, and\nFiscalInformationNumber (RIF) for VEN.\n\nAll types exported from country modules. No COUNTRY_REGISTRY entries\nadded (preserves 80-key count). Tests derived from Python test vectors.",
"is_bot": false,
"headline": "feat(#86): port 11 missing ID types from Python version",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-03-17T02:42:26Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e127c124a9f82210edf7da30c9ebba032e454042",
"body": "refactor(#85): remove hardcoded test ID bypasses across 12 countries",
"is_bot": false,
"headline": "Merge pull request #89 from identique/idnumbers-node-issue-85",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-03-17T02:20:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3751cbf3fe49dd165b2cbeada6a329e71eb799e1",
"body": "Remove hardcoded ID string bypasses that masked algorithm bugs in ARE,\nAUS, CHE, CZE, EST, ITA, LVA, NGA, NZL, PHL, PRT, and SVK.\n\nSource changes:\n- ARE: remove testValidIds/testInvalidIds arrays, rely on Luhn\n- AUS: remove '5123456701' bypass, rely on weighted checksum\n- CHE: remove specific ID che\n[…]\nXX' prefix case, fix regex to digits-only year\n\nTest changes:\n- Replace all affected test IDs with algorithmically valid data\n- Add previously-invalid IDs as valid where Python accepts them (NGA, PHL)",
"is_bot": false,
"headline": "refactor(#85): remove hardcoded test ID bypasses across 12 countries",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-03-15T09:20:23Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "becf0bef7e11579326e39c47222fbf936feab494",
"body": "fix(#84): fix over-validation rejecting valid IDs in DNK, CAN, ALB",
"is_bot": false,
"headline": "Merge pull request #88 from identique/idnumbers-node-issue-84",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-03-15T08:56:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f7bccc8be0b4d33b3cfd273972f48e6b60bbc0af",
"body": "Add 050308094A (year 1805, previously clamped to 1905) and\nI90308094A (Python test vector). Assert parsed birthDate year\nto prove year-clamping removal works correctly.",
"is_bot": false,
"headline": "test(#84): add ALB year-clamping regression test vectors",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-03-15T08:53:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "24a41dec171e0f66873a61d5154b7fd3658b3486",
"body": "- DNK: move 0101701235 to valid (proves checksum removal), add\n 061085-1178, use 3201701234 as invalid (bad date)\n- CAN: add 0-prefix and 8-prefix valid SINs (046454286, 812345676),\n add Python test vector 130692544, update migration invalidId\n- ALB: update example comment for CAN first-digit change",
"is_bot": false,
"headline": "test(#84): update test data for DNK, CAN, ALB fixes",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-03-15T08:47:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2314b2f360c34fe515e866176b647ee529efdfb7",
"body": "Remove year-range clamping (not present in Python source).\nChange gender/month threshold from <= 12 to < 50 to match Python.\nSet hasChecksum: false to match Python metadata.",
"is_bot": false,
"headline": "fix(#84): remove year clamping and fix gender threshold in ALB",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-03-15T08:46:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7d4ba6e596bd9721beaa0624e8c6e86fe90e7b4f",
"body": "Python source has no restriction on SINs starting with 0 or 8.\nValidation should rely solely on Luhn checksum.",
"is_bot": false,
"headline": "fix(#84): remove first-digit restriction from CAN SIN",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-03-15T08:46:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "82c1e6934a38781d695c49427c373129728b196a",
"body": "CPR numbers issued after October 2007 do not use check digits.\nPython source marks checksum: False. Remove the validateChecksum()\nfunction and hardcoded bypasses, set hasChecksum: false in metadata.",
"is_bot": false,
"headline": "fix(#84): remove checksum validation from DNK CPR",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-03-15T08:46:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a2b618d8ccaf5940d7e9b6a90f5f3c047322be16",
"body": "fix(#83): correct validation logic in BGR, TUR, SGP, JPN, LKA",
"is_bot": false,
"headline": "Merge pull request #87 from identique/idnumbers-node-issue-83",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-03-15T08:32:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "472eb10781cd8dea252a203edabf15283e2760f6",
"body": "Add M1234567N (valid) and M1234567X (invalid) to confirm the\nM-series check letter lookup table is correct.",
"is_bot": false,
"headline": "test(#83): add SGP M-prefix test vectors",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-03-15T08:21:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f3a149bbbee3143c1ee1fd6dd4b1248ecdcf78ae",
"body": "Replace incorrect test data with Python-verified IDs:\n- BGR: use 7501020018/7542011030 with correct parse expectations\n- TUR: add 15973515680 valid case\n- SGP: add Python test IDs (S8076606H, G4549883U, etc.)\n- LKA: use proper checksum-validated IDs from Python test suite",
"is_bot": false,
"headline": "test(#83): update test data for BGR, TUR, SGP, LKA fixes",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-03-15T08:21:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "173cc5b76ec5c2f09afffc1247763907dcf337fb",
"body": "Replace hardcoded blacklists and permissive validation with proper\nweighted modulus 11 checksum. Support both old format (9d+V/X) and\nnew format (12d) with old-to-new conversion matching Python source.",
"is_bot": false,
"headline": "fix(#83): rewrite LKA validation with proper checksum algorithm",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-03-15T08:21:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c98b7ab979f5fa389cd6dc6a0e76cfdf21d327a7",
"body": "The checksum weights must be applied in forward order matching the\nPython source. The previous reverse-order application produced\nincorrect checksums for most ID numbers.",
"is_bot": false,
"headline": "fix(#83): apply JPN My Number weights in forward order",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-03-15T08:21:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "245e98d85f3b0b034836402973c599479b75a6ad",
"body": "Replace shared ST/FG maps with offset approach with per-prefix\nlookup tables matching the Python source. The previous shared\nmaps produced incorrect check letters for T, G, and M prefixes.",
"is_bot": false,
"headline": "fix(#83): replace SGP check letter maps with per-prefix tables",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-03-15T08:21:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a160029e8344f9bbd119c40399925be469dbbaff",
"body": "JavaScript's % operator can return negative values unlike Python's.\nUse double-modulus pattern to ensure non-negative result for the\n10th digit calculation in both validate() and checksum().",
"is_bot": false,
"headline": "fix(#83): handle negative modulus in TUR validation",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-03-15T08:21:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d83937157efa0707b6b94c23333e9268fec069d1",
"body": "Change 1800s century offset from incorrect 1900 to correct 1800\nwhen month part exceeds 20. Remove hardcoded test bypass for\n'7523169263' that was masking the date parsing bug.",
"is_bot": false,
"headline": "fix(#83): correct BGR century calculation for monthPart > 20",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-03-15T08:21:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "da4015c7774d719ca93a0c701f40ffceed658822",
"body": null,
"is_bot": false,
"headline": "chore(release): bump version to 1.3.0",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-02-17T13:48:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f96ce520a72730542f9d48f247af5ff578e2c2c2",
"body": null,
"is_bot": false,
"headline": "chore(release): update CHANGELOG for v1.3.0",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-02-17T13:47:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "962f5740b10210220c05435f75e7f5232ff4fa5c",
"body": "refactor(#53): migrate getCountryIdFormat to registry lookup",
"is_bot": false,
"headline": "Merge pull request #81 from identique/idnumbers-node-issue-53",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-02-17T13:35:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2be8fe018c75661f34acee1215ea81958800e7be",
"body": null,
"is_bot": false,
"headline": "style(#53): fix Prettier formatting in migration test",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-02-17T11:17:40Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4c628a95e7198a449678f080456e248973670d75",
"body": "- Replace Cyrillic 'С' with ASCII 'C' in LKA format string\n- Return enriched copy instead of mutating registry object",
"is_bot": false,
"headline": "fix(#53): address Copilot review feedback",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-02-17T11:08:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8b6de6b54595e20885929fb41fd6ef2f5e53cd13",
"body": "Add 142 tests covering all 80 countries (complete IdFormat fields),\n18 format string assertions, 25 alias resolutions, case insensitivity,\nedge cases, and former stub entries returning null.",
"is_bot": false,
"headline": "test(#53): add getCountryIdFormat parity tests",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-02-17T08:55:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0c9e4fc1721012d50ac3fbbd4a636a73c068846e",
"body": "Replace the ~340-line switch statement with a registry-based lookup\nenriched by SUPPORTED_COUNTRIES data and preserved format strings.\nAll 80 registered countries now return complete IdFormat info.\nRemove 19 unused country imports. Tighten return type to IdFormat | null.",
"is_bot": false,
"headline": "refactor(#53): replace getCountryIdFormat switch with registry lookup",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-02-17T08:54:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8e95155008442612ec15a23e726d17fdec91fde3",
"body": "refactor(#51): migrate validateNationalId to registry lookup",
"is_bot": false,
"headline": "Merge pull request #80 from identique/idnumbers-node-issue-51",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-02-17T08:47:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "274f07b93f7cef1b6d2e2e7a815da3624c3d2d91",
"body": "refactor(#52): migrate parseIdInfo to registry lookup",
"is_bot": false,
"headline": "Merge pull request #79 from identique/idnumbers-node-issue-52",
"author_name": "Angus",
"author_login": "AngusHsu",
"committed_at": "2026-02-17T08:47:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5eb81acd1e72ec237f1f3f1d952016c31faa0b9d",
"body": "…parse()\n\nDNK's validate() only checked format and checksum but not date validity,\nwhile parse() did validate dates. This caused a regression where IDs with\nimpossible dates (e.g. month 13) would pass validate() but fail parse(),\nreturning isValid:true with null extractedInfo.",
"is_bot": false,
"headline": "fix(#51): add date validation to DNK validate() for consistency with …",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-02-16T18:31:05Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2df0a7750d5d4c866bf9242ff3de30340cdb9385",
"body": "Add 389 parity tests covering all 80 countries, composite validators\n(BGD, SMR, NZL), alias resolution, and error handling. Add 7 unit tests\nfor the new resolveKey() method on ValidatorRegistry.",
"is_bot": false,
"headline": "test(#51): add validateNationalId parity tests and resolveKey unit tests",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-02-16T18:19:01Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2a12dd90b3a51ae1b781af31c507409a61cc2892",
"body": "Replace the ~800-line switch statement with a unified registry-based\npattern: resolve key, validate, conditionally parse, return result.\nRemove ~60 unused class imports that were only needed by the switch.",
"is_bot": false,
"headline": "refactor(#51): replace validateNationalId switch with registry lookup",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-02-16T17:33:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d3f3644de64d3bba6e52c68b35f02f82b04bef6c",
"body": "- BGD: create composite validator supporting both old (13-digit) and new\n (17-digit) national ID formats with OR logic\n- SMR: create composite validator supporting both SSI and COE formats\n- NZL: change registration from NationalID to DriverLicense to match\n the existing validateNationalId switch behavior",
"is_bot": false,
"headline": "fix(#51): correct BGD, SMR, NZL validator registrations",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-02-16T17:30:55Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7490c0148d690a07643cde353e03b8b20e602abf",
"body": "Add resolveKey() method that returns the primary key (alpha-3) for any\nkey or alias. Refactor get(), has(), and getFormat() to use resolveKey()\ninternally, eliminating duplicated alias resolution logic.",
"is_bot": false,
"headline": "feat(#51): add resolveKey() to ValidatorRegistry",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-02-16T17:28:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "70d2511df9fb30ad93c5ae39879a3658c33fe212",
"body": "…mport\n\n- Replace `any` types in adapters.ts with explicit CountryModule, AnyMetadata,\n and FunctionBasedMetadata interfaces\n- Replace `any` in RegistryEntry with CountryModule type\n- Remove side-effect import from registry/index.ts to keep it side-effect free\n for type-only consumers\n- Re-export new adapter types from barrel\n\nAddresses Copilot review feedback on PR #79.",
"is_bot": false,
"headline": "refactor(#52): improve type safety and remove redundant side-effect i…",
"author_name": "Angus Hsu",
"author_login": "AngusHsu",
"committed_at": "2026-02-16T17:26:00Z",
"body_truncated": false,
"is_coding_agent": false
}
],
"releases_count": 12,
"commits_last_year": 137,
"latest_release_at": "2026-07-17T11:33:00Z",
"latest_release_tag": "v1.9.0",
"releases_from_tags": false,
"days_since_last_push": 4,
"active_weeks_last_year": 16,
"days_since_latest_release": 5,
"mean_days_between_releases": 25.4
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": false,
"health_percentage": 50,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "idnumbers",
"exists": true,
"license": "MIT",
"keywords": [
"id",
"identification",
"validation",
"national-id",
"ssn",
"medicare",
"nino",
"sin",
"tax-id",
"typescript",
"verification",
"usa",
"australia",
"south-africa",
"united-kingdom",
"canada",
"germany",
"france",
"netherlands",
"albania",
"austria",
"belgium",
"italy",
"spain",
"denmark",
"poland",
"czech-republic",
"finland",
"social-security",
"national-insurance",
"social-insurance",
"fiscal-code",
"dni",
"cpr",
"bsn",
"atin",
"pesel",
"hetu",
"birth-number"
],
"ecosystem": "npm",
"matches_repo": true,
"registry_url": "https://www.npmjs.com/package/idnumbers",
"is_deprecated": false,
"latest_version": "1.9.0",
"repository_url": "https://github.com/identique/idnumbers-npm",
"versions_count": 12,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": 1,
"monthly_downloads": 12676,
"first_published_at": "2025-11-02T02:59:48.610000Z",
"latest_published_at": "2026-07-17T11:39:35.934000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 4
}
]
},
"popularity": {
"forks": 2,
"stars": 0,
"watchers": 0,
"fork_history": {
"days": [
{
"date": "2026-01-21",
"count": 1
},
{
"date": "2026-06-29",
"count": 1
}
],
"complete": true,
"collected": 2,
"total_forks": 2
},
"star_history": {
"days": [],
"complete": true,
"collected": 0,
"total_stars": 0
},
"open_issues_and_prs": 59
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [
"examples"
],
"has_llms_txt": false,
"has_dockerfile": false,
"has_mcp_signal": false,
"bootstrap_files": [],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [
"tsconfig.json"
],
"toolchain_manifests": [],
"largest_source_bytes": 23937,
"source_files_sampled": 197,
"oversized_source_files": 0,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"dependencies": {
"manifests": [
"package.json"
],
"advisories": {
"error": null,
"scope": null,
"source": null,
"findings": [],
"collected": false,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 0,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 0,
"direct_affected_count": 0
},
"ecosystems": [
"npm"
],
"dependencies": [],
"all_dependencies": {
"error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
"source": null,
"packages": [],
"collected": false,
"truncated": false,
"total_count": null,
"direct_count": null,
"indirect_count": null
}
},
"maintainership": {
"issues": {
"open_prs": 8,
"merged_prs": 44,
"open_issues": 51,
"closed_ratio": 0.532,
"closed_issues": 58,
"closed_unmerged_prs": 1
},
"bus_factor": 1,
"bot_contributors": 0,
"top_contributors": [
{
"type": "User",
"login": "AngusHsu",
"commits": 137,
"avatar_url": "https://avatars.githubusercontent.com/u/26132913?v=4"
}
],
"contributors_sampled": 1,
"top_contributor_share": 1
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"ci.yml",
"npm-publish.yml",
"test-npm-publish.yml"
],
"has_docs_dir": true,
"linter_configs": [
".eslintrc.js"
],
"has_editorconfig": false,
"has_linter_config": true,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [
"package-lock.json"
],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 10,
"reason": "no binaries found in the repo",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": 8,
"reason": "branch protection is not maximal on development and all release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": 10,
"reason": "13 out of 13 merged PRs checked by a CI test -- score normalized to 10",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 0,
"reason": "Found 1/14 approved changesets -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 0,
"reason": "project has 0 contributing companies or organizations -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 0,
"reason": "no update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 10,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 10,
"reason": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": 10,
"reason": "packaging workflow detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
},
{
"name": "Pinned-Dependencies",
"score": 3,
"reason": "dependency not pinned by hash detected -- score normalized to 3",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "SAST tool is not run on all commits -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 0,
"reason": "security policy file not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": null,
"reason": "no releases found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 0,
"reason": "detected GitHub workflow tokens with excessive permissions",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 0,
"reason": "24 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "b2ec45bf46eb8155da8c9769526c64895726afa7",
"ran_at": "2026-07-22T11:39:34Z",
"aggregate_score": 4.4,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": false
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-17T11:39:39Z",
"oldest_open_prs": [
{
"number": 114,
"created_at": "2026-06-29T12:47:56Z",
"last_comment_at": "2026-07-19T17:48:11Z",
"last_comment_author": "ramezhanna"
},
{
"number": 154,
"created_at": "2026-07-17T04:21:21Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 156,
"created_at": "2026-07-17T11:54:57Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 157,
"created_at": "2026-07-17T11:55:00Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 158,
"created_at": "2026-07-17T11:55:02Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 159,
"created_at": "2026-07-17T11:55:05Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 161,
"created_at": "2026-07-18T05:45:37Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 162,
"created_at": "2026-07-18T05:45:43Z",
"last_comment_at": null,
"last_comment_author": null
}
],
"last_merged_pr_at": "2026-07-17T11:32:33Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": [
{
"number": 39,
"created_at": "2025-11-26T08:34:28Z",
"last_comment_at": "2025-11-29T21:27:19Z",
"last_comment_author": "VidhyaDivakar"
},
{
"number": 40,
"created_at": "2025-11-26T08:34:32Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 41,
"created_at": "2025-11-26T08:35:03Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 54,
"created_at": "2025-11-26T08:47:37Z",
"last_comment_at": "2026-07-02T12:35:49Z",
"last_comment_author": "ramezhanna"
},
{
"number": 55,
"created_at": "2025-11-26T08:47:41Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 56,
"created_at": "2025-11-26T08:47:46Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 57,
"created_at": "2025-11-26T08:47:55Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 58,
"created_at": "2025-11-26T08:48:02Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 59,
"created_at": "2025-11-26T08:48:10Z",
"last_comment_at": "2026-07-17T07:28:39Z",
"last_comment_author": "AngusHsu"
},
{
"number": 60,
"created_at": "2025-11-26T08:48:14Z",
"last_comment_at": "2026-07-17T07:28:40Z",
"last_comment_author": "AngusHsu"
},
{
"number": 61,
"created_at": "2025-11-26T08:48:20Z",
"last_comment_at": "2026-07-17T07:28:42Z",
"last_comment_author": "AngusHsu"
},
{
"number": 115,
"created_at": "2026-07-06T11:17:29Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 116,
"created_at": "2026-07-06T11:17:30Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 117,
"created_at": "2026-07-06T11:17:32Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 118,
"created_at": "2026-07-06T11:17:34Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 119,
"created_at": "2026-07-06T11:17:36Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 120,
"created_at": "2026-07-06T11:17:37Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 121,
"created_at": "2026-07-06T11:17:39Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 122,
"created_at": "2026-07-06T11:17:42Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 123,
"created_at": "2026-07-06T11:17:44Z",
"last_comment_at": null,
"last_comment_author": null
}
]
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/identique/idnumbers-npm",
"host": "github.com",
"name": "idnumbers-npm",
"owner": "identique"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 61,
"inputs": {
"security": 44,
"vitality": 85,
"community": 35,
"governance": 50,
"engineering": 84
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "excellent",
"name": "Vitality",
"value": 85,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "good",
"name": "Development activity",
"note": null,
"notes": [],
"value": 75,
"inputs": {
"commits_last_year": 137,
"human_commit_share": 1,
"days_since_last_push": 4,
"active_weeks_last_year": 16
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 4 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 4
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "16/52 weeks with commits",
"points": 11.1,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 16
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "137 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 137
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 100,
"inputs": {
"releases_count": 12,
"latest_release_tag": "v1.9.0",
"releases_from_tags": false,
"days_since_latest_release": 5,
"mean_days_between_releases": 25.4
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "12 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 12
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 5 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 5
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~25.4 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 25.4
}
}
],
"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": 5,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "last human commit 5 days ago",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_maintained",
"params": {
"days": 5
}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "at_risk",
"name": "Community & Adoption",
"value": 35,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "critical",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 1,
"inputs": {
"forks": 2,
"stars": 0,
"watchers": 0,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "0 stars",
"points": 0,
"status": "missed",
"details": [
{
"code": "stars",
"params": {
"count": 0
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "2 forks",
"points": 0,
"status": "missed",
"details": [
{
"code": "forks",
"params": {
"count": 2
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "0 watchers",
"points": 0,
"status": "missed",
"details": [
{
"code": "watchers",
"params": {
"count": 0
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "moderate",
"name": "Community health",
"note": null,
"notes": [],
"value": 50,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": false,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (MIT)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "MIT"
}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.3
}
]
},
{
"key": "ecosystem_adoption",
"band": "moderate",
"name": "Ecosystem adoption (downloads)",
"note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"registry_dependents"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 68,
"inputs": {
"packages": [
"idnumbers"
],
"dependents": null,
"ecosystems": "npm",
"total_downloads": null,
"monthly_downloads": 12676
},
"components": [
{
"key": "monthly_downloads",
"name": "Monthly downloads",
"detail": "12,676 downloads/month across npm",
"points": 54.7,
"status": "partial",
"details": [
{
"code": "downloads_monthly",
"params": {
"count": 12676,
"ecosystems": "npm"
}
}
],
"max_points": 80
},
{
"key": "registry_dependents",
"name": "Registry dependents",
"detail": "not reported by this ecosystem",
"points": 0,
"status": "excluded",
"details": [
{
"code": "not_reported_by_this_ecosystem",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 50,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 10,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 1,
"top_contributor_share": 1
},
"components": [
{
"key": "bus_factor",
"name": "Bus factor",
"detail": "1 contributor(s) cover half of all commits",
"points": 9,
"status": "partial",
"details": [
{
"code": "bus_factor",
"params": {
"count": 1
}
}
],
"max_points": 54
},
{
"key": "commit_distribution",
"name": "Commit distribution",
"detail": "top contributor authored 100% of commits",
"points": 0,
"status": "missed",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 100
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "1 contributors",
"points": 1.4,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 1
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 0 contributing companies or organizations -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "moderate",
"name": "Issue & PR responsiveness",
"note": null,
"notes": [],
"value": 62,
"inputs": {
"merged_prs": 44,
"open_issues": 51,
"closed_issues": 58,
"issue_closed_ratio": 0.532,
"closed_unmerged_prs": 1
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "53% of issues closed",
"points": 24.9,
"status": "partial",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 53
}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "44/45 decided PRs merged",
"points": 37.4,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 44,
"decided": 45
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 1/14 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "at_risk",
"name": "Ownership & stewardship",
"note": null,
"notes": [],
"value": 44,
"inputs": {
"followers": 1,
"owner_type": "Organization",
"is_verified": null,
"owner_login": "identique",
"public_repos": 3,
"account_age_days": 1269
},
"components": [
{
"key": "ownership_backing",
"name": "Ownership backing",
"detail": "organization-owned",
"points": 30,
"status": "met",
"details": [
{
"code": "owner_organization",
"params": {}
}
],
"max_points": 30
},
{
"key": "verified_domain",
"name": "Verified domain",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "owner_reach",
"name": "Owner reach",
"detail": "1 followers of identique",
"points": 2.2,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 1,
"login": "identique"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "3 public repos, account ~3 yr old",
"points": 11.3,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 3
}
},
{
"code": "account_age_years",
"params": {
"years": 3
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"idnumbers"
],
"ecosystems": "npm",
"any_deprecated": false,
"min_days_since_publish": 4
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "1 package(s) on npm",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 1,
"ecosystems": "npm"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 4 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 4
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "12 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 12
}
}
],
"max_points": 20
},
{
"key": "not_deprecated",
"name": "Not deprecated",
"detail": "active, not deprecated or yanked",
"points": 20,
"status": "met",
"details": [
{
"code": "package_not_deprecated",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
},
{
"key": "engineering",
"band": "good",
"name": "Engineering Quality",
"value": 84,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "good",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 84,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": false,
"has_linter_config": true,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "3 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 3
}
}
],
"max_points": 24
},
{
"key": "tests_present",
"name": "Tests present",
"detail": null,
"points": 24,
"status": "met",
"details": [],
"max_points": 24
},
{
"key": "linter_config",
"name": "Linter config",
"detail": ".eslintrc.js",
"points": 16,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": ".eslintrc.js"
}
}
],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "13 out of 13 merged PRs checked by a CI test -- score normalized to 10",
"points": 20,
"status": "met",
"details": [],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "excellent",
"name": "Documentation",
"note": null,
"notes": [],
"value": 85,
"inputs": {
"topics": [
"identification-number",
"idnumbers",
"national-id",
"national-id-validator",
"national-identification-number",
"national-identity",
"nodejs",
"npm",
"parser-library",
"typescript",
"validation-library"
],
"has_wiki": true,
"homepage": null,
"has_readme": true,
"has_docs_dir": true,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 25,
"status": "met",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": "11 topics",
"points": 10,
"status": "met",
"details": [
{
"code": "topics_count",
"params": {
"count": 11
}
}
],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "at_risk",
"name": "Security",
"value": 44,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "at_risk",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 44,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 17,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 1,
"scorecard_aggregate": 4.4
},
"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 is not maximal on development and all release branches",
"points": 6,
"status": "partial",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "13 out of 13 merged PRs checked by a CI test -- score normalized to 10",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 1/14 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 0 contributing companies or organizations -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "no update tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow detected",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "pinned_dependencies",
"name": "Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 3",
"points": 1.5,
"status": "partial",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "SAST tool is not run on all commits -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "detected GitHub workflow tokens with excessive permissions",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "24 existing vulnerabilities detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "excellent",
"name": "High-Risk Jurisdiction Exposure",
"note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
"notes": [
{
"code": "jurisdiction_evidence_limits",
"params": {}
}
],
"value": 100,
"inputs": {
"meaning": "self-published location evidence; not nationality or citizenship",
"red_flag": false,
"exposures": [],
"policy_countries": [
"Russia",
"Iran",
"North Korea"
],
"review_only_matches": 0,
"assessed_self_published_locations": 1
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "moderate",
"name": "AI Readiness",
"value": 56,
"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.99,
"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": "99 of 100 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 99,
"sampled": 100
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "moderate",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 57,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [
"package-lock.json"
],
"has_dockerfile": false,
"typed_language": true,
"bootstrap_files": [],
"has_devcontainer": false,
"has_linter_config": true,
"typecheck_configs": [
"tsconfig.json"
],
"agent_commit_share": 0,
"toolchain_manifests": [],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": ".eslintrc.js",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": ".eslintrc.js"
}
}
],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "tsconfig.json",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "tsconfig.json"
}
}
],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": "lockfile",
"points": 10,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "lockfile"
}
}
],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "no agent-authored commits among the last 100",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_authored_commits",
"params": {
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "no automated dependency updates observed",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_dependency_automation",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 3",
"points": 3,
"status": "partial",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "excellent",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"primary_language": "TypeScript",
"largest_source_bytes": 23937,
"source_files_sampled": 197,
"oversized_source_files": 0
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "TypeScript (statically typed)",
"points": 45,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "TypeScript"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "0/197 source files over 60KB",
"points": 55,
"status": "met",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 197,
"oversized": 0
}
}
],
"max_points": 55
}
]
},
{
"key": "ai_interfaces",
"band": "at_risk",
"name": "Machine-readable interfaces",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"example_dirs": [
"examples"
],
"has_mcp_signal": false,
"api_schema_files": []
},
"components": [
{
"key": "api_schema_openapi_graphql_proto",
"name": "API schema (OpenAPI/GraphQL/proto)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 40
},
{
"key": "mcp_server",
"name": "MCP server",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "runnable_examples",
"name": "Runnable examples",
"detail": "examples",
"points": 40,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "examples"
}
}
],
"max_points": 40
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
}
],
"metrics_version": "1.13.0"
},
"warnings": [
"GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
"deps.dev does not index npm:idnumbers@1.9.0; advisories assessed against the repository dependency graph instead"
],
"report_type": "repository",
"generated_at": "2026-07-22T11:39:49.702934Z",
"schema_version": "0.26.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/i/identique/idnumbers-npm.svg",
"full_name": "identique/idnumbers-npm",
"license_state": "standard",
"license_spdx": "MIT"
}