原始 JSON 报告 机器可读
{
"data": {
"repo": {
"topics": [
"chemometrics",
"design-of-experiments",
"multivariate-analysis",
"multivariate-statistics",
"pca",
"pls",
"batch-process",
"latent-variables",
"multiblock-structures",
"partial-least-squares",
"partial-least-squares-regression",
"principal-component-analysis-pca",
"principal-components-regression",
"process-monitoring",
"statistical-process-control",
"experimental-design",
"batch-data-analysis"
],
"is_fork": false,
"size_kb": 9363,
"has_wiki": false,
"homepage": "https://kgdunn.github.io/process-improve/",
"languages": {
"Python": 3120270,
"Makefile": 2229
},
"pushed_at": "2026-07-30T06:09:21Z",
"created_at": "2019-09-08T14:09:58Z",
"owner_type": "User",
"updated_at": "2026-07-29T19:54:42Z",
"description": "Python toolkit for analysis of industrial process data; multivariate analysis, designed experiments, process monitoring.",
"is_archived": false,
"is_disabled": false,
"license_spdx": "MIT",
"default_branch": "main",
"license_spdx_raw": "MIT",
"primary_language": "Python",
"significant_languages": [
"Python"
]
},
"owner": {
"blog": "https://learnche.org",
"name": "Kevin Dunn",
"type": "User",
"login": "kgdunn",
"company": null,
"location": "Delft, Netherlands",
"followers": 34,
"avatar_url": "https://avatars.githubusercontent.com/u/578383?v=4",
"created_at": "2011-01-22T19:36:45Z",
"is_verified": null,
"public_repos": 40,
"account_age_days": 5667
},
"license": {
"state": "standard",
"spdx_id": "MIT",
"raw_spdx": "MIT",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v1.62.1",
"kind": "patch",
"published_at": "2026-07-30T06:09:21Z"
},
{
"tag": "v1.61.0",
"kind": "minor",
"published_at": "2026-07-25T21:25:08Z"
},
{
"tag": "v1.60.0",
"kind": "minor",
"published_at": "2026-07-24T07:56:31Z"
},
{
"tag": "v1.58.0",
"kind": "minor",
"published_at": "2026-07-23T10:39:00Z"
},
{
"tag": "v1.55.1",
"kind": "patch",
"published_at": "2026-07-21T05:27:53Z"
},
{
"tag": "v1.52.2",
"kind": "patch",
"published_at": "2026-07-10T05:17:16Z"
},
{
"tag": "v1.51.3",
"kind": "patch",
"published_at": "2026-07-09T05:13:43Z"
},
{
"tag": "v1.51.2",
"kind": "patch",
"published_at": "2026-07-05T07:58:59Z"
},
{
"tag": "v1.51.0",
"kind": "minor",
"published_at": "2026-06-30T08:06:52Z"
},
{
"tag": "v1.47.0",
"kind": "minor",
"published_at": "2026-06-22T05:23:03Z"
},
{
"tag": "v1.46.0",
"kind": "minor",
"published_at": "2026-06-21T21:25:40Z"
},
{
"tag": "v1.44.0",
"kind": "minor",
"published_at": "2026-06-20T07:41:36Z"
},
{
"tag": "v1.42.0",
"kind": "minor",
"published_at": "2026-06-19T21:49:13Z"
},
{
"tag": "v1.40.2",
"kind": "patch",
"published_at": "2026-06-12T08:34:04Z"
},
{
"tag": "v1.40.1",
"kind": "patch",
"published_at": "2026-06-11T11:49:47Z"
},
{
"tag": "v1.39.0",
"kind": "minor",
"published_at": "2026-06-07T20:58:24Z"
},
{
"tag": "v1.38.0",
"kind": "minor",
"published_at": "2026-06-07T16:32:10Z"
},
{
"tag": "v1.27.1",
"kind": "patch",
"published_at": "2026-06-06T07:52:19Z"
},
{
"tag": "v1.24.9",
"kind": "patch",
"published_at": "2026-06-02T17:30:10Z"
},
{
"tag": "v1.24.8",
"kind": "patch",
"published_at": "2026-06-02T17:18:23Z"
},
{
"tag": "v1.24.7",
"kind": "patch",
"published_at": "2026-06-02T16:48:22Z"
},
{
"tag": "v1.24.6",
"kind": "patch",
"published_at": "2026-06-02T16:42:22Z"
},
{
"tag": "v1.24.5",
"kind": "patch",
"published_at": "2026-06-02T16:37:00Z"
},
{
"tag": "v1.24.4",
"kind": "patch",
"published_at": "2026-06-02T13:58:39Z"
},
{
"tag": "v1.24.3",
"kind": "patch",
"published_at": "2026-06-02T13:34:12Z"
},
{
"tag": "v1.24.2",
"kind": "patch",
"published_at": "2026-06-02T12:51:44Z"
},
{
"tag": "v1.24.1",
"kind": "patch",
"published_at": "2026-06-02T11:49:04Z"
},
{
"tag": "v1.24.0",
"kind": "minor",
"published_at": "2026-06-02T10:59:47Z"
},
{
"tag": "v1.23.2",
"kind": "patch",
"published_at": "2026-06-02T10:20:25Z"
},
{
"tag": "v1.23.1",
"kind": "patch",
"published_at": "2026-06-02T06:37:02Z"
},
{
"tag": "v1.23.0",
"kind": "minor",
"published_at": "2026-06-02T06:14:46Z"
},
{
"tag": "v1.22.21",
"kind": "patch",
"published_at": "2026-06-02T05:38:15Z"
},
{
"tag": "v1.22.20",
"kind": "patch",
"published_at": "2026-06-02T05:14:47Z"
},
{
"tag": "v1.22.19",
"kind": "patch",
"published_at": "2026-06-02T04:50:21Z"
},
{
"tag": "v1.22.18",
"kind": "patch",
"published_at": "2026-06-02T04:32:53Z"
},
{
"tag": "v1.22.17",
"kind": "patch",
"published_at": "2026-06-01T21:43:53Z"
},
{
"tag": "v1.22.16",
"kind": "patch",
"published_at": "2026-06-01T20:51:58Z"
},
{
"tag": "v1.22.15",
"kind": "patch",
"published_at": "2026-06-01T19:37:26Z"
},
{
"tag": "v1.22.14",
"kind": "patch",
"published_at": "2026-06-01T19:24:08Z"
},
{
"tag": "v1.22.13",
"kind": "patch",
"published_at": "2026-06-01T10:00:27Z"
},
{
"tag": "v1.22.12",
"kind": "patch",
"published_at": "2026-06-01T07:28:54Z"
},
{
"tag": "v1.22.11",
"kind": "patch",
"published_at": "2026-06-01T07:16:43Z"
},
{
"tag": "v1.22.10",
"kind": "patch",
"published_at": "2026-06-01T06:21:57Z"
},
{
"tag": "v1.22.9",
"kind": "patch",
"published_at": "2026-05-30T05:07:13Z"
},
{
"tag": "v1.22.8",
"kind": "patch",
"published_at": "2026-05-29T21:54:38Z"
},
{
"tag": "v1.22.7",
"kind": "patch",
"published_at": "2026-05-29T21:01:30Z"
},
{
"tag": "v1.22.6",
"kind": "patch",
"published_at": "2026-05-29T17:04:22Z"
},
{
"tag": "v1.22.5",
"kind": "patch",
"published_at": "2026-05-29T15:15:22Z"
},
{
"tag": "v1.22.4",
"kind": "patch",
"published_at": "2026-05-29T07:59:24Z"
},
{
"tag": "v1.22.3",
"kind": "patch",
"published_at": "2026-05-27T04:52:54Z"
},
{
"tag": "v1.22.2",
"kind": "patch",
"published_at": "2026-05-22T18:39:21Z"
},
{
"tag": "v1.22.1",
"kind": "patch",
"published_at": "2026-05-21T20:26:21Z"
},
{
"tag": "v1.22.0",
"kind": "minor",
"published_at": "2026-05-21T09:41:39Z"
},
{
"tag": "v1.21.7",
"kind": "patch",
"published_at": "2026-05-18T09:58:52Z"
},
{
"tag": "v1.21.6",
"kind": "patch",
"published_at": "2026-05-17T17:13:33Z"
},
{
"tag": "v1.21.5",
"kind": "patch",
"published_at": "2026-05-17T15:47:13Z"
},
{
"tag": "v1.21.4",
"kind": "patch",
"published_at": "2026-05-17T15:35:36Z"
},
{
"tag": "v1.21.3",
"kind": "patch",
"published_at": "2026-05-17T14:49:12Z"
},
{
"tag": "v1.21.2",
"kind": "patch",
"published_at": "2026-05-17T14:44:26Z"
},
{
"tag": "v1.21.1",
"kind": "patch",
"published_at": "2026-05-17T14:13:58Z"
},
{
"tag": "v1.21.0",
"kind": "minor",
"published_at": "2026-05-17T13:47:13Z"
},
{
"tag": "v1.20.0",
"kind": "minor",
"published_at": "2026-05-17T13:34:29Z"
},
{
"tag": "v1.19.0",
"kind": "minor",
"published_at": "2026-05-17T12:54:02Z"
},
{
"tag": "v1.18.0",
"kind": "minor",
"published_at": "2026-05-17T12:26:24Z"
},
{
"tag": "v1.17.0",
"kind": "minor",
"published_at": "2026-05-17T11:56:23Z"
},
{
"tag": "v1.16.12",
"kind": "patch",
"published_at": "2026-05-17T07:52:32Z"
},
{
"tag": "v1.16.11",
"kind": "patch",
"published_at": "2026-05-17T07:23:57Z"
},
{
"tag": "v1.16.10",
"kind": "patch",
"published_at": "2026-05-17T07:09:52Z"
},
{
"tag": "v1.16.9",
"kind": "patch",
"published_at": "2026-05-16T06:50:48Z"
},
{
"tag": "v1.16.8",
"kind": "patch",
"published_at": "2026-05-14T12:23:54Z"
},
{
"tag": "v1.16.7",
"kind": "patch",
"published_at": "2026-05-14T09:28:40Z"
},
{
"tag": "v1.16.6",
"kind": "patch",
"published_at": "2026-05-12T07:05:49Z"
},
{
"tag": "v1.16.5",
"kind": "patch",
"published_at": "2026-05-12T06:43:01Z"
},
{
"tag": "v1.16.4",
"kind": "patch",
"published_at": "2026-05-12T06:09:37Z"
},
{
"tag": "v1.16.3",
"kind": "patch",
"published_at": "2026-05-12T05:50:51Z"
},
{
"tag": "v1.16.2",
"kind": "patch",
"published_at": "2026-05-12T05:42:50Z"
},
{
"tag": "v1.16.1",
"kind": "patch",
"published_at": "2026-05-11T22:16:54Z"
},
{
"tag": "v1.16.0",
"kind": "minor",
"published_at": "2026-05-11T21:27:38Z"
},
{
"tag": "v1.15.3",
"kind": "patch",
"published_at": "2026-05-11T10:11:48Z"
},
{
"tag": "v1.15.2",
"kind": "patch",
"published_at": "2026-05-11T05:53:21Z"
},
{
"tag": "v1.15.1",
"kind": "patch",
"published_at": "2026-05-11T05:29:32Z"
},
{
"tag": "v1.15.0",
"kind": "minor",
"published_at": "2026-05-10T22:43:38Z"
},
{
"tag": "v1.14.0",
"kind": "minor",
"published_at": "2026-05-10T22:00:25Z"
},
{
"tag": "v1.13.12",
"kind": "patch",
"published_at": "2026-05-07T17:57:07Z"
},
{
"tag": "v1.13.11",
"kind": "patch",
"published_at": "2026-05-06T19:00:54Z"
},
{
"tag": "v1.13.9",
"kind": "patch",
"published_at": "2026-05-06T18:41:07Z"
},
{
"tag": "v1.13.8",
"kind": "patch",
"published_at": "2026-05-06T18:27:32Z"
},
{
"tag": "v1.13.7",
"kind": "patch",
"published_at": "2026-05-06T07:07:22Z"
},
{
"tag": "v1.13.6",
"kind": "patch",
"published_at": "2026-05-03T12:33:07Z"
},
{
"tag": "v1.13.5",
"kind": "patch",
"published_at": "2026-04-29T20:39:25Z"
},
{
"tag": "v1.13.4",
"kind": "patch",
"published_at": "2026-04-29T19:39:14Z"
},
{
"tag": "v1.13.3",
"kind": "patch",
"published_at": "2026-04-29T18:23:21Z"
},
{
"tag": "v1.13.2",
"kind": "patch",
"published_at": "2026-04-29T08:25:31Z"
},
{
"tag": "v1.13.1",
"kind": "patch",
"published_at": "2026-04-29T08:04:35Z"
},
{
"tag": "v1.13.0",
"kind": "minor",
"published_at": "2026-04-29T04:55:21Z"
},
{
"tag": "v1.9.3",
"kind": "patch",
"published_at": "2026-04-28T06:07:24Z"
},
{
"tag": "v1.9.2",
"kind": "patch",
"published_at": "2026-04-28T05:41:31Z"
},
{
"tag": "v1.9.1",
"kind": "patch",
"published_at": "2026-04-28T05:20:21Z"
},
{
"tag": "v1.9.0",
"kind": "minor",
"published_at": "2026-04-28T04:26:24Z"
},
{
"tag": "v1.8.1",
"kind": "patch",
"published_at": "2026-04-28T04:15:30Z"
}
],
"recent_commits": [
{
"oid": "2ab876fa8378e00e34c5d2b770b2f18b2582bdc2",
"body": "* Document model inversion, and pin the constants the book quotes\n\nThe inversion and O-PLS APIs landed with docstrings but no narrative page, so\nthe reasoning behind them lived only in the book. The new user-guide page\ncovers PLS.invert, walking the null space, why inversion can need more\ncomponents\n[…]\ne way on main.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01DsTypY4FcRbrXRxorb9raz\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Document model inversion, and pin the constants the book quotes (#478)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-29T19:54:38Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0513197e33791aef54b739af777fd11e60131461",
"body": "…shared desirability, intervals at the optimum (#474)\n\n* Share one desirability implementation between optimizer and plots\n\nThe Derringer-Suich desirability helpers existed twice, in\nexperiments/optimization.py and in the optimisation plots module, and the\ntwo copies had drifted apart. The plotting \n[…]\nreversed pair.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01TVbQmQNRwrSerdh7WQX2Aw\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Make multi-response optimization work end to end: sweet-spot region, …",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-26T06:52:00Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "14d658cf06ee1094929257cbe9a4f63dbc1721f5",
"body": "* Compute score contributions from the data, not from the score\n\nscore_contributions() back-projected a score-space difference through the\nloadings: contributions = (t_end - t_start) @ P. That expression never\nreceives the observation's data. With one component it reduces exactly to\n-t_1 * p_1, so i\n[…]\nxt still\npass.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01D58KmvE1L75DDE7pqfJPeL\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Compute score contributions from the data, not from the score (#476)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-25T21:21:56Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "499a0bef3166b159854dac621c1abe3987c9e3d1",
"body": "…ost-hoc) (#471)\n\n* Add designed-mode panel comparison: factorial ANOVA + Tukey/Dunnett post-hoc\n\nNew module process_improve.sensory.designed complements the observational\nrelate with the designed-mode question: which product treatments differ, and\nby how much, on each attribute, for a randomized co\n[…]\nGELOG entry.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018Ra2KAdJeGtnUzi68yDFaR\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add designed-mode panel comparison (factorial ANOVA + Tukey/Dunnett p…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-24T07:31:13Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2462a4318ba9ec6e161cf06c8ef4f2c93015ead3",
"body": "* Add PLS.invert() for model inversion and null-space design\n\nGiven a desired response on the original Y scale, PLS.invert() runs the\nmodel backwards to return the minimum-norm input vector that achieves it,\nplus an orthonormal basis for the (A - r)-dimensional null space of input\nvectors that all y\n[…]\nsponse only.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01DsTypY4FcRbrXRxorb9raz\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add PLS model inversion (null space) and O-PLS support (#470)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-23T22:13:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a17b81a95a0cc75bde8875ab2980a1df76121ec4",
"body": "…e (#468)\n\n* Add permutation-column VIP / CV-beta null for the sensory relate\n\nIn the p >> n observational relate, even a descriptor with no real relationship\nearns a non-trivial VIP, so a magnitude threshold cannot come from the fit alone.\n`permutation_column_null` builds one from the data itself: \n[…]\ncov flagged.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018M9u5EpSjHa3mjNaYDJ7qq\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add permutation-column VIP / CV-beta null for the observational relat…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-23T10:30:52Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3d4d3c092861710f4f51eb7c2251c820c7fd4073",
"body": "* Add delete-d option to the marginal-association influence gate\n\nLeave-one-out cannot demote a correlation carried by exactly two observations:\ndeleting either one leaves the other holding it up, so the jackknife interval\nnever spans zero. Add an `influence_deletions` parameter (default 1) to\n`anal\n[…]\ned at d = 2.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018M9u5EpSjHa3mjNaYDJ7qq\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add delete-d option to the observational relate influence gate (#467)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-23T06:07:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "042fc3307c8d1982df041d8b1cc81596638353c7",
"body": "…(#466)\n\n* Add influence-robust jackknife gate to observational sensory relate\n\nSparse, wide predictor blocks (many descriptors non-zero on only a single\nproduct) let a lone high-leverage observation manufacture a \"driver\": after\nunit-variance scaling that single non-zero becomes a fixed spike, so i\n[…]\nt-confirmed.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_018M9u5EpSjHa3mjNaYDJ7qq\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Influence-robust jackknife gate for the observational sensory relate …",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-23T05:24:59Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7a041c4d000d4bd6cc5947320f4417f7b520e72d",
"body": "Updates the requirements on [mypy](https://github.com/python/mypy) to permit the latest version.\n- [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md)\n- [Commits](https://github.com/python/mypy/compare/v1.19.1...v2.3.0)\n\n---\nupdated-dependencies:\n- dependency-name: mypy\n dependency-version: 2.3.0\n dependency-type: direct:development\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps-dev): Update mypy requirement (#456)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-21T05:25:40Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e77642106c0acb4a74997d047e7ecee2ea3d0e21",
"body": "Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6 to 7.\n- [Release notes](https://github.com/actions/setup-python/releases)\n- [Commits](https://github.com/actions/setup-python/compare/v6...v7)\n\n---\nupdated-dependencies:\n- dependency-name: actions/setup-python\n dependency-\n[…]\nirect:production\n update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): Bump actions/setup-python from 6 to 7 (#464)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-21T05:25:07Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a2c2172f6b34e6f866a3c65e596f0e7299e7f093",
"body": "* docs(readme): highlight adaptive monitoring, OMARS/optimal DOE, sensory; soften sklearn framing\n\nRefresh the front page for recent releases: add a What's new section and\nnew quick-start snippets for on-line monitoring with AdaptivePCA and for\nOMARS / D-optimal designs. Reframe the scikit-learn sec\n[…]\nive examples\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01X762hoccCvqtJuDgwUf6BH\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Update README + docs landing for recent releases (#465)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-21T05:24:45Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2a9df036c951d4253f5286d005a9897a2d1751fa",
"body": null,
"is_bot": false,
"headline": "Adaptive (recursive) PCA and PLS for on-line process monitoring (#443)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-19T21:59:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4d4a6f435521833d4178807e6997f721a6aa9c12",
"body": null,
"is_bot": false,
"headline": "Make descriptive validation tolerant of real panel/covariate data (#458)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-14T05:12:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d25c06532b41a8080a55f3ba17700c4024fef3ea",
"body": "…amilies (#455)\n\n* Add fixed_runs augmentation to generate_design for optimal families\n\ngenerate_design(..., fixed_runs=<DataFrame>) holds a set of runs fixed while the\npyoptex coordinate exchange optimizes the rest, forwarding to pyoptex's\ncreate_parameters(prior=...). The fixed runs occupy the fir\n[…]\n3.0; CITATION and CHANGELOG updated.\n\n* Cover fixed_runs validation branches (non-DataFrame, empty, non-numeric, multi-run, pyoptex-required)\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add fixed_runs (design augmentation) to generate_design for optimal f…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-11T17:58:31Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "936a314b43b40952e794d96d1df376651cc72b0e",
"body": "The SPE reconstruction was built as scores @ self._x_loadings.T on the scores\nDataFrame, which relabelled the result columns 0..K-1. With named (string)\nfeature columns the following X - X_hat subtraction then aligned by label to\nall-NaN and every SPE collapsed to 0; integer-labelled columns hid the\n[…]\nLS on named-column data and asserts\ndiagnose(X).spe matches the fitted spe_ (and is non-zero).\n\nBumps version to 1.52.4; CITATION and CHANGELOG updated.\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Fix PLS.diagnose().spe returning 0 for named-column X (#454)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-11T16:41:42Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e7197e3b9e28d6359c6a825dad640f5af26881f8",
"body": "…ADME, drop committed artifact (#451)\n\n* Start maintenance WP1: pytest and tooling hygiene (#448)\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01CynhA39u8mQeFWR3Ccf2UJ\n\n* Remove --pdb and --exitfirst from default pytest addopts (#448)\n\n--pdb \n[…]\n and Windows.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01CynhA39u8mQeFWR3Ccf2UJ\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Maintenance WP1: pytest addopts fix, linter dedup, stale CLAUDE.md/RE…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-11T05:44:27Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0358cf12f44975572d1761b1fcba26ad516837f8",
"body": "* Start test-coverage work: enable pyoptex and close coverage gaps\n\nEmpty commit to open the tracking PR. Upcoming commits add pyoptex to the\ndev dependency group (with uv override-dependencies to relax its plotly and\nnumba pins), rework the optimal-design fallback tests, add pyoptex-path\ntests, and\n[…]\nersedes #415.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_012KfWQwqC9Fm3K4eqQ5fzGt\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Boost test coverage: enable pyoptex in CI and close measured gaps (#436)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-10T04:57:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "295033227654e67c86074c86aee04c27e376d189",
"body": "* Declare pyoptex as an optional extra and alias optimality metrics\n\nAdd a `pyoptex` optional-dependency extra (`process-improve[pyoptex]`,\nalso folded into `[all]`), so the coordinate-exchange I-/A-optimal and\nhard_to_change split-plot designs have a declared install path like the\nother heavy optio\n[…]\n this PATCH.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01TvUM1DPgi2S3JFLjRJTJWj\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Alias optimality metrics and clarify the pyoptex install path (#447)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-09T21:54:13Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "6aca6e542218d80778d546fc210894aa5220634c",
"body": "…ss (#446)\n\nGenerating and evaluating a design with a categorical factor alongside\ncontinuous ones previously required dropping to pyoptex and patsy by hand.\nThis wires it through the public API:\n\n- generate_design forwards model_type to the optimal dispatchers (it was\n accepted by dispatch_{d,i,a}\n[…]\nror.\n\nBump 1.51.5 -> 1.52.0 (new feature); sync CITATION.cff and CHANGELOG.md.\n\n\nClaude-Session: https://claude.ai/code/session_01TvUM1DPgi2S3JFLjRJTJWj\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Make mixed-level (categorical + continuous) optimal designs first-cla…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-09T21:53:15Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "799a3cab082231850b0bbef4ac78d77954f6719b",
"body": "…ag unenforced options (#445)\n\n* DOE consistency: drop RunOrder/Block, allow categorical contrasts, flag unenforced options\n\nFour small independent fixes to the designed-experiments module:\n\n- analyze_experiment no longer treats the design-bookkeeping columns\n RunOrder and Block as model factors wh\n[…]\new DOE tests\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01TvUM1DPgi2S3JFLjRJTJWj\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "DOE consistency: drop RunOrder/Block, allow categorical contrasts, fl…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-09T21:52:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "000dd6c1447f4d9d8b2c15b472b73900b6ea82fe",
"body": "…444)\n\nWhen scale=True, PLS fits NIPALS in the internally standardized space and\nmaps predictions_ / beta_coefficients_ back to original units. rmse_ was\nleft in the standardized space, so a scale=True fit on unscaled data\nreturned an RMSE in units of a Y standard deviation, inconsistent with\npredic\n[…]\nly, are unchanged.\n\nBump 1.51.3 -> 1.51.4; sync CITATION.cff and CHANGELOG.md.\n\n\nClaude-Session: https://claude.ai/code/session_01TvUM1DPgi2S3JFLjRJTJWj\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Report PLS.rmse_ (and prediction_interval) on the original Y scale (#…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-09T21:47:55Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2d16e7b6cf2368ed9fb5c93f7355c96ae5b18cd4",
"body": null,
"is_bot": false,
"headline": "Fix PLS(scale=True) to actually scale the X and Y blocks (#442)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-09T04:49:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "01bf600b9b92b4f459515fb8b30d4e6e4488d649",
"body": "The OLS estimator and the Huber-T fit_robust_lm helper were listed in\nprocess_improve.regression.methods.__all__ but not re-exported by the\npackage __init__, so `from process_improve.regression import OLS`\nraised ImportError while the three other regression helpers imported\nfine. The least squares c\n[…]\n\nVersion 1.51.0 -> 1.51.1 (patch), CITATION.cff synced, changelog entry\nadded.\n\n\nClaude-Session: https://claude.ai/code/session_01VCJ1WYunYpnLKgKi7bhEMT\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Export OLS and fit_robust_lm from process_improve.regression (#438)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-05T07:14:10Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0d3ad1c26f40581b4ed800eed15c4a6c8bed6c5a",
"body": "Docstring/comment-only changes across multiple modules; no runtime\nbehaviour changes:\n\n- MBPCA class docstring (_mbpca.py): drop phantom super_vip_ entry from\n fitted-attributes list; fit() only populates block_vip_.\n- TPLS class docstring example (_tpls.py): wrap all_data dict in\n DataFrameDict(a\n[…]\ntching the style\n of the other parameters.\n\nCITATION.cff version + date-released bumped to match, CHANGELOG.md\ngains a 1.51.1 section under Unreleased.\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Fix docstring drift surfaced by audit (v1.51.1) (#437)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-07-03T22:14:27Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "751c8d779d35fe4b5aa3ac003900065c006f601c",
"body": "* Add reusable analysis-recipe framework and sensory recipes\n\nA package-wide recipe framework (process_improve/recipes.py): frozen\nRecipeStep / AnalysisRecipe dataclasses, a register_recipe registry with\nlazy discover_recipes (mirroring discover_tools), a substring cue matcher\nselect_recipe, and a g\n[…]\nis a registered tool), and the select_analysis_recipe tool\npath. MINOR version bump for the new feature, with CITATION and CHANGELOG in\nsync.\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Reusable analysis-recipe framework with sensory recipes (#434)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-30T07:06:50Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3319698bba521f97ee84bbeec11f66dfafa983ae",
"body": null,
"is_bot": true,
"headline": "chore(deps): Bump codecov/codecov-action from 6 to 7 (#412)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-30T06:22:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6251178d2e54e12bc58ae929a887126d1642a4af",
"body": "…tep (#433)",
"is_bot": false,
"headline": "Sensory: cross-validated discriminator for the observational relate s…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-30T06:21:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "01869b896862f17384d5c1f99e562fd1beb3a230",
"body": "…(#432)",
"is_bot": false,
"headline": "Sensory: ignore-columns reshape option + end-to-end tutorial example …",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-30T03:12:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4c9967f11bb166202995b4a6635541238d6c559f",
"body": "…nel check, relate) (#430)\n\n* Scaffold sensory subpackage for descriptive panel-data analysis\n\nAdd the package skeleton for a generic descriptive panel-data pipeline:\nvalidate, panel-anomaly check, and relate attributes to the product (designed\nor observational). Subsequent commits fill in the modul\n[…]\n Test added.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01UwuQz5XGKg9ArqCQEhQkPh\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add sensory subpackage: descriptive panel-data pipeline (validate, pa…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-29T19:54:40Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "00f4be4592ebced53acfbd7b9bc923d5c97b5564",
"body": null,
"is_bot": true,
"headline": "chore(deps): Bump actions/checkout from 6 to 7 (#428)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-27T21:39:26Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "260018dbf5f0e86da83fdb1cdcc97b998e49840b",
"body": "…#427)\n\nThe OMARS ILP generator selected a half-design by a pure feasibility (or\nminimize-size) solve, then ranked a handful of near-identical designs found\nwith no-good cuts. That sample was tiny and undiverse, so the generator\nmissed the high-efficiency members the enumerated OMARS catalogue conta\n[…]\nthe max_candidates floor.\n\nBump to 1.48.0; sync CITATION.cff and CHANGELOG.md.\n\n\nClaude-Session: https://claude.ai/code/session_01M7mKa66G9JcUGPaVUcYRm9\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Make generate_omars competitive via randomized-objective multistart (…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-22T12:56:29Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4667e2b7e4b05d5e6b19921e32fe36c4d3d7d44f",
"body": "* Reconcile OMARS entry points and add reduced-model ILP sizing\n\nTwo related OMARS changes so the library can build the mid-spectrum members\nused in the book, not only the minimal foldover.\n\n1. generate_design(design_type=\"omars\", budget=N) now routes to the ILP\n enumerator (a thin wrapper over de\n[…]\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01M7mKa66G9JcUGPaVUcYRm9\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Reconcile OMARS entry points and add reduced-model ILP sizing (#426)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-22T04:48:54Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "79736ff4b246c427ac74e5338ee4c0858033ad32",
"body": "* Add generate_omars(): integer-programming OMARS design generator\n\nThe existing design_type=\"omars\" only builds the minimal conference-foldover\nmember (2k+1 / 2k+3 runs), which is saturated for a full second-order model so\nanalyze_omars() has no error degrees of freedom. This adds generate_omars()\n\n[…]\n raised when no enumerated design meets the thresholds, or when an\nunknown threshold key is supplied. Documents the parameter and adds tests.\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add generate_omars(): integer-programming OMARS design generator (#425)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-21T11:37:59Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0a3debcda61f8a14d8674444bb1e0eafcfc4b1ce",
"body": "…gn (#424)\n\nThe existing recovery tests use a face-centered CCD, whose quadratic terms\nare aliased, so a spurious second-order term or two can be flagged. Add a\nfull 3-level factorial fixture whose second-order columns are mutually\northogonal (zero aliasing, verified via the Gram matrix), the zero-a\n[…]\nar main effect\n\nThis is the cleanest available stand-in for a true OMARS design until a\ncatalogued OMARS generator is in place. Bumps version to 1.45.1.\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Test analyze_omars() exact recovery on an orthogonal three-level desi…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-21T09:28:53Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d5c07c76c0d3957996747c9829b454496785a572",
"body": null,
"is_bot": false,
"headline": "Add analyze_omars() for staged analysis of OMARS-design data (#416)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-20T21:57:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9e74f060792c9f217949a3b2451afb42a7e4293b",
"body": "Add a \"Evaluating Design Quality\" user-guide page covering evaluate_design: the\noptimality/efficiency metrics, the residualised term-correlation summary, the\ngeneral alias (bias) matrix, prediction variance and the FDS curve, power, the\nseeded region-sampling controls and their reproducibility, and \n[…]\nl metric list, metric=\"all\",\nand the region / FDS parameters). Bump to 1.44.1.\n\n\nClaude-Session: https://claude.ai/code/session_01RxmJV48DXSRmrqZKcwjhat\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Document the design-evaluation metrics and FDS curve (#423)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-20T07:51:32Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "61c98329be49eee816803156b497eb40e6a1229d",
"body": "* Add tunable-resolution FDS curve to evaluate_design\n\nThe fds metric returned only an 11-point quantile summary. Add an optional\nfds_resolution parameter (threaded through evaluate_design, evaluate_all, and\nthe evaluation context): when set, the fds payload gains a dense `curve`\nsub-dict with lengt\n[…]\nroject.toml.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01RxmJV48DXSRmrqZKcwjhat\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Tunable-resolution FDS curve in evaluate_design (#422)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-20T07:39:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5750607773350cc60a542656ab2b7a0b193bbe1d",
"body": "…(#421)\n\n* Start: complete model-aware design-evaluation metric set\n\nScaffolding commit for the evaluate_design metric expansion: A/E-optimality,\nterm correlation, general alias matrix, FDS curve, metric=\"all\", and the\ni/g-efficiency model-mismatch fix.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anth\n[…]\nroject.toml.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01RxmJV48DXSRmrqZKcwjhat\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Complete model-aware design-evaluation metric set in evaluate_design …",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-20T01:00:37Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "278cf63e1431ff40a9449511afba0d153dd2c3b2",
"body": "…) (#420)\n\n* Fix typo in center() docstring: 'but' -> 'must'\n\n* Add Returns section to scale() docstring\n\n* Fix TPLS d_matrix docstring type to match flat-dict validation\n\n* Clarify spe_ attribute docstring in PCA and PLS\n\n* Document control chart variant strings in lowercase and note case-insensitive comparison\n\n* Bump version to 1.41.1 and update changelog\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Resolve conflicts for #418: docstring fixes rebased onto main (1.42.1…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-19T22:08:28Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "ae89a75ad7c6c7e5d1e92fd4421b8ab2b5776c4f",
"body": "* Start: resolution-V fractional cube for CCD generator\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014G7BGizqABL4d1LbNDGbBn\n\n* Add fractional resolution-V cube option to the CCD generator\n\ngenerate_design(design_type='ccd', cu\n[…]\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014G7BGizqABL4d1LbNDGbBn\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add resolution-V fractional cube option to the CCD generator (#419)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-19T21:24:25Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "cafc3fa71f4d5874288084fafd2cc7d747edb1bc",
"body": "* Add OMARS designs: constructive generator and property verifiers\n\nAdd OMARS (Orthogonal Minimally Aliased Response Surface) designs as a\nfirst-class design type in the experiments module.\n\n- designs_omars.py: dispatch_omars() builds the conference-matrix foldover\n family (the definitive screening\n[…]\nthat exercise the\ndefensive branches directly, bringing the module to full coverage.\n\n* Fix spelling of author Núñez Ares in OMARS references\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add OMARS designs: constructive generator and property verifiers (#417)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-15T21:29:45Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b1fdb5954e14368c15a3a514754f5585885e367d",
"body": "… vary\n\nA symmetric warm-up residual distribution can yield MAD = 0 even though\nthe data has real variability, which previously tripped the\nzero-variance guard and produced undefined control limits. Fall back to\nthe standard deviation in that case; a genuinely constant window still\nraises.\n\nBump version to 1.40.2 and update CITATION.cff + CHANGELOG.md.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "ControlChart warm-up: fall back to std when MAD is zero but residuals…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-12T08:32:21Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "a88bac292ca8979a991b3af68c11c6d1c46cb8bf",
"body": "* Stop mutating global Plotly default template on import\n\nprocess_improve.visualization sets plotly.io.templates.default on\nimport, silently restyling every other Plotly user in the same\nprocess. Fix incoming: register themes (additive) but do not set the\nglobal default.\n\nCo-Authored-By: Claude Opus\n[…]\no 1.40.1; changelog for global Plotly default fix\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Stop mutating global Plotly default template on import (#413)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-11T11:44:24Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7c34ca77b2197ec6af81dbc5fe5562fd38d5eea8",
"body": "…#411)\n\n* WIP: PLS sample_weight (#394)\n\nhttps://claude.ai/code/session_01CD8jKbCmCEsa3qN8XGcRcs\n\n* PLS.fit accepts sample_weight via sqrt(w) NIPALS rescale (#394)\n\nAdds weighted PLS via row-weighting of the NIPALS cross-products.\nThe implementation uses the sqrt(w) identity: rescaling X and Y by\nsq\n[…]\nponents and nested_cv.\nSame per-fold-subset pattern applies; left as a future scope.\n\nhttps://claude.ai/code/session_01CD8jKbCmCEsa3qN8XGcRcs\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "PLS.fit(sample_weight=...) via sqrt(w) NIPALS rescale (closes #394) (…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-08T05:36:35Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "85c8e7cece49d510a2b60383e07234e4e78b09e2",
"body": null,
"is_bot": false,
"headline": "Add q2_se (Q2-scale standard error) to the component selectors (#410)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-07T20:56:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ca57884c799a64352b0bd5e22ddb6a611b1bb32c",
"body": "The three multiblock classes followed the same antipattern that #406\nremoved from PCA: predict() returns a rich diagnostics Bunch rather\nthan the sklearn-convention ndarray/DataFrame. For the regressors\n(MBPLS, TPLS) this notionally blocks Pipeline / cross_val_score /\nGridSearchCV interop, though TP\n[…]\n4 (PATCH; deprecation, no removal yet).\nCHANGELOG.md / CITATION.cff updated in the same commit.\n\nhttps://claude.ai/code/session_01CD8jKbCmCEsa3qN8XGcRcs\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "diagnose() on MBPLS / MBPCA / TPLS, deprecate predict (#395) (#409)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-07T20:02:01Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c7e5b346e1e19dccffc1f7609c385965c4757bee",
"body": "make_column_transformer + HalvingGridSearchCV (closes #397, #399, #398)\n\nThree \"drop the estimators into a more demanding sklearn composition\nand check it works end-to-end\" tests, all spun out of the audit in\n#383. Each issue posited that something would probably surface; in\npractice nothing did - t\n[…]\nn 1.38.2 -> 1.38.3 (PATCH; tests only). CHANGELOG.md /\nCITATION.cff updated in the same commit.\n\nhttps://claude.ai/code/session_01CD8jKbCmCEsa3qN8XGcRcs\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "sklearn-interop verification: TransformedTargetRegressor + (#408)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-07T19:42:42Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a84b1c08c35d2677df8e2ab97b0d815c50fa667d",
"body": "PCA, PLS, and MCUVScaler already expose feature_names_in_ as a\nside-effect of validate_data(reset=True) (landed in #402). The\nmultiblock estimators don't go through validate_data because their\ninput is a dict[str, DataFrame], so they were missing the public\nsklearn-convention attribute even though n\n[…]\nion 1.38.1 -> 1.38.2 (PATCH; additive). CHANGELOG.md / CITATION.cff\nupdated in the same commit.\n\nhttps://claude.ai/code/session_01CD8jKbCmCEsa3qN8XGcRcs\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feature_names_in_ on MBPCA / MBPLS (#392) (#407)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-07T17:36:07Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "bba7100b3c30bfa012119adf26adf90921d9ad38",
"body": "PCA.predict historically returned a Bunch(scores, hotellings_t2, spe),\nwhile PLS.predict returns y_hat and PLS.diagnose returns the rich\nBunch. The asymmetry is the issue: same name, different contract.\n\nThis commit renames the existing PCA.predict logic to PCA.diagnose\n(matching PLS.diagnose), and \n[…]\n1 (PATCH; deprecation, no removal yet).\nCHANGELOG.md / CITATION.cff updated in the same commit.\n\nhttps://claude.ai/code/session_01CD8jKbCmCEsa3qN8XGcRcs\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "PCA.diagnose (alias of predict), deprecate PCA.predict (#396) (#406)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-07T17:01:06Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "99b002449aaa87266ee6a24e489b3270ac3e1b4b",
"body": "Adds three small get_feature_names_out methods so the sklearn 1.2+\nset_output mechanism, Pipeline introspection, and ecosystem tools\n(SHAP, eli5, model-card libraries) can resolve the output column\nnames of these estimators.\n\n- MCUVScaler.get_feature_names_out(): column-preserving; returns the\n fit\n[…]\nATIBILITY.md updated. Full multivariate suite green\n(162 passed, 1 skipped). Lint + mypy clean.\n\nhttps://claude.ai/code/session_01CD8jKbCmCEsa3qN8XGcRcs\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "get_feature_names_out on MCUVScaler / PCA / PLS (#391) (#405)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-07T16:28:44Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "77893f46369f0417da0ddba1b762c87b65ec4f46",
"body": "… (#393) (#403)\n\nAdds __sklearn_tags__ overrides on each of the three sklearn-fluent\nmultivariate estimators so sklearn 1.6+ resolves their capability tags\ncorrectly:\n- MCUVScaler: input_tags.allow_nan = True. fit/transform use\n np.nanmean / np.nanstd and pass NaN through unchanged.\n- PCA: input_ta\n[…]\nATIBILITY.md updated. Full multivariate suite green\n(161 passed, 1 skipped). Lint + mypy clean.\n\nhttps://claude.ai/code/session_01CD8jKbCmCEsa3qN8XGcRcs\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "__sklearn_tags__ for MCUVScaler / PCA / PLS + fix PLS NaN-fit TSR bug…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-07T15:02:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4bf8af8f32af6b74e0333af285fe950a7ff486fa",
"body": "…1) (#402)\n\n* Lint fix carried forward from the audit branch into #401\n\nPR #400 merged before commit 1427ba9 (the lint follow-up) had landed,\nso main is currently failing ruff on tools/check_estimator_audit.py.\nRe-apply the same three changes here so CI on this branch is green:\n\n- Add tools/** to pe\n[…]\nefore never read; CodeQL flagged it.\n\nRemoved the capture and the dead reassignment.\n\nhttps://claude.ai/code/session_01CD8jKbCmCEsa3qN8XGcRcs\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Route fit/predict/transform through sklearn.validate_data (closes #40…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-07T14:48:49Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2665e29640ef46c20e25d335b3aaaf2d46a1ae0c",
"body": null,
"is_bot": false,
"headline": "tools: add check_estimator audit script + main-branch baseline (#400)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-07T14:03:32Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2f34af7fff62f4eefcfd46c32cf80b52eee69426",
"body": "… (closes #383) (#390)\n\n* Partial sklearn Pipeline interop for MCUVScaler + PCA / PLS (#383)\n\nAudit-driven fixes from writing end-to-end Pipeline / cross_val_score /\nGridSearchCV tests. Two small, non-breaking fixes land here; the third\n(PLS.predict's rich Bunch return type) is architecturally signi\n[…]\ngressorMixin, so its\npredict()-returning-Bunch is not a sklearn-contract violation).\n\nhttps://claude.ai/code/session_01CD8jKbCmCEsa3qN8XGcRcs\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "sklearn Pipeline interop: PLS.predict -> ndarray + PLS.diagnose Bunch…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-07T12:51:56Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "781fb94706eda9a120c2376540a6d386a42ef7d8",
"body": "…389)\n\n* Add nested CV for an honest PLS performance estimate\n\nCloses #381.\n\nAdds PLS.nested_cv: outer loop splits the data; inner loop runs\nPLS.select_n_components on each outer-train to pick the component\ncount for that fold; a final PLS is fit on the outer-train at that\ncount and predicts the out\n[…]\n_cv splitter (KFold instance, not int).\n\nThis commit adds one focused test for each.\n\nhttps://claude.ai/code/session_01CD8jKbCmCEsa3qN8XGcRcs\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add nested CV for an honest PLS performance estimate (closes #381) (#…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-07T11:41:58Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e3910ccd2799a222d8e7d289f1b6c10136500609",
"body": "Closes #380.\n\nWhen selection_rule is \"1se\" or \"min\" and n_repeats > 1, the chosen\nrule is re-applied to each repeat's slice of per-fold RMSE values; the\ndistribution of votes is tabulated as an uncertainty signal.\n\nA concentrated distribution flags a confident recommendation; a flat\nor multi-modal o\n[…]\n3.0; CITATION.cff and CHANGELOG updated.\nFull multivariate suite green (151 passed, 1 skipped).\n\nhttps://claude.ai/code/session_01CD8jKbCmCEsa3qN8XGcRcs\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Stability-selection diagnostic on PLS.select_n_components (#388)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-07T11:20:29Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c8ba66ba293a1105593f4a6f29886644a32ca3b6",
"body": "Closes #379.\n\nAdds a fourth selection_rule alongside the existing 1se / min /\nq2_increment. Van der Voet (1994, Chemom. Intell. Lab. Syst.\n25(2):313-323) compares each candidate model against the argmin-RMSECV\nreference under the null that the two have the same predictive ability;\nit picks the small\n[…]\n2.0; CITATION.cff and CHANGELOG updated.\nFull multivariate suite green (150 passed, 1 skipped).\n\nhttps://claude.ai/code/session_01CD8jKbCmCEsa3qN8XGcRcs\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add Van der Voet's randomization test as a PLS selection rule (#387)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-07T10:28:05Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "73dea6a4f2d29b7e66f1c21c95e2a6099a382268",
"body": "…-checks (#386)\n\nCloses #378.\n\nTwo cheap, principled cross-checks for the ekf-CV recommendation from\nPCA.select_n_components, plus a consensus mode that surfaces all three\nside by side.\n\nAdditions\n- PCA.minka_mle(X) -> int: Minka (2000) closed-form Bayesian model\n selection on the PPCA evidence. Wr\n[…]\n1.0; CITATION.cff and CHANGELOG updated.\nFull multivariate suite green (149 passed, 1 skipped).\n\nhttps://claude.ai/code/session_01CD8jKbCmCEsa3qN8XGcRcs\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add Minka MLE and Horn parallel analysis as PCA component-count cross…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-07T10:00:08Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "181ec37c368f2a3a7e6520b2268e768df9dfcba7",
"body": "…oses #382) (#385)\n\n* Port repeated K-fold + in-fold scaling from PR #376 to PCA ekf CV\n\nCloses #382.\n\nFinishes the PCA cross-validation story started in #384 (which landed\nthe ekf algorithm itself per Bro 2008), bringing the PCA selector to\nfeature parity with PLS.select_n_components.\n\nChanges\n- _p\n[…]\nnitialisation outside the branch and skip the in-fold\nfit work entirely under False.\n\nhttps://claude.ai/code/session_01CD8jKbCmCEsa3qN8XGcRcs\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Port repeated K-fold + in-fold scaling from PR #376 to PCA ekf CV (cl…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-07T08:42:06Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3146dce8b7f8cb0399e4c343f261210440f3da2d",
"body": "…#384)",
"is_bot": false,
"headline": "Replace row-wise PCA CV with element-wise k-fold (ekf) per Bro 2008 (…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-07T08:21:34Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1ffd5c0f33721d0aba372988796c8c63a373f725",
"body": "…ling (supersedes #371) (#376)",
"is_bot": false,
"headline": "Step up PLS cross-validation: 1-SE rule, repeated K-fold, in-fold sca…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-07T07:51:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a9203d4be78994a0a84cca1a36c0e2a0a74d2013",
"body": null,
"is_bot": false,
"headline": "Fix publish workflow SBOM flag (--outfile -> --output-file) (#370)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-06T08:00:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "52855ffb940934cbb1847eab6fe693be26bc6a43",
"body": "…369)",
"is_bot": false,
"headline": "Add canonical T² and SPE per-variable contributions to PCA and PLS (#…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-06T07:31:01Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "525d4d02a7d873e035d228fcab92c99e4f913631",
"body": null,
"is_bot": false,
"headline": "Security/maintenance audit pass: SEC-34..SEC-37 (v1.25.2) (#367)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-06T07:16:28Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "dffba7ec0943d5287f02b1baa01323556bab6822",
"body": "…t (#368)",
"is_bot": false,
"headline": "Fix multivariate scale/selector inconsistencies surfaced by ScorePilo…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-06T06:55:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "40b82c3f4db3716001bacc712657efdcdeced7b9",
"body": "* plan: docstring/implementation mismatch audit\n\n* docs: fix median_absolute_deviation default scale in docstring\n\nThe docstring claimed the default was 1.0, but the actual signature\ndefault is 'normal'. Update the docstring to match the function and to\nexplain the consistency factor more clearly.\n\n\n[…]\nt /\nTPLS.predict Bunch fields, and Model.summary side-effect description.\n\nCHANGELOG.md and CITATION.cff updated in sync with pyproject.toml.\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: fix docstring/implementation mismatches (#366)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-05T07:26:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8c081c65597adc0d217caff5927308d437ae81dd",
"body": "Ground the remaining TPLS gaps in Garcia-Munoz (2014):\n\n1. D-block scaling (section 2.1): block-scale each D-block by 1/sqrt(P_i * M_i)\n instead of 1/sqrt(M_i), driving trace(X_i^T X_i) ~= 1 per block and removing\n bias toward blocks with more lots or properties. The old factor left\n trace = P\n[…]\n V^T S ~= I, so deflated and default coincide; they differ for the F-block.\n\n3. Store the D-block scaling factor as a scalar and expose it read-only via the\n d_block_scaling_ property.\n\nCloses #192.",
"is_bot": false,
"headline": "#192: paper-faithful TPLS D-block scaling + deflated VIP variant (#365)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T19:39:52Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4f79525d83bf8a6bd770d043e39c9d75da8e51bc",
"body": "… (#364)\n\nRemove a stale TODO: scratch block leaking into TPLS.help() output (the listed\nattributes are methods now, per ENG-05) and add a .vip() line. Add test coverage\nfor the previously-untested feature_importance / vip() surface (structure, finite\nnon-negative VIPs, feature-name indexing, vip() \n[…]\nr and error cases),\npinning the current VIP-based behaviour so the open deflated-matrix question in\n#192 can be settled deliberately.\n\nThe scaling-vector and deflated-matrix items of #192 remain open.",
"is_bot": false,
"headline": "#192 (part 1): TPLS feature_importance test coverage + help() cleanup…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T19:13:34Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f4f28c50044cd0c3ffbf57cc72f339bdccb7db79",
"body": "…363)\n\nalign_with_path averages the batch samples mapping to the same reference index\n(a warping-path compression). The running accumulator was seeded from an\ninitial_row argument - a reference row in dtw_core, an out-of-space batch row in\nthe interpolation caller - so the row-0 average mixed in an \n[…]\nemove the misleading initial_row parameter from both callers.\nAdds direct align_with_path unit tests.\n\nRefs #197 (the page-181 averaging generalisation and band / Sakoe-Chiba\nconstraints remain open).",
"is_bot": false,
"headline": "Fix #197: don't contaminate row-0 of DTW batch-alignment averaging (#…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T18:39:45Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "6631fad2296bd57c665e7234590ea73a8c83c253",
"body": "PCA and PLS NIPALS seeded the score iteration from the arbitrary first column.\nSeed instead from the column with the greatest sum-of-squares (variance, for\ncentred data), reusing the start_ss_col / start_SSY_col arrays already computed.\nNIPALS converges to the same component for any non-degenerate s\n[…]\ns the sign, so the fitted result is unchanged\n(full multivariate suite, incl. reference and property tests, stays green); the\nhighest-variance column is simply the best-conditioned seed.\n\nCloses #195.",
"is_bot": false,
"headline": "#195: seed NIPALS from the highest-variance column (#362)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T18:04:53Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "53d0e77983d2fb8a47e985e7ba2cd02032845524",
"body": "…361)\n\nPCA and PLS only checked the column count of data passed to transform/predict,\nso a correctly-shaped frame with reordered or renamed columns was projected\npositionally (PCA) or silently label-aligned to all-NaN (PLS). Add a shared\n_align_to_fit_features helper (mirroring sklearn's feature_nam\n[…]\nnnamed data keep count-only validation. Drop the redundant TODO in\nTPLS.predict (that per-block check already exists).\n\nRefs #195 (column-name-consistency item; NIPALS variance-optimal start remains).",
"is_bot": false,
"headline": "Fix #195: validate fit/predict feature-name consistency in PCA/PLS (#…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T17:52:46Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "89fe65739e1a5ccaca284387a97b06d08ce72294",
"body": "Refactor _select_screening_design (experiments/strategy/engine.py), which\ncarried # noqa: C901, PLR0912, PLR0915, into four focused helpers\n(_mixture_screening_stage, _factorial_screening_stage,\n_large_factor_screening_choice, _screening_design_params) and drop a dead\nlocal reasoning list (user-faci\n[…]\nSuppression count 68 -> 67.\n\nBump version to 1.24.30 (PATCH) and sync CITATION.cff + CHANGELOG.\n\nhttps://claude.ai/code/session_01JYy57y6F4BYtMgEoCLzbXW\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "ENG-25: chip away screening-design complexity suppression (#360)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T17:00:12Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "26a3d28f990d3a14b593627d7bc1118b8588af55",
"body": "DataFrameDict subclasses dict but stores all data in self.datadict, leaving the\ndict base empty, so the inherited dict.__eq__/__ne__ reported every instance as\nequal regardless of contents (CodeQL py/missing-equals). Add value-based\n__eq__/__ne__ (comparing block structure and each contained DataFra\n[…]\ninstances explicitly unhashable. __ne__ is defined\nexplicitly because the C-level dict.__ne__ would otherwise bypass the Python\n__eq__. Surfaced by CodeQL during the ENG-01 split (#342).\n\nCloses #343.",
"is_bot": false,
"headline": "Fix #343: value-based equality for DataFrameDict (#359)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T16:53:29Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "e896fdcb9d95f238d507a18b8990800fc463022f",
"body": "Generalises the single-tool fuzz template to every registered @tool_spec tool;\nderives a hypothesis strategy from each tool's input_schema and asserts\nexecute_tool_call never leaks an undocumented exception. Deterministic\n(derandomize=True) so it is a stable CI gate.\n\nFixes two real boundary leaks it found: control_chart AssertionError on\nconstant/degenerate data (now ValueError; also closes the SEC-17 -O gap), and\nfit_pca RuntimeError/IndexError on degenerate/empty data.\n\nCloses #297.",
"is_bot": false,
"headline": "ENG-15: MCP-boundary fuzz suite + fix the 2 leaks it found (#358)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T16:15:26Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "651317a80cacbfbbb5f9be9c2b68f5babf3f3822",
"body": "The 3.13t/3.14t matrix rows only ever failed at install: several deps (llvmlite\nvia numba, plus Rust-built deps like pydantic-core and some mcp transitives)\nlack free-threaded wheels and fail their source builds on the GitHub images.\nThey produced a permanent non-blocking red check with no signal, s\n[…]\ne ecosystem catches up; issue #43). Rebased onto main after the\nENG-03/ENG-20 typecheck change.\n\nhttps://claude.ai/code/session_01JYy57y6F4BYtMgEoCLzbXW\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "ci: remove the perpetually-failing free-threaded test rows (#356)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T15:40:26Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4ca3108dc304ecd613f0ede5e9113c40941a0803",
"body": "…357)\n\n* ENG-03: clear mypy errors in 7 modules (batch 1)\n\nBehaviour-preserving type fixes:\n- _analyses/model_selection: annotate current_terms once (no-redef)\n- _analyses/box_cox, analysis: np.asarray(...) instead of .values.astype(float)\n- monitoring/metrics: float()-wrap center/spread so _safe_ra\n[…]\nL unreachable code). Behaviour-neutral.\n\nmypy still 0; ruff clean; smoke tests pass.\n\nhttps://claude.ai/code/session_01JYy57y6F4BYtMgEoCLzbXW\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "ENG-03/ENG-20: drive mypy to zero; make typecheck a blocking check (#…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T15:32:26Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5632101418939acaee961009e39bf78bd4efbf87",
"body": "…deferred) (#355)\n\n* ENG-19: document the in-memory assumption and RAM limits\n\nPer the issue, the out-of-core code path is deferred (demand-driven); this\nmakes the 'production-grade' claim honest about scale. New docs/scaling.rst\nexplains the in-memory assumption, how to estimate memory (~rows x col\n[…]\nonly change (in-memory/scale documentation). Sync CITATION.cff and\nchangelog footer.\n\nhttps://claude.ai/code/session_01JYy57y6F4BYtMgEoCLzbXW\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "ENG-19: document in-memory assumption + RAM limits (out-of-core code …",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T11:20:10Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "389a6db5faabd6819b874dd41d357a62863d51dd",
"body": "* ENG-14: move to src/ layout; relocate examples out of the package\n\n- Move process_improve/ -> src/process_improve/ (uv_build now uses its default\n src module-root; the module-root=\"\" override is removed). No import changes:\n the package is still imported as process_improve.\n- Move process_improv\n[…]\nge). Sync CITATION.cff and\nchangelog footer; refresh the stale mypy-exclude comment.\n\nhttps://claude.ai/code/session_01JYy57y6F4BYtMgEoCLzbXW\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "ENG-14: adopt src/ layout; relocate examples out of the package (#354)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T11:11:22Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "56e72eaf0c72509426e55d2e7e8599093752dfcf",
"body": "…#353)\n\n* ENG-30: offload MCP tool dispatch to a worker thread\n\nThe FastMCP handler was async but called the synchronous tool path directly\n(blocking on a ProcessPoolExecutor future in safe mode, or running the tool\nin-process otherwise), serialising concurrent requests on the event loop.\nFactor the\n[…]\nlog entry\n\nSync CITATION.cff and changelog footer for the async MCP dispatch change.\n\nhttps://claude.ai/code/session_01JYy57y6F4BYtMgEoCLzbXW\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "ENG-30: offload MCP tool dispatch to a worker thread (non-blocking) (…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T10:46:03Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5df7bb72336ebc355bf35baa0dc72833af9c509a",
"body": "* ENG-26: add architecture overview + tool-authoring guide; link from README\n\nNew docs/architecture.rst (package layout, conventions, the multivariate\nestimator stack, the MCP tool layer, and a 'where to make a change' map) and\ndocs/development/tool_authoring.rst (step-by-step for adding an MCP tool\n[…]\nchitecture overview + tool-authoring guide). Sync\nCITATION.cff and changelog footer.\n\nhttps://claude.ai/code/session_01JYy57y6F4BYtMgEoCLzbXW\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "ENG-26: architecture overview + tool-authoring guide (#350)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T10:14:29Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5e3e3e2498b6ce4c200ffffff3c99687d48f07f0",
"body": "Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 8.\n- [Release notes](https://github.com/actions/download-artifact/releases)\n- [Commits](https://github.com/actions/download-artifact/compare/v4...v8)\n\n---\nupdated-dependencies:\n- dependency-name: actions/downlo\n[…]\nirect:production\n update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): Bump actions/download-artifact from 4 to 8 (#352)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-03T10:11:39Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "13479c0d267d4dc21b12c8d763dd5a8c2eb15499",
"body": "Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 7.\n- [Release notes](https://github.com/actions/upload-artifact/releases)\n- [Commits](https://github.com/actions/upload-artifact/compare/v4...v7)\n\n---\nupdated-dependencies:\n- dependency-name: actions/upload-artifac\n[…]\nirect:production\n update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): Bump actions/upload-artifact from 4 to 7 (#351)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-03T10:11:20Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "70c693f80b7de0aa597403c160c21a32e70a18f0",
"body": "* ENG-12: add module loggers + NIPALS convergence debug logs (multivariate)\n\nAdd module-level loggers to the multivariate algorithm modules and emit a\nlogger.debug at each component's NIPALS convergence (iterations + tolerance)\nfor PCA, PLS, the shared PLS inner loop (_nipals), MBPLS, MBPCA and TPLS\n[…]\ngelog entry\n\nSync CITATION.cff and changelog footer for the diagnostic-logging work.\n\nhttps://claude.ai/code/session_01JYy57y6F4BYtMgEoCLzbXW\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "ENG-12: module-level loggers + algorithm logging (targeted) (#349)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T07:39:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "32e02105dba4cb0a8197b5e553e1db3823cab426",
"body": "…iews (#348)\n\n* ENG-18: add _LazyFrame descriptor + pickle-excluded cache to the base\n\nNew _LazyFrame descriptor builds a cached pd.DataFrame view from a private\nndarray plus index/column metadata. _LatentVariableModel now also inherits\nBaseEstimator and overrides __getstate__/__setstate__ to drop t\n[…]\nnge (public DataFrame views byte-identical). Sync CITATION.cff\nand changelog footer.\n\nhttps://claude.ai/code/session_01JYy57y6F4BYtMgEoCLzbXW\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "ENG-18: ndarray-backed fitted attributes with lazy cached DataFrame v…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T07:06:51Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "bd7e0c66052dd7fcbbb8e517635f12779c95a495",
"body": "…e estimators (#347)\n\n* ENG-17: add _LatentVariableModel base + rename/hotellings mixins\n\nNew _base.py factors the duplicated PCA/PLS scaffolding into:\n_RenameGetattrMixin (migration __getattr__ via per-class _ATTRIBUTE_RENAMES),\n_HotellingsT2LimitMixin (the hotellings_t2_limit shared by PCA/PLS/MBP\n[…]\nntVariableModel base; no public API change).\nSync CITATION.cff and changelog footer.\n\nhttps://claude.ai/code/session_01JYy57y6F4BYtMgEoCLzbXW\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "ENG-17: shared _LatentVariableModel base class for the latent-variabl…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T06:30:52Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4c82418d5ff3c18f9d25857f8d0bb38298a308fd",
"body": "… compatibility (#346)\n\n* docs(ENG-05/ENG-07): correct CLAUDE.md architecture notes\n\n- Convenience methods are now real methods (ENG-05 #287), not functools.partial.\n- PLS does not inherit PLSRegression; it keeps only the sklearn mixins +\n BaseEstimator (ENG-07 #289). Note fitted attrs are set in f\n[…]\nog entry\n\nSync CITATION.cff and changelog footer for the sklearn-compat enforcement.\n\nhttps://claude.ai/code/session_01JYy57y6F4BYtMgEoCLzbXW\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "ENG-07: keep PLS decoupled from PLSRegression; enforce + test sklearn…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T05:56:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d11bc81aba863e72610454e67daf4fc30a0e02ed",
"body": "…s (#345)\n\n* ENG-05: add _model_method factory for introspectable bound methods\n\nPrecursor for replacing the functools.partial convenience bindings on the\nmultivariate estimators with real, introspectable methods (help/signature/\npickle/subclassing). See issue #287.\n\nhttps://claude.ai/code/session_0\n[…]\nnience\nmethods); no API or call-site change. Sync CITATION.cff and changelog footer.\n\nhttps://claude.ai/code/session_01JYy57y6F4BYtMgEoCLzbXW\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "ENG-05: replace functools.partial bindings with introspectable method…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T05:38:10Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1a7b4994d928cbdef6eb5ff7f676c1c95978774c",
"body": "* ENG-02: begin splitting experiments tools.py and analysis.py\n\nOpen PR up front. Subsequent commits extract each MCP tool wrapper into\nexperiments/_tools/ and each _run_* analysis into experiments/_analyses/,\nkeeping analyze_experiment() and tools.py as dispatcher/aggregator shims.\nThe MCP tool-spe\n[…]\nude.ai/code/session_01JYy57y6F4BYtMgEoCLzbXW\n\n* ENG-02: sort _tools __all__ (RUF022)\n\nhttps://claude.ai/code/session_01JYy57y6F4BYtMgEoCLzbXW\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "ENG-02: split experiments tools.py and analysis.py god modules (#344)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-03T05:06:56Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "29df1fb6254bc4b22718bfeb1efa2c62df6b5905",
"body": null,
"is_bot": false,
"headline": "ENG-01: Split the 6,210-line _pca_pls.py into focused submodules (#342)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-02T22:16:55Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "45f23058da00b2c14ff40112ef5dd5cb898fe0fa",
"body": "…g (#341)\n\nTwo internal helpers now take a single bundled options dataclass\ninstead of loose positional arguments. The arg count drops below\nthe PLR0913 threshold (5) and the suppression goes with it.\n\nevaluate.py::_build_context\n---------------------------\n9 args -> 1: bundles design_df, factor_nam\n[…]\nng ENG-25 count\nis now 65, down from 68 at the start of this release window.\n\nPATCH bump 1.24.12 -> 1.24.13. CITATION.cff in sync. No public API\nchange.\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor(ENG-25): chip away 2 noqa: PLR0913 via dataclass arg bundlin…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-02T20:54:53Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a0626cf18d28a573bf9b5261fac8ed58882ff0c1",
"body": "…pecific paths (#340)\n\n* refactor(ENG-23): rename ambiguous methods.py / models.py to domain-specific paths\n\nCloses #305. Four files in three packages all carried the generic\nname methods.py (and a similar models.py in experiments),\nhiding the domain and confusing filename-ranked tooling (Jump-to-\nF\n[…]\nDelete the unused SE_b0 walrus from the no-variation branch.\n\nFull pytest suite (1514 tests + 10 skipped) passes locally.\nruff check . clean.\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor(ENG-23): rename ambiguous methods.py / models.py to domain-s…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-02T20:41:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f97e297f12ad3a65a9c4a953a85dfd63f9b02866",
"body": "… / mcp / fast) (#339)\n\n* feat(ENG-13): split runtime deps into extras (plotting / expt / batch / mcp / fast)\n\nCloses #295. The runtime dependency closure shrinks from 16 packages\nto 8. pip install process-improve (core) now installs only\nnumpy, pandas, scikit-learn, statsmodels, patsy,\npydantic, py\n[…]\nno cover -\nexercised via env-without-... marker that the .coveragerc\nexclude_lines regex matches. Add it so coverage.py honors the\nexclusion.\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(ENG-13): split runtime deps into extras (plotting / expt / batch…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-02T20:06:59Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "6ab7ce0ef69020843f22329043ed0bd46bc88a14",
"body": "… (#338)\n\nCloses #303. The previous publish workflow auto-detected version\nchanges on push to main and shipped a PyPI release without a human\npress-the-button step. A typo in pyproject.toml could publish.\n\nThis PR:\n\n1. **Gates publishing on an explicit human action.** publish.yml now\n triggers onl\n[…]\n:\n1. Bump version in a PR; merge it.\n2. Push the matching v<version> tag (or click 'Run workflow').\n\nPATCH bump 1.24.9 -> 1.24.10. CITATION.cff in sync.\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(ENG-21): manual-gate release; add sigstore attestations and SBOM…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-02T17:56:26Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e75e0b3f044bf267c9a05eca18a3bcd6b8d54eb6",
"body": "… sub-items (#337)\n\nCloses #282. SEC-33 lists six small mechanical fixes; all six landed\nin code during the earlier engineering / security waves but four\nlacked dedicated regression tests. This PR adds the missing tests\nand closes the issue.\n\nTests added\n-----------\n- Sub-item 1 -- terminate_check_o\n[…]\nbsorbed into\n #206.\n\nPATCH bump 1.24.8 -> 1.24.9. Full pytest suite (1505 tests + 10\nskipped) passes locally. ruff check . clean. CITATION.cff in sync.\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "test(SEC-33): pin regression tests for 4 of 6 numerical / correctness…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-02T17:29:14Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "771ef1fa3369cfe8ad36e428af4a457b78912d2e",
"body": "…ore np.array allocation (#336)\n\n* fix(SEC-25): cap model_params arrays in pca_predict / pls_predict\n\nCloses #274. pca_predict and pls_predict previously took an unbounded\nmodel_params dict and read sizes straight into np.array(...).\nThe input schema was {type: object} with no inner shape, so an\natt\n[…]\none short-circuit fires, then asserts the validator does not\n itself raise (any subsequent failure is downstream of the SEC-25\n invariant).\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(SEC-25): cap model_params arrays in pca_predict / pls_predict bef…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-02T17:18:06Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "62059ec7deefc4d36f79e02c0fe34b18e0132c1f",
"body": "Closes #306. The pi_* attributes on Expt and Column carry library-managed\nmetadata; new readers had to grep the codebase to discover that the\nprefix stands for 'process-improve' and not, say, a math constant.\n\nCONTRIBUTING.md gains a 'Naming conventions' subsection covering:\n\n- The pi_ prefix on met\n[…]\nders at the CONTRIBUTING section.\n\nNote: stacked on PR #333 -> #334; rebases cleanly after both land.\nPATCH bump 1.24.6 -> 1.24.7. CITATION.cff in sync.\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(ENG-24): document the pi_ prefix and Expt class (#335)",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-02T16:47:03Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "edea6a1f99e92293ef5861b0009c0602bde7ecee",
"body": "…eError (#334)\n\n* fix(SEC-13): bound find_reference_batch cutoff loop; raise clear ValueError\n\nCloses #261. The previous code in find_reference_batch had an unbounded\ncutoff-relaxation loop:\n\n start_cutoff = 0.5\n spe_metrics = metrics[metrics['SPE'] < pca_second.spe_limit(conf_level=0.5)]\n while \n[…]\ns; this exercises (a) the cutoff-relaxation\nloop body, (b) the multi-batch index slicing return path, and\n(c) the list-return type assertion.\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(SEC-13): bound find_reference_batch cutoff loop; raise clear Valu…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-02T16:42:05Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3742a18b8ec7a6c253f082ad520b1cb99d08b063",
"body": "…nd ENG-27 (#333)\n\nInvestigation of the open audit-finding backlog found that seven items\nalready shipped code-level fixes during the engineering / security\nprogram but were never closed because they lacked dedicated regression\ntests. This PR adds the missing tests and closes the issues.\n\nTests adde\n[…]\n pydantic field.\n\nPATCH bump 1.24.4 -> 1.24.5. CITATION.cff in sync. Full pytest\nsuite (1490 tests + 10 skipped) passes locally. ``ruff check .``\nclean.\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "test: pin regression tests for 7 audit findings; close SEC-20/27-32 a…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-02T16:36:46Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "04379f8266e1b2f76e2b47e19572cba34a5ab523",
"body": "…ntic migration is complete (#332)\n\n* chore: open follow-up PR to delete the legacy input_schema= path\n\nNow that every @tool_spec uses input_model= (PR1 #328, PR2 #329,\nPR3 #330, PR4 #331), the legacy input_schema= parameter,\nvalidate_against_schema(), and _filter_to_declared_keys() can be\ndeleted. \n[…]\nule(), which\nis a pre-existing defensive path for missing optional dependencies\nthat would need import mocking to exercise; leaving it as-is.\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(ENG-04, ENG-10): delete legacy input_schema= path now that pyda…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-02T13:58:23Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "fa11056f64b3e92700cf2d218c770fc916e2b9b8",
"body": "…tion (PR4/N) (#331)\n\n* chore: open PR4/N for batch + visualization + simulation pydantic migration\n\nFinal tracking PR in the per-package pydantic @tool_spec roll-out\nestablished in PR1 (#328) and continued in PR2 (#329) and PR3 (#330).\nThis PR closes out the remaining tool surface: batch (1 tool),\n\n[…]\nydantic does not\npreclude; leaving them uncovered is fine.\n\nFull suite: 1492 passing (3 new tests added), 10 skipped, ``ruff\ncheck .`` clean.\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(ENG-04, ENG-10): pydantic-migrate batch + visualization + simula…",
"author_name": "Kevin Dunn",
"author_login": "kgdunn",
"committed_at": "2026-06-02T13:33:57Z",
"body_truncated": true,
"is_coding_agent": true
}
],
"releases_count": 100,
"commits_last_year": 282,
"latest_release_at": "2026-07-30T06:09:21Z",
"latest_release_tag": "v1.62.1",
"releases_from_tags": false,
"days_since_last_push": 0,
"active_weeks_last_year": 20,
"days_since_latest_release": 0,
"mean_days_between_releases": 4.2
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": true,
"health_percentage": 100,
"has_issue_template": false,
"has_code_of_conduct": true,
"has_pull_request_template": true
},
"ecosystem": {
"packages": [
{
"name": "process-improve",
"exists": true,
"license": "MIT",
"keywords": [
"Designed Experiments",
"Latent Variables",
"PCA",
"PLS",
"Multivariate Data Analysis",
"Batch data analysis",
"Development Status :: 4 - Beta",
"Intended Audience :: Science/Research",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Scientific/Engineering",
"Topic :: Scientific/Engineering :: Information Analysis"
],
"ecosystem": "pypi",
"matches_repo": false,
"registry_url": "https://pypi.org/project/process-improve/",
"is_deprecated": false,
"latest_version": "1.62.1",
"repository_url": "https://github.com/kgdunn/process_improve",
"versions_count": 254,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": 6802,
"first_published_at": "2019-10-03T07:26:25.746286Z",
"latest_published_at": "2026-07-30T06:09:19.094713Z",
"latest_version_yanked": null,
"days_since_latest_publish": 0
}
]
},
"popularity": {
"forks": 13,
"stars": 15,
"watchers": 2,
"fork_history": {
"days": [
{
"date": "2020-09-24",
"count": 1
},
{
"date": "2020-12-15",
"count": 1
},
{
"date": "2021-04-07",
"count": 1
},
{
"date": "2023-05-30",
"count": 1
},
{
"date": "2023-06-21",
"count": 1
},
{
"date": "2024-03-21",
"count": 1
},
{
"date": "2024-04-18",
"count": 1
},
{
"date": "2025-07-26",
"count": 1
},
{
"date": "2026-05-17",
"count": 2
},
{
"date": "2026-05-18",
"count": 1
},
{
"date": "2026-05-21",
"count": 1
},
{
"date": "2026-07-08",
"count": 1
}
],
"complete": true,
"collected": 13,
"total_forks": 13
},
"star_history": null,
"open_issues_and_prs": 50
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [
"examples",
"notebooks"
],
"has_llms_txt": false,
"has_dockerfile": false,
"has_mcp_signal": true,
"bootstrap_files": [
"Makefile",
"docs/Makefile"
],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [
"src/process_improve/py.typed"
],
"toolchain_manifests": [],
"largest_source_bytes": 202691,
"source_files_sampled": 239,
"oversized_source_files": 7,
"agent_instruction_files": [
"CLAUDE.md"
],
"agent_instruction_max_bytes": 13630
},
"dependencies": {
"manifests": [
"pyproject.toml"
],
"advisories": {
"error": "No resolved dependencies carried a version and a supported ecosystem",
"scope": "repository_graph",
"source": null,
"findings": [],
"collected": false,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 0,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 38,
"direct_affected_count": 0
},
"ecosystems": [
"pypi"
],
"dependencies": [
{
"name": "numpy",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=2.2.6"
},
{
"name": "pandas",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=2.3.3,<3.0"
},
{
"name": "patsy",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=1.0.2"
},
{
"name": "pydantic",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=2.12.5"
},
{
"name": "pyyaml",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=6.0"
},
{
"name": "scikit-learn",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=1.7.2"
},
{
"name": "statsmodels",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=0.14.6"
},
{
"name": "tqdm",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=4.67.1"
}
],
"all_dependencies": {
"error": null,
"source": "github-sbom",
"packages": [
{
"name": "numpy",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pandas",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "patsy",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pydantic",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pyyaml",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "scikit-learn",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "statsmodels",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tqdm",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "coverage",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "hypothesis",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "ipykernel",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "matplotlib",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "matplotlib-stubs",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "mcp",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "mypy",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "nbsphinx",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "numba",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "openpyxl",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pandas-stubs",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "plotly",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "plotly-stubs",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pre-commit",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pulp",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pydata-sphinx-theme",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pydoe3",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pyoptex",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pytest",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pytest-benchmark",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pytest-cov",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pytest-xdist",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "ridgeplot",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "ruff",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "scikit-image",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "seaborn",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "sphinx",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tqdm-stubs",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "uv-build",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "watchdog",
"direct": false,
"version": null,
"ecosystem": "pypi"
}
],
"collected": true,
"truncated": false,
"total_count": 38,
"direct_count": 8,
"indirect_count": 30
}
},
"maintainership": {
"issues": {
"open_prs": 15,
"merged_prs": 270,
"open_issues": 35,
"closed_ratio": 0.792,
"closed_issues": 133,
"closed_unmerged_prs": 25
},
"bus_factor": 1,
"bot_contributors": 2,
"top_contributors": [
{
"type": "User",
"login": "kgdunn",
"commits": 642,
"avatar_url": "https://avatars.githubusercontent.com/u/578383?v=4"
},
{
"type": "User",
"login": "claude",
"commits": 2,
"avatar_url": "https://avatars.githubusercontent.com/u/81847?v=4"
},
{
"type": "User",
"login": "hoechenberger",
"commits": 2,
"avatar_url": "https://avatars.githubusercontent.com/u/2046265?v=4"
},
{
"type": "User",
"login": "mars-hub",
"commits": 2,
"avatar_url": "https://avatars.githubusercontent.com/u/57363237?v=4"
},
{
"type": "User",
"login": "sisyphusse1-ops",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/280933538?v=4"
},
{
"type": "User",
"login": "pelssers",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/8984694?v=4"
}
],
"contributors_sampled": 6,
"top_contributor_share": 0.988
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"codeql.yml",
"docs.yml",
"publish.yml",
"run-tests.yml"
],
"has_docs_dir": true,
"linter_configs": [],
"has_editorconfig": true,
"has_linter_config": true,
"has_precommit_config": true
},
"security_signals": {
"lockfiles": [],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 10,
"reason": "no binaries found in the repo",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": 0,
"reason": "branch protection not enabled on development/release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": 10,
"reason": "30 out of 30 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 0/26 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": 10,
"reason": "update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 10,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 10,
"reason": "30 commit(s) and 30 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": 0,
"reason": "dependency not pinned by hash detected -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 10,
"reason": "SAST tool is run on all commits",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 10,
"reason": "security policy file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": 0,
"reason": "Project has not signed or included provenance with any releases.",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 0,
"reason": "detected GitHub workflow tokens with excessive permissions",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 10,
"reason": "0 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "2ab876fa8378e00e34c5d2b770b2f18b2582bdc2",
"ran_at": "2026-07-30T06:10:37Z",
"aggregate_score": 5.7,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": true,
"has_security_policy": true,
"has_dependabot_config": true
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-30T06:09:24Z",
"oldest_open_prs": [
{
"number": 414,
"created_at": "2026-06-12T07:20:24Z",
"last_comment_at": "2026-06-12T07:31:15Z",
"last_comment_author": "codecov"
},
{
"number": 435,
"created_at": "2026-07-01T20:21:18Z",
"last_comment_at": "2026-07-01T20:29:17Z",
"last_comment_author": "codecov"
},
{
"number": 452,
"created_at": "2026-07-10T22:10:20Z",
"last_comment_at": "2026-07-10T22:25:37Z",
"last_comment_author": "codecov"
},
{
"number": 453,
"created_at": "2026-07-10T22:20:34Z",
"last_comment_at": "2026-07-10T22:36:13Z",
"last_comment_author": "codecov"
},
{
"number": 459,
"created_at": "2026-07-16T20:59:17Z",
"last_comment_at": "2026-07-16T21:03:13Z",
"last_comment_author": "codecov"
},
{
"number": 460,
"created_at": "2026-07-16T22:09:13Z",
"last_comment_at": "2026-07-16T22:15:02Z",
"last_comment_author": "codecov"
},
{
"number": 461,
"created_at": "2026-07-16T22:23:18Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 462,
"created_at": "2026-07-16T22:34:01Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 463,
"created_at": "2026-07-17T07:22:12Z",
"last_comment_at": "2026-07-17T07:27:11Z",
"last_comment_author": "codecov"
},
{
"number": 469,
"created_at": "2026-07-23T11:22:23Z",
"last_comment_at": "2026-07-23T11:27:25Z",
"last_comment_author": "codecov"
},
{
"number": 472,
"created_at": "2026-07-24T07:26:41Z",
"last_comment_at": "2026-07-24T07:29:42Z",
"last_comment_author": "codecov"
},
{
"number": 473,
"created_at": "2026-07-24T07:39:00Z",
"last_comment_at": "2026-07-24T07:43:43Z",
"last_comment_author": "codecov"
},
{
"number": 475,
"created_at": "2026-07-25T06:19:13Z",
"last_comment_at": "2026-07-25T06:24:27Z",
"last_comment_author": "codecov"
},
{
"number": 477,
"created_at": "2026-07-27T21:24:02Z",
"last_comment_at": "2026-07-27T21:29:36Z",
"last_comment_author": "codecov"
},
{
"number": 479,
"created_at": "2026-07-30T05:54:38Z",
"last_comment_at": "2026-07-30T06:00:40Z",
"last_comment_author": "codecov"
}
],
"last_merged_pr_at": "2026-07-29T19:54:38Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": [
{
"number": 16,
"created_at": "2019-10-17T09:15:35Z",
"last_comment_at": "2026-05-22T21:48:19Z",
"last_comment_author": "kgdunn"
},
{
"number": 37,
"created_at": "2025-07-26T20:03:56Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 39,
"created_at": "2025-07-27T06:03:29Z",
"last_comment_at": "2026-05-22T21:48:29Z",
"last_comment_author": "kgdunn"
},
{
"number": 43,
"created_at": "2025-07-27T18:30:12Z",
"last_comment_at": "2026-05-22T21:48:32Z",
"last_comment_author": "kgdunn"
},
{
"number": 154,
"created_at": "2026-05-13T20:32:07Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 155,
"created_at": "2026-05-13T20:32:20Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 156,
"created_at": "2026-05-13T20:32:38Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 176,
"created_at": "2026-05-17T07:54:59Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 177,
"created_at": "2026-05-17T07:55:07Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 178,
"created_at": "2026-05-17T07:55:15Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 179,
"created_at": "2026-05-17T07:55:20Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 180,
"created_at": "2026-05-17T07:55:24Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 189,
"created_at": "2026-05-17T14:43:14Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 191,
"created_at": "2026-05-17T14:43:19Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 193,
"created_at": "2026-05-17T14:43:27Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 199,
"created_at": "2026-05-17T14:44:11Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 200,
"created_at": "2026-05-17T14:44:15Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 208,
"created_at": "2026-05-17T14:44:46Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 211,
"created_at": "2026-05-17T14:45:01Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 213,
"created_at": "2026-05-17T14:45:08Z",
"last_comment_at": null,
"last_comment_author": null
}
]
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/kgdunn/process-improve",
"host": "github.com",
"name": "process-improve",
"owner": "kgdunn"
},
"metrics": {
"overall": {
"key": "overall",
"band": "excellent",
"name": "Overall health",
"note": "The weighted overall 68 is calibrated to 80 on the published index scale (record calibration 2026-08-02).",
"notes": [
{
"code": "overall_calibration",
"params": {
"raw": 68,
"calibrated": 80,
"calibration": "2026-08-02"
}
}
],
"value": 80,
"inputs": {
"security": 57,
"vitality": 83,
"community": 58,
"governance": 46,
"calibration": "2026-08-02",
"engineering": 96,
"ai_readiness": 78,
"weighted_overall_raw": 68
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "excellent",
"name": "Vitality",
"value": 83,
"weight": 0.21,
"metrics": [
{
"key": "development_activity",
"band": "good",
"name": "Development activity",
"note": null,
"notes": [],
"value": 78,
"inputs": {
"commits_last_year": 282,
"human_commit_share": 0.94,
"days_since_last_push": 0,
"active_weeks_last_year": 20
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 0 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 0
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "20/52 weeks with commits",
"points": 13.8,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 20
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "282 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 282
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "30 commit(s) and 30 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": null,
"notes": [],
"value": 90,
"inputs": {
"releases_count": 100,
"latest_release_tag": "v1.62.1",
"releases_from_tags": false,
"days_since_latest_release": 0,
"mean_days_between_releases": 4.2
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "100 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 100
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 0 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 0
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~4.2 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 4.2
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "Project has not signed or included provenance with any releases.",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "exceptional",
"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": 4,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "last human commit 4 days ago",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_maintained",
"params": {
"days": 4
}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "moderate",
"name": "Community & Adoption",
"value": 58,
"weight": 0.17,
"metrics": [
{
"key": "popularity",
"band": "at_risk",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 28,
"inputs": {
"forks": 13,
"stars": 15,
"watchers": 2,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "15 stars",
"points": 18.6,
"status": "partial",
"details": [
{
"code": "stars",
"params": {
"count": 15
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "13 forks",
"points": 9,
"status": "partial",
"details": [
{
"code": "forks",
"params": {
"count": 13
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "2 watchers",
"points": 0,
"status": "missed",
"details": [
{
"code": "watchers",
"params": {
"count": 2
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "excellent",
"name": "Community health",
"note": null,
"notes": [],
"value": 92,
"inputs": {
"has_readme": true,
"has_license": true,
"readme_badges": null,
"has_contributing": true,
"has_issue_template": false,
"has_code_of_conduct": true,
"readme_badge_services": [],
"has_pull_request_template": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (MIT)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "MIT"
}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 18,
"status": "met",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 13.5,
"status": "met",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 6.3,
"status": "met",
"details": [],
"max_points": 6.3
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "weak",
"name": "Sustainability & Governance",
"value": 46,
"weight": 0.23,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 17,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 6,
"top_contributor_share": 0.988
},
"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 99% of commits",
"points": 0.3,
"status": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 99
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "6 contributors",
"points": 8.1,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 6
}
}
],
"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": "good",
"name": "Issue & PR responsiveness",
"note": "Excluded from scoring (no data or not applicable): Newcomer PR acceptance. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"newcomer_pr_acceptance"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 70,
"inputs": {
"merged_prs": 270,
"open_issues": 35,
"closed_issues": 133,
"prs_merged_7d": null,
"prs_decided_7d": null,
"prs_merged_30d": null,
"prs_decided_30d": null,
"issue_closed_ratio": 0.792,
"closed_unmerged_prs": 25,
"first_time_authors_30d": null,
"first_time_prs_merged_30d": null,
"first_time_prs_decided_30d": null
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "79% of issues closed",
"points": 33.3,
"status": "partial",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 79
}
}
],
"max_points": 42
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "270/295 decided PRs merged",
"points": 27.5,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 270,
"decided": 295
}
}
],
"max_points": 30
},
{
"key": "newcomer_pr_acceptance",
"name": "Newcomer PR acceptance",
"detail": "no first-time contributor's PR decided in 30d",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_newcomer_prs",
"params": {
"days": 30
}
}
],
"max_points": 13
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 0/26 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "moderate",
"name": "Ownership & stewardship",
"note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"verified_domain"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 56,
"inputs": {
"followers": 34,
"owner_type": "User",
"is_verified": null,
"owner_login": "kgdunn",
"public_repos": 40,
"account_age_days": 5667
},
"components": [
{
"key": "ownership_backing",
"name": "Ownership backing",
"detail": "personal (user) account",
"points": 10,
"status": "partial",
"details": [
{
"code": "owner_personal",
"params": {}
}
],
"max_points": 30
},
{
"key": "verified_domain",
"name": "Verified domain",
"detail": "not applicable to user accounts",
"points": 0,
"status": "excluded",
"details": [
{
"code": "not_applicable_to_user_accounts",
"params": {}
}
],
"max_points": 20
},
{
"key": "owner_reach",
"name": "Owner reach",
"detail": "34 followers of kgdunn",
"points": 11.1,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 34,
"login": "kgdunn"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "40 public repos, account ~15 yr old",
"points": 23.7,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 40
}
},
{
"code": "account_age_years",
"params": {
"years": 15
}
}
],
"max_points": 25
}
]
}
],
"description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
},
{
"key": "engineering",
"band": "exceptional",
"name": "Engineering Quality",
"value": 96,
"weight": 0.19,
"metrics": [
{
"key": "engineering_practices",
"band": "exceptional",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": true,
"has_linter_config": true,
"has_precommit_config": true
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "4 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 4
}
}
],
"max_points": 24
},
{
"key": "tests_present",
"name": "Tests present",
"detail": null,
"points": 24,
"status": "met",
"details": [],
"max_points": 24
},
{
"key": "linter_config",
"name": "Linter config",
"detail": null,
"points": 16,
"status": "met",
"details": [],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 9.6,
"status": "met",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 6.4,
"status": "met",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "30 out of 30 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": 90,
"inputs": {
"topics": [
"chemometrics",
"design-of-experiments",
"multivariate-analysis",
"multivariate-statistics",
"pca",
"pls",
"batch-process",
"latent-variables",
"multiblock-structures",
"partial-least-squares",
"partial-least-squares-regression",
"principal-component-analysis-pca",
"principal-components-regression",
"process-monitoring",
"statistical-process-control",
"experimental-design",
"batch-data-analysis"
],
"has_wiki": false,
"homepage": "https://kgdunn.github.io/process-improve/",
"has_readme": true,
"has_docs_dir": true,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 25,
"status": "met",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": "https://kgdunn.github.io/process-improve/",
"points": 15,
"status": "met",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": "17 topics",
"points": 10,
"status": "met",
"details": [
{
"code": "topics_count",
"params": {
"count": 17
}
}
],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "moderate",
"name": "Security",
"value": 57,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "moderate",
"name": "Security posture",
"note": null,
"notes": [],
"value": 57,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 18,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 0,
"scorecard_aggregate": 5.7
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "no binaries found in the repo",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "branch protection not enabled on development/release branches",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "30 out of 30 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 0/26 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": "update tool detected",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "30 commit(s) and 30 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 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "SAST tool is run on all commits",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file detected",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "Project has not signed or included provenance with any releases.",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "detected GitHub workflow tokens with excessive permissions",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "0 existing vulnerabilities detected",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "exceptional",
"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"
],
"commit_weight_rule": {
"min_commits": 50,
"min_commit_share": 0.1
},
"review_only_matches": 0,
"below_threshold_exposures": [],
"assessed_self_published_locations": 3
},
"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": "good",
"name": "AI Readiness",
"value": 78,
"weight": 0.04,
"metrics": [
{
"key": "ai_agent_context",
"band": "excellent",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 85,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 0.936,
"agent_instruction_files": [
"CLAUDE.md"
],
"agent_instruction_max_bytes": 13630
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "CLAUDE.md",
"points": 45,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "CLAUDE.md"
}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "88 of 94 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 88,
"sampled": 94
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "excellent",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 80,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [],
"has_dockerfile": false,
"typed_language": false,
"bootstrap_files": [
"Makefile",
"docs/Makefile"
],
"has_devcontainer": false,
"has_linter_config": true,
"typecheck_configs": [
"src/process_improve/py.typed"
],
"agent_commit_share": 0.72,
"toolchain_manifests": [],
"dependency_bot_commit_share": 0.06
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": "Makefile, docs/Makefile",
"points": 18,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "Makefile, docs/Makefile"
}
}
],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": null,
"points": 11,
"status": "met",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "src/process_improve/py.typed",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "src/process_improve/py.typed"
}
}
],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "72 of the last 100 commits agent-authored or agent-credited",
"points": 10,
"status": "met",
"details": [
{
"code": "agent_authored_commits",
"params": {
"count": 72,
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "6 of the last 100 commits are automated dependency updates",
"points": 8,
"status": "met",
"details": [
{
"code": "dependency_bot_commits",
"params": {
"count": 6,
"sampled": 100
}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "excellent",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 80,
"inputs": {
"primary_language": "Python",
"largest_source_bytes": 202691,
"source_files_sampled": 239,
"oversized_source_files": 7
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "Python with type-check config (src/process_improve/py.typed)",
"points": 27,
"status": "partial",
"details": [
{
"code": "typecheck_config_language",
"params": {
"files": "src/process_improve/py.typed",
"language": "Python"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "7/239 source files over 60KB",
"points": 53.4,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 239,
"oversized": 7
}
}
],
"max_points": 55
}
]
},
{
"key": "ai_interfaces",
"band": "moderate",
"name": "Machine-readable interfaces",
"note": null,
"notes": [],
"value": 60,
"inputs": {
"example_dirs": [
"examples",
"notebooks"
],
"has_mcp_signal": true,
"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": 20,
"status": "met",
"details": [],
"max_points": 20
},
{
"key": "runnable_examples",
"name": "Runnable examples",
"detail": "examples, notebooks",
"points": 40,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "examples, notebooks"
}
}
],
"max_points": 40
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? Carries a deliberately small weight: agent tooling is a real maintenance signal, but its absence must never gate the top of the scale (calibration saturates at raw 91, so 100/100 remains reachable with AI Readiness at zero)."
}
],
"classification": {
"labels": [],
"scores": {
"mcp-server": 3
},
"primary": null,
"evidence": [
{
"tier": "structure",
"label": "mcp-server",
"source": "mcp_signal",
"weight": 3
}
],
"artifacts": [],
"confidence": "none",
"host_extension": false,
"runs_as_process": false,
"consumed_by_code": false
},
"metrics_version": "2.3.1"
},
"warnings": [
"Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
"pypi package 'process-improve' points at a different repository (https://github.com/kgdunn/process_improve); excluded from ecosystem scoring",
"deps.dev does not index pypi:process-improve@1.62.1; advisories assessed against the repository dependency graph instead",
"No resolved dependencies carried a version and a supported ecosystem"
],
"report_type": "repository",
"generated_at": "2026-07-30T06:10:58.305917Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/k/kgdunn/process-improve.svg",
"full_name": "kgdunn/process-improve",
"license_state": "standard",
"license_spdx": "MIT"
}