Звіт у форматі JSON машиночитний
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 6121,
"has_wiki": true,
"homepage": null,
"languages": {
"Rust": 238829,
"Python": 1206499,
"Dockerfile": 724,
"Jupyter Notebook": 130625
},
"pushed_at": "2026-07-25T09:34:43Z",
"created_at": "2021-12-31T03:48:09Z",
"owner_type": "User",
"updated_at": "2026-07-25T09:34:55Z",
"description": "pyResToolbox - A collection of Reservoir Engineering Utilities",
"is_archived": false,
"is_disabled": false,
"license_spdx": "GPL-3.0",
"default_branch": "main",
"license_spdx_raw": "GPL-3.0",
"primary_language": "Python",
"significant_languages": [
"Python",
"Rust"
]
},
"owner": {
"blog": null,
"name": "Mark W. Burgoyne",
"type": "User",
"login": "mwburgoyne",
"company": null,
"location": "Australia",
"followers": 140,
"avatar_url": "https://avatars.githubusercontent.com/u/29671046?v=4",
"created_at": "2017-06-24T05:39:53Z",
"is_verified": null,
"public_repos": 15,
"account_age_days": 3318
},
"license": {
"state": "standard",
"spdx_id": "GPL-3.0",
"raw_spdx": "GPL-3.0",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v3.7.2",
"kind": "patch",
"published_at": "2026-07-25T09:40:03Z"
},
{
"tag": "v3.7.1",
"kind": "patch",
"published_at": "2026-07-19T10:40:21Z"
},
{
"tag": "v3.7.0",
"kind": "minor",
"published_at": "2026-07-11T03:26:19Z"
},
{
"tag": "v3.6.0",
"kind": "minor",
"published_at": "2026-06-11T11:25:42Z"
},
{
"tag": "v3.5.0",
"kind": "minor",
"published_at": "2026-05-31T04:03:44Z"
},
{
"tag": "v3.4.0",
"kind": "minor",
"published_at": "2026-05-31T04:03:43Z"
},
{
"tag": "v3.3.0",
"kind": "minor",
"published_at": "2026-05-31T04:03:42Z"
},
{
"tag": "v3.2.0",
"kind": "minor",
"published_at": "2026-05-31T04:03:42Z"
},
{
"tag": "v3.1.5",
"kind": "patch",
"published_at": "2026-05-31T04:03:41Z"
},
{
"tag": "v3.1.4",
"kind": "patch",
"published_at": "2026-05-31T04:03:40Z"
},
{
"tag": "v3.1.3",
"kind": "patch",
"published_at": "2026-05-31T04:03:39Z"
},
{
"tag": "v3.1.2",
"kind": "patch",
"published_at": "2026-05-31T04:03:38Z"
},
{
"tag": "v3.1.1",
"kind": "patch",
"published_at": "2026-05-31T04:03:37Z"
},
{
"tag": "v3.1.0",
"kind": "minor",
"published_at": "2026-05-31T04:03:36Z"
},
{
"tag": "3.0.5",
"kind": "patch",
"published_at": "2026-03-14T02:57:30Z"
},
{
"tag": "v3.0.4",
"kind": "patch",
"published_at": "2026-03-09T07:34:08Z"
},
{
"tag": "v3.0.1",
"kind": "patch",
"published_at": "2026-03-01T13:37:28Z"
},
{
"tag": "v3.0.0",
"kind": "major",
"published_at": "2026-02-28T03:16:38Z"
},
{
"tag": "v2.5.2",
"kind": "patch",
"published_at": "2026-02-27T12:06:44Z"
},
{
"tag": "v2.5.1",
"kind": "patch",
"published_at": "2026-02-27T09:56:02Z"
},
{
"tag": "v2.5.0",
"kind": "minor",
"published_at": "2026-02-23T07:31:37Z"
},
{
"tag": "v2.2.3",
"kind": "patch",
"published_at": "2026-02-20T09:25:59Z"
},
{
"tag": "v2.2.2",
"kind": "patch",
"published_at": "2026-02-16T20:01:55Z"
},
{
"tag": "v2.2.1",
"kind": "patch",
"published_at": "2026-02-16T09:23:47Z"
},
{
"tag": "v2.2",
"kind": "other",
"published_at": "2026-02-14T03:06:17Z"
},
{
"tag": "v2.14",
"kind": "other",
"published_at": "2025-08-03T01:25:03Z"
},
{
"tag": "v2.13",
"kind": "other",
"published_at": "2024-12-28T02:11:28Z"
},
{
"tag": "v2.1.2",
"kind": "patch",
"published_at": "2024-12-21T04:42:08Z"
},
{
"tag": "v2.1.1",
"kind": "patch",
"published_at": "2024-11-01T05:41:26Z"
},
{
"tag": "v2.0",
"kind": "other",
"published_at": "2024-08-02T01:18:16Z"
},
{
"tag": "v1.4.4",
"kind": "patch",
"published_at": "2024-04-06T01:38:19Z"
},
{
"tag": "v1.4.3",
"kind": "patch",
"published_at": "2024-02-04T00:32:04Z"
},
{
"tag": "v1.4.2",
"kind": "patch",
"published_at": "2023-08-05T05:27:40Z"
},
{
"tag": "v1.4.1",
"kind": "patch",
"published_at": "2023-08-04T10:29:45Z"
},
{
"tag": "v1.4.0",
"kind": "minor",
"published_at": "2023-08-01T09:06:10Z"
},
{
"tag": "1.3.9",
"kind": "patch",
"published_at": "2023-06-20T05:25:17Z"
},
{
"tag": "1.3.8",
"kind": "patch",
"published_at": "2023-01-04T03:31:23Z"
},
{
"tag": "1.3.5",
"kind": "patch",
"published_at": "2022-03-18T00:00:00Z"
},
{
"tag": "1.3.4",
"kind": "patch",
"published_at": "2022-03-10T08:50:24Z"
},
{
"tag": "1.3.2",
"kind": "patch",
"published_at": "2022-03-03T11:01:54Z"
},
{
"tag": "1.3.0",
"kind": "minor",
"published_at": "2022-02-27T09:53:19Z"
},
{
"tag": "1.2.0",
"kind": "minor",
"published_at": "2022-01-30T05:35:59Z"
},
{
"tag": "1.1.4",
"kind": "patch",
"published_at": "2022-01-29T01:11:48Z"
},
{
"tag": "v1.1",
"kind": "other",
"published_at": "2022-01-26T02:54:52Z"
},
{
"tag": "v1.0.0",
"kind": "major",
"published_at": "2022-01-07T01:24:40Z"
}
],
"recent_commits": [
{
"oid": "55aa5224c6b42da14d722704aa61e30deab2e981",
"body": "VSHIFT['C3H8'] = -0.112963, giving V_phi = 72.85 cm3/mol at 298 K, 20 MPa, so\npropane no longer falls back to the Plyasunov correlation.\n\nThis entry is weaker than the other six and is labelled so wherever it appears.\nNo densimetry for propane in water exists, so it is not fitted to a data set:\nit i\n[…]\n tagged, so main\nwould otherwise carry post-release code labelled 3.7.2. Not tagged or released.\n\n954 tests with Rust, 852 + 102 skipped without.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add C3H8 volume shift; bump to 3.7.3 (unreleased)",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-07-25T09:34:41Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a473ae2a1cd8212516fc6cabead96f7d0895e6e7",
"body": "Dissolved-gas apparent molar volume, viscosity corrections and the Garcia\nmixing-rule solvent basis. Full detail in pyrestoolbox/docs/changelist.rst.\n\n- V_phi now comes from the Soreide-Whitson modified PR route plus one\n dimensionless volume shift per gas, by default. New brine.pr_vphi (exposed\n \n[…]\nlity\n source Murphy & Gaines themselves used.\n- IAPWS-IF97 saturation-line guard (p_sat_if97).\n\nTests: 953 with Rust, 851 + 102 skipped without.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Release 3.7.2",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-07-25T09:09:55Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e357f4787de2fd19168ed194af435b5d6c195b4d",
"body": "Ostermann plateau ratios refit to ln(ratio) = 93.6918*exp(-0.957408*\n(T_K/142-1))*x_CH4 (slope residuals <=3.4%), capped at the measured\nplateau. Unchanged at saturation; below ~2000 psi CH4 partial pressure\nthe correction scales with dissolved CH4 instead of the on/off plateau\nstep. Suite green (926).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add Calabrese-form sub-plateau ramp to CH4 viscosity correction",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-07-19T10:53:10Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "6d7c75857e99aa5087806ce2d0342a522fbccd75",
"body": "Replaces the T-independent Islam-Carlson (2012) factor in both\nCO2_Brine_Mixture and SoreideWhitson. Calabrese Eq. 25 is fitted over\n274-449 K to 100 MPa (415 NaCl points, AARD 0.9%), salt-type and\nmolality independent to m=6; Islam-Carlson agrees only near its\n25-35 degC calibration window and overstates the increment 3.5x at\n200 degF. Full suite green (926).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Move CO2 dissolved-gas viscosity to Calabrese (2019) Eq. 25",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-07-19T10:41:25Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "124fa4dee091f67aca072609c443e8683c86cf36",
"body": "The 42e18f0 feed fix changes mixed-gas flash results; frozen baselines\nand doc examples captured under the 95/5 feed are re-pinned: brine.rst\nmixed-gas Rs_total 6.31 -> 8.51 sm3/sm3 (old value had H2S/CO2 vapor\ndepleted by the feed artifact), gas_hydrate SW water-balance values\nshift <0.15%. Full suite green with and without Rust (926 / 824+102).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Re-pin mixed-gas baselines and doc examples for flash feed fix",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-07-19T10:10:16Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9530b9528373eac9373e02ed471b2a625319fc04",
"body": "Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Release 3.7.1",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-07-19T10:07:02Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "42e18f0685c3458ff1e066773155d7c681d01bed",
"body": "calc_gas_brine_equilibrium(method='flash') fed a hardcoded 95% water /\n5% gas mixture. At high P the more-soluble components preferentially\ndissolve, so the equilibrium vapor drifts off the requested dry-gas\ncomposition (CH4+CO2 at 50 MPa: dry-basis CO2 depleted 0.73 -> ~0.65,\nbiasing x_CO2 ~10% low\n[…]\nagainst ternary CH4+CO2+H2O VLE (Qin 2008; Al Ghafri 2014,\n37 points): x_CO2 MARE 26% -> 16%, binaries unchanged <0.04%, brine\ntest suite 37/37.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Fix multicomponent flash feed: gas-excess with water-rich retries",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-07-19T09:59:54Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "868c386baee30ac451ff9cb7694c460ef6d0008f",
"body": "…engine\n\ncalc_water_content_with_kij: the successive substitution has multiple\nfixed points near the dew boundary (high T, P within a few multiples of\nPsat); the converged branch depended on damping. The adaptive-damping\npass (canonical, values unchanged where unique) is now verified by a\nfixed-damp\n[…]\nHalley and np.roots fail; callers propagate NaN and flash_tp\nstops rather than iterating on NaN. All 813 tests pass; SoreideWhitson\nclass results unaffected (it uses the flash path for water content).",
"is_bot": false,
"headline": "Harden water-content solver and cubic EOS root handling in brine VLE …",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-07-19T03:31:18Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "78514dd796ff8a1c4c0b858bffb6f47956ec45e9",
"body": "Gases without an embedded csw term in the original S&W kij correlations\n(H2S, H2) received no salting-out at all when the flash was run with\nframework='sw_original' and salinity_method='embedded' - dissolved H2S\nin brine was overpredicted (e.g. x=0.0299 vs 0.0212 at 350 K, 50 bar,\n4 m NaCl). They no\n[…]\nack to the proposed-framework delta_kij,\nmatching the binary path's 'embedded' routing. Docstrings updated\n(previously claimed an H2-to-gamma_phi fallback that did not exist).\nAll 37 brine tests pass.",
"is_bot": false,
"headline": "Fix H2S/H2 salting gap under salinity_method='embedded' with sw_original",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-07-19T03:17:55Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "bd5ca29979a5769da4051dc468203cecdc2579ce",
"body": "Separate distribution in mcp/ (own pyproject, not part of the wheel;\nmcp SDK needs Python >= 3.10 vs library >= 3.8). Meta-tool design\nrather than one tool per function: list_functions/describe/call reach\nthe full public API, plus recommend_methods and one-shot wrappers for\nthe stateful brine and DC\n[…]\nless, /mcp\nendpoint) for remote hosting behind an API gateway. Dockerfile and\nDEPLOYMENT.md included for enterprise deployment. 17 tests including\na full protocol round-trip over an in-process client.",
"is_bot": false,
"headline": "Add pyrestoolbox-mcp: MCP server exposing the library",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-07-16T12:57:45Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "b91b0a535d6fdd1296488da5d0c88e8ddbbc2aa3",
"body": "- HY Z-factor initial guess is now Z=1 (classic Hall-Yarborough start) in\n both Python and Rust; WYW coefficients and helper functions deleted.\n Converged values agree with the WYW-seeded results to ~1e-11 at the\n frozen baseline point, ~1e-6 worst-case at grid extremes; all frozen\n baselines an\n[…]\ng pointers so agents can find the shipped docs\n- Document the plyasunov module (plyasunov.rst, doc-example tests,\n docstring completions); add plyasunov to the lazy submodules list\n- Tests 920 -> 926",
"is_bot": false,
"headline": "Remove residual WYW code and fix documentation drift",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-07-16T12:57:35Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a8fc7b064fc456d128ccfbbec35b6286588beac1",
"body": "- Changelist for 3.7.0 (two-segment decline models, b > 1 relaxation,\n mh/hyp2 fitting and forecasting).\n- CI actions to Node 24 runtimes: checkout v5, setup-python v6,\n upload-artifact v6, download-artifact v7, action-gh-release v3.",
"is_bot": false,
"headline": "Release v3.7.0",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-07-11T02:51:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2ccc6a11f0f97725d4829cd207c17a662d2660d5",
"body": "…ased two-stage hyperbolic\n\n- mh_rate/mh_cum/mh_eur: hyperbolic (b default 2.0) to terminal decline dterm,\n exponential after (Robertson 1988). Analytic piecewise cumulative and EUR.\n- hyp2_rate/hyp2_cum/hyp2_eur: b1 (default 2.0) to specified telf, then second\n hyperbolic b2 (default 0.5) with ra\n[…]\n\n DeclineResult gains dterm, b2, telf; forecast() dispatches both models.\n- 32 new tests incl. workbook regressions for all four solver modes; RST docs\n and doc-example tests for every new function.",
"is_bot": false,
"headline": "Add two-segment decline models to dca: modified hyperbolic and telf-b…",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-07-11T02:51:14Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "3f6afcf64aafc2f8a68a722934dfe57592bac390",
"body": null,
"is_bot": false,
"headline": "Ignore HANDOFF.md in Claude Code context",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-07-05T02:34:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fb108d80a3511529d060b14fe4f4f73134e283d0",
"body": "Installing the built wheel in the manylinux test container pulls scipy,\nwhose binary wheels need a newer glibc than the container provides, so pip\nfalls back to building scipy from source and fails on missing OpenBLAS.\nThis skip was removed in the sweep as a perceived CI gap but is load-bearing;\nLinux import and full-suite coverage live in tests.yml instead.",
"is_bot": false,
"headline": "CI: restore manylinux CIBW_TEST_SKIP",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-06-11T10:56:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a27242dabde40a2d4aacf0214ece9cdfc3f75722",
"body": null,
"is_bot": false,
"headline": "Release v3.6.0",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-06-11T10:24:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9817feb4c3ca0d2ca02d025f03b82e9ce91563f6",
"body": "Sixteen High findings plus the medium/low and structural items, every\ncorrelation change verified against primary literature before landing.\nFrozen baselines and doc examples re-pinned to corrected values (approved).\n\n- Gas: Hall-Yarborough solver now converges (was one Newton step), DAK\n Newton de\n[…]\npe_inputs with ~40x scalar fast path, wrong-enum ValueError,\n bisect_solve bracket check, CI test workflow, pytest-delegating\n run_all_tests\n\n870 tests pass (Rust parity included); cargo test 41/41.",
"is_bot": false,
"headline": "Correctness sweep: fix all verified findings from the 2026-06-10 review",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-06-11T10:24:31Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "524afa6bb4739758e76b3a411d8cc1b9477ef660",
"body": "…ing style)",
"is_bot": false,
"headline": "docs: remove em-dashes from 3.5.0 changelist (spaced hyphens per writ…",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-05-31T04:19:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "336b30c95d33ec04d78312ef35fd0d8e662eae7c",
"body": "After publishing to PyPI, the publish job now extracts the matching\n'Changelist in <version>:' section from docs/changelist.rst, lightly converts\nRST->Markdown, and creates a GitHub Release via softprops/action-gh-release.\nNo binary assets are attached (PyPI is canonical; pip does not use GH Release\nassets). Adds contents:write to the publish job and a checkout step.\n\nBackfilled v3.1.0-v3.5.0 GitHub Releases from the changelist (done out-of-band\nvia gh); v3.5.0 pinned as Latest.",
"is_bot": false,
"headline": "CI: auto-create notes-only GitHub Release on tag push",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-05-31T04:05:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "49f43742555ddc52707dfe44b56440fb436e587d",
"body": "Bump version 3.4.0 -> 3.5.0. Changelist finalized covering the gas pseudoskins,\nPVTO export fix, oil/oil.py removal, brine framework-gate + converged-flag fixes,\noil_harmonize pbmethod unification, nodal HB Rust parity, simtools.rr_solver\nsingle-phase guard, oil_matbal aquifer influx (We/WDI), hydrate code split, and\nassorted validation/hardening. 838 tests pass.",
"is_bot": false,
"headline": "Release v3.5.0",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-05-31T03:17:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e59c59d28959970e103fc240aab3a28184901ca2",
"body": "…m gas.py\n\nWS-3 — oil_matbal water-drive support:\n- New optional We parameter (cumulative aquifer influx, reservoir volume rb|rm3),\n mirroring gas_matbal. Subtracted from underground withdrawal before estimating\n OOIP (Havlena-Odeh F - We = N*[Eo + m*Eg + (1+m)*Efw]); fed to both the Python\n and \n[…]\nes). Public API unchanged via\n re-export from gas.py. _hydrate imports gas_water_content lazily to avoid a\n circular import. Updated the one test that imported the internal helpers.\n\n838 tests pass.",
"is_bot": false,
"headline": "Architecture: oil_matbal aquifer influx (We) + split hydrate code fro…",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-05-31T03:08:58Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "1f94e88a28923a1e4c4783ac1674626c6d3c28a9",
"body": "…ethod default\n\nCorrectness:\n- Brine: gate Rust flash dispatch on framework=='proposed' so dropin/sw_original\n no longer silently downgrade to proposed when the accelerator is installed.\n- Brine: propagate the real convergence flag out of flash_tp_rust (4-tuple) and\n co2_brine_solubility_rust (6-t\n[…]\nustness / hygiene:\n- nodal.fthp: validate well_type/vlpmethod/bhp at entry.\n- validate_pe_inputs: array-safe sg and inert-fraction checks.\n\nDocs/tests: changelist, nodal.rst HB values, 835 tests pass.",
"is_bot": false,
"headline": "Fix sweep: brine framework gate, Rust parity/converged flags, oil pbm…",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-05-31T02:54:11Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "973c4c84cba9b0b3958b4a4d2213cbda337142eb",
"body": null,
"is_bot": false,
"headline": "Update 3.5.0 changelist: PVTO export fix and oil/oil.py removal",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-05-05T13:01:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a9e217392fb6732452a53c88c463187a8f9f0618",
"body": "Eclipse PVTO uses '/' as the stem terminator: each saturated record may\nbe followed by undersaturated continuation rows (blank Rs), and a single\n'/' terminates the LAST row of the stem. The previous output placed '/'\non every saturated row, prematurely closing the stem before its\nundersaturated cont\n[…]\nted row carries '/' only when the stem has\nno undersaturated rows; otherwise the last undersaturated row carries\nthe terminator. Final '/' null record on its own line still terminates\nthe whole table.",
"is_bot": false,
"headline": "Fix PVTO export: '/' on last row of each stem only",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-05-05T12:59:01Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "eab231326118aa48c1e41d2f34ad0be80863afa2",
"body": "Three new public functions in pyrestoolbox.gas plus matching GasPVT\nconvenience methods, with oilfield and metric unit support throughout.\n\n- gas_hvf_beta(k, method='FK'|'JONES'|'TCK', phi, metric): Forchheimer β.\n FK (default) is a log-log fit of the Firoozabadi & Katz (1979) JPT Feb\n consolidate\n[…]\non. 12 new doc-example tests pin every\nRST example value. Reference S_p values verified against a 50,000-term\ndirect evaluation of the Streltsova-Adams series.\n\n824 tests total (up from 812 in 3.4.0).",
"is_bot": false,
"headline": "Add gas non-Darcy HVF and partial-penetration pseudoskin functions",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-23T23:54:52Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "269eb65ec601bba00f3bc2cbc665040784818f5a",
"body": "…ity harness\n\nCorrectness\n- Rust HB oil VLP: three dimensional bugs in src/vlp/segment_oil.rs (min_l,\n rho_avg, ul) caused up to 75% over-prediction of BHP at low-rate / low-THP\n conditions. WG/GRAY/BB oil were already correct. hb_holdup signature now\n takes rho_l directly; gas-segment call site \n[…]\n extracted\n to oil/_constants.py with paper citations.\n- Oil RST: sg_sto renamed to sg_o (matches code); vis_frac added to\n make_bot_og result-dict table.\n\n794 tests passing (up from 716 in v3.3.0).",
"is_bot": false,
"headline": "Release v3.4.0: HB oil Rust bugfix, brine metric standardization, par…",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-18T07:49:32Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "06d26557e4267df77198edc2b50d9b9ca1c1ec19",
"body": "… Rust)\n\n- _resolve_methods helper couples zmethod/cmethod to BNS when either is BNS,\n emitting a UserWarning that names the overruled counterpart. h2 > 0 still\n auto-selects BNS silently. Non-BNS methods remain freely mixable.\n- User-supplied tc/pc honored across every method. For SUT/PMC they re\n[…]\nz calls explicitly pair zmethod='BNS' with\n cmethod='BNS' to avoid triggering the new coupling warning.\n- 716 tests (up from 713), including Rust-vs-Python parity coverage for\n user Tc/Pc overrides.",
"is_bot": false,
"headline": "Release v3.3.0: BNS coupling, user Tc/Pc honored everywhere (Python +…",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-17T23:49:18Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4757b0d6ebab627ade68155bda70432bcf48239f",
"body": "…nce flag\n\n- DCA: fix duong_cum linspace inversion (negative cum at small t); validate dt/t_end/uptime in forecast\n- simtools.rr_solver: thin wrapper delegating to canonical brine._lib_vle_engine.rr_solver (~100 lines removed)\n- Rust VLE: remove implicit S&W Eq 8 ks fallback in flash_tp_rust; trust \n[…]\npatch sites consolidated into helpers (_clamp_b, _b_max, _flow_fraction_at_x)\n- recommend: document sg and well_type as reserved-unused; signatures preserved\n\n701 tests passing (up from 696 in 3.1.5).",
"is_bot": false,
"headline": "Release v3.2.0: DCA bugfixes, RR dedup, Rust Sechenov guard, converge…",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-17T22:55:32Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "74a44d544de4b500ef2d03c21582b8168e0fe09b",
"body": "Numerical fixes:\n- Garcia CO2-brine density: algebraic reformulation of Eq 18 removes\n xCO2 -> 1 singularity. Applied in brine.garciaDensity and\n SoreideWhitson._calc_properties. Finite limit at xCO2=1 equals\n MwG/V_phi. Mathematically identical to old formula for xCO2 < 1.\n- oil.Rs_velarde: guar\n[…]\n truncate\n ndarray fields to shape/dtype.\n- nodal Reservoir and WellSegment error messages echo original\n user-supplied values + units (not post-metric-conversion numbers).\n\n696 tests (up from 691).",
"is_bot": false,
"headline": "v3.1.5: numerical fixes + agent-friendly UX",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-17T22:30:33Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "61399720e11ea880a566bf759401670f2b376d74",
"body": "…ject.toml\n\nModern setuptools (>=69, Python 3.12) requires 'name' in [project] per\nPEP 621. Previous fix only included version. New approach: copy entire\n[project] section from real pyproject.toml, swap only [build-system]\nfrom maturin to setuptools, and strip [tool.maturin].",
"is_bot": false,
"headline": "Fix pure-Python build: preserve full [project] metadata in temp pypro…",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-13T13:58:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a727da78f128af9092f1177d5efcac912a5da5d4",
"body": null,
"is_bot": false,
"headline": "Fix pure-Python build: preserve version in temporary pyproject.toml",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-13T05:39:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ec53e35a4415549e1c1bf942726d9d9dbf84bd49",
"body": null,
"is_bot": false,
"headline": "Bump version to 3.1.4 and update changelist",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-13T04:52:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "98f8bb75c1e851c15b1471ab433b57201ecfe260",
"body": "…liases\n\nAdaptive damping in flash_tp and calc_water_content_with_kij (Python + Rust):\nstarts conservative, accelerates when converging, brakes when stalling.\n\nLRU cache on Plyasunov V2_inf (256 entries) and instance-level kij matrix\ncache keyed by (T_K, mode) to avoid redundant computation.\n\nStandardize parameter naming across brine_props, CO2_Brine_Mixture, and\nSoreideWhitson: all three now accept both p/degf/wt and pres/temp/ppm aliases\nwith automatic wt<->ppm conversion.",
"is_bot": false,
"headline": "Tier 4 brine improvements: adaptive VLE damping, caching, parameter a…",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-13T01:47:02Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f7ad39ab80ec2a9c0f53173432850e7b3cb586a9",
"body": "…ted decorator\n\nSplit oil.py (2144 lines) into 10 sub-files by concern: _correlations, _density,\n_compressibility, _rate, _separator, _harmonize, _tables, _pvt_class, _utils,\n_constants. All public names re-exported via oil/__init__.py.\n\nExtract ~100 named constant groups with paper citations across\n[…]\nng inline magic numbers. Add @rust_accelerated decorator\nto _accelerator.py for simple Rust dispatch. Add validate_pe_inputs to brine\nand nodal entry points. Update test imports for new oil structure.",
"is_bot": false,
"headline": "Tier 3 tech debt: split oil monolith, named constants, @rust_accelera…",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-13T01:34:16Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "5183ed778ac7559667edec5437d99656e73bc87e",
"body": "OilPVT.rs/bo/density/viscosity now accept lists, tuples, or numpy\narrays for the pressure parameter, returning numpy arrays. Scalar\ninputs still return scalars. GasPVT already supported arrays via\nthe underlying gas module functions.",
"is_bot": false,
"headline": "Add array support to OilPVT methods (rs, bo, density, viscosity)",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-12T23:58:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bc88b1064899a6dddeac3584be953fab898f5f46",
"body": "Rust HB gas/oil: replace buggy midpoint-accumulation temperature scheme\nwith correct (i-0.5)/ndiv midpoint approach matching WG/GRAY/BB and\nthe Python HB path. Removes depth/dz/incr/temp/p arrays in favor of\nsimple running pressure variable.\n\nAll 4 Rust gas VLP methods: lower low-rate fallback thres\n[…]\nn at near-zero\ngas rates (produces non-physical pressure spikes).\n\nTest baselines updated for corrected HB temperature discretization.\nRust/Python HB equivalence tolerance restored to standard (1e-3).",
"is_bot": false,
"headline": "Fix Rust HB temperature discretization and low-rate threshold",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-12T23:38:32Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8dfd0fe1cd1cc3361257eaa6f9d464b8d74573cf",
"body": "…lbacks\n\nReplace 8 VLP functions (4 gas + 4 oil, ~920 lines) with 2 shared march\nfunctions + 4 reusable gradient callbacks. 450 net lines removed.\n\n_segment_march_gas/_segment_march_oil handle preamble, geometry, segment\nloop, PVT, and state dict construction. Method-specific holdup, friction,\nand g\n[…]\ndient math lives in _hb/_wg/_gray/_bb_gradient_gas callbacks.\n\nAlso fixes HB Python temperature discretization bug (midpoint-accumulation\novershoot replaced with correct (i-0.5)/ndiv midpoint scheme).",
"is_bot": false,
"headline": "Deduplicate VLP scaffold: extract shared segment march + gradient cal…",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-12T23:04:43Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "cbafe6903d6afcd814432d098eae8ef4f05ac00b",
"body": "… enum aliasing, version single-source\n\nGas: SUT hc_frac <= 1e-6 tolerance, DAK/HY/WYW correlation range warnings\nOil: Beggs-Robinson/Petrosky-Farshad viscosity floor guards, Standing/VALMC Pb range warnings\nBrine: Garcia density denominator guard, RR solver convergence warning, Spycher iteration di\n[…]\nth BNS canonical, BUR alias\nBuild: setup.py reads version from pyproject.toml, setup.cfg defers\nRust: gas_ponz2p pseudopressure acceleration\nTests: 61 pytest.raises error-case tests across all modules",
"is_bot": false,
"headline": "Tier 1/2 robustness fixes: FP guards, validity warnings, error tests,…",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-12T23:04:27Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f2f997820ac67c3831095f2e9e4ac4e442abfe40",
"body": null,
"is_bot": false,
"headline": "Bump version to 3.1.3",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-11T02:50:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9c20b014df991bde114c0c721da79f34ecd1d570",
"body": null,
"is_bot": false,
"headline": "Update changelist for 3.1.2",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-11T02:44:28Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "27ce11564a10d927cf6a2afca4436766d5e34af2",
"body": "Replace per-pressure scalar FFI loops with single batch calls that\nprecompute critical properties, BIPs, and LBC params once. Eliminates\n~20,000 Python→Rust round-trips for a typical 10k-point evaluation.\n\nNew Rust functions: bns_zfactor_batch, dak_zfactor_batch, hy_zfactor_batch,\ngas_ug_lge_batch, gas_ug_lbc_batch. LBC batch sees 9.3x speedup over\nscalar; full BNS pipeline (Z + viscosity) now 2x faster than pure Python.",
"is_bot": false,
"headline": "Batch vectorize Rust-accelerated gas_z and gas_ug dispatch",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-11T02:40:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "48813084aa6b60adb16c081cb44a06aaf30061e8",
"body": null,
"is_bot": false,
"headline": "Bump version to 3.1.2",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-09T04:53:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4f66cdbcd44458e44eb9eb46a4f3f4c086f746ce",
"body": "The Halley cubic solver could converge to the wrong (liquid) root at high\npressures (>15000 psia) because the inflection-point initial guess landed\nin the basin of attraction of a non-vapor root. This caused incorrect\nZ-factors (e.g. 0.08 instead of 2.3 at 20000 psia for SG=0.7 gas).\n\nReplaced with \n[…]\nence to the\nvapor root regardless of pressure. Cardano fallback retained as safety net.\n\nApplied to both Python (vectorized) and Rust implementations.\nBuilds on pkirkham's negative-Z guard from PR #4.",
"is_bot": false,
"headline": "Use Z*=Z-B reformulation for robust high-pressure Z-factor convergence",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-09T04:51:25Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "739c52ba3a2e5204e575a5b461cd9e74bf86f86f",
"body": "Fallback to Cardano for negative roots",
"is_bot": false,
"headline": "Merge pull request #4 from pkirkham/main",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-09T04:47:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5e5d7c75460f360b083b33dca74b73b21f036d41",
"body": "If Halley fails to find the maximum positive root (occurs for high pressure > ~17,000 psia) then fall back to Cardano.",
"is_bot": false,
"headline": "Fallback to Cardano for negative roots",
"author_name": "pkirkham",
"author_login": "pkirkham",
"committed_at": "2026-04-09T00:43:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7c3f33b0f8c5a95c46c79d36b5716aa177f6e37a",
"body": "…lds)",
"is_bot": false,
"headline": "Skip all macOS tests (MPFR symbol issue with mixed Python version bui…",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-06T19:06:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d6b64c8b33a0dd8ed319fc76927fc7dfdca8b377",
"body": "Wheels build fine for 3.8/3.9 but test step fails because\nilt-inversion may not have matching wheels on PyPI yet.",
"is_bot": false,
"headline": "Skip tests for cp38/cp39 in CI (ilt-inversion PyPI timing)",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-06T18:32:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c7cdc47e682fedb91cd8cf036b979c09a3564480",
"body": "- Wire up influence_tables() to call influence_tables_rust() when Rust\n available (full MPFR Bessel + GWR in Rust, no Python callbacks, ~25x speedup)\n- Change influence_tables default M from 8 to 7 (9-digit accuracy, enables\n ilt Rust fast path when prec<=15)\n- Expand CIBW_BUILD from cp310-cp313 to cp38-cp313\n- Lower requires-python to >=3.8\n- Upgrade cibuildwheel to v2.23\n- Bump version to 3.1.1\n- Add benchmark_rust_vs_python.py script",
"is_bot": false,
"headline": "Rust-accelerated influence tables, Python 3.8-3.13 wheels",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-06T18:00:51Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f5ccbf412ba82670c39b20319c8972b2e5bd9c18",
"body": "gmpy2 (~10x) and python-flint (~15x Bessel via ARB) are now required\ndependencies so ILT runs fully accelerated out of the box for all M\nvalues. Users should not need to discover optional packages.",
"is_bot": false,
"headline": "Add python-flint dependency for full ILT acceleration",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-06T14:44:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7af4ed0ef189781fd011782b14881a7df51deb08",
"body": "Pure-Python fallback wheel covers aarch64 users. Native aarch64 Rust\nwheels can be added later with an ARM runner.",
"is_bot": false,
"headline": "Drop Linux aarch64 from cibuildwheel (QEMU GMP compile takes hours)",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-06T14:37:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9de678720680ce47db501795c62bb1d0e429f873",
"body": "gmpy2 provides ~10x speedup for GWR inverse Laplace transform when\nM > 7 (beyond Rust f64 precision limit). Users should not need to\nknow about optional acceleration libraries - it should just work.",
"is_bot": false,
"headline": "Add gmpy2 as required dependency for ILT acceleration",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-06T14:37:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6194606cd23738df0bdc9365f0880e40640311eb",
"body": "Windows cibuildwheel failed because gmp-mpfr-sys rejects MSVC targets.\nSwitch to stable-x86_64-pc-windows-gnu toolchain and install MinGW GCC\nvia pre-installed MSYS2, matching the proven ilt-inversion CI config.",
"is_bot": false,
"headline": "Fix Windows CI: use GNU Rust toolchain and MSYS2 for GMP/MPFR build",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-06T13:59:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "110ade4534ef1d7ea0e2e43283c983f9663bc11a",
"body": "oil_co numerical derivative straddled the SWMH/cofb density formula\nboundary at Pb, causing a 2x step change in Co and an increasing\ntrend below Pb. Add undersaturated_only parameter that uses the\nanalytical cofb correlation (McCain Eq 3.13) at all pressures,\ngiving a smooth continuous curve. BOT now uses this mode, matching\nthe ResToolbox3 app implementation. Regenerate bot.png.",
"is_bot": false,
"headline": "Fix oil_co discontinuity at Pb in BOT, add undersaturated_only mode",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-06T13:51:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c260ecac438da0aed05810b568b7a211e77ad73b",
"body": null,
"is_bot": false,
"headline": "Switch dependency from gwr_inversion to ilt-inversion",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-06T13:25:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a8e2639be96de9f8d124e4042904bf80ff1729f7",
"body": "… functions",
"is_bot": false,
"headline": "Release 3.1.0: Add Rust/MPFR GWR inverse Laplace transform and Bessel…",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-06T13:17:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "33586af3b11c2e7ee62e1724de091e5ac9da5e82",
"body": "Skip all manylinux test steps in CI (scipy cannot build from source\nin manylinux containers due to missing OpenBLAS). Wheels still build\ncorrectly; import test covered by macOS and Windows runners.\n\nRegenerate bot.png to reflect v3.0.5 undersaturated oil compressibility\ndefault — removes the large Co discontinuity at Pb from the old\nsaturated/Perrine definition.",
"is_bot": false,
"headline": "Skip Linux cibuildwheel tests, regenerate bot.png plot",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-05T22:36:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9ce8ff3c79bdd623967ecfb6c8deef76ff120ffd",
"body": "- Remove macos-13 (retired), build ARM-only on macos-14\n- Reduce CIBW_TEST_REQUIRES to numpy only (avoids scipy source build in containers)\n- Drop Python 3.9 (scipy 1.14+ requires 3.10+)\n- Skip tests on cross-compiled architectures (aarch64 on x86, x86_64 on arm)",
"is_bot": false,
"headline": "Fix CI: drop macos-13 runner, reduce test deps, skip cross-arch tests",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-05T22:11:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1634b155661fa03c7a57c35cc790e0a35055fbba",
"body": "- Configure maturin as build backend in pyproject.toml for mixed Python/Rust layout\n- Add GitHub Actions workflow for building pre-built wheels (Linux/macOS/Windows, Python 3.9-3.13) with pure-Python fallback and PyPI publishing\n- Add 27 Rust vs Python equivalence tests covering all accelerated func\n[…]\nix 21 Rust compiler warnings (unused constants, variables, dead code)\n- Update MANIFEST.in to include Rust source in sdist\n- Add build_pure_python.py for generating platform-independent fallback wheel",
"is_bot": false,
"headline": "Add maturin build system, CI wheels, and Rust acceleration tests",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-05T21:46:43Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "2d13ac4f0b3989c356b9d10fcefdefab0c0b526a",
"body": "Spycher-Pruess: RK-EOS cubic solver with low/high temperature paths,\nfugacity coefficients, and iterative convergence for CO2-H2O-NaCl.\n\nVLE Flash: Soreide-Whitson Peng-Robinson EOS with 16-component database,\nsuccessive substitution with Nielsen-Lia Rachford-Rice solver, dual-flash\nequilibrium (AQ \n[…]\nutes activity coefficients using the correct gas-specific\nks models (Dubessy CO2, Akinfiev H2S) before passing to Rust flash, ensuring\nexact numerical parity with Python-only path. All 603 tests pass.",
"is_bot": false,
"headline": "Add Rust acceleration for Spycher-Pruess CO2-Brine and VLE flash engine",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-03T19:11:11Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "0ee484ce21be69d3df8cfa30893d7fc6032f660d",
"body": "PyO3/maturin-based Rust extensions that accelerate VLP segment loops\n(all 8 methods), gas Z-factor/viscosity/pseudopressure, oil density\n(SWMH) and FVF (McCain), DCA hyperbolic grid search with RANSAC, and\nmaterial balance regression objective. All dispatch uses try/except\nfallback — pure Python beh\n[…]\nl-based probe caching avoids repeated load\nfailures. PYRESTOOLBOX_NO_RUST=1 forces Python; PYRESTOOLBOX_RETRY_RUST=1\nretries after a blocked probe.\n\n603 tests pass with and without the Rust extension.",
"is_bot": false,
"headline": "Add optional Rust acceleration for compute-intensive algorithms",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-04-03T13:20:07Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ed485f7c5de1c93dc1e76c0b98b2b23bbfedf016",
"body": "test_viscosity_scaling.py had broken imports (non-existent Garcia_code\ndirectory, bare plyasunov_model import) and caused pytest collection\nerrors. test_unified_brine_design.py was an exploratory script with no\ntest functions. Neither was part of the 603-test suite.",
"is_bot": false,
"headline": "Remove orphan exploratory test scripts",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-25T11:34:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "90ff18c962ca9e899a08c8b879ac413cc93eb843",
"body": null,
"is_bot": false,
"headline": "Fix mutable default argument in lorenz_2_layers",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-23T08:43:57Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "51018853ac7e67ab5fa405964b2f3c6febaf79ee",
"body": "MANIFEST.in now explicitly includes only .py, .xlsx, .rst, .ipynb,\n.png files and prunes tests/ and .ipynb_checkpoints/. setup.py\nexcludes test packages from find_packages(). Docs remain in the\ndistribution for user reference.",
"is_bot": false,
"headline": "Exclude tests, pyc, and checkpoints from wheel and sdist",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-14T02:54:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4c7c0f1c1da2d73e4fd17e2405041fe753f1880a",
"body": "oil_co: new co_sat parameter returns [co_usat, co_sat] list using\nPerrine's definition for saturated compressibility. Default unchanged.\n\noil_bt: new total two-phase FVF function (Bt = Bo + (Rsi-Rs)*Bg).\n\noil_matbal: fix metric unit bug where cw/cf in 1/bar were not\nconverted to 1/psi, causing Efw t\n[…]\nby ~14.5x. Regression\nbounds for cw/cf also now correctly unit-converted.\n\nDocumentation updated for oil_co, oil_bt, matbal compressibility\nguidance. 603 validation tests (up from 588). Version 3.0.5.",
"is_bot": false,
"headline": "Add oil_co saturated compressibility, oil_bt, fix matbal metric cw/cf",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-14T02:49:23Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "b3d4dcea2d625c9852ff90829fe9568af6c396a6",
"body": "brine_props now returns compressibility as [cw_usat, cw_sat] list\ninstead of saturated-only scalar. oil_co changed from saturated\npseudo-compressibility (Co = -1/Bo*(dBo/dp - Bg*dRs/dp)) to\nundersaturated (Co = -1/Bo*dBo/dp at constant Rs), yielding the\nisothermal liquid-phase compressibility without evolved gas volume.\nUpdated all downstream consumers, tests, and documentation.",
"is_bot": false,
"headline": "Return undersaturated compressibility from brine_props and oil_co",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-13T11:14:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4fcd74af6dd3e331b856a4897df7164901179775",
"body": null,
"is_bot": false,
"headline": "Restructure RST docs for logical flow, bump version to 3.0.4",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-09T07:30:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4fd91187eb6cf0b399e5df7a7b0abd0c07396ca6",
"body": "Every function across all 11 module docs now has a structured Returns\ntable between Inputs and Examples, documenting return types, attributes,\nkeys, and descriptions. Covers scalars, tuples, dicts, dataclass results,\nand arrays. Class Objects sections updated with cross-references.",
"is_bot": false,
"headline": "Add standardized Returns tables to all RST documentation files",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-09T06:23:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f6473e1e92a2e7930a3f7321f28b7b74493b60f8",
"body": "Replace np.polyfit with RANSAC linear regression across DCA and matbal\nmodules for outlier robustness. Rewrite hyperbolic fitting to use\ngrid-search-over-b linearization instead of scipy curve_fit, eliminating\nlocal minima. Clean data reproduces OLS exactly (frozen baselines intact).",
"is_bot": false,
"headline": "Add RANSAC regression and linearized hyperbolic DCA fitting",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-09T05:24:57Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "67b2a753d75c06778102541a44c2b49c092fe28c",
"body": null,
"is_bot": false,
"headline": "Fix module doc links: tree/ -> blob/ for file URLs",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-09T04:30:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b3641927cb298fbdeeccc4dfde5d0d6f7c6ae2fc",
"body": null,
"is_bot": false,
"headline": "Fix changelist link path in README",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-09T03:33:21Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ab363af32238f4035b630ee67ed68a03fac01224",
"body": "Add new modules to feature list and module table. Add DCA fitting\nand gas material balance quick-start examples. Add gas hydrate\nprediction and method recommendation to feature highlights.",
"is_bot": false,
"headline": "Update README with DCA, matbal, recommend, sensitivity modules",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-09T03:26:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a9e8a6be40c53e7ee987902cef9b810726e55fa7",
"body": "fit_decline: t_start/t_end windowing parameters\nfit_decline_cum: Np_start/Np_end windowing parameters\noil_matbal: regress parameter for bounded optimization of m/cf/cw/sw_i\noil_matbal: pvt_table for user-supplied Rs/Bo/Bg interpolation\ngas_matbal: pvt_table for user-supplied Z or Bg interpolation",
"is_bot": false,
"headline": "Add DCA windowing, MBAL regression, and tabulated PVT support",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-09T03:23:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "54f9527ec8bac265d6ec146b1d5c55582ae162a6",
"body": "20 new cells: Arps model comparison, decline fitting with noisy data,\ncumulative fitting, forecast with uptime and GOR, EUR sensitivity,\nP/Z gas material balance regression, Havlena-Odeh oil material balance\nwith drive index decomposition.",
"is_bot": false,
"headline": "Add DCA and MBAL examples with plots to examples.ipynb",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-09T01:18:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ab1c2924bd4a57e36129fc67e5f255e9748c4025",
"body": "Full API reference with parameter tables and code examples for all four\nnew modules. 28 new doc example tests validating every documented call.\n533 total tests.",
"is_bot": false,
"headline": "Add RST documentation for dca, matbal, recommend, sensitivity modules",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-08T23:44:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b108f3e622c3941850bbac0e4fb84e89c5a999e7",
"body": "DCA: fit_decline_cum for rate-vs-cumulative fitting with uptime inference,\nfit_ratio/ratio_forecast for secondary phase ratio models (GOR, WOR),\nextended forecast() with uptime scaling and multi-ratio support.\nNew modules: matbal, recommend, sensitivity. NodalResult dict subclass\nfor nodal analysis. VLP and gas_cg performance improvements. 505 tests.",
"is_bot": false,
"headline": "Add DCA cumulative fitting, ratio forecasting, and new modules for 3.0.4",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-08T22:22:01Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "68f244cdf39620d6134ec9340acde191679eb162",
"body": null,
"is_bot": false,
"headline": "Add ResToolbox3 privacy policy page",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-06T08:03:02Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0d13877eafff8cd8bc0caa4f856e3650692265c9",
"body": null,
"is_bot": false,
"headline": "Change default hydrate method to Towler, bump version to 3.0.3",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-06T05:24:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "aeae4d17481a675f7869ffcf482af3da9820fd86",
"body": "inhibitor_underdosed means the inhibitor TYPE is insufficient (required\nwt% exceeds physical max), not that the applied dose is insufficient.\nUpdated gas.rst attribute table, HydrateResult dataclass docstring, and\nnotebook cell 6a with explicit \"Protected?\" check and explanatory notes.",
"is_bot": false,
"headline": "Clarify inhibitor_underdosed field semantics in docs and notebook",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-06T04:25:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "60357c7c8ae4480f7e5d6ac8179b5a9b4adba941",
"body": "gas_hydrate(): Full hydrate formation prediction with HFT/HFP (Motiee/\nTowler), inhibitor depression (Ostergaard), 5 inhibitor types with\nphysical concentration caps, water balance (vaporized/condensed/free),\ninjection rate calculation, SoreideWhitson/Danesh water content,\nreservoir P,T decoupling, \n[…]\nto\npass actual rsb instead of current Rs.\n\nNew nodal_hydrate_demo.ipynb: VLP, VFPPROD, nodal solutions, hydrate\nanalysis across gas/oil systems with Field and Metric examples.\n\n416 tests, all passing.",
"is_bot": false,
"headline": "Release 3.0.2: gas hydrate prediction, oil Co bugfixes, demo notebook",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-06T04:13:09Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "aef0c64499607dea001ecd24ed16ff231618db1d",
"body": "New gas_hydrate() function with Motiee (1991) and Towler & Mokhatab (2005)\nHFT correlations, bisection HFP inversion, Østergaard et al. (2005) inhibitor\ndepression, and Newton-Raphson required concentration solver. Five inhibitor\ntypes (MeOH, MEG, DEG, TEG, EtOH). Returns HydrateResult dataclass. Full\nEclipse METRIC unit support. 17 new tests (13 module + 4 doc examples), 392 total.",
"is_bot": false,
"headline": "Add gas hydrate formation prediction and inhibitor calculations",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-05T12:22:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "38ed9ab9513cd87e6a2900073906257403960ae2",
"body": null,
"is_bot": false,
"headline": "Finalize 3.0.1 changelist for release",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-01T13:14:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "00225ba84142e61ff8106a462fadeb320b27818a",
"body": "… relocation\n\nOilPVT constructor now accepts degf, uo_target, p_uo for automatic\nharmonization via oil_harmonize(). rsb is optional when degf is provided.\nfrom_harmonize() simplified to thin wrapper (deprecated).\n\noil_rate_radial/linear accept oil_pvt + degf; gas_rate_radial/linear\naccept gas_pvt — \n[…]\ntes manual PVT lookups for rate calculations.\n\nOilPVT docs moved from nodal.rst to oil.rst; GasPVT docs moved from\nnodal.rst to gas.rst. Cross-references remain in nodal.rst.\n\n375 tests pass (25 new).",
"is_bot": false,
"headline": "Add OilPVT auto-harmonization, PVT objects in rate functions, and doc…",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-03-01T12:58:50Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "12ac87388bf4a31842b7573fc26031518c076185",
"body": "- Completion.geometry_at_md(): query wellbore geometry at any MD\n- Completion.profile(): DataFrame of wellbore profile at segment boundaries\n- Explicit __all__ in all modules for programmatic API discoverability\n- Function-index docstrings on all submodules for help() usability\n- Document outflow_curve() return dict keys\n- 12 new tests, updated docs and changelist for 3.0.1",
"is_bot": false,
"headline": "Add Completion geometry methods, __all__ exports, and module docstrings",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-02-28T22:34:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9b62166063802f3f7d9f1533f485ab162b4f0875",
"body": "Replace 'Unpublished, created by M. Burgoyne 2024' with published\npaper citation: Burgoyne, Nielsen & Stanko (2025), SPE-229932-MS",
"is_bot": false,
"headline": "Update BNS/BUR method references to SPE-229932-MS",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-02-28T06:41:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "82e87c86cd8fe444b8fd1b9a23887681996bf4fc",
"body": null,
"is_bot": false,
"headline": "Remove .gitignore from tracking",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-02-28T05:54:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3eda99e5a9e232c24dab9e88e4a0df35e55a3250",
"body": "- Add setup.py, setup.cfg, pyproject.toml, MANIFEST.in for pip packaging\n- Add .gitignore to exclude build artifacts, __pycache__, and local files\n- Update __init__.py: add 'nodal' to submodules, refresh module docstring",
"is_bot": false,
"headline": "Add build config, .gitignore, and update package init",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-02-28T05:52:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "dd48c1825852bcb45d7956fa23982baba35b955a",
"body": null,
"is_bot": false,
"headline": "Add files via upload",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-02-28T03:15:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "88b87e2c376f6ff0a04a3d5a521dca3b3c2e7ab6",
"body": null,
"is_bot": false,
"headline": "V3.0 release",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-02-28T02:55:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2787bd66aa5630f4f1a68dcd26de35c554dbe839",
"body": null,
"is_bot": false,
"headline": "v3.0",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-02-28T00:47:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ff1cd8cbddb4bcda5a6a7f7fbe53b4673f43830e",
"body": null,
"is_bot": false,
"headline": "Add files via upload",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-02-27T23:34:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "717eac02ef12f29ff138738fa748ee72aec8d534",
"body": null,
"is_bot": false,
"headline": "Add files via upload",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-02-27T23:34:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ab2d49cb65bc967d2d3773df0224698c95140e9b",
"body": null,
"is_bot": false,
"headline": "Add files via upload",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-02-27T23:33:57Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2637944c0176a6b2ba4a814e56e006fdeed552d4",
"body": null,
"is_bot": false,
"headline": "Add files via upload",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-02-27T23:06:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bf3242999c36817cea829100c54b1d0d91441d26",
"body": null,
"is_bot": false,
"headline": "Update README.rst",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-02-27T23:02:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "858951f701c173707ecff71edd41de6d4b1bcd69",
"body": null,
"is_bot": false,
"headline": "Delete setup.py",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-02-27T23:00:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "dd234fc078836d3f2edf0ccdb2788de42e4535e2",
"body": null,
"is_bot": false,
"headline": "Delete setup.cfg",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-02-27T23:00:30Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f60027b7b9b4cbfa4de388f602d25f2e1909c87e",
"body": null,
"is_bot": false,
"headline": "Delete pyrestoolbox/pyrestoolbox.py",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-02-27T22:59:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "90cf1efeacd43341038526b28d3e960c74b669c5",
"body": null,
"is_bot": false,
"headline": "Delete pyrestoolbox/component_library.xlsx",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-02-27T22:59:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "29fe2d2d271f05a8047f10e154c3235dacdacc03",
"body": null,
"is_bot": false,
"headline": "Delete pyrestoolbox/validate/__pycache__ directory",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-02-27T22:58:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bea3ee1616b998fd8bb72bdad873ffff769a0d12",
"body": null,
"is_bot": false,
"headline": "Delete pyrestoolbox/tests/__pycache__ directory",
"author_name": "Mark W. Burgoyne",
"author_login": "mwburgoyne",
"committed_at": "2026-02-27T22:58:42Z",
"body_truncated": false,
"is_coding_agent": false
}
],
"releases_count": 45,
"commits_last_year": 125,
"latest_release_at": "2026-07-25T09:40:03Z",
"latest_release_tag": "v3.7.2",
"releases_from_tags": false,
"days_since_last_push": 0,
"active_weeks_last_year": 17,
"days_since_latest_release": 0,
"mean_days_between_releases": 6.1
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": false,
"health_percentage": 42,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "pyrestoolbox",
"exists": true,
"license": "GPL-3.0-or-later",
"keywords": [
"restoolbox",
"petroleum",
"reservoir",
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Rust"
],
"ecosystem": "pypi",
"matches_repo": true,
"registry_url": "https://pypi.org/project/pyrestoolbox/",
"is_deprecated": false,
"latest_version": "3.7.2",
"repository_url": "https://github.com/mwburgoyne/pyResToolbox",
"versions_count": 54,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": 3185,
"first_published_at": "2022-01-07T03:16:27.244699Z",
"latest_published_at": "2026-07-25T09:39:52.784467Z",
"latest_version_yanked": null,
"days_since_latest_publish": 0
}
]
},
"popularity": {
"forks": 19,
"stars": 90,
"watchers": 3,
"fork_history": {
"days": [
{
"date": "2022-01-09",
"count": 1
},
{
"date": "2022-01-11",
"count": 1
},
{
"date": "2022-01-13",
"count": 1
},
{
"date": "2022-01-20",
"count": 1
},
{
"date": "2022-01-25",
"count": 1
},
{
"date": "2022-01-26",
"count": 1
},
{
"date": "2022-03-04",
"count": 1
},
{
"date": "2022-04-07",
"count": 1
},
{
"date": "2022-07-21",
"count": 1
},
{
"date": "2024-07-01",
"count": 1
},
{
"date": "2025-02-15",
"count": 1
},
{
"date": "2025-09-03",
"count": 1
},
{
"date": "2025-11-20",
"count": 1
},
{
"date": "2026-01-27",
"count": 1
},
{
"date": "2026-04-06",
"count": 1
},
{
"date": "2026-04-09",
"count": 1
},
{
"date": "2026-04-25",
"count": 1
}
],
"complete": true,
"collected": 17,
"total_forks": 19
},
"star_history": null,
"open_issues_and_prs": 0
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [
"notebooks"
],
"has_llms_txt": false,
"has_dockerfile": true,
"has_mcp_signal": true,
"bootstrap_files": [],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [],
"toolchain_manifests": [
"Cargo.toml"
],
"largest_source_bytes": 96833,
"source_files_sampled": 113,
"oversized_source_files": 5,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"dependencies": {
"manifests": [
"Cargo.toml",
"mcp/pyproject.toml",
"pyproject.toml",
"setup.cfg",
"setup.py"
],
"advisories": {
"error": null,
"scope": "repository_graph",
"source": "osv",
"findings": [
{
"name": "pyo3",
"direct": true,
"version": "0.23.5",
"severity": "high",
"ecosystem": "crates",
"cvss_score": 7.5,
"advisory_ids": [
"GHSA-36hh-v3qg-5jq4",
"GHSA-chgr-c6px-7xpp",
"GHSA-pph8-gcv7-4qj5",
"RUSTSEC-2025-0020",
"RUSTSEC-2026-0177"
],
"fixed_version": "0.29.0",
"advisory_count": 5,
"oldest_advisory_days": 479
}
],
"collected": true,
"malicious": [],
"truncated": false,
"by_severity": {
"high": 1
},
"advisory_count": 5,
"affected_count": 1,
"assessed_count": 26,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 13,
"direct_affected_count": 1
},
"ecosystems": [
"crates",
"pypi"
],
"dependencies": [
{
"name": "pyo3",
"manifest": "Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.23"
},
{
"name": "rug",
"manifest": "Cargo.toml",
"ecosystem": "crates",
"version_constraint": "1"
},
{
"name": "mcp",
"manifest": "mcp/pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=1.2"
},
{
"name": "pyrestoolbox",
"manifest": "mcp/pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=3.7"
},
{
"name": "numpy",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "scipy",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "pandas",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "tabulate",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "ilt-inversion",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "mpmath",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "gmpy2",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "python-flint",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "openpyxl",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "numpy",
"manifest": "setup.cfg",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "scipy",
"manifest": "setup.cfg",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "pandas",
"manifest": "setup.cfg",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "tabulate",
"manifest": "setup.cfg",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "ilt-inversion",
"manifest": "setup.cfg",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "mpmath",
"manifest": "setup.cfg",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "gmpy2",
"manifest": "setup.cfg",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "python-flint",
"manifest": "setup.cfg",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "openpyxl",
"manifest": "setup.cfg",
"ecosystem": "pypi",
"version_constraint": null
}
],
"all_dependencies": {
"error": null,
"source": "github-sbom",
"packages": [
{
"name": "pyo3",
"direct": true,
"version": "0.23.5",
"ecosystem": "crates"
},
{
"name": "rug",
"direct": true,
"version": "1.29.0",
"ecosystem": "crates"
},
{
"name": "gmpy2",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "ilt-inversion",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "mcp",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "mpmath",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "numpy",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "openpyxl",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pandas",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pyrestoolbox",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "python-flint",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "scipy",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tabulate",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "autocfg",
"direct": false,
"version": "1.5.0",
"ecosystem": "crates"
},
{
"name": "az",
"direct": false,
"version": "1.3.0",
"ecosystem": "crates"
},
{
"name": "cfg-if",
"direct": false,
"version": "1.0.4",
"ecosystem": "crates"
},
{
"name": "gmp-mpfr-sys",
"direct": false,
"version": "1.7.0",
"ecosystem": "crates"
},
{
"name": "heck",
"direct": false,
"version": "0.5.0",
"ecosystem": "crates"
},
{
"name": "indoc",
"direct": false,
"version": "2.0.7",
"ecosystem": "crates"
},
{
"name": "libc",
"direct": false,
"version": "0.2.184",
"ecosystem": "crates"
},
{
"name": "libm",
"direct": false,
"version": "0.2.16",
"ecosystem": "crates"
},
{
"name": "memoffset",
"direct": false,
"version": "0.9.1",
"ecosystem": "crates"
},
{
"name": "once_cell",
"direct": false,
"version": "1.21.4",
"ecosystem": "crates"
},
{
"name": "portable-atomic",
"direct": false,
"version": "1.13.1",
"ecosystem": "crates"
},
{
"name": "proc-macro2",
"direct": false,
"version": "1.0.106",
"ecosystem": "crates"
},
{
"name": "pyo3-build-config",
"direct": false,
"version": "0.23.5",
"ecosystem": "crates"
},
{
"name": "pyo3-ffi",
"direct": false,
"version": "0.23.5",
"ecosystem": "crates"
},
{
"name": "pyo3-macros",
"direct": false,
"version": "0.23.5",
"ecosystem": "crates"
},
{
"name": "pyo3-macros-backend",
"direct": false,
"version": "0.23.5",
"ecosystem": "crates"
},
{
"name": "quote",
"direct": false,
"version": "1.0.45",
"ecosystem": "crates"
},
{
"name": "rustversion",
"direct": false,
"version": "1.0.22",
"ecosystem": "crates"
},
{
"name": "syn",
"direct": false,
"version": "2.0.117",
"ecosystem": "crates"
},
{
"name": "target-lexicon",
"direct": false,
"version": "0.12.16",
"ecosystem": "crates"
},
{
"name": "unicode-ident",
"direct": false,
"version": "1.0.24",
"ecosystem": "crates"
},
{
"name": "unindent",
"direct": false,
"version": "0.2.4",
"ecosystem": "crates"
},
{
"name": "windows-link",
"direct": false,
"version": "0.2.1",
"ecosystem": "crates"
},
{
"name": "windows-sys",
"direct": false,
"version": "0.61.2",
"ecosystem": "crates"
},
{
"name": "maturin",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "setuptools",
"direct": false,
"version": null,
"ecosystem": "pypi"
}
],
"collected": true,
"truncated": false,
"total_count": 39,
"direct_count": 13,
"indirect_count": 26
}
},
"maintainership": {
"issues": {
"open_prs": 0,
"merged_prs": 2,
"open_issues": 0,
"closed_ratio": null,
"closed_issues": 0,
"closed_unmerged_prs": 0
},
"bus_factor": 1,
"bot_contributors": 0,
"top_contributors": [
{
"type": "User",
"login": "mwburgoyne",
"commits": 367,
"avatar_url": "https://avatars.githubusercontent.com/u/29671046?v=4"
},
{
"type": "User",
"login": "mwentzWW",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/31914755?v=4"
},
{
"type": "User",
"login": "pkirkham",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/9302840?v=4"
}
],
"contributors_sampled": 3,
"top_contributor_share": 0.995
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"build-wheels.yml",
"tests.yml"
],
"has_docs_dir": false,
"linter_configs": [],
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [
"Cargo.lock"
],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 10,
"reason": "no binaries found in the repo",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": 0,
"reason": "branch protection not enabled on development/release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": null,
"reason": "no pull request found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 0,
"reason": "Found 0/30 approved changesets -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 0,
"reason": "project has 0 contributing companies or organizations -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 0,
"reason": "no update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 10,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 10,
"reason": "24 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": 10,
"reason": "packaging workflow detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
},
{
"name": "Pinned-Dependencies",
"score": 0,
"reason": "dependency not pinned by hash detected -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "no SAST tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 0,
"reason": "security policy file not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": null,
"reason": "no releases found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 10,
"reason": "GitHub workflow tokens follow principle of least privilege",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 7,
"reason": "3 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "55aa5224c6b42da14d722704aa61e30deab2e981",
"ran_at": "2026-07-25T09:48:01Z",
"aggregate_score": 4.8,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": false
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-25T09:35:30Z",
"oldest_open_prs": [],
"last_merged_pr_at": "2026-04-09T04:47:40Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": []
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/mwburgoyne/pyResToolbox",
"host": "github.com",
"name": "pyResToolbox",
"owner": "mwburgoyne"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 61,
"inputs": {
"security": 51,
"vitality": 86,
"community": 50,
"governance": 56,
"engineering": 56
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "excellent",
"name": "Vitality",
"value": 86,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "good",
"name": "Development activity",
"note": null,
"notes": [],
"value": 76,
"inputs": {
"commits_last_year": 125,
"human_commit_share": 1,
"days_since_last_push": 0,
"active_weeks_last_year": 17
},
"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": "17/52 weeks with commits",
"points": 11.8,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 17
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "125 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 125
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "24 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 100,
"inputs": {
"releases_count": 45,
"latest_release_tag": "v3.7.2",
"releases_from_tags": false,
"days_since_latest_release": 0,
"mean_days_between_releases": 6.1
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "45 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 45
}
}
],
"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 ~6.1 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 6.1
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "excellent",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "maintained",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": null,
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": 0,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "last human commit 0 days ago",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_maintained",
"params": {
"days": 0
}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "moderate",
"name": "Community & Adoption",
"value": 50,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "at_risk",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 44,
"inputs": {
"forks": 19,
"stars": 90,
"watchers": 3,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "90 stars",
"points": 31.6,
"status": "partial",
"details": [
{
"code": "stars",
"params": {
"count": 90
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "19 forks",
"points": 10.5,
"status": "partial",
"details": [
{
"code": "forks",
"params": {
"count": 19
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "3 watchers",
"points": 1.7,
"status": "partial",
"details": [
{
"code": "watchers",
"params": {
"count": 3
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "moderate",
"name": "Community health",
"note": null,
"notes": [],
"value": 50,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": false,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (GPL-3.0)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "GPL-3.0"
}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.3
}
]
},
{
"key": "ecosystem_adoption",
"band": "moderate",
"name": "Ecosystem adoption (downloads)",
"note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"registry_dependents"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 58,
"inputs": {
"packages": [
"pyrestoolbox"
],
"dependents": null,
"ecosystems": "pypi",
"total_downloads": null,
"monthly_downloads": 3185
},
"components": [
{
"key": "monthly_downloads",
"name": "Monthly downloads",
"detail": "3,185 downloads/month across pypi",
"points": 46.7,
"status": "partial",
"details": [
{
"code": "downloads_monthly",
"params": {
"count": 3185,
"ecosystems": "pypi"
}
}
],
"max_points": 80
},
{
"key": "registry_dependents",
"name": "Registry dependents",
"detail": "not reported by this ecosystem",
"points": 0,
"status": "excluded",
"details": [
{
"code": "not_reported_by_this_ecosystem",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 56,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 13,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 3,
"top_contributor_share": 0.995
},
"components": [
{
"key": "bus_factor",
"name": "Bus factor",
"detail": "1 contributor(s) cover half of all commits",
"points": 9,
"status": "partial",
"details": [
{
"code": "bus_factor",
"params": {
"count": 1
}
}
],
"max_points": 54
},
{
"key": "commit_distribution",
"name": "Commit distribution",
"detail": "top contributor authored 100% of commits",
"points": 0.1,
"status": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 100
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "3 contributors",
"points": 4.1,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 3
}
}
],
"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): Issue resolution. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"issue_resolution"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 72,
"inputs": {
"merged_prs": 2,
"open_issues": 0,
"closed_issues": 0,
"issue_closed_ratio": null,
"closed_unmerged_prs": 0
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "no issues or no data",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_issues_or_data",
"params": {}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "2/2 decided PRs merged",
"points": 38.2,
"status": "met",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 2,
"decided": 2
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "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": 58,
"inputs": {
"followers": 140,
"owner_type": "User",
"is_verified": null,
"owner_login": "mwburgoyne",
"public_repos": 15,
"account_age_days": 3318
},
"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": "140 followers of mwburgoyne",
"points": 15.5,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 140,
"login": "mwburgoyne"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "15 public repos, account ~9 yr old",
"points": 20.8,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 15
}
},
{
"code": "account_age_years",
"params": {
"years": 9
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"pyrestoolbox"
],
"ecosystems": "pypi",
"any_deprecated": false,
"min_days_since_publish": 0
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "1 package(s) on pypi",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 1,
"ecosystems": "pypi"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 0 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 0
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "54 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 54
}
}
],
"max_points": 20
},
{
"key": "not_deprecated",
"name": "Not deprecated",
"detail": "active, not deprecated or yanked",
"points": 20,
"status": "met",
"details": [
{
"code": "package_not_deprecated",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
},
{
"key": "engineering",
"band": "moderate",
"name": "Engineering Quality",
"value": 56,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "moderate",
"name": "Engineering practices",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_ci_tests"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 60,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "2 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 2
}
}
],
"max_points": 24
},
{
"key": "tests_present",
"name": "Tests present",
"detail": null,
"points": 24,
"status": "met",
"details": [],
"max_points": 24
},
{
"key": "linter_config",
"name": "Linter config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "no pull request found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "moderate",
"name": "Documentation",
"note": null,
"notes": [],
"value": 50,
"inputs": {
"topics": [],
"has_wiki": true,
"homepage": null,
"has_readme": true,
"has_docs_dir": false,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "moderate",
"name": "Security",
"value": 51,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "at_risk",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): CI-Tests, Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"ci_tests",
"signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 48,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 16,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 2,
"scorecard_aggregate": 4.8
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "no binaries found in the repo",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "branch protection not enabled on development/release branches",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "no pull request found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 0 contributing companies or organizations -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "no update tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "24 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow detected",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "pinned_dependencies",
"name": "Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "no SAST tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "GitHub workflow tokens follow principle of least privilege",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "3 existing vulnerabilities detected",
"points": 5.2,
"status": "partial",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "dependency_advisories",
"band": "moderate",
"name": "Dependency advisories",
"note": "Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories. Remaining weights renormalized. Matched 26 resolved dependencies against OSV; 13 could not be assessed (no resolved version, an unsupported ecosystem, or beyond the reported package list). This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"indirect_dependencies_free_of_known_advisories"
]
}
},
{
"code": "weights_renormalized",
"params": {}
},
{
"code": "advisories_scope_repository",
"params": {
"assessed": 26
}
},
{
"code": "advisories_unassessed",
"params": {
"count": 13
}
},
{
"code": "advisories_repo_graph_caveat",
"params": {}
},
{
"code": "advisories_reachability",
"params": {}
}
],
"value": 64,
"inputs": {
"source": "osv",
"advisories": 5,
"affected_packages": 1,
"assessed_packages": 26,
"unassessed_packages": 13,
"affected_by_severity": "high 1",
"direct_affected_packages": 1
},
"components": [
{
"key": "direct_dependencies_free_of_known_advisories",
"name": "Direct dependencies free of known advisories",
"detail": "1 affected: pyo3 0.23.5 (high 7.5)",
"points": 14,
"status": "partial",
"details": [
{
"code": "advisories_affected",
"params": {
"count": 1,
"packages": "pyo3 0.23.5 (high 7.5)"
}
}
],
"max_points": 35
},
{
"key": "indirect_dependencies_free_of_known_advisories",
"name": "Indirect dependencies free of known advisories",
"detail": "transitive set not separable from development and test dependencies in this scope",
"points": 0,
"status": "excluded",
"details": [
{
"code": "advisories_scope_not_separable",
"params": {}
}
],
"max_points": 25
},
{
"key": "no_advisories_left_outstanding",
"name": "No advisories left outstanding",
"detail": "1 advisory-carrying package(s) unaddressed past 90 days; oldest published 479 days ago",
"points": 33.7,
"status": "partial",
"details": [
{
"code": "advisories_stale",
"params": {
"days": 90,
"count": 1,
"oldest": 479
}
}
],
"max_points": 40
}
]
},
{
"key": "malicious_dependencies",
"band": "excellent",
"name": "Malicious dependencies",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"source": "osv",
"meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
"packages": [],
"red_flag": false,
"assessed_packages": 26,
"malicious_packages": 0,
"direct_malicious_packages": 0,
"withdrawn_malicious_packages": 0,
"installable_malicious_packages": 0
},
"components": [
{
"key": "no_dependency_reported_as_a_malicious_package",
"name": "No dependency reported as a malicious package",
"detail": "no dependency is reported as a malicious package",
"points": 100,
"status": "met",
"details": [
{
"code": "no_malicious_dependencies",
"params": {}
}
],
"max_points": 100
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "excellent",
"name": "High-Risk Jurisdiction Exposure",
"note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
"notes": [
{
"code": "jurisdiction_evidence_limits",
"params": {}
}
],
"value": 100,
"inputs": {
"meaning": "self-published location evidence; not nationality or citizenship",
"red_flag": false,
"exposures": [],
"policy_countries": [
"Russia",
"Iran",
"North Korea"
],
"review_only_matches": 0,
"assessed_self_published_locations": 2
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "at_risk",
"name": "AI Readiness",
"value": 49,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "at_risk",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 35,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 0.66,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "no CLAUDE.md / AGENTS.md / editor rules",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_instructions",
"params": {}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "66 of 100 human commits state their intent (structured subject or explanatory body)",
"points": 35.2,
"status": "partial",
"details": [
{
"code": "legible_history",
"params": {
"legible": 66,
"sampled": 100
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "moderate",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 55,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [
"Cargo.lock"
],
"has_dockerfile": true,
"typed_language": false,
"bootstrap_files": [],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [],
"agent_commit_share": 0.07,
"toolchain_manifests": [
"Cargo.toml"
],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": "Cargo.toml (toolchain convention, no task runner)",
"points": 12.6,
"status": "partial",
"details": [
{
"code": "toolchain_convention",
"params": {
"files": "Cargo.toml"
}
}
],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": "Dockerfile, lockfile",
"points": 10,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "Dockerfile, lockfile"
}
}
],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "7 of the last 100 commits agent-authored or agent-credited",
"points": 10,
"status": "met",
"details": [
{
"code": "agent_authored_commits",
"params": {
"count": 7,
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "no automated dependency updates observed",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_dependency_automation",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "moderate",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 53,
"inputs": {
"primary_language": "Python",
"largest_source_bytes": 96833,
"source_files_sampled": 113,
"oversized_source_files": 5
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "Python without a type-check config",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_typecheck_config_language",
"params": {
"language": "Python"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "5/113 source files over 60KB",
"points": 52.6,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 113,
"oversized": 5
}
}
],
"max_points": 55
}
]
},
{
"key": "ai_interfaces",
"band": "moderate",
"name": "Machine-readable interfaces",
"note": null,
"notes": [],
"value": 60,
"inputs": {
"example_dirs": [
"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": "notebooks",
"points": 40,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "notebooks"
}
}
],
"max_points": 40
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
}
],
"metrics_version": "1.13.0"
},
"warnings": [
"Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
"Could not fetch crates package 'pyrestoolbox-native' from its registry",
"Could not fetch pypi package 'pyrestoolbox-mcp' from its registry",
"deps.dev does not index pypi:pyrestoolbox@3.7.2; advisories assessed against the repository dependency graph instead"
],
"report_type": "repository",
"generated_at": "2026-07-25T09:48:07.109714Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/m/mwburgoyne/pyResToolbox.svg",
"full_name": "mwburgoyne/pyResToolbox",
"license_state": "standard",
"license_spdx": "GPL-3.0"
}