All notable changes to forti4d are documented here. The format follows Keep a Changelog. Semantic Versioning is used from v0.7.0 onward; earlier releases (v0.1–v0.6) were tagged incrementally before SemVer was adopted.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/acdeveloper-sci/forti4d/llms.txt
Use this file to discover all available pages before exploring further.
v0.8.0 — 2026-08-01
Added
- In-process library API (Bloque 1):
import forti4d; forti4d.run_pipeline(...)runs the full pipeline without subprocess — no more shelling out topython -m forti4d.pipeline. All 19 analyzers now follow a consistentanalyze_xxx()/write_xxx()/main()contract, returning results in memory in addition to (never instead of) writing their CSV/report files. CLI behavior, flags, and output files are unchanged. - Opt-in per-file parallelism (Bloque 2):
--workers N/FORT_WORKERSparallelizes the three heaviest, fully-independent-per-file steps —inventory,profiler,blocks— viaProcessPoolExecutor. Default isworkers=1(sequential); behavior is unchanged unless explicitly requested.forti4d/lib/parallel.py::pmap()guarantees sequential/parallel output parity by construction — both modes run the exact same code path. - Real logging via loguru (Bloque 3): all internal
print()diagnostics across the 19 analyzers replaced withlogger.debug/info/success/warning/error()calls. Every run now writes a full-detail log to<results_dir>/forti4d.log(always DEBUG+, regardless of--quiet); new--log-file PATHand--no-log-fileCLI flags override or disable it. Library callers (forti4d.run_pipeline()) stay silent by default — call the newforti4d.configure_logging()to opt in to console/file output.loguruis forti4d’s first third-party dependency.
Changed
--quietredefined: now a console log-level filter (WARNING+ instead of INFO+) rather than an all-or-nothing toggle. Previously a successful--quietrun discarded all internal diagnostic output with no trace anywhere; now it’s always captured inforti4d.log.run_pipeline()’son_step_endcallback signature changed from(name, success, elapsed, error, output)to(name, success, elapsed, error)— theoutputparam (captured stdout) is gone now that step output goes through loguru instead ofredirect_stdout.run_pipeline()also drops itsquiet=parameter (superseded byconfigure_logging()).
Fixed
clones.py::build_file_index: indexed Fortran source files by basename (f.name) instead of relative path — silently dropped all but one file when multiple files share the same name in different subdirectories (e.g.,main.Fin 19 subdirs of FVCOM); changed tof.relative_to(path).dependencies.py::load_inventory_enhanced: usedFile(basename) as the identifier key for inventory entries, causingdep_00_ambiguities.csvanddep_01_master_data.csvto list only the basename when different files in subdirectories share the same name — changed toRelative_Path, with fallback toFilefor backward compatibility with older inventory files.clones.py: pairwise comparison calledread_logical_lines()once per file pair, re-parsing the same source file multiple times when it appeared in several ambiguity groups — added a per-run parse cache (_parse_cache) so each file is parsed at most once per pipeline run.inventory.py::write_inventory: skipped creatinginventory_report.csventirely when the source directory contained no Fortran units (if rows:guard) — violated the pipeline invariant; now always writes the file, with headers only when the inventory is empty.clones.py::analyze_clones: returnedNoneforreport_cloneswhen the inventory was empty, causingwrite_clonesto skip writing the output file — violated the pipeline invariant; now returns an empty list sowrite_clonesalways writesreport_clones.csv(headers only).cross_analysis.py::to_float(): crashed on nativeint/floatvalues forFan_In/Fan_Outwhen fed in-memory (non-CSV-string) data from the new library API — added anisinstance(val, str)guard before.strip().visual_graph.py: treated0(native int, from in-memory data) as falsy but"0"(CSV string) as truthy, silently dropping theFi=0label for units with zero Fan-In — changed to explicit!= ""comparisons.
Documentation
README.md: Requirements section now listsloguruinstead of claiming stdlib-only; Quick Start documents the new--quietsemantics and--no-log-file.
Tests
tests/test_output_manifest.py,tests/test_lib_pipeline.py: new — byte-for-byte regression gate and library-vs-CLI parity check.tests/test_parallel_helper.py,tests/test_parallel_parity.py: new —pmap()order/parity guarantees and workers=1 vs workers=2 output parity, scoped and full-pipeline.tests/test_logging_setup.py,tests/test_logging_behavior.py: new — raw loguru API assumptions,configure_logging()behavior, and CLI/library end-to-end logging behavior via subprocess.
v0.7.4 — 2026-07-31
Fixed
dependencies.py: always write all sixdep_*output files (dep_01throughdep_06) even when the corpus has no cross-file dependencies — previously the files were omitted for pure library/module corpora, causing downstream failures instructure_analysis,reachability, andclones; also movesdep_06_include_files.csvout of the incorrectly nestedfile_deps_mapblock.
Documentation
doc/scripts/dependencies.md: correct constant names in Configuration table (OUT_*→*_OUT); add “Always written” note to all sevendep_*outputs.
Tests
tests/fixtures_lib_only/+tests/test_empty_outputs.py: mini-corpus of two module-only.f90files and three tests verifying thatdep_00_ambiguities.csv,report_clones.csv, andreport_reachability.csvare written empty (headers only) for a pure-library corpus — exercises the code paths fixed in v0.7.2, v0.7.3, and v0.7.4.
v0.7.3 — 2026-07-31
Fixed
reachability.py: always writereport_reachability.csv(headers only if no entry points exist) — previously the file was omitted for pure library or module-only corpora that contain noPROGRAMorIMPLICIT-MAINunits.
Documentation
doc/scripts/reachability.md: note that the output file is always written and that downstream consumers (consolidate.py,cross_analysis.py) handle the empty-file case gracefully.
v0.7.2 — 2026-07-31
Fixed
dependencies.py: always writedep_00_ambiguities.csv(headers only if no duplicates found) — previously the file was omitted when the corpus had no units with the same name in multiple files, causingclones.pyto treat a valid zero-ambiguity run as a missing-file error.clones.py: treat absentdep_00_ambiguities.csvas zero ambiguities instead of aborting with an ERROR message; createreport_clones.csvempty in that case; fix typo_wrtite_empty_csv→_write_empty_csv.
Documentation
doc/scripts/dependencies.md: note thatdep_00_ambiguities.csvis always written, even when empty.doc/scripts/clones.md: clarify that absent or emptydep_00_ambiguities.csvis a valid outcome; note thatprioritization.pyhandles the empty case.
v0.7.1 — 2026-07-21
Fixed
sloc.py: replacedmax()with+=when accumulating per-file LOC in the console summary —max()returned only the largest unit per file, causing Total LOC to appear smaller than Physical SLOC (arithmetically impossible).executive_summary.py: group files byRelative_Pathinstead ofFile(basename) — basename collisions across subdirectories caused incorrect file counts and merged LOC for files sharing the same name in different directories.pipeline.py: validateFORT_SRCdirectory before executing steps — provides a clear error message when the source path is missing or invalid.inventory.py+ 9 analyzers (profiler,sloc,complexity,symbols,derived_types,equivalences,common_blocks,consolidate,dependencies): addRelative_Pathcolumn to inventory and thread it through all file-access and debug-CSV naming — fixes “file not found” errors for source files located in subdirectories.reader_logical.py: replace extension-only format detection with a content-based heuristic (detect_fortran_format) — correctly handles HPC code that uses.Fextension but is written in free-form F90+ syntax.
Documentation
README.md,doc/mi4d.md: document C preprocessor directive limitation (directives not evaluated; conditional branches always captured; macros and#includenot resolved).doc/scripts/reader_logical.md: documentdetect_fortran_format()and the two-phase format detection logic.doc/scripts/executive_summary.md: updateFilecolumn description infile_statistics.csvto reflect relative path usage.
v0.7.0 — 2026-04-02
SemVer adopted from this release. All releases from v0.7.0 onward follow Semantic Versioning. Prior releases (v0.1–v0.6) were tagged incrementally without a formal versioning scheme.
Added
- Complete English documentation: README rewrite (PyPI mindset, CLI usage, Known Limitations, Future Work),
CONTRIBUTING.md,doc/architecture.md,doc/interpretation.md,doc/mi4d.md(MI4D conceptual overview). doc/scripts/: 22 script reference files — all translated, renamed to English, and updated to reflect current column names and constants.uv.lock: lockfile for reproducible installs..gitignore: standard Python/editor exclusions.
Changed
- Complete English translation of all source code: CSV column names, output filenames, config constants, print statements, internal identifiers.
- SemVer versioning adopted (prior releases tagged as v0.1–v0.6).
- Development branch renamed:
desarrollo→dev.
Fixed
inventory.py:closed_unit.tipo→closed_unit.type(AttributeError blocking the full pipeline).profiler.py,sloc.py:FOLDER_CODE→CODE_PATH(ImportError).complexity.py,consolidate.py,sloc.py,executive_summary.py:r['Archivo']→r['File']in print/report generation (KeyError).
Removed
- All Spanish-language
.mddocumentation files (replaced by English versions).
v0.6 — TBD
Added
- Synthetic Fortran fixtures corpus for testing (
tests/fixtures/). - pytest test suite: 67 tests covering the full pipeline.
Fixed
inventory.py: detection of anonymous INTERFACE blocks.- Two parser bugs exposed by the fixtures corpus.
v0.5 — TBD
Changed
- Full restructure into a proper Python package (
forti4d/). - Source reorganized into
lib/andanalyzers/subdirectories. pyproject.tomladded;forti4dCLI entry point configured.
v0.4 — TBD
Added
html_report.py: self-contained HTML report from prioritization data (step 19 — pipeline grows to 19 steps).- INCLUDE directive tracking in
profiler.pyandinventory.py.
v0.3 — TBD
Changed
- E4 scope signals (
Implicit_None,Has_Equiv) integrated intocross_analysis.pymigration strategy assignment andprioritization.pyrisk scoring.
v0.2 — TBD
Added
symbols.py(step 10): variable, parameter, and implicit symbol extraction.derived_types.py(step 11): derived TYPE definition extraction.equivalences.py(step 12): EQUIVALENCE aliasing groups via union-find.- E4 scope risk signal (
Score_E4) inprioritization.py. - EQUIVALENCE summary columns in
consolidate.py. - Pipeline grows to 18 steps.
v0.1 — TBD
Added
- Initial 15-step static analysis pipeline for Fortran (F77/F90/F95).
- Core scripts:
inventory.py,dependencies.py,profiler.py,block_analysis.py,structure_analysis.py,cross_analysis.py,executive_summary.py,complexity.py,common_blocks.py,sloc.py,clones.py,consolidate.py,visual_graph.py,prioritization.py. pipeline.py: single-command orchestrator with--from,--only,--skip,--quietflags.config.py: centralized path configuration viaFORT_SRC/FORT_OUTenvironment variables.reader_logical.py: F77 fixed-form and F90 free-form continuation handling.