Changelog#
Notable changes to jaxlint are listed here. Versions match the version field in pyproject.toml at release time.
0.1.0a1#
Pre-release (alpha): PEP 440 version
0.1.0a1— first PyPI-oriented line still underDevelopment Status :: 3 - Alpha. Usepip install --pre jaxlintor pinjaxlint==0.1.0a1until a stable0.1.0.License: jaxlint is distributed under the MIT License (see repository
LICENSE).Packaging / metadata: PyPI runway —
[project.urls], Python 3.11 / 3.12 classifiers,Typing :: Typed, reconciled authors — semver reset to the 0.1.x pre-release line.Historical numbering: Sections labeled 0.3.x–0.4.x below document development history prior to the 0.1.x public-metadata reset; treat them as archival changelog sections, not distinct PyPI lines unless that version was already published.
Library / CLI: Default
-j/run_checks(..., jobs=None)usesos.process_cpu_count()on Python 3.13+ and falls back toos.cpu_count()on 3.11 / 3.12 (avoidsAttributeErrorin CI and on older runtimes).Docs: Sphinx linkcheck ignores the OASIS SARIF spec URL (often returns 403 to automated clients).
0.4.1#
SARIF: Each run includes
tool.driver.rules: one reportingDescriptor per distinctruleIdinresults, ordered by first occurrence inDiagnostic.sort_key()order. Known ids use the built-in catalogue (shortDescription,defaultConfiguration.level= default rule severity). Unknown ids useshortDescription"Unknown or custom rule"and omitdefaultConfiguration. EveryresultsetsruleIndexinto thatrulesarray.results[].levelstays the effective severity (afterseverity-overridesand related logic); descriptor defaults document the catalogue only.Config: Optional
sarif-rule-docs-base(HTTPS URL string) under[jaxlint]or[tool.jaxlint]. When set, each rule descriptor getshelpUri= base (trailing slashes trimmed) +/+rule_id. Empty or non-HTTPS values are rejected at parse time. Programmatic SARIF must passcfgintoformat_sarif/format_diagnosticsfor this (see Library).Testing: Tests marked
needs_jaxusepytest-timeout(60s per test function only —timeout_func_onlyinpyproject.toml; markers applied intests/conftest.py).
0.4.0#
CLI:
--format richnow wraps diagnostics in a panel with a severity summary line (error=/warning=/info=counts), configurable width viaCOLUMNS, terminal size when interactive, or 120 columns when stdout is not a TTY. Location may use OSC 8file:hyperlinks when stdout is a TTY andNO_COLORis unset (plain text when piped or when colors are off). See CLI.
0.3.2#
LSP: Server-side debounce and cancellation for
textDocument/didChange: environment variableJAXLINT_LSP_DEBOUNCE_MS(default 200 ms;0disables debounce and restores the previous immediate, sequential behaviour). Per-file canonical URI state: cancel prior debounced asyncio work, generation guard so superseded runs do not publish,didCloseinvalidation and empty diagnostics, live buffer read in the thread worker after debounce. See Language server.
Unreleased#
Docs / HLO: Goldens: mapping vs counts explains
get_operation_inventoryvsget_source_mappingvsget_operations; ADR 0001 tracks Phase A feasibility beforeHLO*rules.LSP (optional):
jaxlint[lsp]adds a diagnostics-only language server (stdio, full document sync,file://URIs only). Entrypoints:jaxlint-lsp,python -m jaxlint.lsp. Usesload_config(path.parent)anddiagnostics_for_python_source(no disk cache in the server path). See Language server.Library:
diagnostics_for_python_sourceonjaxlint.corefor path + source string (sorted diagnostics; cache-free).CI: PR
lint-testsyncs with--extra lsp/--extra mcpand runs full pytest + coverage (same gate as main).Docs / roadmap: LSP sprint notes (
jaxlint-sprint-2026-11) table aligned with plan IDs (L01–L06); formal outcome review APPROVE-with-nits (2026-05-05, no blocking DoD gaps). Open TODOs for non-blocking LSP v1 nits were closed in 0.2.2 (see Roadmap).Performance / CLI: Opt-in disk cache for
jaxlint check:--cache-dir PATHand optional[tool.jaxlint] cache-dir(CLI wins when both are set). Cached entries are keyed by file identity (mtime/size), lint configuration fingerprint, andjaxlintversion. Writes use atomic replace; POSIX usesflockon lock files next to cache blobs.CLI: Invalid
--jobs/-jvalues (for example-j 0) onjaxlint checknow exit with code 2 and a clear message instead of an uncaught traceback.Docs: Roadmap Canonical hosted URLs table plus refreshed
linkcheck_ignorecomments indocs/conf.py(curl -sI -L, 2026-05-06); canonical RTD/GitHub URLs still 404; next review 2026-10-01.Testing: Golden StableHLO under
tests/fixtures/hlo/: outfeed /stablehlo.whileaudit_exportedpaths, plusadd_constant_kernel/multiply_reshape_kernelinventory goldens (duck-typed fake exports;needs_jax). Merge-blocking jax-hlo CI installsjaxlint[hlo]and JAX.CI: On pull requests, the
docsjob runs only whendocs/**,.readthedocs.yml, orREADME.mdchange;main/masterpushes always run it (see workflow header comment for frozen globs).CI: The
jax-hloworkflow pinsjax==0.10.0andjaxlib==0.10.0afteruv syncsoneeds_jaxruns stay reproducible.CLI:
jaxlint checkandjaxlint docaccept--format rich(Rich table: severity, rule, location, message). Depends on explicitrich(seepyproject.toml).Docs: Added this changelog (per roadmap steering).
0.3.1#
Configuration: Native
[jaxlint]table injaxlint.toml(recommended). Legacy[tool.jaxlint]remains valid injaxlint.toml; both sections in the same file is a load-time error.pyproject.tomluses[tool.jaxlint]only — a top-level[jaxlint]table is rejected.jaxlint initemits[jaxlint]. Equivalent native vs legacyjaxlint.tomlyields identicalLintConfig(disk cacheCACHE_FORMAT_VERSIONunchanged).
0.3.0#
Configuration: Optional
jaxlint.tomlin each directory is preferred overpyproject.tomlduring upward discovery; both in the same directory is a load-time error.--configmay point at ajaxlint.tomlorpyproject.tomlfile (parse in place, no walk) or at a directory (walk). Relativecache-dirand other paths resolve against the directory containing the loaded config file.Severity:
severity-overridesunder[tool.jaxlint](or[tool.jaxlint.severity-overrides]) maps rule patterns toerror/warning/info. Overrides apply after sensors andrule_enabled, so they win over JL005strict-shapespromotions. Unknown override keys and invalid severities fail at parse time. Pattern matching matchesselect/ignore(pattern_matches).Cache:
CACHE_FORMAT_VERSIONbumped to2; canonical config fingerprint includesseverity-overrides(sorted keys).Exports: SARIF and GitHub annotations JSON use
Diagnostic.severityas emitted by the runner (post-overrides); no separate severity remap in formatters.Docs / CLI: Updated configuration and CLI reference;
starter_toml_snippet()mentionsseverity-overrides.
0.2.3#
MCP (agent-grade v1):
jaxlint_checkaccepts optionalstructured(JSON envelopejaxlint.mcp.v1withsuccess,diagnostics,error,metaincludingelapsed_msandpaths_resolved),jobs, andcache_dir(path mode only; forwarded torun_checks). Defaultstructured=falsepreserves legacy behaviour (diagnostic array JSON orerror:strings). Source mode rejectsjobs/cache_dirwithunsupported_optionwhen structured. Invalidjobsmaps toinvalid_argument(legacyerror:+ message).MCP: New
jaxlint_capabilitiestool — JSON document withschema_version,package_version, and registered tool metadata (MCP_TOOLS_REGISTRYsingle source of truth).Tests / docs:
pytest -m mcpcovers structured envelopes, option validation, and capabilities; README + roadmap sprint notes updated.
0.2.2#
LSP: Module-level
pytest.mark.lspontests/test_lsp_convert.pyandtests/test_diagnostics_for_python_source.py; PR CI runsuv run pytest -q -m lsp. Subprocess coverage fortextDocument/didClosepublishing empty diagnostics;docs/lsp.mddocuments the clear behaviour. Contributing documents thepytest -m lspworkflow. Roadmap Open TODOs (LSP v1 reviewer nits) checked off where satisfied (see Roadmap).MCP (preview): Optional
jaxlint[mcp]installs the officialmcpSDK. Console scriptjaxlint-mcpandpython -m jaxlint.mcprun a stdio FastMCP server exposingjaxlint_check(paths or in-memorysource+virtual_path),jaxlint_rules, andjaxlint_version. Tests:pytest -q -m mcp(CIlint-testsyncs--extra lsp --extra mcp).
0.2.1#
Performance: Single
read_text+ singleast.parseper file when both performance sensors and doc/MathJax checks run (run_checkscombined path).Library / CLI:
run_checks(..., jobs=...)with defaultmin(32, os.process_cpu_count() or 1);jobs=1serial;jobs>1uses a thread pool over files.jaxlint checkexposes-j/--jobs. Return value islist[Diagnostic]sorted byDiagnostic.sort_key()(stable ordering contract).Internals:
ParsedPythonFile/load_parsed_python_fileinjaxlint.core.parse_context; perf sensors take(tree, path)(no internal parse).
0.2.0#
Packaged release line aligned with the shipped CLI, rules engine, SARIF / compact / GitHub diagnostic formats, Sphinx docs (including API reference for jaxlint.core), and optional jaxlint[hlo] analysis with merge-blocking needs_jax coverage. See the Shipped baseline section in the Roadmap.